280 lines
10 KiB
TypeScript
280 lines
10 KiB
TypeScript
"use client";
|
|
import React from "react";
|
|
import { useRouter } from "next/navigation";
|
|
import { Form } from "@/components/form/Form";
|
|
import { Field } from "@/components/form/Field";
|
|
import { toast } from "sonner";
|
|
import db from "@/lib/dbClient";
|
|
import { Button } from "./ui/button";
|
|
import ParametersList from "@/components/ParametersList";
|
|
import UserAccessList from "@/components/UserAccessList";
|
|
import {
|
|
ResizableHandle,
|
|
ResizablePanel,
|
|
ResizablePanelGroup,
|
|
} from "./ui/resize";
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs";
|
|
type Props = { id?: string; defaults?: any };
|
|
|
|
export default function UserFormClient({ id, defaults }: Props) {
|
|
const router = useRouter();
|
|
const [loading, setLoading] = React.useState(false);
|
|
|
|
return (
|
|
<div className="flex flex-col flex-grow">
|
|
<ResizablePanelGroup direction="vertical" className=" rounded-lg ">
|
|
<ResizablePanel defaultSize={id && id !== "new" ? 75 : 100}>
|
|
<div className="flex h-full flex-col overflow-y-auto">
|
|
<Form
|
|
onSubmit={async (fm: any) => {
|
|
const vals = fm.data;
|
|
delete vals.tenants;
|
|
delete vals.banks;
|
|
delete vals.database;
|
|
console.log("vals", vals);
|
|
if (!id || id === "new") {
|
|
await db.users.create({ data: vals });
|
|
toast.success("User created");
|
|
} else {
|
|
await db.users.update({
|
|
where: { user_id: id },
|
|
data: vals,
|
|
});
|
|
// toast.success("User updated");
|
|
}
|
|
}}
|
|
onLoad={async () => {
|
|
if (id && id !== "new") {
|
|
const user = await db.users.findFirst({
|
|
select: {
|
|
user_id: true,
|
|
username: true,
|
|
tenant_id: true,
|
|
bank_id: true,
|
|
private_key_file: true,
|
|
public_key_file: true,
|
|
pharaphrase: true,
|
|
clientbank_id: true,
|
|
db_id: true,
|
|
tenants: true,
|
|
banks: true,
|
|
database: true,
|
|
},
|
|
where: { user_id: id },
|
|
// include: { tenants: true, banks: true },
|
|
});
|
|
return user || {};
|
|
}
|
|
return {};
|
|
}}
|
|
showResize={false}
|
|
header={(fm: any) => (
|
|
<>
|
|
<div className="flex-grow px-4 py-2 font-semibold flex flex-row items-center gap-2">
|
|
<Button
|
|
disabled={loading}
|
|
onClick={async () => {
|
|
try {
|
|
setLoading(true);
|
|
await fm.submit();
|
|
} catch (e: any) {
|
|
setLoading(false);
|
|
toast.error(String(e?.message || e));
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}}
|
|
>
|
|
{loading ? "Saving..." : "Save"}
|
|
</Button>
|
|
{id && id !== "new" && (
|
|
<Button
|
|
variant="destructive"
|
|
onClick={async () => {
|
|
if (!id || id === "new") return;
|
|
const ok = confirm(
|
|
"Are you sure you want to delete this user?"
|
|
);
|
|
if (!ok) return;
|
|
try {
|
|
setLoading(true);
|
|
await db.users.delete({ where: { user_id: id } });
|
|
toast.success("User deleted");
|
|
router.push("/d/user");
|
|
} catch (e: any) {
|
|
toast.error(String(e?.message || e));
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}}
|
|
disabled={loading || !id || id === "new"}
|
|
>
|
|
Delete
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</>
|
|
)}
|
|
children={(fm: any) => (
|
|
<>
|
|
<div
|
|
className={
|
|
"flex flex-col gap-y-2 md:gap-y-0 md:flex-row flex-wrap px-4 py-2"
|
|
}
|
|
>
|
|
<div
|
|
className={"flex-grow grid gap-4 md:gap-6 md:grid-cols-2"}
|
|
>
|
|
<div>
|
|
<Field
|
|
fm={fm}
|
|
target={"tenant_id"}
|
|
name={"tenants"}
|
|
label={"Tenant"}
|
|
type={"dropdown-async"}
|
|
onLoad={async (param: any) => {
|
|
const res = await db.tenants.findMany({
|
|
where: { name: { contains: param.search || "" } },
|
|
take: param.take || 10,
|
|
skip: param.skip || 0,
|
|
});
|
|
return res;
|
|
}}
|
|
onValue={"tenant_id"}
|
|
onLabel={"name"}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Field
|
|
fm={fm}
|
|
target={"bank_id"}
|
|
name={"banks"}
|
|
label={"Bank"}
|
|
type={"dropdown-async"}
|
|
onLoad={async (param: any) => {
|
|
const res = await db.banks.findMany({
|
|
where: { name: { contains: param.search || "" } },
|
|
take: param.take || 10,
|
|
skip: param.skip || 0,
|
|
});
|
|
return res;
|
|
}}
|
|
onValue={"bank_id"}
|
|
onLabel={"name"}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Field
|
|
fm={fm}
|
|
name={"clientbank_id"}
|
|
label={"Client Bank ID"}
|
|
type={"text"}
|
|
placeholder="Client Bank ID"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<Field
|
|
fm={fm}
|
|
name={"client_id"}
|
|
label={"Midsuit Client ID"}
|
|
type={"text"}
|
|
placeholder="Midsuit Client ID"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Field
|
|
fm={fm}
|
|
target={"db_id"}
|
|
name={"database"}
|
|
label={"Database"}
|
|
type={"dropdown-async"}
|
|
onLoad={async (param: any) => {
|
|
const res = await db.database.findMany({
|
|
where: { name: { contains: param.search || "" } },
|
|
take: param.take || 10,
|
|
skip: param.skip || 0,
|
|
});
|
|
return res;
|
|
}}
|
|
onValue={"db_id"}
|
|
onLabel={"name"}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Field
|
|
fm={fm}
|
|
name={"username"}
|
|
label={"Username"}
|
|
type={"text"}
|
|
placeholder="Username"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Field
|
|
fm={fm}
|
|
name={"password"}
|
|
label={"Password"}
|
|
type={"text"}
|
|
placeholder="********"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Field
|
|
fm={fm}
|
|
name={"private_key_file"}
|
|
label={"Private Key File"}
|
|
type={"upload"}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Field
|
|
fm={fm}
|
|
name={"pharaphrase"}
|
|
label={"Paraphrase"}
|
|
type={"text"}
|
|
placeholder="********"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<Field
|
|
fm={fm}
|
|
name={"public_key_file"}
|
|
label={"Public Key File"}
|
|
type={"upload"}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
/>
|
|
</div>
|
|
</ResizablePanel>
|
|
<ResizableHandle />
|
|
<ResizablePanel defaultSize={id && id !== "new" ? 25 : 0}>
|
|
<div className="flex h-full flex-grow">
|
|
{id && id !== "new" ? (
|
|
<Tabs defaultValue="parameter" className="w-full">
|
|
<div className="bg-muted w-full">
|
|
<TabsList>
|
|
<TabsTrigger value="parameter">Parameters</TabsTrigger>
|
|
<TabsTrigger value="access">User Access</TabsTrigger>
|
|
</TabsList>
|
|
</div>
|
|
<TabsContent value="access">
|
|
<UserAccessList userId={id} />
|
|
</TabsContent>
|
|
<TabsContent value="parameter">
|
|
<ParametersList userId={id} />
|
|
</TabsContent>
|
|
</Tabs>
|
|
) : null}
|
|
</div>
|
|
</ResizablePanel>
|
|
</ResizablePanelGroup>
|
|
</div>
|
|
);
|
|
}
|