diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 2d5cbb1..5480831 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -4,6 +4,8 @@ import { useAuth, useNetworkStatus } from '@/hooks'; import { useAuth as useAuthContext } from '@/contexts/useAuth'; import { EVerificationStatus } from '@/types/identity'; import { useForum } from '@/contexts/useForum'; +import { localDatabase } from '@/lib/database/LocalDatabase'; +import { DelegationFullStatus } from '@/lib/delegation'; import { Button } from '@/components/ui/button'; import { @@ -31,7 +33,8 @@ import { useUserDisplay } from '@/hooks'; const Header = () => { const { verificationStatus } = useAuth(); const { getDelegationStatus } = useAuthContext(); - const delegationInfo = getDelegationStatus(); + const [delegationInfo, setDelegationInfo] = + useState(null); const networkStatus = useNetworkStatus(); const location = useLocation(); const { toast } = useToast(); @@ -57,28 +60,38 @@ const Header = () => { // ✅ Get display name from enhanced hook const { displayName } = useUserDisplay(address || ''); - // Use sessionStorage to persist wizard state across navigation - const getHasShownWizard = () => { + // Load delegation status + React.useEffect(() => { + getDelegationStatus().then(setDelegationInfo).catch(console.error); + }, [getDelegationStatus]); + + // Use LocalDatabase to persist wizard state across navigation + const getHasShownWizard = async (): Promise => { try { - return sessionStorage.getItem('hasShownWalletWizard') === 'true'; + const value = await localDatabase.loadUIState('hasShownWalletWizard'); + return value === true; } catch { return false; } }; - const setHasShownWizard = (value: boolean) => { + const setHasShownWizard = async (value: boolean): Promise => { try { - sessionStorage.setItem('hasShownWalletWizard', value.toString()); - } catch { - // Fallback if sessionStorage is not available + await localDatabase.storeUIState('hasShownWalletWizard', value); + } catch (e) { + console.error('Failed to store wizard state', e); } }; // Auto-open wizard when wallet connects for the first time React.useEffect(() => { - if (isConnected && !getHasShownWizard()) { - setWalletWizardOpen(true); - setHasShownWizard(true); + if (isConnected) { + getHasShownWizard().then(hasShown => { + if (!hasShown) { + setWalletWizardOpen(true); + setHasShownWizard(true).catch(console.error); + } + }); } }, [isConnected]); @@ -88,7 +101,7 @@ const Header = () => { const handleDisconnect = async () => { await disconnect(); - setHasShownWizard(false); // Reset so wizard can show again on next connection + await setHasShownWizard(false); // Reset so wizard can show again on next connection toast({ title: 'Wallet Disconnected', description: 'Your wallet has been disconnected successfully.', @@ -99,7 +112,7 @@ const Header = () => { if (!isConnected) return 'Connect Wallet'; if (verificationStatus === EVerificationStatus.ENS_ORDINAL_VERIFIED) { - return delegationInfo.isValid ? 'Ready to Post' : 'Delegation Expired'; + return delegationInfo?.isValid ? 'Ready to Post' : 'Delegation Expired'; } else if (verificationStatus === EVerificationStatus.WALLET_CONNECTED) { return 'Verified (Read-only)'; } else { @@ -112,7 +125,7 @@ const Header = () => { if ( verificationStatus === EVerificationStatus.ENS_ORDINAL_VERIFIED && - delegationInfo.isValid + delegationInfo?.isValid ) { return 'text-green-400'; } else if (verificationStatus === EVerificationStatus.WALLET_CONNECTED) { @@ -131,7 +144,7 @@ const Header = () => { if ( verificationStatus === EVerificationStatus.ENS_ORDINAL_VERIFIED && - delegationInfo.isValid + delegationInfo?.isValid ) { return ; } else if (verificationStatus === EVerificationStatus.WALLET_CONNECTED) { @@ -244,7 +257,7 @@ const Header = () => {
Address: {address?.slice(0, 8)}...
Status: {getAccountStatusText()}
- {delegationInfo.timeRemaining && ( + {delegationInfo?.timeRemaining && (
Delegation: {delegationInfo.timeRemaining} remaining
diff --git a/src/components/examples/HookDemoComponent.tsx b/src/components/examples/HookDemoComponent.tsx index 44834f2..2e5870a 100644 --- a/src/components/examples/HookDemoComponent.tsx +++ b/src/components/examples/HookDemoComponent.tsx @@ -1,3 +1,4 @@ +import React, { useState, useEffect } from 'react'; import { useForumData, useAuth, @@ -10,6 +11,7 @@ import { useForumSelectors, } from '@/hooks'; import { useAuth as useAuthContext } from '@/contexts/useAuth'; +import { DelegationFullStatus } from '@/lib/delegation'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; @@ -24,6 +26,12 @@ export function HookDemoComponent() { const forumData = useForumData(); const auth = useAuth(); const { getDelegationStatus } = useAuthContext(); + const [delegationStatus, setDelegationStatus] = useState(null); + + // Load delegation status + useEffect(() => { + getDelegationStatus().then(setDelegationStatus).catch(console.error); + }, [getDelegationStatus]); // Derived hooks for specific data const userVotes = useUserVotes(); @@ -137,7 +145,7 @@ export function HookDemoComponent() {
Delegation Active:{' '} - {getDelegationStatus().isValid ? 'Yes' : 'No'} + {delegationStatus?.isValid ? 'Yes' : 'No'}
diff --git a/src/components/ui/delegation-step.tsx b/src/components/ui/delegation-step.tsx index 74feab5..0c97535 100644 --- a/src/components/ui/delegation-step.tsx +++ b/src/components/ui/delegation-step.tsx @@ -1,9 +1,9 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { Button } from './button'; import { useAuth, useAuthActions } from '@/hooks'; import { useAuth as useAuthContext } from '@/contexts/useAuth'; import { CheckCircle, AlertCircle, Trash2 } from 'lucide-react'; -import { DelegationDuration } from '@/lib/delegation'; +import { DelegationDuration, DelegationFullStatus } from '@/lib/delegation'; interface DelegationStepProps { onComplete: () => void; @@ -20,9 +20,15 @@ export function DelegationStep({ }: DelegationStepProps) { const { currentUser, isAuthenticating } = useAuth(); const { getDelegationStatus } = useAuthContext(); - const delegationInfo = getDelegationStatus(); + const [delegationInfo, setDelegationInfo] = + useState(null); const { delegateKey, clearDelegation } = useAuthActions(); + // Load delegation status + useEffect(() => { + getDelegationStatus().then(setDelegationInfo).catch(console.error); + }, [getDelegationStatus]); + const [selectedDuration, setSelectedDuration] = React.useState('7days'); const [delegationResult, setDelegationResult] = React.useState<{ @@ -128,19 +134,19 @@ export function DelegationStep({
{/* Status */}
- {delegationInfo.isValid ? ( + {delegationInfo?.isValid ? ( ) : ( )} - {delegationInfo.isValid ? 'Delegated' : 'Required'} + {delegationInfo?.isValid ? 'Delegated' : 'Required'} - {delegationInfo.isValid && delegationInfo.timeRemaining && ( + {delegationInfo?.isValid && delegationInfo?.timeRemaining && ( {delegationInfo.timeRemaining} remaining @@ -148,7 +154,7 @@ export function DelegationStep({
{/* Duration Selection */} - {!delegationInfo.isValid && ( + {!delegationInfo?.isValid && (