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%
2.7 KB · 64 lines tsx
Raw Blame History
1"use client";2import * as React from "react";3import { useRouter } from "next/navigation";4import { updateOrganization } 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 OrganizationForm({ name, softLimitUsd, hardLimitUsd, canEdit }: { name: string; softLimitUsd: number | null; hardLimitUsd: number | null; canEdit: boolean }) {11  const router = useRouter();12  const [error, setError] = React.useState<string | null>(null);13  const [saved, setSaved] = React.useState(false);14  const [pending, startTransition] = React.useTransition();1516  return (17    <form18      className="grid gap-4"19      onSubmit={(e) => {20        e.preventDefault();21        setError(null);22        setSaved(false);23        const fd = new FormData(e.currentTarget);24        startTransition(async () => {25          const res = await updateOrganization(fd);26          if (!res.ok) {27            setError(res.error);28            return;29          }30          setSaved(true);31          router.refresh();32        });33      }}34    >35      {!canEdit ? <Alert variant="info">Only owners, admins and billing members can change organization settings.</Alert> : null}36      {error ? <Alert variant="danger">{error}</Alert> : null}37      {saved ? <Alert variant="success">Organization updated.</Alert> : null}38      <Field>39        <Label htmlFor="org-name">Organization name</Label>40        <Input id="org-name" name="name" defaultValue={name} maxLength={80} required disabled={!canEdit} className="sm:max-w-sm" />41      </Field>42      <div className="grid gap-4 sm:grid-cols-2 sm:max-w-lg">43        <Field>44          <Label htmlFor="org-soft">Soft limit (USD / month)</Label>45          <Input id="org-soft" name="softLimitUsd" type="number" min={0} step="0.01" inputMode="decimal" defaultValue={softLimitUsd ?? ""} placeholder="No limit" disabled={!canEdit} className="font-mono tabular" />46          <Hint>You get an email when total spend crosses this amount.</Hint>47        </Field>48        <Field>49          <Label htmlFor="org-hard">Hard limit (USD / month)</Label>50          <Input id="org-hard" name="hardLimitUsd" type="number" min={0} step="0.01" inputMode="decimal" defaultValue={hardLimitUsd ?? ""} placeholder="No limit" disabled={!canEdit} className="font-mono tabular" />51          <Hint>All projects stop with USAGE_LIMIT_REACHED until the next month.</Hint>52        </Field>53      </div>54      {canEdit ? (55        <div>56          <Button type="submit" variant="primary" loading={pending}>57            Save organization58          </Button>59        </div>60      ) : null}61    </form>62  );63}64