import { useState } from 'react' import { Head, useForm } from '@inertiajs/react' import Layout from '../Layout' import * as Form from '@radix-ui/react-form' import * as Tabs from '@radix-ui/react-tabs' export default function ProfileShow({ auth, user_stats, errors = {} }) { const { data, setData, patch, processing, reset } = useForm({ name: auth.name || '', email_address: auth.email_address || '', current_password: '', password: '', password_confirmation: '', }) const handleSubmit = (e) => { e.preventDefault() patch('/profile', { onSuccess: () => { reset('current_password', 'password', 'password_confirmation') }, }) } return ( <Layout user={auth}> <Head title="My Profile" /> <Tabs.Root defaultValue="profile" className="bg-white shadow overflow-hidden sm:rounded-lg"> <Tabs.List className="flex border-b border-gray-200"> <Tabs.Trigger value="profile" className="px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none data-[state=active]:border-b-2 data-[state=active]:border-indigo-500 data-[state=active]:text-indigo-600" > Profile </Tabs.Trigger> <Tabs.Trigger value="activity" className="px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none data-[state=active]:border-b-2 data-[state=active]:border-indigo-500 data-[state=active]:text-indigo-600" > Activity </Tabs.Trigger> </Tabs.List> <Tabs.Content value="profile" className="focus:outline-none"> <div className="px-4 py-5 sm:px-6"> <h1 className="text-2xl font-bold text-gray-900">My Profile</h1> <p className="mt-1 max-w-2xl text-sm text-gray-500"> Update your account information </p> </div> <div className="border-t border-gray-200 px-4 py-5 sm:px-6"> <Form.Root className="space-y-6" onSubmit={handleSubmit}> <Form.Field name="name" className="space-y-2"> <Form.Label className="block text-sm font-medium text-gray-700"> Name </Form.Label> <Form.Control asChild> <input type="text" name="name" value={data.name} onChange={(e) => setData('name', e.target.value)} className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" /> </Form.Control> {errors.name && ( <Form.Message className="text-sm text-red-600"> {errors.name} </Form.Message> )} </Form.Field> <Form.Field name="email_address" className="space-y-2"> <Form.Label className="block text-sm font-medium text-gray-700"> Email Address </Form.Label> <Form.Control asChild> <input type="email" name="email_address" value={data.email_address} onChange={(e) => setData('email_address', e.target.value)} className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" /> </Form.Control> {errors.email_address && ( <Form.Message className="text-sm text-red-600"> {errors.email_address} </Form.Message> )} </Form.Field> <div className="pt-5 border-t border-gray-200"> <h3 className="text-lg font-medium text-gray-900">Change Password</h3> <p className="mt-1 text-sm text-gray-500"> Leave these fields blank if you don't want to change your password </p> </div> <Form.Field name="current_password" className="space-y-2"> <Form.Label className="block text-sm font-medium text-gray-700"> Current Password </Form.Label> <Form.Control asChild> <input type="password" name="current_password" value={data.current_password} onChange={(e) => setData('current_password', e.target.value)} className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" /> </Form.Control> {errors.current_password && ( <Form.Message className="text-sm text-red-600"> {errors.current_password} </Form.Message> )} </Form.Field> <Form.Field name="password" className="space-y-2"> <Form.Label className="block text-sm font-medium text-gray-700"> New Password </Form.Label> <Form.Control asChild> <input type="password" name="password" value={data.password} onChange={(e) => setData('password', e.target.value)} className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" /> </Form.Control> {errors.password && ( <Form.Message className="text-sm text-red-600"> {errors.password} </Form.Message> )} </Form.Field> <Form.Field name="password_confirmation" className="space-y-2"> <Form.Label className="block text-sm font-medium text-gray-700"> Confirm New Password </Form.Label> <Form.Control asChild> <input type="password" name="password_confirmation" value={data.password_confirmation} onChange={(e) => setData('password_confirmation', e.target.value)} className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" /> </Form.Control> </Form.Field> <div className="flex justify-end"> <Form.Submit asChild> <button type="submit" disabled={processing} className="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50" > {processing ? 'Saving...' : 'Save Changes'} </button> </Form.Submit> </div> </Form.Root> </div> </Tabs.Content> <Tabs.Content value="activity" className="focus:outline-none"> <div className="px-4 py-5 sm:px-6"> <h1 className="text-2xl font-bold text-gray-900">My Activity</h1> <p className="mt-1 max-w-2xl text-sm text-gray-500"> Your account statistics and recent activity </p> </div> <div className="border-t border-gray-200"> <dl className="sm:divide-y sm:divide-gray-200"> <div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> <dt className="text-sm font-medium text-gray-500">Account created</dt> <dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> {new Date(auth.created_at).toLocaleDateString()} </dd> </div> <div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> <dt className="text-sm font-medium text-gray-500">Total images</dt> <dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> {user_stats.total_images} </dd> </div> <div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> <dt className="text-sm font-medium text-gray-500">Pending review</dt> <dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> {user_stats.pending_images} </dd> </div> <div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> <dt className="text-sm font-medium text-gray-500">Approved images</dt> <dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> {user_stats.approved_images} </dd> </div> <div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> <dt className="text-sm font-medium text-gray-500">Rejected images</dt> <dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> {user_stats.rejected_images} </dd> </div> <div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> <dt className="text-sm font-medium text-gray-500">Most used tags</dt> <dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> <div className="flex flex-wrap gap-1"> {user_stats.top_tags && user_stats.top_tags.length > 0 ? ( user_stats.top_tags.map((tag) => ( <span key={tag.id} className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800" > {tag.name} ({tag.count}) </span> )) ) : ( <span className="text-gray-500">No tags used yet</span> )} </div> </dd> </div> </dl> </div> {user_stats.recent_images && user_stats.recent_images.length > 0 && ( <div className="border-t border-gray-200 px-4 py-5 sm:px-6"> <h3 className="text-lg font-medium text-gray-900">Recent Images</h3> <div className="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"> {user_stats.recent_images.map((image) => ( <div key={image.id} className="relative rounded-lg border border-gray-300 bg-white px-6 py-5 shadow-sm flex items-center space-x-3 hover:border-gray-400" > <div className="flex-shrink-0"> <img className="h-10 w-10 rounded-full object-cover" src={image.file_url} alt="" /> </div> <div className="flex-1 min-w-0"> <a href={`/images/${image.id}`} className="focus:outline-none"> <span className="absolute inset-0" aria-hidden="true" /> <p className="text-sm font-medium text-gray-900">{image.title}</p> <p className="text-sm text-gray-500 truncate"> {new Date(image.created_at).toLocaleDateString()} - {image.status} </p> </a> </div> </div> ))} </div> </div> )} </Tabs.Content> </Tabs.Root> </Layout> ) }