theming, date, time localisation, additional features, seeding initial cleanup

This commit is contained in:
mikicvi
2025-09-26 21:12:59 +01:00
parent b89d91ade2
commit 22c462c61c
43 changed files with 2647 additions and 550 deletions
+56 -12
View File
@@ -5,8 +5,10 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { User, Edit, Mail, Calendar, Save, X } from 'lucide-react';
import { User, Edit, Mail, Calendar, Save, X, Palette } from 'lucide-react';
import { useToast } from '@/hooks/use-toast';
import { ModeToggle } from '@/components/ui/mode-toggle';
import { useTheme } from 'next-themes';
interface User {
id: string;
@@ -15,6 +17,7 @@ interface User {
surname: string;
role: string;
createdAt: string;
themePreference: 'light' | 'dark' | 'system';
}
interface ProfileFormData {
@@ -32,6 +35,7 @@ export function UserProfile() {
surname: '',
});
const { toast } = useToast();
const { theme, setTheme } = useTheme();
const updateFormData = (field: keyof ProfileFormData, value: string) => {
setFormData((prev) => ({
@@ -54,6 +58,10 @@ export function UserProfile() {
name: userData.user.name,
surname: userData.user.surname,
});
// Sync theme with user preference if available
if (userData.user.themePreference && userData.user.themePreference !== theme) {
setTheme(userData.user.themePreference);
}
} else {
toast({
title: 'Error',
@@ -139,8 +147,8 @@ export function UserProfile() {
<Card>
<CardContent className='p-6'>
<div className='flex items-center justify-center'>
<div className='animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900'></div>
<p className='ml-2'>Loading profile...</p>
<div className='animate-spin rounded-full h-8 w-8 border-b-2 border-primary'></div>
<p className='ml-2 text-muted-foreground'>Loading profile...</p>
</div>
</CardContent>
</Card>
@@ -151,7 +159,7 @@ export function UserProfile() {
return (
<Card>
<CardContent className='p-6'>
<div className='text-center text-gray-500'>
<div className='text-center text-muted-foreground'>
<p>Unable to load user profile</p>
</div>
</CardContent>
@@ -182,7 +190,7 @@ export function UserProfile() {
placeholder='Enter your first name'
/>
) : (
<div className='flex items-center gap-2 p-2 bg-gray-50 rounded'>
<div className='flex items-center gap-2 p-2 bg-muted rounded'>
<span>{user.name}</span>
</div>
)}
@@ -199,7 +207,7 @@ export function UserProfile() {
placeholder='Enter your last name'
/>
) : (
<div className='flex items-center gap-2 p-2 bg-gray-50 rounded'>
<div className='flex items-center gap-2 p-2 bg-muted rounded'>
<span>{user.surname}</span>
</div>
)}
@@ -208,20 +216,20 @@ export function UserProfile() {
{/* Email (Read-only) */}
<div className='space-y-2'>
<Label htmlFor='email'>Email Address</Label>
<div className='flex items-center gap-2 p-2 bg-gray-100 rounded text-gray-600'>
<div className='flex items-center gap-2 p-2 bg-muted rounded text-muted-foreground'>
<Mail className='h-4 w-4' />
<span>{user.email}</span>
<span className='text-xs text-gray-500 ml-auto'>(Read-only)</span>
<span className='text-xs text-muted-foreground/60 ml-auto'>(Read-only)</span>
</div>
</div>
{/* Member Since */}
<div className='space-y-2'>
<Label>Member Since</Label>
<div className='flex items-center gap-2 p-2 bg-gray-50 rounded'>
<div className='flex items-center gap-2 p-2 bg-muted rounded'>
<Calendar className='h-4 w-4' />
<span>
{new Date(user.createdAt).toLocaleDateString('en-US', {
{new Date(user.createdAt).toLocaleDateString('en-IE', {
year: 'numeric',
month: 'long',
day: 'numeric',
@@ -268,13 +276,49 @@ export function UserProfile() {
<div className='grid grid-cols-1 md:grid-cols-2 gap-4'>
<div className='space-y-2'>
<Label>Account Type</Label>
<div className='p-2 bg-blue-50 rounded text-blue-800 capitalize font-medium'>
<div className='p-2 bg-blue-50 dark:bg-blue-900/20 rounded text-blue-800 dark:text-blue-200 capitalize font-medium'>
{user.role}
</div>
</div>
<div className='space-y-2'>
<Label>User ID</Label>
<div className='p-2 bg-gray-50 rounded text-gray-600 font-mono text-sm'>{user.id}</div>
<div className='p-2 bg-muted rounded text-muted-foreground font-mono text-sm'>
{user.id}
</div>
</div>
</div>
</CardContent>
</Card>
{/* Theme Preferences Card */}
<Card>
<CardHeader>
<CardTitle className='flex items-center gap-2'>
<Palette className='h-5 w-5' />
Theme Preferences
</CardTitle>
</CardHeader>
<CardContent>
<div className='space-y-4'>
<div className='flex items-center justify-between'>
<div className='space-y-1'>
<Label>App Theme</Label>
<p className='text-sm text-muted-foreground'>
Choose how the app appears to you. System will use your device's theme setting.
</p>
</div>
<ModeToggle />
</div>
<div className='p-3 bg-muted/50 rounded-lg'>
<p className='text-sm'>
<strong>Current theme:</strong>{' '}
<span className='capitalize'>{theme === 'system' ? 'System preference' : theme}</span>
</p>
<p className='text-xs text-muted-foreground mt-1'>
Your theme preference is automatically saved and will be applied across all your
sessions.
</p>
</div>
</div>
</CardContent>