141 lines
3.7 KiB
TypeScript
141 lines
3.7 KiB
TypeScript
import React, { useState, useEffect, useRef } from 'react';
|
|
import { useMutation } from '@tanstack/react-query';
|
|
import { AxiosError } from 'axios';
|
|
import { apiRequest } from '@/shared/request/apiRequest';
|
|
import { links } from '@/shared/request/links';
|
|
import { CertificateFormData } from './types';
|
|
import { SIPaymentResponse } from '../siModal/utils/useFileUpload';
|
|
|
|
interface UseCertificateModalProps {
|
|
document_id: number;
|
|
open: boolean;
|
|
setOpen: () => void;
|
|
}
|
|
|
|
interface CertificatePayload {
|
|
full_name: string;
|
|
file_name: string;
|
|
document_type: number;
|
|
}
|
|
|
|
export function useCertificateModal({
|
|
document_id,
|
|
open,
|
|
setOpen,
|
|
}: UseCertificateModalProps) {
|
|
const [form, setForm] = useState<CertificateFormData>({
|
|
fullname: '',
|
|
document_theme: '',
|
|
type: 0,
|
|
document_id,
|
|
});
|
|
const [success, setSuccess] = useState(false);
|
|
const [visible, setVisible] = useState(false);
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
|
|
const payment = useMutation({
|
|
mutationFn: (id: number) =>
|
|
apiRequest<SIPaymentResponse>('POST', links.demo_pay(id)),
|
|
onSuccess: (res) => {
|
|
window.open(res?.data?.payment_link, '_self');
|
|
},
|
|
});
|
|
|
|
const certificateMutation = useMutation({
|
|
mutationFn: (payload: CertificatePayload) =>
|
|
apiRequest<ArrayBuffer>('POST', links.sertifikat(document_id), payload, {
|
|
responseType: 'arraybuffer',
|
|
}).then((res) => res.data),
|
|
onSuccess: (data: ArrayBuffer) => {
|
|
if (data) {
|
|
const blob = new Blob([data], { type: 'application/pdf' });
|
|
const objectUrl = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = objectUrl;
|
|
a.download = `certificate-${document_id}.pdf`;
|
|
a.click();
|
|
setTimeout(() => URL.revokeObjectURL(objectUrl), 1000);
|
|
}
|
|
setSuccess(true);
|
|
setTimeout(() => {
|
|
setOpen();
|
|
setSuccess(false);
|
|
resetForm();
|
|
}, 1500);
|
|
},
|
|
onError: (error: AxiosError<{ code?: string }>) => {
|
|
if (error?.response?.data?.code === 'not_paid') {
|
|
payment.mutate(document_id);
|
|
}
|
|
},
|
|
});
|
|
|
|
const resetForm = () => {
|
|
setForm({
|
|
fullname: '',
|
|
document_theme: '',
|
|
type: 0,
|
|
document_id,
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (open) {
|
|
setVisible(true);
|
|
setSuccess(false);
|
|
setForm((prev) => ({ ...prev, document_id }));
|
|
setTimeout(() => inputRef.current?.focus(), 300);
|
|
|
|
const data = localStorage.getItem('user');
|
|
if (data) {
|
|
const user = JSON.parse(data);
|
|
setForm((prev) => ({
|
|
...prev,
|
|
fullname: `${user.name} ${user.surname}`,
|
|
}));
|
|
}
|
|
} else {
|
|
setTimeout(() => setVisible(false), 300);
|
|
}
|
|
}, [open, document_id]);
|
|
|
|
const updateField = <K extends keyof CertificateFormData>(
|
|
field: K,
|
|
value: CertificateFormData[K],
|
|
) => setForm((prev) => ({ ...prev, [field]: value }));
|
|
|
|
const isFormValid =
|
|
!!form.fullname.trim() && !!form.document_theme.trim() && !!form.type;
|
|
|
|
const handleSubmit = () => {
|
|
if (!isFormValid || certificateMutation.isPending) return;
|
|
certificateMutation.mutate({
|
|
full_name: form.fullname,
|
|
file_name: form.document_theme,
|
|
document_type: Number(form.type),
|
|
});
|
|
};
|
|
|
|
const handleKeyDown = (e: React.KeyboardEvent) => {
|
|
if (e.key === 'Escape') setOpen();
|
|
if (e.key === 'Enter') handleSubmit();
|
|
};
|
|
|
|
const handleBackdropClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
if (e.target === e.currentTarget) setOpen();
|
|
};
|
|
|
|
return {
|
|
form,
|
|
updateField,
|
|
loading: certificateMutation.isPending,
|
|
success,
|
|
visible,
|
|
isFormValid,
|
|
inputRef,
|
|
handleSubmit,
|
|
handleKeyDown,
|
|
handleBackdropClick,
|
|
};
|
|
}
|