From 9a61e234c70e583c5f876dc09f1ecf400cac693c Mon Sep 17 00:00:00 2001 From: ShivaGupta-14 Date: Wed, 29 Oct 2025 00:34:38 +0530 Subject: [PATCH 1/3] feat: Implement settings page functionality This commit introduces the initial implementation of the user settings page, providing core account management features and improving the UI. Key features include: - Users can now update their display name and select a profile avatar from the account section. - The folder list is now restricted to an initial view of 6 items, with a 'View More' button for more. --- frontend/src/pages/SettingsPage/Settings.tsx | 52 ++++-- .../components/AccountSettingsCard.tsx | 127 ++++++++++++++ .../components/FolderManagementCard.tsx | 158 ++++++++++-------- 3 files changed, 256 insertions(+), 81 deletions(-) create mode 100644 frontend/src/pages/SettingsPage/components/AccountSettingsCard.tsx diff --git a/frontend/src/pages/SettingsPage/Settings.tsx b/frontend/src/pages/SettingsPage/Settings.tsx index fdc84cd8f..e6fe734ad 100644 --- a/frontend/src/pages/SettingsPage/Settings.tsx +++ b/frontend/src/pages/SettingsPage/Settings.tsx @@ -1,28 +1,58 @@ -import React from 'react'; +import React, { useState } from 'react'; // Import modular components import FolderManagementCard from './components/FolderManagementCard'; import UserPreferencesCard from './components/UserPreferencesCard'; import ApplicationControlsCard from './components/ApplicationControlsCard'; +import AccountSettingsCard from './components/AccountSettingsCard'; /** * Settings page component * Acts as an orchestrator for the settings sections */ const Settings: React.FC = () => { + const [activeTab, setActiveTab] = useState('general'); + const baseTabStyle = 'px-4 py-2 rounded-md font-medium transition-colors'; + const activeTabStyle = 'bg-background text-foreground'; + const inactiveTabStyle = + 'text-muted-foreground hover:bg-gray-100 dark:hover:bg-gray-800'; return ( -
-
- {/* Folder Management */} - + <> +

Settings

