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%
1.7 KB · 51 lines tsx
Raw Blame History
1"use client";2import * as React from "react";3import { useRouter } from "next/navigation";4import { updateProfileName } from "@/actions/account";5import { Button } from "@/components/ui/button";6import { Input } from "@/components/ui/input";7import { Field, Hint, Label } from "@/components/ui/label";8import { Alert } from "@/components/ui/alert";910export function ProfileNameForm({ name }: { name: string }) {11  const router = useRouter();12  const [value, setValue] = React.useState(name);13  const [error, setError] = React.useState<string | null>(null);14  const [saved, setSaved] = React.useState(false);15  const [pending, startTransition] = React.useTransition();16  const dirty = value.trim() !== name;1718  return (19    <form20      className="grid gap-3"21      onSubmit={(e) => {22        e.preventDefault();23        setError(null);24        setSaved(false);25        startTransition(async () => {26          const res = await updateProfileName(value);27          if (!res.ok) {28            setError(res.error);29            return;30          }31          setSaved(true);32          router.refresh();33        });34      }}35    >36      {error ? <Alert variant="danger">{error}</Alert> : null}37      {saved ? <Alert variant="success">Name updated.</Alert> : null}38      <Field>39        <Label htmlFor="profile-name">Full name</Label>40        <div className="flex gap-2">41          <Input id="profile-name" value={value} onChange={(e) => setValue(e.target.value)} maxLength={80} autoComplete="name" className="sm:max-w-sm" />42          <Button type="submit" variant="primary" loading={pending} disabled={!dirty || value.trim().length === 0}>43            Save44          </Button>45        </div>46        <Hint>Shown in the dashboard and in emails we send you.</Hint>47      </Field>48    </form>49  );50}51