refactor: more use cases with useToggle
This commit is contained in:
@@ -4,6 +4,7 @@ import AnimatedBottomSheet from '@/components/bottomsheet/AnimatedBottomSheet';
|
||||
import Button from '@/components/button/PrimaryButton';
|
||||
import Combobox, { ComboboxOption } from '@/components/combobox/Combobox';
|
||||
import InputField from '@/components/input/InputField';
|
||||
import useToggle from '@/hooks/helpers/useToggle';
|
||||
import clsx from 'clsx';
|
||||
import { motion } from 'framer-motion';
|
||||
import { ArrowLeft, Box, Card, Cup, Icon, Shop, Ticket, TicketDiscount, TruckTick, Wallet2 } from 'iconsax-react';
|
||||
@@ -26,12 +27,12 @@ function OrderDetailInex() {
|
||||
const [paymentType, setPaymentType] = React.useState<string>('0');
|
||||
const [couponType, setCouponType] = React.useState<string>('0');
|
||||
const [couponCode, setCouponCode] = React.useState<string>('');
|
||||
const [cartModal, setCartModal] = React.useState<boolean>(false);
|
||||
const [couponCodeError, setCouponCodeError] = React.useState<string>(''); // TODO: handle coupon code error
|
||||
const [tableNumber, setTableNumber] = useState(0) // TODO: must be set to table number
|
||||
const incrementTableNumber = () => setTableNumber((prev) => prev + 1); // TODO: must be set to table number
|
||||
const decrementTableNumber = () => setTableNumber((prev) => prev - 1); // TODO: must be set to table number
|
||||
const address = "اراک، مصطفی خمینی، خیابان سینا کوچه چمران ساختمان شهرزاد"
|
||||
const { state: cartModal, toggle: toggleCartModal } = useToggle();
|
||||
|
||||
const deliveryOptions: Array<ComboboxOption> = [
|
||||
{ id: '0', title: t("SectionShipping.InputDeliveryType.Options.Delivery"), icon: TruckTick },
|
||||
@@ -76,10 +77,6 @@ function OrderDetailInex() {
|
||||
setCouponCode(id);
|
||||
}, []);
|
||||
|
||||
const toggleCartModal = useCallback(() => {
|
||||
setCartModal((prev) => !prev);
|
||||
}, []);
|
||||
|
||||
const addressSection = () => {
|
||||
if (deliveryType !== '0') {
|
||||
return null;
|
||||
@@ -313,4 +310,4 @@ function OrderDetailInex() {
|
||||
)
|
||||
}
|
||||
|
||||
export default OrderDetailInex
|
||||
export default OrderDetailInex
|
||||
|
||||
@@ -8,11 +8,11 @@ import Button from '@/components/button/PrimaryButton';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { MarkerData } from '@/app/[name]/(Profile)/profile/address/new/page';
|
||||
import { HandPlatter, Package } from 'lucide-react';
|
||||
import { motion } from 'framer-motion';
|
||||
import AnimatedBar from '@/components/utils/AnimatedBar';
|
||||
import { Clock } from 'iconsax-react';
|
||||
import BlurredOverlayContainer from '@/components/overlays/BlurredOverlayContainer';
|
||||
import clsx from 'clsx';
|
||||
import useToggle from '@/hooks/helpers/useToggle';
|
||||
import Prompt from '@/components/utils/Prompt';
|
||||
|
||||
const CustomMap = dynamic(
|
||||
() => import('@/components/map/CustomMap'),
|
||||
@@ -29,9 +29,8 @@ function OrderTrackingPage() {
|
||||
const [markers, setMarkers] = useState<MarkerData[]>([]);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [mapCenter, setMapCenter] = useState<[number, number]>([Number(params?.get('lon')) || 35.6892, Number(params?.get('lon')) || 51.3890]);
|
||||
const [bottomSheet1State, setBottomSheet1State] = useState<boolean>(false);
|
||||
const [cancelModalVisibility, setCancelModalVisibility] = useState<boolean>(false);
|
||||
const router = useRouter();
|
||||
const { state: cancelModal, toggle: toggleCancelModal } = useToggle();
|
||||
|
||||
// Example initial position (Tehran)
|
||||
const initialPosition = React.useMemo<[number, number]>(() => [35.6892, 51.3890], []);
|
||||
@@ -68,17 +67,7 @@ function OrderTrackingPage() {
|
||||
console.log('Map clicked at:', e.latlng);
|
||||
};
|
||||
|
||||
const toggleBottomSheet1 = () => {
|
||||
setBottomSheet1State((prev) => !prev);
|
||||
}
|
||||
|
||||
const toggleCancelModal = async (e?: React.MouseEvent) => {
|
||||
e?.preventDefault();
|
||||
e?.stopPropagation();
|
||||
setCancelModalVisibility((state) => !state);
|
||||
}
|
||||
|
||||
const onCancelOrder = (e: React.MouseEvent<HTMLButtonElement> | null) => {
|
||||
const onCancelOrder = (e: React.MouseEvent | null) => {
|
||||
if (!e) return;
|
||||
|
||||
};
|
||||
@@ -99,30 +88,6 @@ function OrderTrackingPage() {
|
||||
|
||||
<div className="absolute bottom-0 left-0 right-0 z-[1000]">
|
||||
<div className='relative w-full h-full' >
|
||||
<AnimatedBottomSheet
|
||||
bgOpacity={0}
|
||||
inDuration={0}
|
||||
blurOpacity={100}
|
||||
noBlur
|
||||
visible={bottomSheet1State}
|
||||
showCloseButton={false}
|
||||
showTitle={false}
|
||||
overrideClassName='!pt-6 bg-container!'
|
||||
>
|
||||
<div className='grid grid-cols-2 gap-4 px-4'>
|
||||
<Button
|
||||
onClick={toggleCancelModal}
|
||||
>
|
||||
انتخاب
|
||||
</Button>
|
||||
<Button
|
||||
onClick={toggleBottomSheet1}
|
||||
className='bg-disabled! text-primary!'
|
||||
>
|
||||
انصراف
|
||||
</Button>
|
||||
</div>
|
||||
</AnimatedBottomSheet>
|
||||
|
||||
<AnimatedBottomSheet
|
||||
bgOpacity={0}
|
||||
@@ -193,32 +158,18 @@ function OrderTrackingPage() {
|
||||
|
||||
<div className={clsx(
|
||||
'fixed inset-0 z-1001',
|
||||
!cancelModalVisibility && 'pointer-events-none'
|
||||
!cancelModal && 'pointer-events-none'
|
||||
)}>
|
||||
<BlurredOverlayContainer visible={cancelModalVisibility} onClick={toggleCancelModal} inDuration={100} outDuration={100} outDelay={75}>
|
||||
<div className="absolute top-1/2 left-6 right-6 px-6">
|
||||
<motion.div
|
||||
animate={{ y: cancelModalVisibility ? [10, 0] : [0, 10] }}
|
||||
transition={{ duration: 0.1, ease: 'easeInOut' }}
|
||||
className="top-1/2 absolute left-1/2 min-w-xs w-full max-w-sm text-center -translate-1/2 px-6 pt-8 pb-9 drop-shadow-container bg-white/63 rounded-4xl"
|
||||
>
|
||||
<h2 className="text-base font-medium">
|
||||
لفو سفارش
|
||||
</h2>
|
||||
<p className="text-xs font-medium mt-6">
|
||||
آیا از درخواست خود اطمینان دارید؟
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-5.5 mt-8">
|
||||
<Button onClick={onCancelOrder} className="text-sm font-normal">
|
||||
بله
|
||||
</Button>
|
||||
<Button onClick={toggleCancelModal} className="bg-disabled! text-disabled2! text-sm font-normal">
|
||||
منصرف شدم
|
||||
</Button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</BlurredOverlayContainer>
|
||||
<Prompt
|
||||
title={'لفو سفارش'}
|
||||
description={'آیا از درخواست خود اطمینان دارید؟'}
|
||||
textConfirm={'بله'}
|
||||
textCancel={'منصرف شدم'}
|
||||
onConfirm={onCancelOrder}
|
||||
visible={cancelModal}
|
||||
onClick={toggleCancelModal}
|
||||
onCancel={toggleCancelModal}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -6,11 +6,12 @@ import TabContainer from '@/components/tab/TabContainer';
|
||||
import { TabHeader } from '@/components/tab/TabHeader';
|
||||
import Comment from '@/components/utils/Comment';
|
||||
import RateBar from '@/components/utils/RateBar';
|
||||
import useToggle from '@/hooks/helpers/useToggle';
|
||||
import { AboutDataModel } from '@/lib/api/info/getAboutData';
|
||||
import { ArrowDown2, CallCalling, Clock, Gallery, InfoCircle, Instagram, Location, Star1, Whatsapp } from 'iconsax-react';
|
||||
import { useQueryState } from 'next-usequerystate';
|
||||
import Image from 'next/image';
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import React from 'react'
|
||||
|
||||
const sortings = [
|
||||
'جدیدترین',
|
||||
@@ -18,12 +19,8 @@ const sortings = [
|
||||
]
|
||||
|
||||
function AboutPage({ data }: Readonly<{ data: AboutDataModel; }>) {
|
||||
const [sortingModal, setSortingModal] = useState(false);
|
||||
const [sorting, setSorting] = useQueryState('sortBy', { defaultValue: '0' });
|
||||
|
||||
const toggleSortingModal = useCallback(() => {
|
||||
setSortingModal((state) => !state);
|
||||
}, []);
|
||||
const { state: sortingModal, toggle: toggleSortingModal, set: setSortingModal } = useToggle();
|
||||
|
||||
const changeSorting = (index: number) => {
|
||||
setSorting(() => String(index));
|
||||
@@ -31,6 +28,7 @@ function AboutPage({ data }: Readonly<{ data: AboutDataModel; }>) {
|
||||
}
|
||||
|
||||
const firstTab = () => {
|
||||
|
||||
return (
|
||||
<section aria-labelledby="about-title" className='py-4'>
|
||||
<section
|
||||
|
||||
@@ -35,7 +35,7 @@ function ChatIndex({ }: Props) {
|
||||
const [search, setSearch] = useState('');
|
||||
const [selectedChats, setSelectedChats] = useState<Array<string>>([]);
|
||||
const router = useRouter();
|
||||
const { active: deleteModal, onToggle: onToggleDeleteModal } = useToggle();
|
||||
const { state: deleteModal, toggle: toggleDeleteModal } = useToggle();
|
||||
|
||||
const [chatsList, setChatList] = useState<Array<ChatEntryModel>>([
|
||||
{
|
||||
@@ -106,7 +106,7 @@ function ChatIndex({ }: Props) {
|
||||
if (deleteModal) {
|
||||
setSelectedChats([]);
|
||||
}
|
||||
onToggleDeleteModal()
|
||||
toggleDeleteModal()
|
||||
};
|
||||
|
||||
const deleteSelectedChats = () => {
|
||||
@@ -153,7 +153,7 @@ function ChatIndex({ }: Props) {
|
||||
<SearchBox placeholder={t('InputSearch.Placeholder')} value={search} onChange={(e) => setSearch(e.target.value)} />
|
||||
|
||||
{selectedChats.length > 0 ?
|
||||
<span onClick={onToggleDeleteModal} className='bg-container p-2 rounded-xl active:bg-gray-50'>
|
||||
<span onClick={toggleDeleteModal} className='bg-container p-2 rounded-xl active:bg-gray-50'>
|
||||
<Trash size={24} className='stroke-primary' />
|
||||
</span>
|
||||
:
|
||||
|
||||
@@ -22,6 +22,7 @@ import CategorySmallItemRenderer from "@/components/listview/CategorySmallItemRe
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ComboBox, { ComboboxOption } from "@/components/combobox/Combobox";
|
||||
import useToggle from "@/hooks/helpers/useToggle";
|
||||
|
||||
const categories = new Array(13).fill({ title: "خوراک", icon: "" });
|
||||
|
||||
@@ -148,8 +149,9 @@ const MenuIndex = () => {
|
||||
{ id: '0', title: tMenu('MenuFilterDrawer.SelectDelivery.Options.Courier'), label: '' },
|
||||
]
|
||||
|
||||
const [filterModal, setFilterModal] = useState(false);
|
||||
const [sortingModal, setSortingModal] = useState(false);
|
||||
const { state: filterModal, toggle: toggleFilterModal } = useToggle();
|
||||
const { state: sortingModal, toggle: toggleSortingModal } = useToggle();
|
||||
|
||||
const [, setSorting] = useQueryState('sortBy', { defaultValue: '0' });
|
||||
const [search, setSearch] = useQueryState("q", { defaultValue: '' });
|
||||
const [selectedCategory, setSelectedCategory] = useQueryState('category', { defaultValue: '0' });
|
||||
@@ -191,14 +193,6 @@ const MenuIndex = () => {
|
||||
setSelectedCategory(String(id));
|
||||
}, [setSelectedCategory]);
|
||||
|
||||
const toggleFilterModal = useCallback(() => {
|
||||
setFilterModal((state) => !state);
|
||||
}, []);
|
||||
|
||||
const toggleSortingModal = useCallback(() => {
|
||||
setSortingModal((state) => !state);
|
||||
}, []);
|
||||
|
||||
const changeSorting = (index: number) => {
|
||||
setSorting(() => String(index));
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import AnimatedBottomSheet from '@/components/bottomsheet/AnimatedBottomSheet';
|
||||
import Button from '@/components/button/PrimaryButton';
|
||||
import InputField from '@/components/input/InputField';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import useToggle from '@/hooks/helpers/useToggle';
|
||||
|
||||
const CustomMap = dynamic(
|
||||
() => import('@/components/map/CustomMap'),
|
||||
@@ -60,8 +61,8 @@ function OrderTrackingPage() {
|
||||
const [markers, setMarkers] = useState<MarkerData[]>([]);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [mapCenter, setMapCenter] = useState<[number, number]>([Number(params?.get('lon')) || 35.6892, Number(params?.get('lon')) || 51.3890]);
|
||||
const [bottomSheet1State, setBottomSheet1State] = useState<boolean>(false);
|
||||
const [bottomSheet2State, setBottomSheet2State] = useState<boolean>(false);
|
||||
const { state: confirmModal, toggle: toggleConfirmModal, set: setConfirmModal } = useToggle();
|
||||
const { state: detailsModal, toggle: _toggleDetailsModal, set: setDetailsModal } = useToggle();
|
||||
|
||||
// Example initial position (Tehran)
|
||||
const initialPosition = React.useMemo<[number, number]>(() => [35.6892, 51.3890], []);
|
||||
@@ -97,8 +98,8 @@ function OrderTrackingPage() {
|
||||
setSelectedAddress(null);
|
||||
return position;
|
||||
});
|
||||
setBottomSheet1State(position && true);
|
||||
setBottomSheet2State(false);
|
||||
setConfirmModal(position && true);
|
||||
setDetailsModal(false);
|
||||
// You can handle the selected position here
|
||||
console.log('Selected position:', position);
|
||||
};
|
||||
@@ -111,19 +112,16 @@ function OrderTrackingPage() {
|
||||
console.log('Map clicked at:', e.latlng);
|
||||
};
|
||||
|
||||
const toggleBottomSheet1 = () => {
|
||||
setBottomSheet1State((prev) => !prev);
|
||||
}
|
||||
|
||||
const toggleBottomSheet2 = async () => {
|
||||
const toggleDetailsModal = async () => {
|
||||
if (!selectedPosition) {
|
||||
setBottomSheet1State(false);
|
||||
setBottomSheet2State(false);
|
||||
setConfirmModal(false);
|
||||
setDetailsModal(false);
|
||||
return;
|
||||
}
|
||||
setBottomSheet1State(false);
|
||||
setBottomSheet2State((prev) => !prev);
|
||||
if (!bottomSheet2State) {
|
||||
setConfirmModal(false);
|
||||
_toggleDetailsModal();
|
||||
if (!detailsModal) {
|
||||
const address = await fetchAddressFromCoordinates(selectedPosition[0], selectedPosition[1]);
|
||||
setSelectedAddress(address);
|
||||
}
|
||||
@@ -148,6 +146,32 @@ function OrderTrackingPage() {
|
||||
console.log(formData);
|
||||
}
|
||||
|
||||
const getSelectedAddress = () => {
|
||||
if (!selectedAddress) {
|
||||
return "آدرس یافت نشد"
|
||||
}
|
||||
try {
|
||||
return [
|
||||
selectedAddress.address.state ?? selectedAddress.address.province,
|
||||
selectedAddress.address.city,
|
||||
selectedAddress.address.neighbourhood,
|
||||
!selectedAddress.address.road.startsWith('میدان') &&
|
||||
!selectedAddress.address.road.startsWith('بلوار') &&
|
||||
!selectedAddress.address.road.startsWith('خیابان') &&
|
||||
!selectedAddress.address.road.startsWith('کوچه') ?
|
||||
selectedAddress.type === 'secondary' ? `بلوار ${selectedAddress.address.road}` :
|
||||
selectedAddress.type === 'tertiary' ? `خیابان ${selectedAddress.address.road}` :
|
||||
selectedAddress.type === 'residential' ? `کوچه ${selectedAddress.address.road}` :
|
||||
selectedAddress.address.road : selectedAddress.address.road
|
||||
].filter(x => x).join('، ')
|
||||
} catch {
|
||||
if (selectedAddress.display_name)
|
||||
return selectedAddress.display_name;
|
||||
else
|
||||
return "آدرس یافت نشد"
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-gray-50">
|
||||
|
||||
@@ -175,19 +199,19 @@ function OrderTrackingPage() {
|
||||
inDuration={0}
|
||||
blurOpacity={null}
|
||||
noBlur
|
||||
visible={bottomSheet1State}
|
||||
visible={confirmModal}
|
||||
showCloseButton={false}
|
||||
showTitle={false}
|
||||
overrideClassName='!pt-6 bg-container!'
|
||||
>
|
||||
<div className='grid grid-cols-2 gap-4 px-4'>
|
||||
<Button
|
||||
onClick={toggleBottomSheet2}
|
||||
onClick={toggleDetailsModal}
|
||||
>
|
||||
انتخاب
|
||||
</Button>
|
||||
<Button
|
||||
onClick={toggleBottomSheet1}
|
||||
onClick={toggleConfirmModal}
|
||||
className='bg-disabled! text-foreground!'
|
||||
>
|
||||
انصراف
|
||||
@@ -200,9 +224,9 @@ function OrderTrackingPage() {
|
||||
inDuration={0}
|
||||
blurOpacity={null}
|
||||
noBlur
|
||||
visible={bottomSheet2State}
|
||||
visible={detailsModal}
|
||||
title='آدرس'
|
||||
onClick={toggleBottomSheet2}
|
||||
onClick={toggleDetailsModal}
|
||||
overrideClassName='bg-container!'
|
||||
>
|
||||
<form onSubmit={submitAddressAction}>
|
||||
@@ -214,19 +238,7 @@ function OrderTrackingPage() {
|
||||
className='h-6 w-full'
|
||||
/>
|
||||
:
|
||||
[
|
||||
selectedAddress.address.state ?? selectedAddress.address.province,
|
||||
selectedAddress.address.city,
|
||||
selectedAddress.address.neighbourhood,
|
||||
!selectedAddress.address.road.startsWith('میدان') &&
|
||||
!selectedAddress.address.road.startsWith('بلوار') &&
|
||||
!selectedAddress.address.road.startsWith('خیابان') &&
|
||||
!selectedAddress.address.road.startsWith('کوچه') ?
|
||||
selectedAddress.type === 'secondary' ? `بلوار ${selectedAddress.address.road}` :
|
||||
selectedAddress.type === 'tertiary' ? `خیابان ${selectedAddress.address.road}` :
|
||||
selectedAddress.type === 'residential' ? `کوچه ${selectedAddress.address.road}` :
|
||||
selectedAddress.address.road : selectedAddress.address.road
|
||||
].filter(x => x).join('، ')
|
||||
getSelectedAddress()
|
||||
}
|
||||
</span>
|
||||
<hr className='border border-border mt-3 mb-10 ' />
|
||||
@@ -252,7 +264,7 @@ function OrderTrackingPage() {
|
||||
</Button>
|
||||
<Button
|
||||
type='button'
|
||||
onClick={toggleBottomSheet2}
|
||||
onClick={toggleDetailsModal}
|
||||
className='bg-disabled! text-foreground!'
|
||||
>
|
||||
انصراف
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { Metadata, Viewport } from "next";
|
||||
import "./globals.css";
|
||||
import { ReactQueryProvider } from "@/components/providers/ReactQueryProvider";
|
||||
import { ReactQueryProvider } from "@/features/providers/ReactQueryProvider";
|
||||
import { notFound } from "next/navigation";
|
||||
import i18nConfig from "../../i18nConfig";
|
||||
import initTranslations from '@/lib/i18n';
|
||||
|
||||
Reference in New Issue
Block a user