This commit is contained in:
@@ -4,6 +4,7 @@ import { Link } from 'react-router-dom'
|
||||
import { useDeleteAnnoncement, useGetAnnoncements } from './hooks/useAnnoncementData'
|
||||
import type { AnnoncementItemType } from './types/AnnoncementTypes'
|
||||
import Button from '../../components/Button'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import { Add, Edit } from 'iconsax-react'
|
||||
import Table from '../../components/Table'
|
||||
import moment from 'moment-jalaali'
|
||||
@@ -100,7 +101,11 @@ const AnnouncementList: FC = () => {
|
||||
<div>
|
||||
{t('announcement.announcements')}
|
||||
</div>
|
||||
<div>
|
||||
<div className='flex items-center gap-3'>
|
||||
<RefreshButton
|
||||
onClick={() => getAnnoncements.refetch()}
|
||||
isLoading={getAnnoncements.isFetching}
|
||||
/>
|
||||
<Link to={Paths.announcement.create}>
|
||||
<Button className='px-5'>
|
||||
<div className='flex gap-2'>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type FC, useEffect } from 'react'
|
||||
import Button from '../../components/Button'
|
||||
import BackButton from '@/components/BackButton'
|
||||
import { InfoCircle, TickCircle } from 'iconsax-react'
|
||||
import Input from '../../components/Input'
|
||||
import DatePickerComponent from '../../components/DatePicker'
|
||||
@@ -73,9 +74,7 @@ const Update: FC = () => {
|
||||
return (
|
||||
<div className='w-full mt-4'>
|
||||
<div className='flex w-full justify-between items-center'>
|
||||
<div>
|
||||
ویرایش اطلاعیه
|
||||
</div>
|
||||
<BackButton to={Paths.announcement.list} />
|
||||
<div>
|
||||
<Button
|
||||
className='px-5'
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { type FC, Fragment } from 'react'
|
||||
import { useGetDetailCriticisms } from './hooks/useCriticismsData'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import BackButton from '@/components/BackButton'
|
||||
import { Paths } from '@/config/Paths'
|
||||
// import { useTranslation } from 'react-i18next'
|
||||
// import PageLoading from '../../components/PageLoading'
|
||||
import { Paperclip2 } from 'iconsax-react'
|
||||
@@ -21,6 +23,7 @@ const CriticismsDetail: FC = () => {
|
||||
|
||||
return (
|
||||
<div className='mt-4'>
|
||||
<BackButton to={Paths.criticisms.list} />
|
||||
{
|
||||
getDetail.isPending ?
|
||||
<div className="flex justify-center items-center py-8">
|
||||
@@ -28,7 +31,7 @@ const CriticismsDetail: FC = () => {
|
||||
</div>
|
||||
:
|
||||
<Fragment>
|
||||
<div>
|
||||
<div className='mt-4'>
|
||||
{t('criticisms.criticism')}
|
||||
{/* {' #' + getDetail.data?.data?.criticism?.numericId} */}
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useDeleteCriticismsDetail, useGetCriticismsList } from './hooks/useCrit
|
||||
// import { useTranslation } from 'react-i18next'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Eye } from 'iconsax-react'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import { Paths } from '../../config/Paths'
|
||||
import type { CriticismsItemTypes } from './types/CriticismsTypes'
|
||||
import moment from 'moment-jalaali'
|
||||
@@ -81,8 +82,14 @@ const CriticismsList: FC = () => {
|
||||
|
||||
return (
|
||||
<div className='mt-4'>
|
||||
<div>
|
||||
{t('criticisms.criticisms_list')}
|
||||
<div className='flex justify-between items-center'>
|
||||
<div>
|
||||
{t('criticisms.criticisms_list')}
|
||||
</div>
|
||||
<RefreshButton
|
||||
onClick={() => getCriticismsList.refetch()}
|
||||
isLoading={getCriticismsList.isFetching}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
|
||||
@@ -3,6 +3,8 @@ import { Link, useParams } from 'react-router-dom';
|
||||
import moment from 'moment-jalaali';
|
||||
import { Edit } from 'iconsax-react';
|
||||
import { Paths } from '@/config/Paths';
|
||||
import BackButton from '@/components/BackButton';
|
||||
import RefreshButton from '@/components/RefreshButton';
|
||||
import { useGetInvoiceDetail } from './hooks/useInvoiceData';
|
||||
import InvoicePaymentsSection from './components/InvoicePaymentsSection';
|
||||
import { formatItemDiscountDisplay } from './utils/invoiceItem';
|
||||
@@ -12,7 +14,7 @@ const formatAmount = (amount: number) =>
|
||||
|
||||
const DetailPerfomaInvoice: FC = () => {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const { data: invoiceData, isLoading } = useGetInvoiceDetail(id);
|
||||
const { data: invoiceData, isLoading, refetch, isFetching } = useGetInvoiceDetail(id);
|
||||
const invoice = invoiceData?.data;
|
||||
|
||||
if (isLoading || !invoice) {
|
||||
@@ -31,20 +33,25 @@ const DetailPerfomaInvoice: FC = () => {
|
||||
return (
|
||||
<div className="mt-5">
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="text-lg font-light">
|
||||
پیش فاکتور #{invoice.invoiceNumber}
|
||||
</h1>
|
||||
<Link to={Paths.perfomaInvoice.update + invoice.id}>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 rounded-xl bg-primary px-5 py-2.5 text-sm hover:opacity-90"
|
||||
>
|
||||
<Edit size={18} color="black" />
|
||||
ویرایش
|
||||
</button>
|
||||
</Link>
|
||||
<BackButton to={Paths.perfomaInvoice.list} />
|
||||
<div className="flex items-center gap-3">
|
||||
<RefreshButton onClick={() => refetch()} isLoading={isFetching} />
|
||||
<Link to={Paths.perfomaInvoice.update + invoice.id}>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 rounded-xl bg-primary px-5 py-2.5 text-sm hover:opacity-90"
|
||||
>
|
||||
<Edit size={18} color="black" />
|
||||
ویرایش
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 className="text-lg font-light mt-4">
|
||||
پیش فاکتور #{invoice.invoiceNumber}
|
||||
</h1>
|
||||
|
||||
<div className="mt-8 rounded-3xl bg-white p-6">
|
||||
<div className="font-light">اطلاعات پیش فاکتور</div>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import Tabs from '@/components/Tabs'
|
||||
import { useMemo, useState, type FC } from 'react'
|
||||
import { ProformaInvoiceStatusEnum } from './enum/InvoiceEnum'
|
||||
import Filters from '@/components/Filters'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import Table from '@/components/Table'
|
||||
import { Eye, Add, Edit2 } from 'iconsax-react'
|
||||
import { Link } from 'react-router-dom'
|
||||
@@ -16,7 +17,7 @@ const ProformaInvoice: FC = () => {
|
||||
const [page, setPage] = useState(1)
|
||||
const [filters, setFilters] = useState<FilterValues>({})
|
||||
|
||||
const { data, isLoading } = useGetInvoice(page)
|
||||
const { data, isLoading, refetch, isFetching } = useGetInvoice(page)
|
||||
|
||||
const meta = data?.meta
|
||||
|
||||
@@ -86,12 +87,15 @@ const ProformaInvoice: FC = () => {
|
||||
<div className='mt-5'>
|
||||
<div className='flex justify-between items-center'>
|
||||
<h1 className='text-lg font-light'>پیش فاکتورها</h1>
|
||||
<Link to={Paths.perfomaInvoice.create}>
|
||||
<button className='flex items-center gap-2 px-4 py-2 bg-primary text-black text-sm font-medium rounded-xl hover:opacity-90 transition-opacity'>
|
||||
<Add size={18} />
|
||||
پیش فاکتور جدید
|
||||
</button>
|
||||
</Link>
|
||||
<div className='flex items-center gap-3'>
|
||||
<RefreshButton onClick={() => refetch()} isLoading={isFetching} />
|
||||
<Link to={Paths.perfomaInvoice.create}>
|
||||
<button className='flex items-center gap-2 px-4 py-2 bg-primary text-black text-sm font-medium rounded-xl hover:opacity-90 transition-opacity'>
|
||||
<Add size={18} />
|
||||
پیش فاکتور جدید
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='mt-8'>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Link, useSearchParams } from 'react-router-dom'
|
||||
import { Paths } from '@/config/Paths'
|
||||
import type { OrderListItemType } from './types/Types'
|
||||
import Button from '@/components/Button'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import UserSearch from '../user/UserSearch'
|
||||
import DesignerSearch from '../designer/DesignerSearch'
|
||||
import CategoriesSelect from '../product/components/CategoriesSelect'
|
||||
@@ -50,20 +51,23 @@ const OrdersList: FC = () => {
|
||||
}, { replace: true })
|
||||
}
|
||||
|
||||
const { data } = useGetOrders({ designId, categoryId, userId, ...filters })
|
||||
const { data, refetch, isFetching } = useGetOrders({ designId, categoryId, userId, ...filters })
|
||||
|
||||
return (
|
||||
<div className='mt-5'>
|
||||
<div className='flex justify-between items-center'>
|
||||
<h1 className='text-lg font-light'>سفارش ها</h1>
|
||||
<Link to={Paths.convertToOrder}>
|
||||
<Button className='w-fit px-6'>
|
||||
<div className='flex gap-2 items-center'>
|
||||
<AddSquare size={18} color='black' />
|
||||
سفارش جدید
|
||||
</div>
|
||||
</Button>
|
||||
</Link>
|
||||
<div className='flex items-center gap-3'>
|
||||
<RefreshButton onClick={() => refetch()} isLoading={isFetching} />
|
||||
<Link to={Paths.convertToOrder}>
|
||||
<Button className='w-fit px-6'>
|
||||
<div className='flex gap-2 items-center'>
|
||||
<AddSquare size={18} color='black' />
|
||||
سفارش جدید
|
||||
</div>
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='mt-8 flex flex-wrap items-end gap-4'>
|
||||
|
||||
@@ -2,6 +2,9 @@ import { type FC } from 'react'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import moment from 'moment-jalaali'
|
||||
import { User } from 'iconsax-react'
|
||||
import BackButton from '@/components/BackButton'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import { Paths } from '@/config/Paths'
|
||||
import { useGetOrderDetails } from './hooks/useOrderData'
|
||||
import TicketSection from './components/TicketSection'
|
||||
import OrderItem from './components/OrderItem'
|
||||
@@ -20,7 +23,7 @@ const InfoRow: FC<{ label: string; value?: string | number | null }> = ({ label,
|
||||
|
||||
const OrderDetail: FC = () => {
|
||||
const { id } = useParams()
|
||||
const { data } = useGetOrderDetails(id!)
|
||||
const { data, refetch, isFetching } = useGetOrderDetails(id!)
|
||||
const order = data?.data as (OrderDetailDataType & { items?: OrderItemType[] }) | undefined
|
||||
const creator = order?.creator
|
||||
const creatorName = creator ? `${creator.firstName} ${creator.lastName}`.trim() : ''
|
||||
@@ -28,8 +31,12 @@ const OrderDetail: FC = () => {
|
||||
return (
|
||||
<div className="w-full min-h-screen bg-[#eceef6] p-6">
|
||||
{/* Header */}
|
||||
<header className="mb-6">
|
||||
<span className="text-sm text-[#8C90A3]">سفارش #{order?.orderNumber}</span>
|
||||
<header className="flex items-center justify-between mb-6">
|
||||
<BackButton to={Paths.order.list} />
|
||||
<div className="flex items-center gap-3">
|
||||
<RefreshButton onClick={() => refetch()} isLoading={isFetching} />
|
||||
<span className="text-sm text-[#8C90A3]">سفارش #{order?.orderNumber}</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* اطلاعات سفارش */}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Button from '@/components/Button'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import UploadBox from '@/components/UploadBox'
|
||||
import { Microphone, Paperclip2 } from 'iconsax-react'
|
||||
import { useState, type FC } from 'react'
|
||||
@@ -20,7 +21,7 @@ const TicketSection: FC = () => {
|
||||
const [message, setMessage] = useState('')
|
||||
const [files, setFiles] = useState<File[]>([])
|
||||
const addTicket = useAddTicket()
|
||||
const { data, refetch } = useGetTickets(id!)
|
||||
const { data, refetch, isFetching } = useGetTickets(id!)
|
||||
const singleUpload = useSingleUpload()
|
||||
const multiUpload = useMultiUpload()
|
||||
|
||||
@@ -88,6 +89,10 @@ const TicketSection: FC = () => {
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-2xl p-6">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<h2 className="text-lg font-light">گفتگو</h2>
|
||||
<RefreshButton onClick={() => refetch()} isLoading={isFetching} />
|
||||
</div>
|
||||
{
|
||||
data?.data?.map((item) => {
|
||||
if (item.user)
|
||||
|
||||
@@ -3,29 +3,36 @@ import { useGetRequestDetail } from './hooks/useRequestData'
|
||||
import { Link, useParams } from 'react-router-dom'
|
||||
import RequestItem from './components/RequestItem'
|
||||
import { Paths } from '@/config/Paths'
|
||||
import BackButton from '@/components/BackButton'
|
||||
import Button from '@/components/Button'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import { TickSquare } from 'iconsax-react'
|
||||
import TicketSection from '../order/components/TicketSection'
|
||||
|
||||
const RequestDetail: FC = () => {
|
||||
const { id } = useParams()
|
||||
const { data } = useGetRequestDetail(id!)
|
||||
const { data, refetch, isFetching } = useGetRequestDetail(id!)
|
||||
|
||||
return (
|
||||
<div className="w-full min-h-screen bg-[#eceef6] p-6">
|
||||
{/* Header Section */}
|
||||
<div className="flex items-start justify-between mb-6">
|
||||
<div className="text-sm text-[#8C90A3]">
|
||||
درخواست #{data?.data?.requestNumber}
|
||||
</div>
|
||||
<Link to={Paths.perfomaInvoice.create + `?requestId=${id}`}>
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<BackButton to={Paths.requests.list} />
|
||||
<div className="flex items-center gap-3">
|
||||
<RefreshButton onClick={() => refetch()} isLoading={isFetching} />
|
||||
<Link to={Paths.perfomaInvoice.create + `?requestId=${id}`}>
|
||||
<Button className="w-fit px-5">
|
||||
<div className="flex gap-2 items-center">
|
||||
<TickSquare size={20} color="black" />
|
||||
<div>ثبت پیش فاکتور</div>
|
||||
</div>
|
||||
</Button>
|
||||
</Link>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-sm text-[#8C90A3] mb-6">
|
||||
درخواست #{data?.data?.requestNumber}
|
||||
</div>
|
||||
|
||||
{/* Request Information Section */}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Filters from '@/components/Filters'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import Table from '@/components/Table'
|
||||
import TrashWithConfrim from '@/components/TrashWithConfrim'
|
||||
import { extractErrorMessage } from '@/config/func'
|
||||
@@ -12,7 +13,7 @@ import { toast } from 'react-toastify'
|
||||
|
||||
const RequestList: FC = () => {
|
||||
|
||||
const { data } = useGetRequests()
|
||||
const { data, refetch, isFetching } = useGetRequests()
|
||||
const { mutate: deleteRequest, isPending: isDeleting } = useDeleteRequest()
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
@@ -28,7 +29,10 @@ const RequestList: FC = () => {
|
||||
|
||||
return (
|
||||
<div className='mt-5'>
|
||||
<h1 className='text-lg font-light'>درخواست ها</h1>
|
||||
<div className='flex justify-between items-center'>
|
||||
<h1 className='text-lg font-light'>درخواست ها</h1>
|
||||
<RefreshButton onClick={() => refetch()} isLoading={isFetching} />
|
||||
</div>
|
||||
|
||||
<div className='mt-8'>
|
||||
<Filters
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { type FC, useMemo, useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import BackButton from "@/components/BackButton";
|
||||
import Input from "@/components/Input";
|
||||
import { clx } from "@/helpers/utils";
|
||||
import { t } from "@/locale";
|
||||
import { Paths } from "@/config/Paths";
|
||||
import { getTicketDisplayName } from "./types/TicketTypes";
|
||||
import type { TicketDetailType } from "./types/TicketTypes";
|
||||
import { useCloseTicket, useCreateOrReplyTicket, useGetTicketById } from "./hooks/useTicketData";
|
||||
@@ -77,7 +79,8 @@ const TicketDetail: FC = () => {
|
||||
if (getTicket.isPending) {
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<div className="flex gap-1">{t("ticket.ticket_number")}</div>
|
||||
<BackButton to={Paths.tickets.list} />
|
||||
<div className="flex gap-1 mt-4">{t("ticket.ticket_number")}</div>
|
||||
<div className="mt-6">Loading...</div>
|
||||
</div>
|
||||
);
|
||||
@@ -86,7 +89,8 @@ const TicketDetail: FC = () => {
|
||||
if (!ticket) {
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<div className="flex gap-1">{t("ticket.ticket_number")}</div>
|
||||
<BackButton to={Paths.tickets.list} />
|
||||
<div className="flex gap-1 mt-4">{t("ticket.ticket_number")}</div>
|
||||
<div className="mt-6 text-description">{t("ticket.info_ticket")}</div>
|
||||
</div>
|
||||
);
|
||||
@@ -99,7 +103,8 @@ const TicketDetail: FC = () => {
|
||||
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<BackButton to={Paths.tickets.list} />
|
||||
<div className="flex items-center gap-2 flex-wrap mt-4">
|
||||
<span className="text-description">{t("ticket.ticket_number")}:</span>
|
||||
<span className="font-medium">{extendedTicket.numericId ?? ticket.id}</span>
|
||||
<span
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type FC, useState } from 'react'
|
||||
import { Eye } from 'iconsax-react'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import Tabs from '../../components/Tabs'
|
||||
import Table from '../../components/Table'
|
||||
import { Link } from 'react-router-dom'
|
||||
@@ -74,6 +75,10 @@ const TicketList: FC = () => {
|
||||
<div>
|
||||
تیکتهای کاربران
|
||||
</div>
|
||||
<RefreshButton
|
||||
onClick={() => getTickets.refetch()}
|
||||
isLoading={getTickets.isFetching}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='mt-14'>
|
||||
|
||||
Reference in New Issue
Block a user