import { Button, DatePicker, Drawer, Dropdown, Form, Input, Menu, message, Modal, Select, Table, Tooltip, Typography, } from "antd"; import React, { useEffect, useRef, useState } from "react"; import dayjs from "dayjs"; import "dayjs/locale/en"; import localizedFormat from "dayjs/plugin/localizedFormat"; import tagIcon from "../../assets/tagIcon.svg"; import { CheckOutlined, CloseOutlined, DeleteOutlined, DollarOutlined, EditOutlined, EllipsisOutlined, PlusOutlined, QuestionCircleOutlined, SearchOutlined, } from "@ant-design/icons"; import { theme } from "antd"; import { useAccountingData } from "../../Hooks/Accounting"; import moment from "moment"; import api from "../../API/api"; import { useTeamData } from "../../Hooks/Teams"; type Employee = { id: number; full_name: string; username: string; }; type BonusData = { employee: Employee; charges: any[]; total: number; }; interface BonusesTableProps { bonusesData: BonusData[]; } const AccountingCurrent: React.FC = () => { dayjs.extend(localizedFormat); const themes = localStorage.getItem("theme") === "true" ? true : false; const [open, setOpen] = useState(false); const [selectedUser, setSelectedUser] = useState(null); const currentInfo = new Date().toLocaleString("default", { month: "long" }); const { Option } = Select; // const currentMonth = moment().month(); // const currentYear = moment().year(); // const today = moment().endOf("day"); const currentMonth = dayjs().month(); // Hozirgi oy const currentYear = dayjs().year(); // Hozirgi yil const today = dayjs().endOf("day"); // const date = dayjs(new Date()); // new Date() ni dayjs bilan o'rnating // const formattedDate = date.locale("en").format("YYYY-MM-DD"); const disabledDate = (current: dayjs.Dayjs) => { return ( current && (current.month() !== currentMonth || current.year() !== currentYear || current.isAfter(today)) ); }; const [selectedUserId, setSelectedUserId] = useState(null); // const [selectedDate, setSelectedDate] = useState(null); const [selectedDate, setSelectedDate] = useState(null); const [form] = Form.useForm(); const [isBonusModalVisible, setIsBonusModalVisible] = useState(false); const [isChargeModalVisible, setIsChargeModalVisible] = useState(false); const [bonusesData, setBonusesData] = useState([]); const [chargesData, setChargesData] = useState([]); const [search, setSearch] = useState(""); const [team, setTeam] = useState(""); const showBonusModal = (userId: any) => { setSelectedUserId(userId); // Tanlangan user_id ni saqlash setIsBonusModalVisible(true); }; const showChargeModal = (userId: any) => { setIsChargeModalVisible(true); setSelectedUserId(userId); }; const handleCancel = () => { setIsBonusModalVisible(false); setIsChargeModalVisible(false); }; const { data, refetch, isLoading } = useAccountingData({ month: "current", search: search, team: team, }); const handleDateChange = (date: dayjs.Dayjs | null) => { setSelectedDate(date); form.setFieldsValue({ date }); }; const handleOkCharge = () => { form .validateFields() .then((values) => { const { date, amount, notes } = values; const formattedDate = selectedDate ? selectedDate.format("YYYY-MM-DD") : null; if (selectedUserId) { api .post(`/add-charge/${selectedUserId}/`, { date: formattedDate, amount: amount, reason: notes, }) .then((response) => { message.success(response.data.message); setIsChargeModalVisible(false); form.resetFields(); refetch(); }) .catch((error) => { console.error("API error:", error); }); } }) .catch((info) => { console.log("Validate Failed:", info); }); }; const handleOkBonus = () => { form .validateFields() .then((values) => { const { date, amount, notes } = values; const formattedDate = selectedDate ? selectedDate.format("YYYY-MM-DD") : null; if (selectedUserId) { api .post(`/add-bonus/${selectedUserId}/`, { date: formattedDate, amount: amount, reason: notes, }) .then((response) => { message.success(response.data.message); setIsBonusModalVisible(false); form.resetFields(); refetch(); }) .catch((error) => { console.error("API error:", error); }); } }) .catch((info) => { console.log("Validate Failed:", info); }); }; const menu = (userId: any) => ( showBonusModal(userId)}> Add Bonus showChargeModal(userId)}> Add Charge ); useEffect(() => { if (isBonusModalVisible || isChargeModalVisible) { setOpen(false); } }, [isBonusModalVisible, isChargeModalVisible]); const handleRowClick = (record: any, e: React.MouseEvent) => { setSelectedUser(record); const target = e.target as HTMLElement; const employee_id = record.employee_id; const apiUrl = `/bonuses/${employee_id}`; const chargeUrl = `/charges/${employee_id}`; const params = { month: "current", }; api .get(apiUrl, { params }) .then((response) => { const formattedData = response.data?.bonuses?.map( (bonus: any, index: any) => ({ no: index + 1, id: bonus.id, date: bonus.date, amount: bonus.amount, reason: bonus.reason || "", username: response.data.employee.username, total: response.data.total, }) ); setBonusesData(formattedData); }) .catch((error) => { console.error("Error:", error); }); api .get(chargeUrl, { params }) .then((response) => { const formattedData = response.data.charges.map( (charges: any, index: any) => ({ no: index + 1, id: charges.id, date: charges.date, amount: charges.amount, reason: charges.reason || "", username: response.data.employee.username, total: response.data.total, }) ); setChargesData(formattedData); }) .catch((error) => { console.error("Error:", error); }); if (!target.closest(".ant-dropdown-trigger")) { setOpen(true); } }; const [isEditModalVisible, setIsEditModalVisible] = useState(false); const [isEditBonusModalVisible, setIsEditBonusModalVisible] = useState(false); const [selectedRecord, setSelectedRecord] = useState<{ id?: string } | null>( null ); const [selectedRecordBonus, setSelectedRecordBonus] = useState<{ id?: string; } | null>(null); const showModalBonusEdit = (record: any) => { if (!record || typeof record !== "object") { console.error("Invalid record:", record); return; } const { date, ...fieldsWithoutDate } = record; setSelectedRecordBonus(record); form.setFieldsValue(fieldsWithoutDate); setIsEditBonusModalVisible(true); }; const showModal = (record: any) => { if (!record || typeof record !== "object") { console.error("Invalid record:", record); return; } const { date, ...fieldsWithoutDate } = record; setSelectedRecord(record); form.setFieldsValue(fieldsWithoutDate); setIsEditModalVisible(true); }; const Cancel = () => { setIsEditModalVisible(false); setIsEditBonusModalVisible(false); form.resetFields(); }; // const handleOkBonusEdit = async () => { // try { // const values = await form.validateFields(); // console.log(values); // if (!selectedRecordBonus) { // throw new Error("No record selected!"); // } // const updatedData = { // ...(selectedRecordBonus || {}), // ...values, // }; // const response = await api.put( // `bonus/${selectedRecordBonus.id}/`, // updatedData, // { // headers: { // "Content-Type": "application/json", // }, // } // ); // if (response.status === 202) { // setBonusesData((prevData: any) => // prevData.map((item: any) => // item.id === selectedRecordBonus.id // ? { ...item, ...updatedData } // : item // ) // ); // refetch(); // setIsEditBonusModalVisible(false); // } else { // throw new Error("Server Error"); // } // } catch (error) { // console.error(error); // } // }; // EDIT modal Charge const handleOkBonusEdit = async () => { try { const values = await form.validateFields(); if (!selectedRecordBonus) { throw new Error("No record selected!"); } // Faqat kerakli maydonlarni olish const updatedData = { amount: values.amount, reason: values.reason, // Formda `notes` deb saqlanayotgan bo‘lsa }; const response = await api.put( `bonus/${selectedRecordBonus.id}/`, updatedData, { headers: { "Content-Type": "application/json", }, } ); if (response.status === 202) { setBonusesData((prevData: any) => prevData.map((item: any) => item.id === selectedRecordBonus.id ? { ...item, ...updatedData } : item ) ); refetch(); setIsEditBonusModalVisible(false); } else { throw new Error("Server Error"); } } catch (error) { console.error(error); } }; // const handleOk = async () => { // try { // const values = await form.validateFields(); // if (!selectedRecord) { // throw new Error("No record selected!"); // } // const updatedData = { // ...(selectedRecord || {}), // ...values, // }; // const response = await api.put( // `charge/${selectedRecord.id}/`, // updatedData, // { // headers: { // "Content-Type": "application/json", // }, // } // ); // if (response.status === 202) { // setChargesData((prevData: any) => // prevData.map((item: any) => // item.id === selectedRecord.id ? { ...item, ...updatedData } : item // ) // ); // refetch(); // setIsEditModalVisible(false); // } else { // throw new Error("Server Error"); // } // } catch (error) { // console.error(error); // } // }; const handleOk = async () => { try { const values = await form.validateFields(); if (!selectedRecord) { throw new Error("No record selected!"); } // Faqat kerakli maydonlarni olish (masalan, `amount` va `reason`) const updatedData = { amount: values.amount, reason: values.reason, }; const response = await api.put( `charge/${selectedRecord.id}/`, updatedData, { headers: { "Content-Type": "application/json", }, } ); if (response.status === 202) { setChargesData((prevData: any) => prevData.map((item: any) => item.id === selectedRecord.id ? { ...item, ...updatedData } : item ) ); refetch(); setIsEditModalVisible(false); } else { throw new Error("Server Error"); } } catch (error) { console.error(error); } }; const { token } = theme.useToken(); const timerRef = useRef(null); const handleSearchChange = (e: React.ChangeEvent) => { if (timerRef.current) { clearTimeout(timerRef.current); } const searchText = e.target.value; timerRef.current = setTimeout(() => { setSearch(searchText); }, 1000); }; const teamData = useTeamData({}); const teamOptions: { label: string; value: any }[] | undefined = teamData?.data?.map((item) => ({ label: item?.name, value: item?.name, })); const additionalOption = { label: "all", value: "", }; if (teamOptions) { teamOptions.unshift(additionalOption); } const deleteFunctionBonus = (record: any) => { const { id } = record; const apiUrl = `/bonus/${id}`; api .delete(apiUrl) .then((response) => { if (response.status === 200) { setBonusesData((prevData: any) => { const updatedData = prevData.filter((item: any) => item.id !== id); return updatedData; }); message.success(response.data.message); } refetch(); }) .catch((error) => { console.error(error); }); }; const deleteFunctionCharge = (record: any) => { const { id } = record; const apiUrl = `/charge/${id}`; api .delete(apiUrl) .then((response) => { if (response.status === 200) { setChargesData((prevData: any) => { const updatedData = prevData.filter((item: any) => item.id !== id); return updatedData; }); message.success(response.data.message); } refetch(); }) .catch((error) => { console.error(error); }); }; return (
} onChange={handleSearchChange} />
} type="number" style={{ width: "100%" }} placeholder="0" onKeyPress={(e) => { if (e.key === "-" || e.key === "e") { e.preventDefault(); } }} /> {/* Textarea */} {/* Charge Modal */} Add
} cancelText={ Cancel } >
{/* Date Picker */} {/* Amount Input */} } type="number" style={{ width: "100%" }} placeholder="0" onKeyPress={(e) => { if (e.key === "-" || e.key === "e") { e.preventDefault(); } }} /> {/* Textarea */}
{/* EDIT CHARGE MODAL */} Save } cancelText={ Cancel } >
} type="number" style={{ width: "100%" }} placeholder="0" onKeyPress={(e) => { if (e.key === "-" || e.key === "e") { e.preventDefault(); } }} /> {/* Textarea */}
{/* EDIT Bonus MODAL */} Save } cancelText={ Cancel } >
} type="number" style={{ width: "100%" }} placeholder="0" onKeyPress={(e) => { if (e.key === "-" || e.key === "e") { e.preventDefault(); } }} />
); }; export default AccountingCurrent;