129 lines
3.6 KiB
TypeScript
129 lines
3.6 KiB
TypeScript
"use client";
|
|
|
|
import * as React from "react";
|
|
import BaseForm from "@/components/BaseForm";
|
|
import { Field, FieldLabel, FieldContent } from "@/components/ui/field";
|
|
import { Input } from "@/components/ui/input";
|
|
import db from "@/lib/dbClient";
|
|
import { useRouter } from "next/navigation";
|
|
import { useFormContext, Controller } from "react-hook-form";
|
|
import AsyncSelectPaginate from "@/components/AsyncSelectPaginate";
|
|
|
|
function BankFields() {
|
|
const { control } = useFormContext();
|
|
|
|
return (
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<Field>
|
|
<FieldLabel>Name</FieldLabel>
|
|
<FieldContent>
|
|
<Controller
|
|
name="name"
|
|
control={control}
|
|
render={({ field }) => <Input {...field} />}
|
|
/>
|
|
</FieldContent>
|
|
</Field>
|
|
|
|
<Field>
|
|
<FieldLabel>Code</FieldLabel>
|
|
<FieldContent>
|
|
<Controller
|
|
name="code"
|
|
control={control}
|
|
render={({ field }) => <Input {...field} />}
|
|
/>
|
|
</FieldContent>
|
|
</Field>
|
|
|
|
<Field>
|
|
<FieldLabel>Parent Bank</FieldLabel>
|
|
<FieldContent>
|
|
<Controller
|
|
name="parent_bank"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<AsyncSelectPaginate
|
|
value={field.value}
|
|
getOptionLabel={(o: any) => o.label}
|
|
getOptionValue={(o: any) => o.value}
|
|
loader={async (search: string, page: number) => {
|
|
const take = 20;
|
|
const skip = (page - 1) * take;
|
|
|
|
// Query tenants (paginated) from backend via db client
|
|
const res: any = await db.tenants.findMany({
|
|
skip,
|
|
take,
|
|
where: { name: { contains: search } },
|
|
});
|
|
|
|
let items: any[] = [];
|
|
if (Array.isArray(res)) items = res;
|
|
else if (res && Array.isArray(res.rows)) items = res.rows;
|
|
|
|
const options = items.map((it: any) => ({
|
|
label: it.name,
|
|
value: String(it.tenant_id || it.id || it.bank_id),
|
|
}));
|
|
|
|
const hasMore = items.length === take;
|
|
|
|
return { options, hasMore };
|
|
}}
|
|
onChange={(v: any) => field.onChange(v)}
|
|
/>
|
|
)}
|
|
/>
|
|
</FieldContent>
|
|
</Field>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default function BaseBankForm({ id }: { id?: string }) {
|
|
const router = useRouter();
|
|
const [defaults, setDefaults] = React.useState<any>(undefined);
|
|
|
|
React.useEffect(() => {
|
|
let mounted = true;
|
|
(async () => {
|
|
if (id && id !== "new") {
|
|
try {
|
|
const resp = await db.banks.findFirst({ where: { bank_id: id } });
|
|
if (mounted) setDefaults(resp || {});
|
|
} catch (e) {
|
|
console.error("failed to load bank", e);
|
|
if (mounted) setDefaults({});
|
|
}
|
|
} else {
|
|
if (mounted) setDefaults({});
|
|
}
|
|
})();
|
|
|
|
return () => {
|
|
mounted = false;
|
|
};
|
|
}, [id]);
|
|
|
|
const onSubmit = async (values: any) => {
|
|
if (id === "new") await db.banks.create({ data: values });
|
|
else await db.banks.update({ where: { bank_id: id }, data: values });
|
|
|
|
router.push("/d/bank");
|
|
};
|
|
|
|
if (id && id !== "new" && defaults === undefined)
|
|
return <div>Loading...</div>;
|
|
|
|
return (
|
|
<BaseForm
|
|
defaultValues={defaults}
|
|
onSubmit={onSubmit}
|
|
submitLabel={id === "new" ? "Create" : "Save"}
|
|
>
|
|
<BankFields />
|
|
</BaseForm>
|
|
);
|
|
}
|