mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-17 02:16:38 +00:00
✨ create & update role with device approval
This commit is contained in:
@@ -1,5 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Credenza,
|
||||
CredenzaBody,
|
||||
CredenzaClose,
|
||||
CredenzaContent,
|
||||
CredenzaDescription,
|
||||
CredenzaFooter,
|
||||
CredenzaHeader,
|
||||
CredenzaTitle
|
||||
} from "@app/components/Credenza";
|
||||
import { Button } from "@app/components/ui/button";
|
||||
import {
|
||||
Form,
|
||||
@@ -11,37 +21,26 @@ import {
|
||||
FormMessage
|
||||
} from "@app/components/ui/form";
|
||||
import { Input } from "@app/components/ui/input";
|
||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
||||
import { toast } from "@app/hooks/useToast";
|
||||
import { createApiClient, formatAxiosError } from "@app/lib/api";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { build } from "@server/build";
|
||||
import type { CreateRoleBody, CreateRoleResponse } from "@server/routers/role";
|
||||
import { AxiosResponse } from "axios";
|
||||
import { useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTransition } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
Credenza,
|
||||
CredenzaBody,
|
||||
CredenzaClose,
|
||||
CredenzaContent,
|
||||
CredenzaDescription,
|
||||
CredenzaFooter,
|
||||
CredenzaHeader,
|
||||
CredenzaTitle
|
||||
} from "@app/components/Credenza";
|
||||
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||
import type { CreateRoleBody, CreateRoleResponse } from "@server/routers/role";
|
||||
import { formatAxiosError } from "@app/lib/api";
|
||||
import { createApiClient } from "@app/lib/api";
|
||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { CheckboxWithLabel } from "./ui/checkbox";
|
||||
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
||||
import { build } from "@server/build";
|
||||
import { PaidFeaturesAlert } from "./PaidFeaturesAlert";
|
||||
import { CheckboxWithLabel } from "./ui/checkbox";
|
||||
|
||||
type CreateRoleFormProps = {
|
||||
open: boolean;
|
||||
setOpen: (open: boolean) => void;
|
||||
afterCreate?: (res: CreateRoleResponse) => Promise<void>;
|
||||
afterCreate?: (res: CreateRoleResponse) => void;
|
||||
};
|
||||
|
||||
export default function CreateRoleForm({
|
||||
@@ -54,13 +53,14 @@ export default function CreateRoleForm({
|
||||
const { isPaidUser } = usePaidStatus();
|
||||
|
||||
const formSchema = z.object({
|
||||
name: z.string({ message: t("nameRequired") }).max(32),
|
||||
name: z
|
||||
.string({ message: t("nameRequired") })
|
||||
.min(1)
|
||||
.max(32),
|
||||
description: z.string().max(255).optional(),
|
||||
requireDeviceApproval: z.boolean().optional()
|
||||
});
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const api = createApiClient(useEnvContext());
|
||||
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
@@ -72,17 +72,13 @@ export default function CreateRoleForm({
|
||||
}
|
||||
});
|
||||
|
||||
async function onSubmit(values: z.infer<typeof formSchema>) {
|
||||
setLoading(true);
|
||||
const [loading, startTransition] = useTransition();
|
||||
|
||||
async function onSubmit(values: z.infer<typeof formSchema>) {
|
||||
const res = await api
|
||||
.put<AxiosResponse<CreateRoleResponse>>(
|
||||
`/org/${org?.org.orgId}/role`,
|
||||
{
|
||||
name: values.name,
|
||||
description: values.description
|
||||
} as CreateRoleBody
|
||||
)
|
||||
.put<
|
||||
AxiosResponse<CreateRoleResponse>
|
||||
>(`/org/${org?.org.orgId}/role`, values satisfies CreateRoleBody)
|
||||
.catch((e) => {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
@@ -105,12 +101,8 @@ export default function CreateRoleForm({
|
||||
setOpen(false);
|
||||
}
|
||||
|
||||
if (afterCreate) {
|
||||
afterCreate(res.data.data);
|
||||
}
|
||||
afterCreate?.(res.data.data);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -119,7 +111,6 @@ export default function CreateRoleForm({
|
||||
open={open}
|
||||
onOpenChange={(val) => {
|
||||
setOpen(val);
|
||||
setLoading(false);
|
||||
form.reset();
|
||||
}}
|
||||
>
|
||||
@@ -133,7 +124,9 @@ export default function CreateRoleForm({
|
||||
<CredenzaBody>
|
||||
<Form {...form}>
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
onSubmit={form.handleSubmit((values) =>
|
||||
startTransition(() => onSubmit(values))
|
||||
)}
|
||||
className="space-y-4"
|
||||
id="create-role-form"
|
||||
>
|
||||
@@ -168,23 +161,37 @@ export default function CreateRoleForm({
|
||||
)}
|
||||
/>
|
||||
{build !== "oss" && (
|
||||
<>
|
||||
<div className="pt-3">
|
||||
<PaidFeaturesAlert />
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="requireDeviceApproval"
|
||||
render={({ field }) => (
|
||||
<FormItem className="pt-3">
|
||||
<FormItem className="my-2">
|
||||
<FormControl>
|
||||
<CheckboxWithLabel
|
||||
{...field}
|
||||
disabled={
|
||||
!isPaidUser
|
||||
}
|
||||
value={undefined}
|
||||
defaultChecked={
|
||||
field.value
|
||||
}
|
||||
value="on"
|
||||
checked={form.watch(
|
||||
"requireDeviceApproval"
|
||||
)}
|
||||
onCheckedChange={(
|
||||
checked
|
||||
) => {
|
||||
if (
|
||||
checked !==
|
||||
"indeterminate"
|
||||
) {
|
||||
form.setValue(
|
||||
"requireDeviceApproval",
|
||||
checked
|
||||
);
|
||||
}
|
||||
}}
|
||||
label={t(
|
||||
"requireDeviceApproval"
|
||||
)}
|
||||
@@ -201,7 +208,7 @@ export default function CreateRoleForm({
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
Reference in New Issue
Block a user