Files
GSB-Construction/resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.tsx

145 lines
7.7 KiB
TypeScript

import { FormEventHandler } from 'react';
import InputError from '@/Components/InputError';
import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label';
import { Button } from '@/Components/ui/button';
import { Transition } from '@headlessui/react';
import { Link, useForm, usePage } from '@inertiajs/react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/Components/ui/card';
import { Lock, User as UserIcon, CheckCircle2, Shield } from 'lucide-react';
import { PageProps } from '@/types';
export default function UpdateProfileInformation({
mustVerifyEmail,
status,
className = '',
}: {
mustVerifyEmail: boolean;
status?: string;
className?: string;
}) {
const user = usePage<PageProps>().props.auth.user;
const { data, setData, patch, errors, processing, recentlySuccessful } =
useForm({
name: user.name,
email: user.email,
});
const submit: FormEventHandler = (e) => {
e.preventDefault();
patch(route('profile.update'));
};
return (
<Card className={`border-slate-200/80 dark:border-slate-800 shadow-xs bg-white dark:bg-slate-900 overflow-hidden ${className}`}>
<CardHeader className="bg-slate-50/70 dark:bg-slate-800/50 border-b border-slate-100 dark:border-slate-800/80 py-4 px-6">
<CardTitle className="text-base font-bold text-slate-800 dark:text-slate-100 flex items-center gap-2">
<div className="p-1.5 rounded-lg bg-emerald-50 dark:bg-emerald-950/50 text-emerald-600 dark:text-emerald-400">
<UserIcon className="h-4 w-4" />
</div>
Profile Information
</CardTitle>
<CardDescription className="text-xs text-slate-500 dark:text-slate-400">
Update your display name across all modules and audit activity logs.
</CardDescription>
</CardHeader>
<CardContent className="p-6">
<form onSubmit={submit} className="space-y-5">
{/* Text Fields */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div className="space-y-1.5">
<Label htmlFor="name" className="text-xs font-bold text-slate-700 dark:text-slate-300">
Full Name
</Label>
<Input
id="name"
className="bg-white dark:bg-slate-950 text-xs border-slate-200 dark:border-slate-800 focus-visible:ring-emerald-500 focus-visible:border-emerald-500 h-9 font-medium"
value={data.name}
onChange={(e) => setData('name', e.target.value)}
required
autoComplete="name"
placeholder="Your full name"
/>
<InputError className="mt-1" message={errors.name} />
</div>
<div className="space-y-1.5">
<div className="flex items-center justify-between">
<Label htmlFor="email" className="text-xs font-bold text-slate-700 dark:text-slate-300">
Email Address
</Label>
<span className="text-[10px] text-slate-400 dark:text-slate-500 font-semibold flex items-center gap-1 bg-slate-100 dark:bg-slate-800 px-1.5 py-0.5 rounded">
<Lock className="h-2.5 w-2.5" /> Locked
</span>
</div>
<Input
id="email"
type="email"
className="bg-slate-50 dark:bg-slate-950/50 text-xs border-slate-200 dark:border-slate-800 text-slate-500 dark:text-slate-400 cursor-not-allowed h-9 select-none font-medium"
value={data.email}
disabled
readOnly
autoComplete="username"
/>
<p className="text-[11px] text-slate-400 dark:text-slate-500 mt-1">
Primary login email is managed by your system administrator.
</p>
<InputError className="mt-1" message={errors.email} />
</div>
</div>
{mustVerifyEmail && user.email_verified_at === null && (
<div className="bg-amber-50/70 dark:bg-amber-950/30 border border-amber-200 dark:border-amber-900/50 p-3 rounded-lg flex items-start gap-2.5">
<Shield className="h-4 w-4 text-amber-600 dark:text-amber-400 mt-0.5 shrink-0" />
<div className="text-xs text-amber-800 dark:text-amber-300">
<p>
Your email address is unverified.
<Link
href={route('verification.send')}
method="post"
as="button"
className="ml-1.5 font-semibold text-amber-700 dark:text-amber-400 underline hover:text-amber-900 focus:outline-none"
>
Click here to re-send verification link.
</Link>
</p>
{status === 'verification-link-sent' && (
<div className="mt-1.5 font-semibold text-emerald-600 dark:text-emerald-400 flex items-center gap-1">
<CheckCircle2 className="h-3.5 w-3.5" /> A new verification link has been sent to your email.
</div>
)}
</div>
</div>
)}
<div className="flex items-center justify-between pt-2 border-t border-slate-100 dark:border-slate-800/80">
<Button
type="submit"
disabled={processing}
className="bg-emerald-600 hover:bg-emerald-700 text-white text-xs font-semibold h-9 px-4 shadow-2xs transition-colors"
>
Save Changes
</Button>
<Transition
show={recentlySuccessful}
enter="transition ease-in-out duration-300"
enterFrom="opacity-0 translate-x-2"
enterTo="opacity-100 translate-x-0"
leave="transition ease-in-out duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="flex items-center gap-1.5 text-emerald-600 dark:text-emerald-400 text-xs font-semibold">
<CheckCircle2 className="h-4 w-4" />
<span>Profile updated successfully.</span>
</div>
</Transition>
</div>
</form>
</CardContent>
</Card>
);
}