Add logout functionality and username display
- Added logout button at bottom of sidebar - Display username with avatar (first letter) - Clear all credentials and state on logout - Username persists from saved credentials - Clean logout flow returns to login screen
This commit is contained in:
16
src/App.tsx
16
src/App.tsx
@@ -13,6 +13,7 @@ function App() {
|
|||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
const [showFavoritesOnly, setShowFavoritesOnly] = useState(false);
|
const [showFavoritesOnly, setShowFavoritesOnly] = useState(false);
|
||||||
const [fontSize] = useState(14);
|
const [fontSize] = useState(14);
|
||||||
|
const [username, setUsername] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const savedServer = localStorage.getItem('serverURL');
|
const savedServer = localStorage.getItem('serverURL');
|
||||||
@@ -26,6 +27,7 @@ function App() {
|
|||||||
password: savedPassword,
|
password: savedPassword,
|
||||||
});
|
});
|
||||||
setApi(apiInstance);
|
setApi(apiInstance);
|
||||||
|
setUsername(savedUsername);
|
||||||
setIsLoggedIn(true);
|
setIsLoggedIn(true);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
@@ -58,9 +60,21 @@ function App() {
|
|||||||
|
|
||||||
const apiInstance = new NextcloudAPI({ serverURL, username, password });
|
const apiInstance = new NextcloudAPI({ serverURL, username, password });
|
||||||
setApi(apiInstance);
|
setApi(apiInstance);
|
||||||
|
setUsername(username);
|
||||||
setIsLoggedIn(true);
|
setIsLoggedIn(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
localStorage.removeItem('serverURL');
|
||||||
|
localStorage.removeItem('username');
|
||||||
|
localStorage.removeItem('password');
|
||||||
|
setApi(null);
|
||||||
|
setUsername('');
|
||||||
|
setNotes([]);
|
||||||
|
setSelectedNoteId(null);
|
||||||
|
setIsLoggedIn(false);
|
||||||
|
};
|
||||||
|
|
||||||
const handleCreateNote = async () => {
|
const handleCreateNote = async () => {
|
||||||
if (!api) return;
|
if (!api) return;
|
||||||
try {
|
try {
|
||||||
@@ -136,6 +150,8 @@ function App() {
|
|||||||
onCreateNote={handleCreateNote}
|
onCreateNote={handleCreateNote}
|
||||||
onDeleteNote={handleDeleteNote}
|
onDeleteNote={handleDeleteNote}
|
||||||
onSync={syncNotes}
|
onSync={syncNotes}
|
||||||
|
onLogout={handleLogout}
|
||||||
|
username={username}
|
||||||
searchText={searchText}
|
searchText={searchText}
|
||||||
onSearchChange={setSearchText}
|
onSearchChange={setSearchText}
|
||||||
showFavoritesOnly={showFavoritesOnly}
|
showFavoritesOnly={showFavoritesOnly}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ interface NotesListProps {
|
|||||||
onCreateNote: () => void;
|
onCreateNote: () => void;
|
||||||
onDeleteNote: (note: Note) => void;
|
onDeleteNote: (note: Note) => void;
|
||||||
onSync: () => void;
|
onSync: () => void;
|
||||||
|
onLogout: () => void;
|
||||||
|
username: string;
|
||||||
searchText: string;
|
searchText: string;
|
||||||
onSearchChange: (text: string) => void;
|
onSearchChange: (text: string) => void;
|
||||||
showFavoritesOnly: boolean;
|
showFavoritesOnly: boolean;
|
||||||
@@ -21,6 +23,8 @@ export function NotesList({
|
|||||||
onCreateNote,
|
onCreateNote,
|
||||||
onDeleteNote,
|
onDeleteNote,
|
||||||
onSync,
|
onSync,
|
||||||
|
onLogout,
|
||||||
|
username,
|
||||||
searchText,
|
searchText,
|
||||||
onSearchChange,
|
onSearchChange,
|
||||||
showFavoritesOnly,
|
showFavoritesOnly,
|
||||||
@@ -168,6 +172,27 @@ export function NotesList({
|
|||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* User Info and Logout */}
|
||||||
|
<div className="border-t border-gray-200 p-4 bg-white">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center space-x-2 min-w-0">
|
||||||
|
<div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-white font-semibold flex-shrink-0">
|
||||||
|
{username.charAt(0).toUpperCase()}
|
||||||
|
</div>
|
||||||
|
<span className="text-sm text-gray-700 truncate font-medium">{username}</span>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={onLogout}
|
||||||
|
className="p-2 hover:bg-gray-100 rounded-lg transition-colors flex-shrink-0"
|
||||||
|
title="Logout"
|
||||||
|
>
|
||||||
|
<svg className="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user