koperasi/services/frontend/app/routes/app.my-projects.$id._index/components/modal/sign-contract.tsx
2025-08-08 14:12:40 +07:00

107 lines
3.4 KiB
TypeScript

import { zodResolver } from "@hookform/resolvers/zod";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { Button } from "~/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "~/components/ui/dialog";
import { Form, FormControl, FormField, FormItem, FormLabel } from "~/components/ui/form";
import { Input } from "~/components/ui/input";
import RequiredIcon from "~/components/ui/required-icon";
import { useAgreementProject } from "~/services/projects/agreement";
export const signContractSchema = z.object({
id: z.string().optional(),
contract: z.instanceof(File).refine((file) => file.size < 4 * 1024 * 1024, {
message: "Ukuran file maksimal 4MB",
}),
});
interface SignContractDialogProps {
id: string;
disabled?: boolean;
}
export default function SignContractDialog({ id, disabled }: SignContractDialogProps) {
const { mutateAsync } = useAgreementProject();
const [isOpen, setIsOpen] = useState(false);
const [loading, setLoading] = useState(false);
const form = useForm<z.infer<typeof signContractSchema>>({
resolver: zodResolver(signContractSchema),
defaultValues: {
id: id,
contract: undefined,
},
});
const onSubmit = async (data: z.infer<typeof signContractSchema>) => {
try {
setLoading(true);
await mutateAsync({ id: data.id, contract: data.contract });
toast.success("Tanda tangan kontrak berhasil");
} catch (error) {
console.error(error);
toast.error("Gagal menandatangani kontrak");
}
setLoading(false);
};
return (
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogTrigger asChild disabled={disabled}>
<button
disabled={disabled}
type="button"
className="mt-2 rounded border border-blue-500 bg-white px-4 py-2 text-blue-500 transition-colors hover:bg-blue-50"
>
Tanda Tangan Kontrak
</button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Tanda Tangan Kontrak</DialogTitle>
<DialogDescription className="sr-only">
This action cannot be undone. This will permanently delete your account and remove your
data from our servers.
</DialogDescription>
</DialogHeader>
<Form {...form}>
<form className="space-y-4" onSubmit={form.handleSubmit(onSubmit)}>
<FormField
control={form.control}
name="contract"
render={({ field }) => (
<FormItem>
<FormLabel>
Input Tanda Tangan <RequiredIcon />
</FormLabel>
<FormControl>
<Input
type="file"
accept="image/*"
onChange={(e) => field.onChange(e.target.files?.[0])}
onBlur={field.onBlur}
name={field.name}
ref={field.ref}
/>
</FormControl>
</FormItem>
)}
/>
<Button disabled={loading} type="submit">
{loading ? "Menandatangani..." : "Tanda Tangan"}
</Button>
</form>
</Form>
</DialogContent>
</Dialog>
);
}