ProfilePage.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { Transition } from '@headlessui/react';
  2. import { Form, Head, Link, usePage } from '@inertiajs/react';
  3. import ProfileController from '@/actions/App/Http/Controllers/Settings/ProfileController';
  4. import { DeleteUser } from '@/common/DeleteUser';
  5. import { HeadingSmall } from '@/common/HeadingSmall';
  6. import { InputError } from '@/common/InputError';
  7. import { type BreadcrumbItem, type SharedData } from '@/common/types';
  8. import AppLayout from '@/pages/layouts/AppLayout';
  9. import SettingsLayout from '@/pages/layouts/settings/layout';
  10. import { edit } from '@/routes/profile';
  11. import { send } from '@/routes/verification';
  12. import { Button } from '@/shadcn/button';
  13. import { Input } from '@/shadcn/input';
  14. import { Label } from '@/shadcn/label';
  15. const breadcrumbs: BreadcrumbItem[] = [
  16. {
  17. title: 'Profile settings',
  18. href: edit().url,
  19. },
  20. ];
  21. export default function ProfilePage({ mustVerifyEmail, status }: { mustVerifyEmail: boolean; status?: string }) {
  22. const { auth } = usePage<SharedData>().props;
  23. return (
  24. <AppLayout breadcrumbs={breadcrumbs}>
  25. <Head title="Profile settings" />
  26. <SettingsLayout>
  27. <div className="space-y-6">
  28. <HeadingSmall title="Profile information" description="Update your name and email address" />
  29. <Form
  30. {...ProfileController.update.form()}
  31. options={{
  32. preserveScroll: true,
  33. }}
  34. className="space-y-6"
  35. >
  36. {({ processing, recentlySuccessful, errors }) => (
  37. <>
  38. <div className="grid gap-2">
  39. <Label htmlFor="name">Name</Label>
  40. <Input
  41. id="name"
  42. className="mt-1 block w-full"
  43. defaultValue={auth.user.name}
  44. name="name"
  45. required
  46. autoComplete="name"
  47. placeholder="Full name"
  48. />
  49. <InputError className="mt-2" message={errors.name} />
  50. </div>
  51. <div className="grid gap-2">
  52. <Label htmlFor="email">Email address</Label>
  53. <Input
  54. id="email"
  55. type="email"
  56. className="mt-1 block w-full"
  57. defaultValue={auth.user.email}
  58. name="email"
  59. required
  60. autoComplete="username"
  61. placeholder="Email address"
  62. />
  63. <InputError className="mt-2" message={errors.email} />
  64. </div>
  65. {mustVerifyEmail && auth.user.email_verified_at === null && (
  66. <div>
  67. <p className="-mt-4 text-sm text-muted-foreground">
  68. Your email address is unverified.{' '}
  69. <Link
  70. href={send()}
  71. as="button"
  72. className="text-foreground underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-neutral-500"
  73. >
  74. Click here to resend the verification email.
  75. </Link>
  76. </p>
  77. {status === 'verification-link-sent' && (
  78. <div className="mt-2 text-sm font-medium text-green-600">
  79. A new verification link has been sent to your email address.
  80. </div>
  81. )}
  82. </div>
  83. )}
  84. <div className="flex items-center gap-4">
  85. <Button disabled={processing}>Save</Button>
  86. <Transition
  87. show={recentlySuccessful}
  88. enter="transition ease-in-out"
  89. enterFrom="opacity-0"
  90. leave="transition ease-in-out"
  91. leaveTo="opacity-0"
  92. >
  93. <p className="text-sm text-neutral-600">Saved</p>
  94. </Transition>
  95. </div>
  96. </>
  97. )}
  98. </Form>
  99. </div>
  100. <DeleteUser />
  101. </SettingsLayout>
  102. </AppLayout>
  103. );
  104. }