File size: 5,500 Bytes
5c876be | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | import { useState, useEffect, useCallback } from 'react';
import { eq } from 'drizzle-orm';
import { useDatabase } from './useDatabase';
import { currentUser } from '../db/schema';
// βββ Types βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
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>;
}
// βββ Hook ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
export function useCurrentUser(): UseCurrentUserReturn {
const { db } = useDatabase();
const [user, setUser] = useState<CurrentUserData | null>(null);
const [loading, setLoading] = useState(true);
// ββ Load user ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
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]);
// ββ Generic field update βββββββββββββββββββββββββββββββββββββββββββββββββββββ
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],
);
// ββ Update role (stored in appState or custom column) ββββββββββββββββββββββββ
const updateRole = useCallback(
async (_role: 'rider' | 'driver') => {
// Role can be stored in app_state or extended current_user table
// For now we update a field on current_user if the column exists
await updateField('role', _role);
},
[updateField],
);
// ββ Toggle online status βββββββββββββββββββββββββββββββββββββββββββββββββββββ
const toggleOnline = useCallback(async () => {
await updateField('online', !user?.online);
}, [updateField, user]);
// ββ Bulk profile update ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
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],
);
// ββ Dark mode preference βββββββββββββββββββββββββββββββββββββββββββββββββββββ
const setDarkMode = useCallback(
async (isDark: boolean) => {
await updateField('darkMode', isDark);
},
[updateField],
);
// ββ Notifications preference βββββββββββββββββββββββββββββββββββββββββββββββββ
const setNotificationsOn = useCallback(
async (enabled: boolean) => {
await updateField('notificationsOn', enabled);
},
[updateField],
);
return {
user,
loading,
refresh: loadUser,
updateField,
updateRole,
toggleOnline,
updateProfile,
setDarkMode,
setNotificationsOn,
};
}
|