From 5f5efbd0631568fc198fb257130edb0a9499b9fa Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Tue, 30 Sep 2025 15:41:42 +0330 Subject: [PATCH] manage document --- src/pages/setting/ManageDocument.tsx | 130 ++++++++++++++++ .../setting/components/AddDocumentModal.tsx | 142 ++++++++++++++++++ src/pages/setting/hooks/useSettingData.ts | 22 ++- src/pages/setting/service/SettingService.ts | 17 +++ src/pages/setting/types/Types.ts | 25 +++ src/router/Main.tsx | 2 + 6 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 src/pages/setting/ManageDocument.tsx create mode 100644 src/pages/setting/components/AddDocumentModal.tsx diff --git a/src/pages/setting/ManageDocument.tsx b/src/pages/setting/ManageDocument.tsx new file mode 100644 index 0000000..f010c09 --- /dev/null +++ b/src/pages/setting/ManageDocument.tsx @@ -0,0 +1,130 @@ +import { type FC, useState } from 'react' +import { useGetDocuments } from './hooks/useSettingData' +import { type DocumentTypeItem } from './types/Types' +import PageLoading from '../../components/PageLoading' +import Error from '../../components/Error' +import Td from '../../components/Td' +import { Calendar, DocumentText, TickCircle } from 'iconsax-react' +import Button from '@/components/Button' +import AddDocumentModal from './components/AddDocumentModal' + +const ManageDocument: FC = () => { + + const { data: documents, isLoading, error } = useGetDocuments() + + // Modal states + const [isModalOpen, setIsModalOpen] = useState(false) + + // Handlers + const handleOpenModal = () => { + setIsModalOpen(true) + } + + const handleCloseModal = () => { + setIsModalOpen(false) + } + + if (isLoading) { + return ( +
+ +
+ ); + } + + if (error) { + return ( +
+ +
+ ); + } + + const documentItems = documents?.results?.documentTypes || []; + + const formatDate = (dateString: string) => { + if (!dateString) return '-'; + return new Date(dateString).toLocaleDateString('fa-IR'); + }; + + const truncateText = (text: string, maxLength: number = 50) => { + if (text.length <= maxLength) return text; + return text.substring(0, maxLength) + '...'; + }; + + return ( +
+
+
+
+ + + + + + + {documentItems.length === 0 ? ( + + + + ) : ( + documentItems.map((item: DocumentTypeItem) => ( + + + + + + + )) + )} + +
+ + + +
+ هیچ سندی یافت نشد +
+
+ + {item.title} +
+
+
+ + {truncateText(item.description)} + +
+
+
+ + + {item.required ? "ضروری" : "اختیاری"} + +
+
+
+ + {formatDate(item.createdAt)} +
+
+
+ + {/* Add Document Modal */} + +
+ ) +} + +export default ManageDocument \ No newline at end of file diff --git a/src/pages/setting/components/AddDocumentModal.tsx b/src/pages/setting/components/AddDocumentModal.tsx new file mode 100644 index 0000000..96360b8 --- /dev/null +++ b/src/pages/setting/components/AddDocumentModal.tsx @@ -0,0 +1,142 @@ +import { type FC, useState } from 'react' +import { useCreateDocument } from '../hooks/useSettingData' +import { useQueryClient } from '@tanstack/react-query' +import Button from '@/components/Button' +import Input from '@/components/Input' +import Textarea from '@/components/Textarea' +import Switch from '@/components/Switch' +import DefaulModal from '@/components/DefaulModal' + +interface Props { + open: boolean + onClose: () => void +} + +const AddDocumentModal: FC = ({ open, onClose }) => { + const queryClient = useQueryClient() + const createDocumentMutation = useCreateDocument() + + // Form states + const [formData, setFormData] = useState({ + title: '', + description: '', + required: false + }) + + // Form errors + const [formErrors, setFormErrors] = useState({ + title: '', + description: '' + }) + + // Handlers + const handleClose = () => { + onClose() + // Reset form when closing + setFormData({ + title: '', + description: '', + required: false + }) + setFormErrors({ + title: '', + description: '' + }) + } + + const handleInputChange = (field: string, value: string | boolean) => { + setFormData(prev => ({ + ...prev, + [field]: value + })) + // Clear error when user starts typing + if (formErrors[field as keyof typeof formErrors]) { + setFormErrors(prev => ({ + ...prev, + [field]: '' + })) + } + } + + const validateForm = () => { + const errors = { + title: '', + description: '' + } + + if (!formData.title.trim()) { + errors.title = 'عنوان سند الزامی است' + } + + if (!formData.description.trim()) { + errors.description = 'توضیحات سند الزامی است' + } + + setFormErrors(errors) + return !errors.title && !errors.description + } + + const handleSubmit = async () => { + if (!validateForm()) return + + try { + await createDocumentMutation.mutateAsync(formData) + handleClose() + // Refetch documents + queryClient.invalidateQueries({ queryKey: ['documents'] }) + } catch (error) { + console.error('Error creating document:', error) + } + } + + return ( + +
+ handleInputChange('title', e.target.value)} + placeholder="عنوان سند را وارد کنید" + error_text={formErrors.title} + /> + +