"use client"; import * as React from "react"; import { useRouter } from "next/navigation"; import { Plus, Trash2 } from "lucide-react"; import { deleteFeatureFlag, setFeatureFlag, upsertFeatureFlag, type AdminActionResult } from "@/actions/admin"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Field, Hint, Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { ActionButton, ResultMessage } from "./action-button"; export function FlagSwitch({ flagKey, enabled }: { flagKey: string; enabled: boolean }) { const router = useRouter(); const [pending, start] = React.useTransition(); const [result, setResult] = React.useState(null); return (
start(async () => { const r = await setFeatureFlag(flagKey, v); setResult(r); if (r.ok) router.refresh(); }) } /> {result && !result.ok ? : null}
); } export function DeleteFlagButton({ flagKey }: { flagKey: string }) { return ( deleteFeatureFlag(flagKey)} confirm={{ title: `Delete flag ${flagKey}?`, description: "Code that reads this flag will treat it as disabled.", confirmLabel: "Delete" }}> ); } export function NewFlagDialog() { const router = useRouter(); const [open, setOpen] = React.useState(false); const [pending, start] = React.useTransition(); const [key, setKey] = React.useState(""); const [description, setDescription] = React.useState(""); const [plans, setPlans] = React.useState(""); const [orgIds, setOrgIds] = React.useState(""); const [result, setResult] = React.useState(null); return ( <> Create a feature flag Flags start disabled. Optional targeting by plan or organization id narrows who sees the feature when enabled.
{ e.preventDefault(); start(async () => { const r = await upsertFeatureFlag({ key: key.trim(), description, enabled: false, plans: plans.split(",").map((s) => s.trim()).filter(Boolean) as never, organizationIds: orgIds.split(/[\s,]+/).map((s) => s.trim()).filter(Boolean), }); setResult(r); if (r.ok) { setOpen(false); setKey(""); setDescription(""); setPlans(""); setOrgIds(""); router.refresh(); } }); }} > setKey(e.target.value)} placeholder="e.g. browser.beta" className="font-mono" required /> Lowercase letters, digits, `.` `_` `-`. setDescription(e.target.value)} placeholder="What this flag gates" />
setPlans(e.target.value)} placeholder="growth, business" className="font-mono" /> setOrgIds(e.target.value)} placeholder="org_a, org_b" className="font-mono" />
); }