This commit is contained in:
@@ -12,7 +12,7 @@ import { extractErrorMessage } from '@/config/func'
|
||||
|
||||
const LoginStep1: FC = () => {
|
||||
|
||||
const { phone, setPhone, setStepLogin } = useAuthStore()
|
||||
const { phone, setPhone, setStepLogin, setDevOtpCode } = useAuthStore()
|
||||
const loginWithOtp = useLoginWithOtp()
|
||||
const checkHasAccount = useCheckHasAccount()
|
||||
|
||||
@@ -27,7 +27,10 @@ const LoginStep1: FC = () => {
|
||||
onSubmit(values) {
|
||||
setPhone(values.phone_email)
|
||||
loginWithOtp.mutate({ phone: values.phone_email }, {
|
||||
onSuccess() {
|
||||
onSuccess(data) {
|
||||
// TODO: remove before production — dev-only OTP autofill
|
||||
const code = data?.data?.code
|
||||
if (code) setDevOtpCode(String(code))
|
||||
setStepLogin(2)
|
||||
toast('کد تایید ارسال شد', 'success')
|
||||
},
|
||||
|
||||
@@ -15,7 +15,7 @@ import { Paths } from '@/config/Paths'
|
||||
|
||||
const LoginStep2: FC = () => {
|
||||
|
||||
const { phone, setStepLogin } = useAuthStore()
|
||||
const { phone, setStepLogin, devOtpCode, setDevOtpCode } = useAuthStore()
|
||||
const { value, reset } = useCountDown(2, true)
|
||||
const otpVerify = useOtpVerify()
|
||||
const loginWithOtp = useLoginWithOtp()
|
||||
@@ -24,7 +24,8 @@ const LoginStep2: FC = () => {
|
||||
const formik = useFormik<OtpVerifyType>({
|
||||
initialValues: {
|
||||
phone: phone,
|
||||
otp: ''
|
||||
// TODO: remove before production — dev-only OTP autofill
|
||||
otp: devOtpCode,
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
otp: Yup.string()
|
||||
@@ -81,7 +82,14 @@ const LoginStep2: FC = () => {
|
||||
|
||||
const reSend = () => {
|
||||
loginWithOtp.mutate({ phone: phone }, {
|
||||
onSuccess: () => {
|
||||
onSuccess: (data) => {
|
||||
// TODO: remove before production — dev-only OTP autofill
|
||||
const code = data?.data?.code
|
||||
if (code) {
|
||||
const otp = String(code)
|
||||
setDevOtpCode(otp)
|
||||
formik.setFieldValue('otp', otp)
|
||||
}
|
||||
reset()
|
||||
toast('کد مجدد ارسال شد', 'success')
|
||||
},
|
||||
|
||||
@@ -14,4 +14,8 @@ export const useAuthStore = create<AuthStoreType>((set) => ({
|
||||
setStepLogin(value) {
|
||||
set({ stepLogin: value });
|
||||
},
|
||||
devOtpCode: "",
|
||||
setDevOtpCode(value) {
|
||||
set({ devOtpCode: value });
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -12,6 +12,9 @@ export type AuthStoreType = {
|
||||
setEmail: (value: string) => void;
|
||||
stepLogin: number;
|
||||
setStepLogin: (value: number) => void;
|
||||
/** TODO: remove before production — dev-only OTP from API response */
|
||||
devOtpCode: string;
|
||||
setDevOtpCode: (value: string) => void;
|
||||
};
|
||||
|
||||
export type LoginWithPasswordType = {
|
||||
|
||||
+109
-32
@@ -1,21 +1,29 @@
|
||||
import { type FC } from 'react'
|
||||
import { useParams, useNavigate } from 'react-router-dom'
|
||||
import { useState, type FC } from 'react'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { useFormik } from 'formik'
|
||||
import { useGetSections } from '../print/hooks/usePrintData'
|
||||
import { useGetOrderPrint, useSubmitOrderPrint } from './hooks/useOrderData'
|
||||
import type { OrderPrintFormType } from './types/Types'
|
||||
import ManageForms from '../print/components/ManageForms'
|
||||
import PrintSectionCard from './components/PrintSectionCard'
|
||||
import PrintSectionNav from './components/PrintSectionNav'
|
||||
import { ORDER_PRINT_STORAGE_KEY } from './PrintPreview'
|
||||
import Button from '@/components/Button'
|
||||
import BackButton from '@/components/BackButton'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import { TickSquare } from 'iconsax-react'
|
||||
import { toast } from '@/shared/toast'
|
||||
import { extractErrorMessage } from '@/config/func'
|
||||
import { Paths } from '@/config/Paths'
|
||||
|
||||
const OrderPrint: FC = () => {
|
||||
const { id: orderId } = useParams()
|
||||
const navigate = useNavigate()
|
||||
const { data } = useGetSections()
|
||||
const { data, refetch: refetchSections, isFetching: isSectionsFetching } = useGetSections()
|
||||
const { isPending, mutate } = useSubmitOrderPrint()
|
||||
const { data: print } = useGetOrderPrint(orderId!)
|
||||
const { data: print, refetch: refetchPrint, isFetching: isPrintFetching } = useGetOrderPrint(orderId!)
|
||||
|
||||
const sections = data?.data ?? []
|
||||
|
||||
const [selectedSections, setSelectedSections] = useState<Set<string>>(() => new Set())
|
||||
|
||||
const formik = useFormik<OrderPrintFormType>({
|
||||
initialValues: {
|
||||
@@ -29,7 +37,6 @@ const OrderPrint: FC = () => {
|
||||
{
|
||||
onSuccess: () => {
|
||||
toast('با موفقیت ذخیره شد', 'success')
|
||||
navigate(-1)
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(extractErrorMessage(error), 'error')
|
||||
@@ -39,35 +46,105 @@ const OrderPrint: FC = () => {
|
||||
}
|
||||
})
|
||||
|
||||
const toggleSection = (id: string) => {
|
||||
setSelectedSections((prev) => {
|
||||
const next = new Set(prev)
|
||||
if (next.has(id)) next.delete(id)
|
||||
else next.add(id)
|
||||
return next
|
||||
})
|
||||
}
|
||||
|
||||
const toggleAll = (checked: boolean) => {
|
||||
setSelectedSections(checked ? new Set(sections.map((s) => s.id)) : new Set())
|
||||
}
|
||||
|
||||
const selectFilledSections = () => {
|
||||
const filledFieldIds = new Set(
|
||||
formik.values.fields
|
||||
.filter((f) => f.value?.trim())
|
||||
.map((f) => f.fieldId)
|
||||
)
|
||||
|
||||
const filledSectionIds = sections
|
||||
.filter((section) => section.fields.some((field) => filledFieldIds.has(field.id)))
|
||||
.map((s) => s.id)
|
||||
|
||||
if (filledSectionIds.length === 0) {
|
||||
toast('هیچ بخشی با مقدار پر شده یافت نشد', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
setSelectedSections(new Set(filledSectionIds))
|
||||
}
|
||||
|
||||
const handlePrint = () => {
|
||||
if (selectedSections.size === 0) {
|
||||
toast('حداقل یک بخش را انتخاب کنید', 'error')
|
||||
return
|
||||
}
|
||||
if (!orderId) return
|
||||
|
||||
sessionStorage.setItem(
|
||||
ORDER_PRINT_STORAGE_KEY(orderId),
|
||||
JSON.stringify({ fields: formik.values.fields })
|
||||
)
|
||||
|
||||
const sectionIds = Array.from(selectedSections).join(',')
|
||||
window.open(`${Paths.orderPrint}${orderId}/preview?sections=${sectionIds}`, '_blank')
|
||||
}
|
||||
|
||||
const handleRefresh = () => {
|
||||
refetchSections()
|
||||
refetchPrint()
|
||||
}
|
||||
|
||||
const isRefreshing = isSectionsFetching || isPrintFetching
|
||||
|
||||
return (
|
||||
<div className='mt-5'>
|
||||
<div className='flex justify-between items-center'>
|
||||
<h1 className='text-lg font-light'>فرم چاپ سفارش</h1>
|
||||
<Button
|
||||
className='w-fit px-6'
|
||||
isLoading={isPending}
|
||||
onClick={() => formik.handleSubmit()}
|
||||
>
|
||||
<div className='flex gap-1.5'>
|
||||
<TickSquare size={18} color='black' />
|
||||
<div className='text-[13px] font-light'>ذخیره</div>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
<div className='flex flex-col gap-5 mt-6'>
|
||||
{data?.data?.map((section) => (
|
||||
<div
|
||||
key={section.id}
|
||||
className='bg-white p-6 rounded-3xl'
|
||||
<div className="mt-5">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center gap-4">
|
||||
<BackButton to={Paths.order.list} />
|
||||
<h1 className="text-lg font-light">فرم چاپ سفارش</h1>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<RefreshButton onClick={handleRefresh} isLoading={isRefreshing} />
|
||||
<Button
|
||||
className="w-fit px-6"
|
||||
isLoading={isPending}
|
||||
onClick={() => formik.handleSubmit()}
|
||||
>
|
||||
<div className='font-bold'>{section.title}</div>
|
||||
<ManageForms
|
||||
<div className="flex gap-1.5">
|
||||
<TickSquare size={18} color="black" />
|
||||
<div className="text-[13px] font-light">ذخیره</div>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-6 mt-6 items-start">
|
||||
<div className="flex-1 flex flex-col gap-5 min-w-0">
|
||||
{sections.map((section) => (
|
||||
<PrintSectionCard
|
||||
key={section.id}
|
||||
title={section.title}
|
||||
fields={section.fields}
|
||||
formik={formik}
|
||||
attributes={section.fields}
|
||||
formFieldKey='fields'
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
))}
|
||||
</div>
|
||||
|
||||
{sections.length > 0 && (
|
||||
<PrintSectionNav
|
||||
sections={sections}
|
||||
selectedIds={selectedSections}
|
||||
onToggle={toggleSection}
|
||||
onToggleAll={toggleAll}
|
||||
onSelectFilled={selectFilledSections}
|
||||
onPrint={handlePrint}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
import { useEffect, useMemo, type FC } from 'react'
|
||||
import { useParams, useSearchParams } from 'react-router-dom'
|
||||
import { useGetSections } from '@/pages/print/hooks/usePrintData'
|
||||
import { useGetOrderPrint } from './hooks/useOrderData'
|
||||
import PrintFieldDisplay from './components/PrintFieldDisplay'
|
||||
import Button from '@/components/Button'
|
||||
import { Printer } from 'iconsax-react'
|
||||
|
||||
const ORDER_PRINT_STORAGE_KEY = (orderId: string) => `order-print-draft-${orderId}`
|
||||
|
||||
const OrderPrintPreview: FC = () => {
|
||||
const { id: orderId } = useParams()
|
||||
const [searchParams] = useSearchParams()
|
||||
const { data: sectionsData } = useGetSections()
|
||||
const { data: printData } = useGetOrderPrint(orderId!)
|
||||
|
||||
const selectedSectionIds = useMemo(() => {
|
||||
const param = searchParams.get('sections')
|
||||
return param ? param.split(',').filter(Boolean) : []
|
||||
}, [searchParams])
|
||||
|
||||
const fieldValues = useMemo(() => {
|
||||
const stored = sessionStorage.getItem(ORDER_PRINT_STORAGE_KEY(orderId!))
|
||||
if (stored) {
|
||||
try {
|
||||
const parsed = JSON.parse(stored) as { fields: { fieldId: string; value: string }[] }
|
||||
return parsed.fields ?? []
|
||||
} catch {
|
||||
// fall through to API data
|
||||
}
|
||||
}
|
||||
return printData?.data?.fileds ?? []
|
||||
}, [orderId, printData?.data?.fileds])
|
||||
|
||||
const sections = useMemo(
|
||||
() =>
|
||||
(sectionsData?.data ?? []).filter((s) => selectedSectionIds.includes(s.id)),
|
||||
[sectionsData?.data, selectedSectionIds]
|
||||
)
|
||||
|
||||
const handlePrint = () => window.print()
|
||||
|
||||
useEffect(() => {
|
||||
document.title = 'چاپ فرم سفارش'
|
||||
|
||||
const html = document.documentElement
|
||||
const root = document.getElementById('root')
|
||||
|
||||
const enableScroll = (el: HTMLElement) => {
|
||||
el.style.setProperty('overflow', 'auto', 'important')
|
||||
el.style.setProperty('height', 'auto', 'important')
|
||||
el.style.setProperty('min-height', '100%', 'important')
|
||||
}
|
||||
|
||||
const resetScroll = (el: HTMLElement) => {
|
||||
el.style.removeProperty('overflow')
|
||||
el.style.removeProperty('height')
|
||||
el.style.removeProperty('min-height')
|
||||
}
|
||||
|
||||
enableScroll(html)
|
||||
enableScroll(document.body)
|
||||
if (root) enableScroll(root)
|
||||
|
||||
return () => {
|
||||
resetScroll(html)
|
||||
resetScroll(document.body)
|
||||
if (root) resetScroll(root)
|
||||
}
|
||||
}, [])
|
||||
|
||||
if (!sections.length) {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-white p-8">
|
||||
<p className="text-gray-500">بخشی برای چاپ انتخاب نشده است.</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="print-preview-page min-h-screen bg-white overflow-y-auto pb-16">
|
||||
<div className="no-print fixed top-4 left-4 z-50 flex gap-3">
|
||||
<Button className="w-auto px-6 shadow-lg" onClick={handlePrint}>
|
||||
<div className="flex gap-2 items-center">
|
||||
<Printer size={18} color="black" />
|
||||
<span className="text-[13px] font-medium">چاپ</span>
|
||||
</div>
|
||||
</Button>
|
||||
<Button
|
||||
className="w-auto px-6 shadow-lg bg-gray-200 !text-gray-700"
|
||||
onClick={() => window.close()}
|
||||
>
|
||||
<span className="text-[13px] font-medium">بستن</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="max-w-[210mm] mx-auto p-8 print:p-0">
|
||||
<header className="text-center mb-8 pb-4 border-b-2 border-gray-800">
|
||||
<h1 className="text-2xl font-bold text-gray-900">فرم چاپ سفارش</h1>
|
||||
<p className="text-sm text-gray-500 mt-2">
|
||||
{new Date().toLocaleDateString('fa-IR')}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div className="flex flex-col gap-6">
|
||||
{sections.map((section) => (
|
||||
<section
|
||||
key={section.id}
|
||||
className="flex border border-gray-300 rounded-lg overflow-hidden break-inside-avoid"
|
||||
>
|
||||
<div className="bg-gray-100 flex items-center justify-center px-3 py-5 shrink-0 w-[64px] border-l border-gray-200">
|
||||
<h2 className="text-lg font-bold text-gray-700 [writing-mode:vertical-rl] rotate-180 whitespace-nowrap">
|
||||
{section.title}
|
||||
</h2>
|
||||
</div>
|
||||
<div className="flex-1 p-5">
|
||||
<PrintFieldDisplay
|
||||
fields={section.fields}
|
||||
values={fieldValues}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<footer className="mt-8 pt-4 border-t border-gray-200 text-center text-xs text-gray-400 print:mt-6">
|
||||
نگاره — فرم چاپ سفارش
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<style>{`
|
||||
@media screen {
|
||||
html, body, #root {
|
||||
overflow: auto !important;
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
.no-print { display: none !important; }
|
||||
.print-preview-page { background: white !important; overflow: visible !important; }
|
||||
html, body, #root { overflow: visible !important; height: auto !important; background: white !important; }
|
||||
@page { margin: 15mm; size: A4; }
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export { ORDER_PRINT_STORAGE_KEY }
|
||||
export default OrderPrintPreview
|
||||
@@ -0,0 +1,44 @@
|
||||
import { type FC } from 'react'
|
||||
import type { EntityType } from '@/pages/formBuilder/types/Types'
|
||||
import type { OrderPrintFieldType } from '../types/Types'
|
||||
import { FieldTypeEnum } from '@/pages/formBuilder/enum/Enum'
|
||||
|
||||
type Props = {
|
||||
fields: EntityType[]
|
||||
values: OrderPrintFieldType[]
|
||||
}
|
||||
|
||||
const PrintFieldDisplay: FC<Props> = ({ fields, values }) => {
|
||||
const getValue = (fieldId: string) =>
|
||||
values.find((v) => v.fieldId === fieldId)?.value ?? ''
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-4">
|
||||
{fields.map((field) => {
|
||||
const value = getValue(field.id)
|
||||
const displayValue =
|
||||
field.type === FieldTypeEnum.checkbox && value
|
||||
? value.split(',').map((v) => v.trim()).filter(Boolean).join('، ')
|
||||
: value || '—'
|
||||
|
||||
return (
|
||||
<div
|
||||
key={field.id}
|
||||
className={
|
||||
field.type === FieldTypeEnum.textarea
|
||||
? 'sm:col-span-2'
|
||||
: ''
|
||||
}
|
||||
>
|
||||
<div className="text-xs text-gray-500 mb-1">{field.name}</div>
|
||||
<div className="text-sm text-gray-900 font-medium border-b border-gray-200 pb-1.5 min-h-[28px]">
|
||||
{displayValue}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PrintFieldDisplay
|
||||
@@ -0,0 +1,32 @@
|
||||
import { type FC } from 'react'
|
||||
import type { FormikProps } from 'formik'
|
||||
import type { EntityType } from '@/pages/formBuilder/types/Types'
|
||||
import type { OrderPrintFormType } from '../types/Types'
|
||||
import ManageForms from '@/pages/print/components/ManageForms'
|
||||
|
||||
type Props = {
|
||||
title: string
|
||||
fields: EntityType[]
|
||||
formik: FormikProps<OrderPrintFormType>
|
||||
}
|
||||
|
||||
const PrintSectionCard: FC<Props> = ({ title, fields, formik }) => {
|
||||
return (
|
||||
<div className="flex bg-white rounded-2xl overflow-hidden border border-gray-200 shadow-sm min-h-[100px]">
|
||||
<div className="bg-gray-100 flex items-center justify-center px-3 py-6 shrink-0 w-[72px]">
|
||||
<h2 className="text-xl font-bold text-gray-700 [writing-mode:vertical-rl] rotate-180 whitespace-nowrap tracking-wide">
|
||||
{title}
|
||||
</h2>
|
||||
</div>
|
||||
<div className="flex-1 p-6">
|
||||
<ManageForms
|
||||
formik={formik}
|
||||
attributes={fields}
|
||||
formFieldKey="fields"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PrintSectionCard
|
||||
@@ -0,0 +1,81 @@
|
||||
import { type FC } from 'react'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import Button from '@/components/Button'
|
||||
import { Printer } from 'iconsax-react'
|
||||
import type { SectionItemType } from '@/pages/print/types/Types'
|
||||
|
||||
type Props = {
|
||||
sections: SectionItemType[]
|
||||
selectedIds: Set<string>
|
||||
onToggle: (id: string) => void
|
||||
onToggleAll: (checked: boolean) => void
|
||||
onSelectFilled: () => void
|
||||
onPrint: () => void
|
||||
}
|
||||
|
||||
const PrintSectionNav: FC<Props> = ({
|
||||
sections,
|
||||
selectedIds,
|
||||
onToggle,
|
||||
onToggleAll,
|
||||
onSelectFilled,
|
||||
onPrint,
|
||||
}) => {
|
||||
const allSelected = sections.length > 0 && selectedIds.size === sections.length
|
||||
const someSelected = selectedIds.size > 0 && selectedIds.size < sections.length
|
||||
|
||||
return (
|
||||
<aside className="w-80 shrink-0 sticky top-4 self-start">
|
||||
<div className="bg-white rounded-2xl border border-gray-200 shadow-sm p-5 flex flex-col gap-4">
|
||||
<h3 className="text-sm font-bold text-gray-800 border-b border-gray-100 pb-3">
|
||||
بخشهای چاپ
|
||||
</h3>
|
||||
|
||||
<div className="flex items-center justify-between gap-2 pb-2 border-b border-gray-100">
|
||||
<label className="flex items-center gap-2.5 cursor-pointer">
|
||||
<Checkbox
|
||||
checked={allSelected ? true : someSelected ? 'indeterminate' : false}
|
||||
onCheckedChange={(checked) => onToggleAll(checked === true)}
|
||||
/>
|
||||
<span className="text-sm text-gray-600">انتخاب همه</span>
|
||||
</label>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onSelectFilled}
|
||||
className="text-xs text-[#8C90A3] hover:text-black border border-border rounded-lg px-2.5 py-1.5 transition-colors shrink-0 whitespace-nowrap"
|
||||
>
|
||||
دارای مقدار
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
{sections.map((section) => (
|
||||
<label
|
||||
key={section.id}
|
||||
className="flex items-center gap-2.5 cursor-pointer hover:bg-gray-50 rounded-lg p-1.5 -mx-1.5 transition-colors"
|
||||
>
|
||||
<Checkbox
|
||||
checked={selectedIds.has(section.id)}
|
||||
onCheckedChange={() => onToggle(section.id)}
|
||||
/>
|
||||
<span className="text-sm text-gray-700 leading-snug">{section.title}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
className="mt-2 w-full"
|
||||
onClick={onPrint}
|
||||
disabled={selectedIds.size === 0}
|
||||
>
|
||||
<div className="flex gap-2 items-center justify-center">
|
||||
<Printer size={18} color="black" />
|
||||
<span className="text-[13px] font-medium">چاپ</span>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
|
||||
export default PrintSectionNav
|
||||
@@ -67,14 +67,31 @@ const ManageForms: FC<Props> = (props) => {
|
||||
<div className='text-sm mb-3'>{item.name}</div>
|
||||
<div className='flex gap-5 flex-wrap'>
|
||||
{
|
||||
item.options?.map((value) => {
|
||||
item.options?.map((option) => {
|
||||
const selectedValues = (value?.value ?? '')
|
||||
.split(',')
|
||||
.map((v) => v.trim())
|
||||
.filter(Boolean)
|
||||
const isChecked = selectedValues.includes(option.value)
|
||||
|
||||
const handleCheckboxChange = (checked: boolean) => {
|
||||
if (item.multiple) {
|
||||
const next = checked
|
||||
? [...selectedValues, option.value]
|
||||
: selectedValues.filter((v) => v !== option.value)
|
||||
handleChange(item.id, next.join(','))
|
||||
} else {
|
||||
handleChange(item.id, checked ? option.value : '')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={value.id} className='flex gap-2 items-center'>
|
||||
<div>{value.value}</div>
|
||||
<div key={option.id} className='flex gap-2 items-center'>
|
||||
<div>{option.value}</div>
|
||||
<Checkbox
|
||||
name={item.id + ''}
|
||||
checked={value?.value === value.value}
|
||||
onCheckedChange={(checked) => handleChange(item.id, checked ? value.value : '')}
|
||||
checked={isChecked}
|
||||
onCheckedChange={handleCheckboxChange}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type FC } from "react";
|
||||
import { Route, Routes } from "react-router-dom";
|
||||
import { Route, Routes, useLocation } from "react-router-dom";
|
||||
import Home from "../pages/home/Home";
|
||||
import SideBar from "../shared/Sidebar";
|
||||
import Header from "../shared/Header";
|
||||
@@ -54,11 +54,23 @@ import UpdateRole from "@/pages/role/Update";
|
||||
import RequestDetail from "@/pages/requests/Detail";
|
||||
import ConvertToOrders from "@/pages/order/ConvertToOrders";
|
||||
import OrderPrint from "@/pages/order/Print";
|
||||
import OrderPrintPreview from "@/pages/order/PrintPreview";
|
||||
import TicketList from "@/pages/ticket/TicketList";
|
||||
import TicketDetail from "@/pages/ticket/Detail";
|
||||
import PaymentsList from "@/pages/payment/List";
|
||||
|
||||
const MainRouter: FC = () => {
|
||||
const location = useLocation()
|
||||
const isPrintPreview = /\/order\/print\/[^/]+\/preview/.test(location.pathname)
|
||||
|
||||
if (isPrintPreview) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path={Paths.orderPrint + ':id/preview'} element={<OrderPrintPreview />} />
|
||||
</Routes>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-4 overflow-hidden">
|
||||
<Header />
|
||||
@@ -99,6 +111,7 @@ const MainRouter: FC = () => {
|
||||
<Route path={Paths.order.create} element={<NewOrder />} />
|
||||
<Route path={Paths.order.edit + ":id"} element={<EditOrder />} />
|
||||
<Route path={Paths.convertToOrder} element={<ConvertToOrders />} />
|
||||
<Route path={Paths.orderPrint + ':id/preview'} element={<OrderPrintPreview />} />
|
||||
<Route path={Paths.orderPrint + ':id'} element={<OrderPrint />} />
|
||||
|
||||
<Route path={Paths.tickets.list} element={<TicketList />} />
|
||||
|
||||
@@ -67,7 +67,7 @@ const SideBar: FC = () => {
|
||||
title={t('sidebar.mainPage')}
|
||||
isActive={isActive('/home')}
|
||||
link={Paths.home}
|
||||
activeName='dashboard'
|
||||
activeName=''
|
||||
/>
|
||||
|
||||
<SideBarItem
|
||||
@@ -123,7 +123,7 @@ const SideBar: FC = () => {
|
||||
title={'فرم ساز'}
|
||||
isActive={isActive('print')}
|
||||
link={Paths.print.list}
|
||||
activeName='view_print'
|
||||
activeName='view_print_form'
|
||||
/>
|
||||
|
||||
<SideBarItem
|
||||
|
||||
Reference in New Issue
Block a user