SPB Git forge

spb/fetcha

Public
11commits 1branches 0releases
1.5 MBsize
maindefault branch
16 days agolast push
TypeScript 97.5% SQL 1.4% Python 0.8%
3.6 KB · 94 lines tsx
Raw Blame History
1"use client";2import * as React from "react";3import { authClient } from "@/lib/auth-client";4import { Button } from "@/components/ui/button";5import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";6import { Input } from "@/components/ui/input";7import { Field, Hint, Label } from "@/components/ui/label";8import { Alert } from "@/components/ui/alert";910export function ChangeEmailDialog({ currentEmail }: { currentEmail: string }) {11  const [open, setOpen] = React.useState(false);12  const [email, setEmail] = React.useState("");13  const [error, setError] = React.useState<string | null>(null);14  const [sent, setSent] = React.useState(false);15  const [loading, setLoading] = React.useState(false);1617  async function submit(e: React.FormEvent) {18    e.preventDefault();19    setError(null);20    const newEmail = email.trim().toLowerCase();21    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(newEmail)) {22      setError("Enter a valid email address.");23      return;24    }25    if (newEmail === currentEmail.toLowerCase()) {26      setError("That is already your email address.");27      return;28    }29    setLoading(true);30    const { error } = await authClient.changeEmail({ newEmail, callbackURL: "/dashboard/settings?email-changed=1" });31    setLoading(false);32    if (error) {33      setError(error.message ?? "Could not start the email change. Try again.");34      return;35    }36    setSent(true);37  }3839  return (40    <Dialog41      open={open}42      onOpenChange={(o) => {43        setOpen(o);44        if (!o) {45          setSent(false);46          setError(null);47          setEmail("");48        }49      }}50    >51      <DialogTrigger asChild>52        <Button variant="outline" size="sm">53          Change email54        </Button>55      </DialogTrigger>56      <DialogContent size="sm">57        <DialogHeader>58          <DialogTitle>Change email address</DialogTitle>59          <DialogDescription>60            For your security we first send an approval link to your <strong className="text-fg">current</strong> address ({currentEmail}). Once you approve it, the new address becomes your login and must be verified in turn.61          </DialogDescription>62        </DialogHeader>63        {sent ? (64          <>65            <Alert variant="success" title="Approval email sent">66              Open the link we sent to {currentEmail} to approve switching to <strong className="text-fg">{email.trim()}</strong>. The link expires in 24 hours. Until then you keep signing in with your current address.67            </Alert>68            <DialogFooter>69              <Button onClick={() => setOpen(false)}>Done</Button>70            </DialogFooter>71          </>72        ) : (73          <form onSubmit={submit} className="grid gap-4" noValidate>74            {error ? <Alert variant="danger">{error}</Alert> : null}75            <Field>76              <Label htmlFor="new-email">New email</Label>77              <Input id="new-email" type="email" autoComplete="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@company.com" required autoFocus />78              <Hint>API keys, projects and usage are unaffected.</Hint>79            </Field>80            <DialogFooter>81              <Button type="button" variant="outline" onClick={() => setOpen(false)} disabled={loading}>82                Cancel83              </Button>84              <Button type="submit" variant="primary" loading={loading} disabled={!email.trim()}>85                Send approval email86              </Button>87            </DialogFooter>88          </form>89        )}90      </DialogContent>91    </Dialog>92  );93}94