diff --git a/frontend/app/profile/page.tsx b/frontend/app/profile/page.tsx new file mode 100644 index 00000000..7722b3e1 --- /dev/null +++ b/frontend/app/profile/page.tsx @@ -0,0 +1,127 @@ +'use client' + +import { useEffect, useState } from 'react' +import { useForm } from 'react-hook-form' +import { z } from 'zod' +import { zodResolver } from '@hookform/resolvers/zod' +import Head from 'next/head' + +const profileSchema = z.object({ + name: z.string().min(1, 'Name is required'), + email: z.string().email('Invalid email'), +}) + +type ProfileFormData = z.infer + +type UserProfile = { + id: string + name: string + email: string + walletAddress: string + accountType: string + dateJoined: string +} + +export default function ProfilePage() { + const [user, setUser] = useState(null) + const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) + + const { + register, + handleSubmit, + formState: { errors }, + reset, + } = useForm({ + resolver: zodResolver(profileSchema), + }) + + // Fetch user data + useEffect(() => { + const fetchUser = async () => { + try { + const res = await fetch('/api/users/me') + if (!res.ok) throw new Error('Failed to fetch user data') + const data = await res.json() + setUser(data) + reset({ name: data.name, email: data.email }) + } catch (err) { + setError((err as Error).message) + } finally { + setLoading(false) + } + } + + fetchUser() + }, [reset]) + + const onSubmit = async (data: ProfileFormData) => { + try { + const res = await fetch('/api/users/me', { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(data), + }) + if (!res.ok) throw new Error('Failed to update profile') + alert('Profile updated!') + } catch (err) { + alert((err as Error).message) + } + } + + if (loading) return

Loading...

+ if (error) return

{error}

+ if (!user) return null + + return ( +
+ + User Profile + + +

User Profile

+ + +
+

Full Name: {user.name}

+

Email: {user.email}

+

Wallet Address: {user.walletAddress}

+

Account Type: {user.accountType}

+

Date Joined: {new Date(user.dateJoined).toLocaleDateString()}

+
+ + +
+

Edit Profile

+
+
+ + + {errors.name &&

{errors.name.message}

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

{errors.email.message}

} +
+ + +
+
+
+ ) +} diff --git a/frontend/package.json b/frontend/package.json index d1b6b9cb..06f31941 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -26,7 +26,9 @@ "sonner": "^2.0.7", "tailwind-merge": "^3.3.1", "zod": "^4.1.11", - "zustand": "^5.0.8" + "zustand": "^5.0.8", + "react-hook-form": "^7.49.2", + "@hookform/resolvers": "^3.3.4" }, "devDependencies": { "@eslint/eslintrc": "^3",