This commit is contained in:
hamid zarghami
2025-12-10 10:42:50 +03:30
parent 9248fe3cee
commit a18e052909
9 changed files with 279 additions and 109 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+7
View File
@@ -0,0 +1,7 @@
'use client';
export default function PagerPage() {
// This page is just a route trigger, the actual modal is handled in DialogsLayout
// We return an empty div so the route exists for pathname detection
return <div className="hidden" />;
}
+18 -2
View File
@@ -12,7 +12,11 @@ import HomeIcon from '../icons/HomeIcon'
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useCart } from '@/app/[name]/(Dialogs)/cart/hook/useCart'; import { useCart } from '@/app/[name]/(Dialogs)/cart/hook/useCart';
function BottomNavBar() { type BottomNavBarProps = {
onPagerClick?: () => void;
};
function BottomNavBar({ onPagerClick }: BottomNavBarProps) {
const params = useParams(); const params = useParams();
const { name } = params; const { name } = params;
const pathname = usePathname(); const pathname = usePathname();
@@ -64,7 +68,19 @@ function BottomNavBar() {
} }
value={t('Cart')} value={t('Cart')}
/> />
<BottomNavLink href={`/${name}/pager`} icon={<PagerIcon width={20} height={20} />} value={t('Pager')} /> {onPagerClick ? (
<button
onClick={onPagerClick}
className="flex flex-col justify-arround items-center gap-[5px] text-disabled2 pointer-events-auto dark:**:stroke-neutral-500"
>
<PagerIcon width={20} height={20} />
<span className="text-xs2 text-disabled-text">
{t('Pager')}
</span>
</button>
) : (
<BottomNavLink href={`/${name}/pager`} icon={<PagerIcon width={20} height={20} />} value={t('Pager')} />
)}
<BottomNavHighlightLink <BottomNavHighlightLink
href={`/${name}`} href={`/${name}`}
icon={ icon={
+112
View File
@@ -0,0 +1,112 @@
'use client';
import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { motion } from 'framer-motion';
import AnimatedBottomSheet from '@/components/bottomsheet/AnimatedBottomSheet';
import NotificationBellIcon from '@/components/icons/NotificationBellIcon';
import PlusIcon from '@/components/icons/PlusIcon';
import MinusIcon from '@/components/icons/MinusIcon';
import Button from '../button/PrimaryButton';
import { Button as OutlineButton } from '@/components/ui/button';
import { usePager } from './hooks/usePagerData';
import { toast } from '../Toast';
import { extractErrorMessage } from '@/lib/func';
type PagerModalProps = {
visible: boolean;
onClose: () => void;
};
export default function PagerModal({ visible, onClose }: PagerModalProps) {
const { t } = useTranslation('parallels', { keyPrefix: 'Pager' });
const [tableNumber, setTableNumber] = useState(1);
const { mutate: mutatePager, isPending } = usePager();
const [message, setMessage] = useState('');
const handleIncrement = () => {
setTableNumber((prev) => prev + 1);
};
const handleDecrement = () => {
setTableNumber((prev) => Math.max(1, prev - 1));
};
const handlePage = () => {
mutatePager({ tableNumber: tableNumber.toString(), message: message }, {
onSuccess: () => {
handleClose();
toast('درخواست شما با موفقیت ثبت شد', 'success');
},
onError: (error) => {
toast(extractErrorMessage(error), 'error');
}
});
};
const handleClose = () => {
setTableNumber(1);
onClose();
};
useEffect(() => {
if (!visible) {
setTableNumber(1);
}
}, [visible]);
return (
<AnimatedBottomSheet
visible={visible}
onClick={handleClose}
showTitle={false}
showCloseButton={false}
overrideClassName="!pt-6 bg-container!"
blurOpacity={null}
noBlur={false}
>
<div className="px-6 pb-8 flex flex-col">
<div className='flex justify-center gap-2 border-b border-border pb-10'>
<NotificationBellIcon width={24} height={24} className="text-foreground" />
<div className='font-bold'>پیجر گارسون</div>
</div>
<div className='mt-6 flex items-center justify-between border-b border-border pb-6'>
<div className='text-sm font-bold'>شماره میز خود را وارد کنید</div>
<div className='max-w-[123px] w-full flex justify-between items-center'>
<button onClick={handleIncrement} className='size-8 bg-[#F2F2F2] rounded-[6px] flex justify-center items-center'>
<PlusIcon size={14} className="text-foreground" />
</button>
<div className='pt-1 font-semibold'>{tableNumber}</div>
<button onClick={handleDecrement} className='size-8 bg-[#F2F2F2] rounded-[6px] flex justify-center items-center'>
<MinusIcon size={14} className="text-foreground" />
</button>
</div>
</div>
<div className='mt-3'>
<textarea
className='w-full px-4 py-2.5 mt-4 text-sm2 leading-6 outline-0 border border-border rounded-normal resize-none focus:ring-0'
placeholder='پیام خود را وارد کنید (اختیاری)'
id='description'
name='description'
value={message}
onChange={(e) => setMessage(e.target.value)}
></textarea>
</div>
<div className='mt-7 flex gap-4 items-center'>
<div className='flex-1'>
<Button pending={isPending} onClick={handlePage}>پیج کنید</Button>
</div>
<div className='flex-1'>
<OutlineButton onClick={handleClose} variant="outline" className="w-full bg-white rounded-normal p-3 font-normal text-sm">انصراف</OutlineButton>
</div>
</div>
</div>
</AnimatedBottomSheet>
);
}
@@ -0,0 +1,8 @@
import { useMutation } from "@tanstack/react-query";
import * as api from "../service/PagerService";
export const usePager = () => {
return useMutation({
mutationFn: api.pager,
});
};
@@ -0,0 +1,7 @@
import { api } from "@/config/axios";
import { CreatePagerType } from "../types/Types";
export const pager = async (params: CreatePagerType) => {
const { data } = await api.post("/public/pager", params);
return data;
};
+4
View File
@@ -0,0 +1,4 @@
export type CreatePagerType = {
tableNumber: string;
message: string;
};
@@ -5,8 +5,9 @@ import TopBar from '../topbar/TopBar'
import SideMenu from '../menu/SideMenu' import SideMenu from '../menu/SideMenu'
import BottomNavBar from '../navigation/BottomNavBar' import BottomNavBar from '../navigation/BottomNavBar'
import useToggle from '@/hooks/helpers/useToggle'; import useToggle from '@/hooks/helpers/useToggle';
import { usePathname } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import usePreference from '@/hooks/helpers/usePreference'; import usePreference from '@/hooks/helpers/usePreference';
import PagerModal from '../pager/PagerModal';
type Props = {} & React.AllHTMLAttributes<HTMLBodyElementEventMap> type Props = {} & React.AllHTMLAttributes<HTMLBodyElementEventMap>
@@ -15,6 +16,9 @@ function ClientMenuRouteWrapper({ children }: Props) {
const { state: menuState, toggle: _toggleMenuState, set: setMenuState } = useToggle(false); const { state: menuState, toggle: _toggleMenuState, set: setMenuState } = useToggle(false);
const { state: searchModal, toggle: _toggleSearchModal } = useToggle(false); const { state: searchModal, toggle: _toggleSearchModal } = useToggle(false);
const { state: nightMode, toggle: _toggleNightMode } = usePreference<boolean>('night-mode', false); const { state: nightMode, toggle: _toggleNightMode } = usePreference<boolean>('night-mode', false);
const { state: pagerOpen, toggle: togglePager, set: setPagerOpen } = useToggle(false);
const router = useRouter();
const pathname = usePathname();
const toggleProfileDrop = () => { const toggleProfileDrop = () => {
_toggleProfileDrop(); _toggleProfileDrop();
@@ -32,6 +36,10 @@ function ClientMenuRouteWrapper({ children }: Props) {
_toggleSearchModal(); _toggleSearchModal();
} }
const handleClosePager = () => {
setPagerOpen(false);
};
const location = usePathname(); const location = usePathname();
useEffect(() => { useEffect(() => {
@@ -59,7 +67,7 @@ function ClientMenuRouteWrapper({ children }: Props) {
<div className="fixed bottom-0 left-0 right-0 z-45 px-4"> <div className="fixed bottom-0 left-0 right-0 z-45 px-4">
<BottomNavBar /> <BottomNavBar onPagerClick={togglePager} />
</div> </div>
@@ -76,6 +84,8 @@ function ClientMenuRouteWrapper({ children }: Props) {
> >
{children} {children}
</main> </main>
<PagerModal visible={pagerOpen} onClose={handleClosePager} />
</div> </div>
) )
+110 -104
View File
@@ -1,107 +1,113 @@
{ {
"Report": { "Report": {
"Heading": "گزارش اشکال", "Heading": "گزارش اشکال",
"FormHeading": "با برنامه به مشکلی برخوردید؟", "FormHeading": "با برنامه به مشکلی برخوردید؟",
"Description": "توضیحات خود را برای بررسی توسط ما ثبت کنید", "Description": "توضیحات خود را برای بررسی توسط ما ثبت کنید",
"InputTitle": { "InputTitle": {
"Label": "عنوان گزارش", "Label": "عنوان گزارش",
"Placeholder": "عنوان گزارش خود را وارد کنید" "Placeholder": "عنوان گزارش خود را وارد کنید"
},
"InputDescription": {
"Label": "توضیحات",
"Placeholder": "توضیحات خود را وارد کنید"
},
"ButtonSubmit": "ثبت"
}, },
"Cart": { "InputDescription": {
"Heading": "سبد خرید", "Label": "توضیحات",
"Description": "", "Placeholder": "توضیحات خود را وارد کنید"
"InputDescription": {
"Label": "توضیحات",
"Placeholder": ""
},
"SumOfItemsLabel": "جمع خرید:",
"SumOfItemsValue": "{price} تومان",
"ButtonCheckout": "مشاهده فاکتور و پرداخت"
}, },
"OrderDetail": { "ButtonSubmit": "ثبت"
"Heading": "ثبت نهایی", },
"Description": "در صورت بروز مشکل در پرداخت، لطفا با ما تماس بگیرید.", "Cart": {
"SectionShipping": { "Heading": "سبد خرید",
"Title": "روش تحویل", "Description": "",
"InputDeliveryType": { "InputDescription": {
"Label": "", "Label": "توضیحات",
"Options": { "Placeholder": ""
"Delivery": "ارسال با پیک", },
"Serve": "سرو در رستوران", "SumOfItemsLabel": "جمع خرید:",
"Pickup": "تحویل در محل" "SumOfItemsValue": "{price} تومان",
} "ButtonCheckout": "مشاهده فاکتور و پرداخت"
} },
}, "OrderDetail": {
"SectionAddress": { "Heading": "ثبت نهایی",
"Title": "آدرس", "Description": "در صورت بروز مشکل در پرداخت، لطفا با ما تماس بگیرید.",
"ButtonChangeAddress": "تغییر آدرس", "SectionShipping": {
"InputAddressType": { "Title": "روش تحویل",
"Label": "نوع آدرس", "InputDeliveryType": {
"Options": { "Label": "",
"Home": "آدرس منزل", "Options": {
"Work": "آدرس محل کار", "Delivery": "ارسال با پیک",
"Other": "آدرس دیگر" "Serve": "سرو در رستوران",
} "Pickup": "تحویل در محل"
}, }
"InputAddressDetails": { }
"Label": "", },
"Placeholder": "خیابان ولیعصر، کوچه 12، پلاک 34" "SectionAddress": {
} "Title": "آدرس",
}, "ButtonChangeAddress": "تغییر آدرس",
"SectionTable": { "InputAddressType": {
"Title": "شماره میز" "Label": "نوع آدرس",
}, "Options": {
"SectionPayment": { "Home": "آدرس منزل",
"Title": "انتخاب شیوه پرداخت", "Work": "آدرس محل کار",
"InputPaymentType": { "Other": "آدرس دیگر"
"Label": "", }
"Options": { },
"Online": "پرداخت آنلاین درگاه بانکی", "InputAddressDetails": {
"CashOnDelivery": "موجودی کیف پول" "Label": "",
} "Placeholder": "خیابان ولیعصر، کوچه 12، پلاک 34"
} }
}, },
"SectionCoupon": { "SectionTable": {
"Title": "کوپن", "Title": "شماره میز"
"InputCouponType": { },
"Label": "نوع کوپن", "SectionPayment": {
"Options": { "Title": "انتخاب شیوه پرداخت",
"Discount": "استفاده از امتیاز ها", "InputPaymentType": {
"GiftCard": "استفاده از کد تخفیف" "Label": "",
} "Options": {
}, "Online": "پرداخت آنلاین درگاه بانکی",
"InputCouponCode": { "CashOnDelivery": "موجودی کیف پول"
"Label": "", }
"Placeholder": "F12BB587", }
"Options": { },
"Default": "پیشفرض" "SectionCoupon": {
} "Title": "کوپن",
} "InputCouponType": {
}, "Label": "نوع کوپن",
"SectionSummary": { "Options": {
"Title": "جزئیات پرداخت", "Discount": "استفاده از امتیاز ها",
"Description": "لطفا قبل از پرداخت، اطلاعات زیر را بررسی کنید.", "GiftCard": "استفاده از کد تخفیف"
"SumOfItemsLabel": "جمع خرید:", }
"SumOfItemsValue": "{price} T", },
"DeliveryLabel": "هزینه ارسال:", "InputCouponCode": {
"DeliveryValue": "{shipping} T", "Label": "",
"DiscountLabel": "تخفیف:", "Placeholder": "F12BB587",
"DiscountValue": "{discount} T", "Options": {
"TaxLabel": "مالیات:", "Default": "پیشفرض"
"TaxValue": "{tax} T", }
"TotalLabel": "جمع کل:", }
"TotalValue": "{total} T", },
"ButtonViewCart": "مشاهده اقلام" "SectionSummary": {
}, "Title": "جزئیات پرداخت",
"CartModal": { "Description": "لطفا قبل از پرداخت، اطلاعات زیر را بررسی کنید.",
"Title": "اقلام سفارش" "SumOfItemsLabel": "جمع خرید:",
}, "SumOfItemsValue": "{price} T",
"ButtonSubmit": "پرداخت" "DeliveryLabel": "هزینه ارسال:",
} "DeliveryValue": "{shipping} T",
} "DiscountLabel": "تخفیف:",
"DiscountValue": "{discount} T",
"TaxLabel": "مالیات:",
"TaxValue": "{tax} T",
"TotalLabel": "جمع کل:",
"TotalValue": "{total} T",
"ButtonViewCart": "مشاهده اقلام"
},
"CartModal": {
"Title": "اقلام سفارش"
},
"ButtonSubmit": "پرداخت"
},
"Pager": {
"Title": "پیجر گارسون",
"TableNumberLabel": "شماره میز خود را وارد کنید",
"ButtonPage": "پیج کنید",
"ButtonCancel": "انصراف"
}
}