feat(ui): add Button, Modal, Spinner, Toast, and Tooltip components with styles
All checks were successful
Build and Release / build-and-release (push) Successful in 13m12s

- Implemented Button component with various props for customization.
- Created Modal component with header, content, and footer subcomponents.
- Added Spinner component for loading indicators.
- Developed Toast component for displaying notifications.
- Introduced Tooltip component for contextual hints with keyboard shortcuts.
- Added corresponding CSS modules for styling each component.
- Updated index file to export new components.
- Configured TypeScript settings for the UI package.
This commit is contained in:
Bryan1029384756
2026-04-14 09:02:14 -05:00
parent 9ef839938e
commit b7a4cf4ce8
376 changed files with 52619 additions and 167641 deletions

View File

@@ -0,0 +1,45 @@
import { useCallback } from 'react';
import { usePlatform } from '../platform';
/**
* useLogout — wipes all client-side auth state and hard-reloads the
* app so AuthGuard lands on /login with a clean React tree (no stale
* Convex subscriptions, no lingering in-memory keys). Callers don't
* need to navigate themselves — the reload does it.
*
* Storage cleared (mirrors what AuthGuard hydrates on restore):
* - localStorage: userId, username, publicKey, userPrefs_<userId>
* - sessionStorage: privateKey, signingKey, masterKey, searchDbKey
* - platform.session: full encrypted blob (Electron safeStorage / web localStorage)
*/
export function useLogout(): () => Promise<void> {
const { session } = usePlatform();
return useCallback(async () => {
try {
await session?.clear?.();
} catch (err) {
console.warn('Failed to clear platform session:', err);
}
try {
const userId = localStorage.getItem('userId');
localStorage.removeItem('userId');
localStorage.removeItem('username');
localStorage.removeItem('publicKey');
if (userId) localStorage.removeItem(`userPrefs_${userId}`);
sessionStorage.removeItem('privateKey');
sessionStorage.removeItem('signingKey');
sessionStorage.removeItem('masterKey');
sessionStorage.removeItem('searchDbKey');
} catch (err) {
console.warn('Failed to clear auth storage:', err);
}
// Hard reload: dumps the React tree, LiveKit rooms, Convex
// client, and any open audio/video contexts. AuthGuard then
// mounts fresh with empty storage and redirects to /login.
window.location.reload();
}, [session]);
}