| import { useState, useEffect, useCallback } from 'react'; |
| import { eq } from 'drizzle-orm'; |
| import { useDatabase } from './useDatabase'; |
| import { currentUser } from '../db/schema'; |
|
|
| |
|
|
| interface CurrentUserData { |
| id: string; |
| phone: string; |
| fullName: string; |
| email: string | null; |
| avatarUrl: string | null; |
| gender: 'male' | 'female' | 'other' | null; |
| homeAddress: string | null; |
| workAddress: string | null; |
| preferredLanguage: string | null; |
| rating: number | null; |
| totalRides: number | null; |
| verified: boolean | null; |
| createdAt: string | null; |
| updatedAt: string | null; |
| } |
|
|
| interface UseCurrentUserReturn { |
| user: CurrentUserData | null; |
| loading: boolean; |
| refresh: () => Promise<void>; |
| updateField: (field: string, value: unknown) => Promise<void>; |
| updateRole: (role: 'rider' | 'driver') => Promise<void>; |
| toggleOnline: () => Promise<void>; |
| updateProfile: (data: Partial<Omit<CurrentUserData, 'id' | 'createdAt'>>) => Promise<void>; |
| setDarkMode: (isDark: boolean) => Promise<void>; |
| setNotificationsOn: (enabled: boolean) => Promise<void>; |
| } |
|
|
| |
|
|
| export function useCurrentUser(): UseCurrentUserReturn { |
| const { db } = useDatabase(); |
| const [user, setUser] = useState<CurrentUserData | null>(null); |
| const [loading, setLoading] = useState(true); |
|
|
| |
|
|
| const loadUser = useCallback(async () => { |
| try { |
| setLoading(true); |
| const rows = await db.select().from(currentUser).limit(1).all(); |
| if (rows.length > 0) { |
| setUser(rows[0] as CurrentUserData); |
| } else { |
| setUser(null); |
| } |
| } catch (error) { |
| console.error('[useCurrentUser] Failed to load user:', error); |
| setUser(null); |
| } finally { |
| setLoading(false); |
| } |
| }, [db]); |
|
|
| useEffect(() => { |
| loadUser(); |
| }, [loadUser]); |
|
|
| |
|
|
| const updateField = useCallback( |
| async (field: string, value: unknown) => { |
| if (!user) return; |
|
|
| try { |
| await db |
| .update(currentUser) |
| .set({ [field]: value, updatedAt: new Date().toISOString() } as never) |
| .where(eq(currentUser.id, user.id)) |
| .run(); |
|
|
| await loadUser(); |
| } catch (error) { |
| console.error(`[useCurrentUser] Failed to update ${field}:`, error); |
| } |
| }, |
| [db, user, loadUser], |
| ); |
|
|
| |
|
|
| const updateRole = useCallback( |
| async (_role: 'rider' | 'driver') => { |
| |
| |
| await updateField('role', _role); |
| }, |
| [updateField], |
| ); |
|
|
| |
|
|
| const toggleOnline = useCallback(async () => { |
| await updateField('online', !user?.online); |
| }, [updateField, user]); |
|
|
| |
|
|
| const updateProfile = useCallback( |
| async ( |
| data: Partial<Omit<CurrentUserData, 'id' | 'createdAt'>>, |
| ) => { |
| if (!user) return; |
|
|
| try { |
| await db |
| .update(currentUser) |
| .set({ |
| ...data, |
| updatedAt: new Date().toISOString(), |
| } as never) |
| .where(eq(currentUser.id, user.id)) |
| .run(); |
|
|
| await loadUser(); |
| } catch (error) { |
| console.error('[useCurrentUser] Failed to update profile:', error); |
| } |
| }, |
| [db, user, loadUser], |
| ); |
|
|
| |
|
|
| const setDarkMode = useCallback( |
| async (isDark: boolean) => { |
| await updateField('darkMode', isDark); |
| }, |
| [updateField], |
| ); |
|
|
| |
|
|
| const setNotificationsOn = useCallback( |
| async (enabled: boolean) => { |
| await updateField('notificationsOn', enabled); |
| }, |
| [updateField], |
| ); |
|
|
| return { |
| user, |
| loading, |
| refresh: loadUser, |
| updateField, |
| updateRole, |
| toggleOnline, |
| updateProfile, |
| setDarkMode, |
| setNotificationsOn, |
| }; |
| } |
|
|