Files
pangolin/src/components/resource-policy/EditPolicyNameSectionForm.tsx
Fred KISSIE f80e212b07 🚧 wip
2026-03-11 00:27:27 +01:00

156 lines
5.2 KiB
TypeScript

"use client";
import {
SettingsSection,
SettingsSectionBody,
SettingsSectionDescription,
SettingsSectionFooter,
SettingsSectionForm,
SettingsSectionHeader,
SettingsSectionTitle
} from "@app/components/Settings";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { zodResolver } from "@hookform/resolvers/zod";
import { useTranslations } from "next-intl";
import z from "zod";
import { toast } from "@app/hooks/useToast";
import { createApiClient, formatAxiosError } from "@app/lib/api";
import { type ResourcePolicy } from "@server/db";
import type { AxiosResponse } from "axios";
import { useRouter } from "next/navigation";
import { Button } from "@app/components/ui/button";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage
} from "@app/components/ui/form";
import { Input } from "@app/components/ui/input";
import { useResourcePolicyContext } from "@app/providers/ResourcePolicyProvider";
import { useActionState } from "react";
import { useForm } from "react-hook-form";
// ─── PolicyNameSection ──────────────────────────────────────────────────
export function EditPolicyNameSectionForm({ readonly }: { readonly?: boolean }) {
const t = useTranslations();
const api = createApiClient(useEnvContext());
const router = useRouter();
const { policy } = useResourcePolicyContext();
const form = useForm({
resolver: zodResolver(
z.object({
name: z.string()
})
),
defaultValues: {
name: policy.name
}
});
const [, formAction, isSubmitting] = useActionState(onSubmit, null);
async function onSubmit() {
if (readonly) return;
const isValid = await form.trigger();
if (!isValid) return;
const payload = form.getValues();
try {
const res = await api
.put<AxiosResponse<ResourcePolicy>>(
`/resource-policy/${policy.resourcePolicyId}`,
{
name: payload.name
}
)
.catch((e) => {
toast({
variant: "destructive",
title: t("policyErrorUpdate"),
description: formatAxiosError(
e,
t("policyErrorUpdateDescription")
)
});
});
if (res && res.status === 200) {
toast({
title: t("success"),
description: t("policyUpdatedSuccess")
});
router.refresh();
}
} catch (e) {
toast({
variant: "destructive",
title: t("policyErrorUpdate"),
description: t("policyErrorUpdateMessageDescription")
});
}
}
return (
<Form {...form}>
<form action={formAction}>
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>
{t("resourcePolicyName")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t("resourcePolicyNameDescription")}
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
<SettingsSectionForm>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("name")}</FormLabel>
<FormControl>
<Input
{...field}
disabled={readonly}
placeholder={t(
"resourcePolicyNamePlaceholder"
)}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</SettingsSectionForm>
</SettingsSectionBody>
<SettingsSectionFooter>
<Button
type="submit"
loading={isSubmitting}
disabled={readonly || isSubmitting}
>
{t("saveSettings")}
</Button>
</SettingsSectionFooter>
</SettingsSection>
</form>
</Form>
);
}