161 lines
7.9 KiB
TypeScript
161 lines
7.9 KiB
TypeScript
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
|
import { Save } from 'lucide-react';
|
|
import { useToast } from '@/hooks/use-toast';
|
|
import { Textarea } from '@/components/ui/textarea';
|
|
import { useI18n } from '@/locales/client';
|
|
|
|
const mockUserProfile = {
|
|
name: 'Alice Wonderland',
|
|
email: 'alice@example.com',
|
|
avatarUrl: 'https://placehold.co/100x100.png?text=AW',
|
|
bio: "Lover of imaginative play and sharing joy. I have a collection of classic storybooks and dress-up costumes.",
|
|
phone: '555-123-4567',
|
|
location: 'Springfield Gardens, USA',
|
|
};
|
|
|
|
export default function ProfilePage() {
|
|
const { toast } = useToast();
|
|
const t = useI18n();
|
|
|
|
const [name, setName] = useState(mockUserProfile.name);
|
|
const [email, setEmail] = useState(mockUserProfile.email);
|
|
const [avatarUrl, setAvatarUrl] = useState(mockUserProfile.avatarUrl);
|
|
const [bio, setBio] = useState(mockUserProfile.bio);
|
|
const [phone, setPhone] = useState(mockUserProfile.phone);
|
|
const [location, setLocation] = useState(mockUserProfile.location);
|
|
const [currentPassword, setCurrentPassword] = useState('');
|
|
const [newPassword, setNewPassword] = useState('');
|
|
const [confirmNewPassword, setConfirmNewPassword] = useState('');
|
|
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [isPasswordLoading, setIsPasswordLoading] = useState(false);
|
|
|
|
const handleProfileUpdate = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
setIsLoading(true);
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
console.log("Updating profile:", { name, avatarUrl, bio, phone, location });
|
|
toast({ title: "Profile Updated", description: "Your profile information has been saved." }); // Translate
|
|
setIsLoading(false);
|
|
};
|
|
|
|
const handlePasswordChange = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
if (newPassword !== confirmNewPassword) {
|
|
toast({ title: "Password Mismatch", description: "New passwords do not match.", variant: "destructive" }); // Translate
|
|
return;
|
|
}
|
|
if (newPassword.length < 6) {
|
|
toast({ title: "Password Too Short", description: "Password must be at least 6 characters.", variant: "destructive" }); // Translate
|
|
return;
|
|
}
|
|
setIsPasswordLoading(true);
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
console.log("Changing password");
|
|
toast({ title: "Password Updated", description: "Your password has been changed successfully." }); // Translate
|
|
setCurrentPassword('');
|
|
setNewPassword('');
|
|
setConfirmNewPassword('');
|
|
setIsPasswordLoading(false);
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-8 max-w-3xl mx-auto">
|
|
<div>
|
|
<h1 className="text-3xl font-bold font-headline text-primary">{t('dashboard.profile.title')}</h1>
|
|
<p className="text-muted-foreground">{t('dashboard.profile.description')}</p>
|
|
</div>
|
|
|
|
<Card className="shadow-lg">
|
|
<CardHeader>
|
|
<CardTitle className="text-xl font-headline">{t('dashboard.profile.personal_info_title')}</CardTitle>
|
|
<CardDescription>{t('dashboard.profile.personal_info_description')}</CardDescription>
|
|
</CardHeader>
|
|
<form onSubmit={handleProfileUpdate}>
|
|
<CardContent className="space-y-6">
|
|
<div className="flex items-center space-x-4">
|
|
<Avatar className="h-20 w-20">
|
|
<AvatarImage src={avatarUrl} alt={name} data-ai-hint="user avatar"/>
|
|
<AvatarFallback>{name.split(' ').map(n => n[0]).join('').toUpperCase()}</AvatarFallback>
|
|
</Avatar>
|
|
<div className="flex-1 space-y-1">
|
|
<Label htmlFor="avatarUrl">{t('dashboard.profile.avatar_url_label')}</Label>
|
|
<Input id="avatarUrl" value={avatarUrl} onChange={(e) => setAvatarUrl(e.target.value)} placeholder="https://example.com/avatar.png" disabled={isLoading} />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div className="space-y-1">
|
|
<Label htmlFor="name">{t('dashboard.profile.full_name_label')}</Label>
|
|
<Input id="name" value={name} onChange={(e) => setName(e.target.value)} placeholder="Your Name" disabled={isLoading} />
|
|
</div>
|
|
<div className="space-y-1">
|
|
<Label htmlFor="email">{t('dashboard.profile.email_label')}</Label>
|
|
<Input id="email" type="email" value={email} readOnly disabled className="bg-muted/50 cursor-not-allowed" />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-1">
|
|
<Label htmlFor="bio">{t('dashboard.profile.bio_label')}</Label>
|
|
<Textarea id="bio" value={bio} onChange={(e) => setBio(e.target.value)} placeholder="Tell us a bit about yourself and your toys..." rows={3} disabled={isLoading}/>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div className="space-y-1">
|
|
<Label htmlFor="phone">{t('dashboard.profile.phone_label')}</Label>
|
|
<Input id="phone" type="tel" value={phone} onChange={(e) => setPhone(e.target.value)} placeholder="Your Phone" disabled={isLoading} />
|
|
</div>
|
|
<div className="space-y-1">
|
|
<Label htmlFor="location">{t('dashboard.profile.location_label')}</Label>
|
|
<Input id="location" value={location} onChange={(e) => setLocation(e.target.value)} placeholder="City, Country" disabled={isLoading} />
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
<CardFooter>
|
|
<Button type="submit" disabled={isLoading}>
|
|
<Save className="mr-2 h-4 w-4" />
|
|
{isLoading ? t('dashboard.profile.saving_button') : t('dashboard.profile.save_button')}
|
|
</Button>
|
|
</CardFooter>
|
|
</form>
|
|
</Card>
|
|
|
|
<Card className="shadow-lg">
|
|
<CardHeader>
|
|
<CardTitle className="text-xl font-headline">{t('dashboard.profile.change_password_title')}</CardTitle>
|
|
<CardDescription>{t('dashboard.profile.change_password_description')}</CardDescription>
|
|
</CardHeader>
|
|
<form onSubmit={handlePasswordChange}>
|
|
<CardContent className="space-y-4">
|
|
<div className="space-y-1">
|
|
<Label htmlFor="currentPassword">{t('dashboard.profile.current_password_label')}</Label>
|
|
<Input id="currentPassword" type="password" value={currentPassword} onChange={(e) => setCurrentPassword(e.target.value)} required disabled={isPasswordLoading} />
|
|
</div>
|
|
<div className="space-y-1">
|
|
<Label htmlFor="newPassword">{t('dashboard.profile.new_password_label')}</Label>
|
|
<Input id="newPassword" type="password" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} required disabled={isPasswordLoading} />
|
|
</div>
|
|
<div className="space-y-1">
|
|
<Label htmlFor="confirmNewPassword">{t('dashboard.profile.confirm_new_password_label')}</Label>
|
|
<Input id="confirmNewPassword" type="password" value={confirmNewPassword} onChange={(e) => setConfirmNewPassword(e.target.value)} required disabled={isPasswordLoading} />
|
|
</div>
|
|
</CardContent>
|
|
<CardFooter>
|
|
<Button type="submit" disabled={isPasswordLoading}>
|
|
<Save className="mr-2 h-4 w-4" />
|
|
{isPasswordLoading ? t('dashboard.profile.updating_password_button') : t('dashboard.profile.update_password_button')}
|
|
</Button>
|
|
</CardFooter>
|
|
</form>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|