From e1f6499ba0a7ab5d9e4c1fc5b1140f19a37ec7b4 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Wed, 10 Dec 2025 15:15:40 +0330 Subject: [PATCH] list of pager + change status --- src/langs/fa.json | 10 + src/pages/pager/List.tsx | 73 ++-- .../pager/components/PagerDetailModal.tsx | 168 ++++++++++ .../pager/components/PagerFiltersFields.tsx | 10 - .../pager/components/PagerTableColumns.tsx | 67 +++- src/pages/pager/enum/Enum.ts | 6 + src/pages/pager/hooks/README.md | 317 ------------------ src/pages/pager/hooks/usePagerData.ts | 21 ++ src/pages/pager/service/PagerService.ts | 13 + src/pages/pager/types/Types.ts | 20 +- 10 files changed, 321 insertions(+), 384 deletions(-) create mode 100644 src/pages/pager/components/PagerDetailModal.tsx create mode 100644 src/pages/pager/enum/Enum.ts delete mode 100644 src/pages/pager/hooks/README.md create mode 100644 src/pages/pager/hooks/usePagerData.ts create mode 100644 src/pages/pager/service/PagerService.ts diff --git a/src/langs/fa.json b/src/langs/fa.json index 41d6724..e0a2a14 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -875,5 +875,15 @@ "poor_quality": "کیفیت پایین", "overpriced": "قیمت بالا", "unfriendly_service": "خدمات نامناسب" + }, + "pager": { + "status": { + "pending": "در انتظار", + "acknowledged": "تایید شده", + "rejected": "رد شده", + "completed": "تکمیل شده" + }, + "change_status": "تغییر وضعیت", + "save": "ذخیره" } } diff --git a/src/pages/pager/List.tsx b/src/pages/pager/List.tsx index 8941b16..ffb0999 100644 --- a/src/pages/pager/List.tsx +++ b/src/pages/pager/List.tsx @@ -1,19 +1,21 @@ -import { type FC, useEffect, useState, useMemo } from 'react' -import { useSocket } from '@/pages/pager/hooks/useSocket' -import { getToken } from '@/config/func' -import type { PagersType, Pager } from './types/Types' +import { type FC, useMemo, useState } from 'react' +import type { Pager } from './types/Types' import Table from '@/components/Table' import Filters from '@/components/Filters' import { usePagerFilters } from './hooks/usePagerFilters' import { getPagerTableColumns } from './components/PagerTableColumns' import { usePagerFiltersFields } from './components/PagerFiltersFields' import type { RowDataType } from '@/components/types/TableTypes' +import { useGetPagers } from './hooks/usePagerData' +import PagerDetailModal from './components/PagerDetailModal' +import { useTranslation } from 'react-i18next' const PagersList: FC = () => { - const token = `Bearer ${getToken()}` - const { connect, isConnected, socket } = useSocket(import.meta.env.VITE_SOCKET_URL, token) + const { t } = useTranslation('global') + const [selectedPager, setSelectedPager] = useState(null) + const [isModalOpen, setIsModalOpen] = useState(false) - const [pagers, setPagers] = useState() + const { data: pagersData, isLoading } = useGetPagers() const { filters, @@ -25,42 +27,9 @@ const PagersList: FC = () => { totalPages, } = usePagerFilters() - useEffect(() => { - connect() - }, [connect]) - - const handleJoinRestaurant = () => { - socket?.emit('get:pagers') - } - - const handlePagersList = (data: PagersType) => { - setPagers(data) - } - - useEffect(() => { - if (isConnected && socket) { - socket.emit('join:restaurant') - } - }, [isConnected, socket]) - - useEffect(() => { - if (socket) { - socket.on('joined', handleJoinRestaurant) - socket.on('pagers:list', handlePagersList) - } - - return () => { - if (socket) { - socket.off('joined', handleJoinRestaurant) - socket.off('pagers:list', handlePagersList) - } - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [socket]) - const pagersList = useMemo(() => { - return pagers?.pagers || [] - }, [pagers]) + return pagersData?.data || [] + }, [pagersData]) const filteredPagers = useMemo(() => { return filteredData(pagersList) as Pager[] @@ -74,7 +43,17 @@ const PagersList: FC = () => { return totalPages(filteredPagers.length) }, [filteredPagers.length, totalPages]) - const columns = getPagerTableColumns() + const handleViewDetails = (pager: Pager) => { + setSelectedPager(pager) + setIsModalOpen(true) + } + + const handleCloseModal = () => { + setIsModalOpen(false) + setSelectedPager(null) + } + + const columns = getPagerTableColumns({ onViewDetails: handleViewDetails, t }) const filterFields = usePagerFiltersFields() return ( @@ -95,13 +74,19 @@ const PagersList: FC = () => { columns={columns} data={paginatedPagers as (Pager & RowDataType)[]} - isloading={false} + isloading={isLoading} pagination={{ currentPage, totalPages: totalPagesCount, onPageChange: handlePageChange, }} /> + + ) } diff --git a/src/pages/pager/components/PagerDetailModal.tsx b/src/pages/pager/components/PagerDetailModal.tsx new file mode 100644 index 0000000..df8d705 --- /dev/null +++ b/src/pages/pager/components/PagerDetailModal.tsx @@ -0,0 +1,168 @@ +import { type FC, useState, useEffect } from 'react' +import DefaulModal from '@/components/DefaulModal' +import type { Pager } from '../types/Types' +import { formatOptionalDate } from '@/helpers/func' +import Status from '@/components/Status' +import Select from '@/components/Select' +import Button from '@/components/Button' +import { useTranslation } from 'react-i18next' +import { useUpdatePagerStatus } from '../hooks/usePagerData' +import { PagerStatus } from '../enum/Enum' +import type { ItemsSelectType } from '@/components/Select' + +interface Props { + open: boolean + close: () => void + pager: Pager | null +} + +const PagerDetailModal: FC = ({ open, close, pager }) => { + const { t } = useTranslation('global') + const [selectedStatus, setSelectedStatus] = useState('') + const { mutate: updateStatus, isPending } = useUpdatePagerStatus() + + useEffect(() => { + if (pager) { + setSelectedStatus(pager.status) + } + }, [pager]) + + if (!pager) return null + + const statusOptions: ItemsSelectType[] = [ + { value: PagerStatus.Pending, label: t('pager.status.pending') }, + { value: PagerStatus.Acknowledged, label: t('pager.status.acknowledged') }, + { value: PagerStatus.Rejected, label: t('pager.status.rejected') }, + { value: PagerStatus.Completed, label: t('pager.status.completed') }, + ] + + const getStatusVariant = (status: string) => { + switch (status) { + case PagerStatus.Pending: + return 'warning' + case PagerStatus.Acknowledged: + return 'info' + case PagerStatus.Rejected: + return 'error' + case PagerStatus.Completed: + return 'success' + default: + return 'pending' + } + } + + const getStatusLabel = (status: string) => { + const option = statusOptions.find(opt => opt.value === status) + return option?.label || status + } + + const handleSaveStatus = () => { + if (selectedStatus && selectedStatus !== pager.status) { + updateStatus( + { id: pager.id, status: selectedStatus as PagerStatus }, + { + onSuccess: () => { + close() + }, + } + ) + } + } + + const statusVariant = getStatusVariant(pager.status) + const statusLabel = getStatusLabel(pager.status) + + return ( + +
+
+
+ +

+ {pager.tableNumber || '-'} +

+
+ +
+ +
+ +
+
+ + + +
+ +

+ {pager.user || '-'} +

+
+ + {pager.deletedAt && ( +
+ +

+ {formatOptionalDate(pager.deletedAt, { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + })} +

+
+ )} +
+ +
+ +

+ {pager.message || '-'} +

+
+ +
+ +