+
+
+
+ + +
+
+ {activeTab === 'general' && ( + <> + + + + + )} - {/* User Preferences */} - - - {/* Application Controls */} - + {activeTab === 'account' && ( + <> + + + )} +
+
-
+ ); }; diff --git a/frontend/src/pages/SettingsPage/components/AccountSettingsCard.tsx b/frontend/src/pages/SettingsPage/components/AccountSettingsCard.tsx new file mode 100644 index 000000000..9e7604f0d --- /dev/null +++ b/frontend/src/pages/SettingsPage/components/AccountSettingsCard.tsx @@ -0,0 +1,127 @@ +import React, { useState, useEffect } from 'react'; +import { useDispatch } from 'react-redux'; +import { Label } from '@/components/ui/label'; +import { Input } from '@/components/ui/input'; +import { setAvatar, setName } from '@/features/onboardingSlice'; +import { User } from 'lucide-react'; +import SettingsCard from './SettingsCard'; +import { avatars } from '@/constants/avatars'; +import { CardContent } from '@/components/ui/card'; +import { Button } from '@/components/ui/button'; + +const AccountSettingsCard: React.FC = () => { + const dispatch = useDispatch(); + const [name, setLocalName] = useState( + () => localStorage.getItem('name') || '', + ); + const [selectedAvatar, setLocalAvatar] = useState( + () => localStorage.getItem('avatar') || '', + ); + const [nameError, setNameError] = useState(false); + + useEffect(() => { + const savedName = localStorage.getItem('name'); + const savedAvatar = localStorage.getItem('avatar'); + if (savedName) setLocalName(savedName); + if (savedAvatar) setLocalAvatar(savedAvatar); + }, []); + + const handleAvatarSelect = (avatar: string) => { + setLocalAvatar(avatar); + }; + + const handleNameChange = (value: string) => { + setLocalName(value); + if (nameError) { + setNameError(false); + } + }; + + const handleNextClick = () => { + if (!name.trim()) { + setNameError(true); + return; + } + + setNameError(false); + if (!selectedAvatar) return; + + dispatch(setName(name)); + dispatch(setAvatar(selectedAvatar)); + localStorage.setItem('name', name); + localStorage.setItem('avatar', selectedAvatar); + }; + + return ( + + +
+ {/* Name Change */} +
+ + handleNameChange(e.target.value)} + className={`h-10 w-full text-sm placeholder:text-sm ${ + nameError + ? 'border-red-500 placeholder:text-red-500/80 focus-visible:ring-red-500' + : '' + }`} + /> +
+ + {/* Avatar Section */} +
+ +
+ {avatars.map((avatar) => { + const isSelected = selectedAvatar === avatar; + return ( + + ); + })} +
+
+
+ + {/* Save Changes Button */} + +
+
+ ); +}; + +export default AccountSettingsCard; diff --git a/frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx b/frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx index db4b029fa..711a5f0be 100644 --- a/frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx +++ b/frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Folder, Trash2, Check } from 'lucide-react'; import { Switch } from '@/components/ui/switch'; @@ -29,6 +29,12 @@ const FolderManagementCard: React.FC = () => { (state: RootState) => state.folders.taggingStatus, ); + const [visibleFoldersCount, setVisibleFoldersCount] = useState(6); + + const handleViewMore = () => { + setVisibleFoldersCount((prevCount) => prevCount + 5); + }; + return ( { > {folders.length > 0 ? (
- {folders.map((folder: FolderDetails, index: number) => ( -
-
-
-
- - - {folder.folder_path} - + {folders + .slice(0, visibleFoldersCount) + .map((folder: FolderDetails, index: number) => ( +
+
+
+
+ + + {folder.folder_path} + +
-
-
-
- - AI Tagging - - toggleAITagging(folder)} - disabled={ - enableAITaggingPending || disableAITaggingPending - } - /> -
+
+
+ + AI Tagging + + toggleAITagging(folder)} + disabled={ + enableAITaggingPending || disableAITaggingPending + } + /> +
- + +
-
- {folder.AI_Tagging && ( -
-
- AI Tagging Progress - +
+ AI Tagging Progress + = 100 + ? 'flex items-center gap-1 text-green-500' + : 'text-muted-foreground' + } + > + {(taggingStatus[folder.folder_id]?.tagging_percentage ?? + 0) >= 100 && } + {Math.round( + taggingStatus[folder.folder_id]?.tagging_percentage ?? + 0, + )} + % + +
+ = 100 - ? 'flex items-center gap-1 text-green-500' - : 'text-muted-foreground' + ? 'bg-green-500' + : 'bg-blue-500' } - > - {(taggingStatus[folder.folder_id]?.tagging_percentage ?? - 0) >= 100 && } - {Math.round( - taggingStatus[folder.folder_id]?.tagging_percentage ?? - 0, - )} - % -
+ />
- = 100 - ? 'bg-green-500' - : 'bg-blue-500' - } - /> -
- )} -
- ))} + )} +
+ ))}
) : (
@@ -128,6 +136,16 @@ const FolderManagementCard: React.FC = () => {
)} + {folders.length > visibleFoldersCount && ( + + )} +
From 36ef59c7cf8c10523482709c339bbdb666eacec5 Mon Sep 17 00:00:00 2001 From: Shiva Gupta Date: Wed, 29 Oct 2025 01:22:39 +0530 Subject: [PATCH 2/3] Update AccountSettingsCard.tsx --- .../SettingsPage/components/AccountSettingsCard.tsx | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/frontend/src/pages/SettingsPage/components/AccountSettingsCard.tsx b/frontend/src/pages/SettingsPage/components/AccountSettingsCard.tsx index 9e7604f0d..4cfe11de4 100644 --- a/frontend/src/pages/SettingsPage/components/AccountSettingsCard.tsx +++ b/frontend/src/pages/SettingsPage/components/AccountSettingsCard.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; // No need for useEffect import { useDispatch } from 'react-redux'; import { Label } from '@/components/ui/label'; import { Input } from '@/components/ui/input'; @@ -19,12 +19,7 @@ const AccountSettingsCard: React.FC = () => { ); const [nameError, setNameError] = useState(false); - useEffect(() => { - const savedName = localStorage.getItem('name'); - const savedAvatar = localStorage.getItem('avatar'); - if (savedName) setLocalName(savedName); - if (savedAvatar) setLocalAvatar(savedAvatar); - }, []); + // The redundant useEffect has been removed. const handleAvatarSelect = (avatar: string) => { setLocalAvatar(avatar); @@ -37,7 +32,7 @@ const AccountSettingsCard: React.FC = () => { } }; - const handleNextClick = () => { + const handleSave = () => { if (!name.trim()) { setNameError(true); return; @@ -114,7 +109,7 @@ const AccountSettingsCard: React.FC = () => { {/* Save Changes Button */}