diff --git a/src/app/admin/settings/user/page.tsx b/src/app/admin/settings/user/page.tsx index 0a365a2..54a04a3 100644 --- a/src/app/admin/settings/user/page.tsx +++ b/src/app/admin/settings/user/page.tsx @@ -16,8 +16,9 @@ import { import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { useToast } from "@/hooks/use-toast"; -import { useEffect, useTransition } from "react"; +import { useEffect, useState, useTransition } from "react"; import { getUser, updateUser } from "@/lib/actions/user"; +import { Skeleton } from "@/components/ui/skeleton"; const userProfileSchema = z.object({ name: z.string().min(1, "Name is required"), @@ -34,6 +35,7 @@ type UserProfileFormValues = z.infer; export default function UserProfilePage() { const { toast } = useToast(); const [isSaving, startSavingTransition] = useTransition(); + const [isLoading, setIsLoading] = useState(true); const { register, @@ -52,6 +54,7 @@ export default function UserProfilePage() { useEffect(() => { const fetchUser = async () => { + setIsLoading(true); const user = await getUser(); if (user) { reset({ @@ -60,10 +63,17 @@ export default function UserProfilePage() { password: "", confirmPassword: "" }); + } else { + toast({ + title: "Error", + description: "Could not load user profile.", + variant: "destructive", + }); } + setIsLoading(false); }; fetchUser(); - }, [reset]); + }, [reset, toast]); const onSubmit: SubmitHandler = (data) => { startSavingTransition(async () => { @@ -99,16 +109,31 @@ export default function UserProfilePage() { -
- - - {errors.name &&

{errors.name.message}

} -
-
- - - {errors.email &&

{errors.email.message}

} -
+ {isLoading ? ( + <> +
+ + +
+
+ + +
+ + ) : ( + <> +
+ + + {errors.name &&

{errors.name.message}

} +
+
+ + + {errors.email &&

{errors.email.message}

} +
+ + )}
@@ -121,7 +146,7 @@ export default function UserProfilePage() {
- diff --git a/src/lib/actions/user.ts b/src/lib/actions/user.ts index 8f0e681..6aab8d0 100644 --- a/src/lib/actions/user.ts +++ b/src/lib/actions/user.ts @@ -2,9 +2,9 @@ 'use server'; import db from '@/lib/db'; -import type { User as DbUser } from '@/lib/types'; import { z } from 'zod'; import { auth } from '@/app/api/auth/[...nextauth]/route'; +import { User as DbUser } from '@/lib/types'; const UserUpdateSchema = z.object({ name: z.string().min(1, 'Name is required'), @@ -12,18 +12,26 @@ const UserUpdateSchema = z.object({ password: z.string().optional(), }); -type UserWithId = DbUser & { id: string }; +type UserForClient = { + id: string; + name: string; + email: string; +} -export async function getUser(): Promise { +export async function getUser(): Promise { const session = await auth(); if (!session?.user?.id) { + console.error('getUser: Not authenticated'); return null; } try { const stmt = db.prepare('SELECT id, name, email FROM users WHERE id = ?'); const user = stmt.get(session.user.id) as DbUser | undefined; - if (!user) return null; - return { ...user, id: user.id.toString() }; + if (!user) { + console.error('getUser: User not found in DB'); + return null; + } + return { id: user.id.toString(), name: user.name, email: user.email }; } catch (error) { console.error('Failed to get user:', error); return null; @@ -50,6 +58,7 @@ export async function updateUser( try { if (password && password.trim().length > 0) { + // In a real app, you would hash the password here const stmt = db.prepare( 'UPDATE users SET name = ?, email = ?, password = ? WHERE id = ?' );