make components for checkout
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
'use client';
|
||||
|
||||
import { ChevronLeft } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type AddressSectionProps = {
|
||||
address: string;
|
||||
};
|
||||
|
||||
export const AddressSection = ({ address }: AddressSectionProps) => {
|
||||
const params = useParams<{ name: string }>();
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
|
||||
return (
|
||||
<section className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<div className='w-full flex justify-between items-center gap-2'>
|
||||
<h3 className="text-sm2 font-medium leading-5 inline-block">{t("SectionAddress.Title")}</h3>
|
||||
<Link href={`/${params.name}/profile/address?redirect=/${params.name}/order/checkout/${params.id}`}>
|
||||
<button
|
||||
className='text-sm2 text-primary dark:text-foreground cursor-pointer'
|
||||
onClick={() => { /* Handle address change */ }}
|
||||
>
|
||||
{t("SectionAddress.ButtonChangeAddress")}
|
||||
<ChevronLeft className='inline-block mr-1 mb-0.5 stroke-primary dark:stroke-foreground' size='16' />
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
<p className='mt-6 text-sm2'>
|
||||
{address}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
'use client';
|
||||
|
||||
import { ArrowLeft } from 'iconsax-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const CheckoutHeader = () => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<div className='grid grid-cols-3 items-center py-4 '>
|
||||
<span></span>
|
||||
<h1 className='text-sm2 place-self-center font-medium'>{t("Heading")}</h1>
|
||||
<ArrowLeft
|
||||
className='cursor-pointer place-self-end'
|
||||
size='24'
|
||||
color='currentColor'
|
||||
onClick={() => { router.back() }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
'use client';
|
||||
|
||||
import Combobox, { ComboboxOption } from '@/components/combobox/Combobox';
|
||||
import InputField from '@/components/input/InputField';
|
||||
import clsx from 'clsx';
|
||||
import { Cup, Icon, Ticket, TicketDiscount } from 'iconsax-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type CouponSectionProps = {
|
||||
couponType: string;
|
||||
couponCode: string;
|
||||
couponCodeError: string;
|
||||
onCouponTypeChange: (id: string) => void;
|
||||
onCouponCodeChange: (value: string) => void;
|
||||
};
|
||||
|
||||
export const CouponSection = ({
|
||||
couponType,
|
||||
couponCode,
|
||||
couponCodeError,
|
||||
onCouponTypeChange,
|
||||
onCouponCodeChange,
|
||||
}: CouponSectionProps) => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
|
||||
const couponOptions: Array<{ id: string, label: string, icon: Icon }> = [
|
||||
{ id: '0', label: t("SectionCoupon.InputCouponType.Options.Discount"), icon: Cup },
|
||||
{ id: '1', label: t("SectionCoupon.InputCouponType.Options.GiftCard"), icon: Ticket },
|
||||
];
|
||||
|
||||
const couponDropdownOptions: Array<ComboboxOption> = [
|
||||
{ id: '0', title: t("SectionCoupon.InputCouponCode.Options.Default") },
|
||||
{ id: '1', title: "Something" },
|
||||
];
|
||||
|
||||
const handleCouponCodeChange = (id: string) => {
|
||||
if (id === '0') {
|
||||
onCouponCodeChange('');
|
||||
return;
|
||||
}
|
||||
onCouponCodeChange(id);
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<h3 className="text-sm2 font-medium leading-5">{t("SectionCoupon.Title")}</h3>
|
||||
|
||||
<div className='flex flex-col gap-5 mt-6'>
|
||||
{couponOptions.map(({ id, label, icon: Icon }) => (
|
||||
<div key={id} className='flex items-center'>
|
||||
<label className='flex items-center gap-2 w-full' htmlFor={`couponType${id}`}>
|
||||
<Icon
|
||||
size={16}
|
||||
color='currentColor'
|
||||
className='mr-2'
|
||||
/>
|
||||
<span className='text-xs mt-0.5'>{label}</span>
|
||||
</label>
|
||||
|
||||
<input
|
||||
checked={couponType === id}
|
||||
onChange={() => onCouponTypeChange(id)}
|
||||
type='radio'
|
||||
name='couponType'
|
||||
id={`couponType${id}`}
|
||||
className='size-4 accent-primary' />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Combobox
|
||||
className={clsx(
|
||||
'relative mt-6',
|
||||
couponType === '0' ? 'block' : 'hidden',
|
||||
couponCode.length === 0 && 'text-border **:stroke-border dark:text-neutral-500 dark:**:stroke-neutral-500'
|
||||
)}
|
||||
icon={TicketDiscount}
|
||||
placeholder={t("SectionCoupon.InputCouponCode.Placeholder")}
|
||||
title=''
|
||||
searchable={false}
|
||||
options={couponDropdownOptions}
|
||||
selectedId={couponCode}
|
||||
onSelectionChange={(e, i) => handleCouponCodeChange(String(i))}
|
||||
/>
|
||||
|
||||
<InputField
|
||||
autoComplete='off'
|
||||
className={clsx(
|
||||
'relative mt-6',
|
||||
couponType === '1' ? '' : 'hidden!',
|
||||
couponCodeError.trim() === 'valid' && 'text-emerald-400 **:stroke-emerald-400 ring ring-emerald-400'
|
||||
)}
|
||||
placeholder={t("SectionCoupon.InputCouponCode.Placeholder")}
|
||||
htmlFor={'couponCode'}
|
||||
onChange={(e) => onCouponCodeChange(e.target.value)}
|
||||
value={couponCode}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
'use client';
|
||||
|
||||
import { Card, Icon, Wallet2 } from 'iconsax-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type PaymentSectionProps = {
|
||||
paymentType: string;
|
||||
onPaymentTypeChange: (id: string) => void;
|
||||
};
|
||||
|
||||
export const PaymentSection = ({ paymentType, onPaymentTypeChange }: PaymentSectionProps) => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
|
||||
const paymentOptions: Array<{ id: string, label: string, icon: Icon }> = [
|
||||
{ id: '0', label: t("SectionPayment.InputPaymentType.Options.Online"), icon: Card },
|
||||
{ id: '1', label: t("SectionPayment.InputPaymentType.Options.CashOnDelivery"), icon: Wallet2 },
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<h3 className="text-sm2 font-medium leading-5">{t("SectionPayment.Title")}</h3>
|
||||
|
||||
<div className='flex flex-col gap-5 mt-6'>
|
||||
{paymentOptions.map(({ id, label, icon: Icon }) => (
|
||||
<div key={id} className='flex items-center'>
|
||||
<label className='flex items-center gap-2 w-full' htmlFor={`paymentMethod${id}`}>
|
||||
<Icon
|
||||
size={16}
|
||||
color='currentColor'
|
||||
className='mr-2'
|
||||
/>
|
||||
<span className='text-xs mt-0.5'>{label}</span>
|
||||
</label>
|
||||
<input
|
||||
checked={paymentType === id}
|
||||
onChange={() => onPaymentTypeChange(id)}
|
||||
type='radio'
|
||||
name='paymentMethod'
|
||||
id={`paymentMethod${id}`}
|
||||
className='size-4 accent-primary' />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
'use client';
|
||||
|
||||
import Combobox, { ComboboxOption } from '@/components/combobox/Combobox';
|
||||
import { Box, Icon, Shop, TruckTick } from 'iconsax-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type ShippingSectionProps = {
|
||||
deliveryType: string;
|
||||
onDeliveryTypeChange: (id: string) => void;
|
||||
};
|
||||
|
||||
export const ShippingSection = ({ deliveryType, onDeliveryTypeChange }: ShippingSectionProps) => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
|
||||
const deliveryOptions: Array<ComboboxOption> = [
|
||||
{ id: '0', title: t("SectionShipping.InputDeliveryType.Options.Delivery"), icon: TruckTick },
|
||||
{ id: '1', title: t("SectionShipping.InputDeliveryType.Options.Serve"), icon: Shop },
|
||||
{ id: '2', title: t("SectionShipping.InputDeliveryType.Options.Pickup"), icon: Box },
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<h3 className="text-sm2 font-medium leading-5">{t("SectionShipping.Title")}</h3>
|
||||
<Combobox
|
||||
className='relative mt-6'
|
||||
icon={Box}
|
||||
title=''
|
||||
searchable={false}
|
||||
options={deliveryOptions}
|
||||
selectedId={deliveryType}
|
||||
onSelectionChange={(e, i) => onDeliveryTypeChange(String(i))}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
'use client';
|
||||
|
||||
import AnimatedBottomSheet from '@/components/bottomsheet/AnimatedBottomSheet';
|
||||
import Button from '@/components/button/PrimaryButton';
|
||||
import { ChevronLeft } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type SummarySectionProps = {
|
||||
cartModal: boolean;
|
||||
onToggleCartModal: () => void;
|
||||
};
|
||||
|
||||
export const SummarySection = ({ cartModal, onToggleCartModal }: SummarySectionProps) => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="">
|
||||
<div className="py-3 pb-10">
|
||||
<div className='w-full flex justify-between items-center gap-2'>
|
||||
<h3 className="text-sm2 font-medium leading-5 inline-block">{t("SectionSummary.Title")}</h3>
|
||||
<button
|
||||
className='text-sm2 text-primary cursor-pointer dark:text-foreground'
|
||||
onClick={onToggleCartModal}
|
||||
>
|
||||
{t("SectionSummary.ButtonViewCart")}
|
||||
<ChevronLeft className='inline-block mr-1 mb-0.5 stroke-primary dark:stroke-foreground' size='16' />
|
||||
</button>
|
||||
</div>
|
||||
<div className='mt-6 text-sm2 grid grid-cols-2 gap-4'>
|
||||
<span className=''>{t("SectionSummary.SumOfItemsLabel")}</span>
|
||||
<span className='font-medium place-self-end '>100,000 T</span>
|
||||
<span className=''>{t("SectionSummary.DeliveryLabel")}</span>
|
||||
<span className='font-medium place-self-end '>20,000 T</span>
|
||||
<span className='text-emerald-600'>{t("SectionSummary.DiscountLabel")}</span>
|
||||
<span className='font-medium place-self-end text-emerald-600'>10,000 T</span>
|
||||
<span className='font-medium '>{t("SectionSummary.TotalLabel")}</span>
|
||||
<span className='font-bold place-self-end'>110,000 T</span>
|
||||
</div>
|
||||
<Button className='mt-6'>
|
||||
{t("ButtonSubmit")}
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<AnimatedBottomSheet
|
||||
title={t("CartModal.Title")}
|
||||
visible={cartModal}
|
||||
onClick={onToggleCartModal}
|
||||
>
|
||||
<div></div>
|
||||
</AnimatedBottomSheet>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
'use client';
|
||||
|
||||
import { MinusIcon, PlusIcon } from 'lucide-react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type TableSectionProps = {
|
||||
tableNumber: number;
|
||||
onIncrement: () => void;
|
||||
onDecrement: () => void;
|
||||
};
|
||||
|
||||
export const TableSection = ({ tableNumber, onIncrement, onDecrement }: TableSectionProps) => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
|
||||
return (
|
||||
<section className="bg-container rounded-container box-shadow-normal p-4 py-2">
|
||||
<div className="py-3">
|
||||
<div className='w-full grid grid-cols-2 justify-between items-center gap-2'>
|
||||
<h3 className="text-sm2 font-medium leading-5 inline-block">{t("SectionTable.Title")}</h3>
|
||||
|
||||
<div className='w-full flex justify-end'>
|
||||
<motion.div
|
||||
whileTap={{ scale: 1.05 }}
|
||||
className="bg-background active:drop-shadow-xs max-w-[132px] rounded-md w-full h-8 inline-flex p-1 justify-between items-center gap-2"
|
||||
>
|
||||
<button
|
||||
onClick={onIncrement}
|
||||
className="bg-container hover:bg-container/60 size-6 place-items-center active:bg-container/30 rounded-sm"
|
||||
>
|
||||
<PlusIcon size={16} />
|
||||
</button>
|
||||
<motion.div
|
||||
key={tableNumber}
|
||||
initial={{ scale: 1 }}
|
||||
animate={{ scale: [1.2, 0.95, 1] }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="text-sm2 pt-0.5 font-semibold"
|
||||
>
|
||||
{tableNumber}
|
||||
</motion.div>
|
||||
<button
|
||||
onClick={onDecrement}
|
||||
className="bg-container hover:bg-container/60 size-6 place-items-center active:bg-container/30 rounded-sm"
|
||||
>
|
||||
<MinusIcon size={16} />
|
||||
</button>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,64 +1,31 @@
|
||||
'use client';
|
||||
|
||||
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';
|
||||
import { ChevronLeft, MinusIcon, PlusIcon } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type Params = {
|
||||
id: string,
|
||||
name: string,
|
||||
}
|
||||
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { AddressSection } from './components/AddressSection';
|
||||
import { CheckoutHeader } from './components/CheckoutHeader';
|
||||
import { CouponSection } from './components/CouponSection';
|
||||
import { PaymentSection } from './components/PaymentSection';
|
||||
import { ShippingSection } from './components/ShippingSection';
|
||||
import { SummarySection } from './components/SummarySection';
|
||||
import { TableSection } from './components/TableSection';
|
||||
|
||||
function OrderDetailInex() {
|
||||
const params = useParams<Params>();
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
const router = useRouter();
|
||||
const [deliveryType, setDeliveryType] = React.useState<string>('0');
|
||||
const [paymentType, setPaymentType] = React.useState<string>('0');
|
||||
const [couponType, setCouponType] = React.useState<string>('0');
|
||||
const [couponCode, setCouponCode] = React.useState<string>('');
|
||||
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 [couponCodeError, setCouponCodeError] = React.useState<string>('');
|
||||
const [tableNumber, setTableNumber] = useState(0);
|
||||
const address = "اراک، مصطفی خمینی، خیابان سینا کوچه چمران ساختمان شهرزاد";
|
||||
const { state: cartModal, toggle: toggleCartModal } = useToggle();
|
||||
|
||||
const deliveryOptions: Array<ComboboxOption> = [
|
||||
{ id: '0', title: t("SectionShipping.InputDeliveryType.Options.Delivery"), icon: TruckTick },
|
||||
{ id: '1', title: t("SectionShipping.InputDeliveryType.Options.Serve"), icon: Shop },
|
||||
{ id: '2', title: t("SectionShipping.InputDeliveryType.Options.Pickup"), icon: Box },
|
||||
];
|
||||
|
||||
const paymentOptions: Array<{ id: string, label: string, icon: Icon }> = [
|
||||
{ id: '0', label: t("SectionPayment.InputPaymentType.Options.Online"), icon: Card },
|
||||
{ id: '1', label: t("SectionPayment.InputPaymentType.Options.CashOnDelivery"), icon: Wallet2 },
|
||||
];
|
||||
|
||||
const couponOptions: Array<{ id: string, label: string, icon: Icon }> = [
|
||||
{ id: '0', label: t("SectionCoupon.InputCouponType.Options.Discount"), icon: Cup },
|
||||
{ id: '1', label: t("SectionCoupon.InputCouponType.Options.GiftCard"), icon: Ticket },
|
||||
];
|
||||
|
||||
const couponDropdownOptions: Array<ComboboxOption> = [
|
||||
{ id: '0', title: t("SectionCoupon.InputCouponCode.Options.Default") },
|
||||
{ id: '1', title: "Something" },
|
||||
];
|
||||
const incrementTableNumber = () => setTableNumber((prev) => prev + 1);
|
||||
const decrementTableNumber = () => setTableNumber((prev) => prev - 1);
|
||||
|
||||
const changeDeliveryType = useCallback((id: string) => {
|
||||
setDeliveryType(id);
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
const changePaymentType = useCallback((id: string) => {
|
||||
setPaymentType(id);
|
||||
@@ -70,247 +37,50 @@ function OrderDetailInex() {
|
||||
setCouponType(id);
|
||||
}, []);
|
||||
|
||||
const changeCouponCode = useCallback((id: string) => {
|
||||
if (id === '0') {
|
||||
setCouponCode('');
|
||||
return;
|
||||
}
|
||||
setCouponCode(id);
|
||||
const changeCouponCode = useCallback((value: string) => {
|
||||
setCouponCode(value);
|
||||
}, []);
|
||||
|
||||
const addressSection = () => {
|
||||
if (deliveryType !== '0') {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<section
|
||||
className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<div className='w-full flex justify-between items-center gap-2'>
|
||||
<h3 className="text-sm2 font-medium leading-5 inline-block">{t("SectionAddress.Title")}</h3>
|
||||
<Link href={`/${params.name}/profile/address?redirect=/${params.name}/order/checkout/${params.id}`}>
|
||||
<button
|
||||
className='text-sm2 text-primary dark:text-foreground cursor-pointer'
|
||||
onClick={() => { /* Handle address change */ }}
|
||||
>
|
||||
{t("SectionAddress.ButtonChangeAddress")}
|
||||
<ChevronLeft className='inline-block mr-1 mb-0.5 stroke-primary dark:stroke-foreground' size='16' />
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
<p className='mt-6 text-sm2'>
|
||||
{address}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
const tableSection = () => {
|
||||
if (deliveryType !== '1') {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<section
|
||||
className="bg-container rounded-container box-shadow-normal p-4 py-2">
|
||||
<div className="py-3">
|
||||
<div className='w-full grid grid-cols-2 justify-between items-center gap-2'>
|
||||
<h3 className="text-sm2 font-medium leading-5 inline-block">{t("SectionTable.Title")}</h3>
|
||||
|
||||
<div className='w-full flex justify-end'>
|
||||
<motion.div
|
||||
whileTap={{ scale: 1.05 }}
|
||||
className="bg-background active:drop-shadow-xs max-w-[132px] rounded-md w-full h-8 inline-flex p-1 justify-between items-center gap-2"
|
||||
>
|
||||
<button
|
||||
onClick={() => incrementTableNumber()}
|
||||
className="bg-container hover:bg-container/60 size-6 place-items-center active:bg-container/30 rounded-sm"
|
||||
>
|
||||
<PlusIcon size={16} />
|
||||
</button>
|
||||
<motion.div
|
||||
key={tableNumber}
|
||||
initial={{ scale: 1 }}
|
||||
animate={{ scale: [1.2, 0.95, 1] }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="text-sm2 pt-0.5 font-semibold"
|
||||
>
|
||||
{tableNumber}
|
||||
</motion.div>
|
||||
<button
|
||||
onClick={() => decrementTableNumber()}
|
||||
className="bg-container hover:bg-container/60 size-6 place-items-center active:bg-container/30 rounded-sm"
|
||||
>
|
||||
<MinusIcon size={16} />
|
||||
</button>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='h-full bg-inherit flex flex-col gap-5'>
|
||||
<div className='grid grid-cols-3 items-center py-4 '>
|
||||
<span></span>
|
||||
<h1 className='text-sm2 place-self-center font-medium'>{t("Heading")}</h1>
|
||||
<ArrowLeft
|
||||
className='cursor-pointer place-self-end'
|
||||
size='24'
|
||||
color='currentColor'
|
||||
onClick={() => { router.back() }}
|
||||
<CheckoutHeader />
|
||||
|
||||
<ShippingSection
|
||||
deliveryType={deliveryType}
|
||||
onDeliveryTypeChange={changeDeliveryType}
|
||||
/>
|
||||
|
||||
{deliveryType === '0' && (
|
||||
<AddressSection address={address} />
|
||||
)}
|
||||
|
||||
{deliveryType === '1' && (
|
||||
<TableSection
|
||||
tableNumber={tableNumber}
|
||||
onIncrement={incrementTableNumber}
|
||||
onDecrement={decrementTableNumber}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<section
|
||||
className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<h3 className="text-sm2 font-medium leading-5">{t("SectionShipping.Title")}</h3>
|
||||
<Combobox
|
||||
className='relative mt-6'
|
||||
icon={Box}
|
||||
title=''
|
||||
searchable={false}
|
||||
options={deliveryOptions}
|
||||
selectedId={deliveryType}
|
||||
onSelectionChange={(e, i) => changeDeliveryType(String(i))}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
<PaymentSection
|
||||
paymentType={paymentType}
|
||||
onPaymentTypeChange={changePaymentType}
|
||||
/>
|
||||
|
||||
{addressSection()}
|
||||
{tableSection()}
|
||||
<CouponSection
|
||||
couponType={couponType}
|
||||
couponCode={couponCode}
|
||||
couponCodeError={couponCodeError}
|
||||
onCouponTypeChange={changeCouponType}
|
||||
onCouponCodeChange={changeCouponCode}
|
||||
/>
|
||||
|
||||
<section
|
||||
className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<h3 className="text-sm2 font-medium leading-5">{t("SectionPayment.Title")}</h3>
|
||||
|
||||
<div className='flex flex-col gap-5 mt-6'>
|
||||
{paymentOptions.map(({ id, label, icon: Icon }) => (
|
||||
<div key={id} className='flex items-center'>
|
||||
|
||||
<label className='flex items-center gap-2 w-full' htmlFor={`paymentMethod${id}`}>
|
||||
<Icon
|
||||
size={16}
|
||||
color='currentColor'
|
||||
className='mr-2'
|
||||
/>
|
||||
<span className='text-xs mt-0.5'>{label}</span>
|
||||
</label>
|
||||
<input
|
||||
checked={paymentType === id}
|
||||
onChange={() => changePaymentType(id)}
|
||||
type='radio'
|
||||
name='paymentMethod'
|
||||
id={`paymentMethod${id}`}
|
||||
className='size-4 accent-primary' />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<h3 className="text-sm2 font-medium leading-5">{t("SectionCoupon.Title")}</h3>
|
||||
|
||||
<div className='flex flex-col gap-5 mt-6'>
|
||||
{couponOptions.map(({ id, label, icon: Icon }) => (
|
||||
<div key={id} className='flex items-center'>
|
||||
<label className='flex items-center gap-2 w-full' htmlFor={`couponType${id}`}>
|
||||
<Icon
|
||||
size={16}
|
||||
color='currentColor'
|
||||
className='mr-2'
|
||||
/>
|
||||
<span className='text-xs mt-0.5'>{label}</span>
|
||||
</label>
|
||||
|
||||
<input
|
||||
checked={couponType === id}
|
||||
onChange={() => changeCouponType(id)}
|
||||
type='radio'
|
||||
name='couponType'
|
||||
id={`couponType${id}`}
|
||||
className='size-4 accent-primary' />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Combobox
|
||||
className={clsx(
|
||||
'relative mt-6',
|
||||
couponType === '0' ? 'block' : 'hidden',
|
||||
couponCode.length === 0 && 'text-border **:stroke-border dark:text-neutral-500 dark:**:stroke-neutral-500'
|
||||
)}
|
||||
icon={TicketDiscount}
|
||||
placeholder={t("SectionCoupon.InputCouponCode.Placeholder")}
|
||||
title=''
|
||||
searchable={false}
|
||||
options={couponDropdownOptions}
|
||||
selectedId={couponCode}
|
||||
onSelectionChange={(e, i) => changeCouponCode(String(i))}
|
||||
/>
|
||||
|
||||
<InputField
|
||||
autoComplete='off'
|
||||
className={clsx(
|
||||
'relative mt-6',
|
||||
couponType === '1' ? '' : 'hidden!',
|
||||
couponCodeError.trim() === 'valid' && 'text-emerald-400 **:stroke-emerald-400 ring ring-emerald-400'
|
||||
)}
|
||||
placeholder={t("SectionCoupon.InputCouponCode.Placeholder")}
|
||||
htmlFor={'couponCode'}
|
||||
onChange={(e) => changeCouponCode(e.target.value)}
|
||||
value={couponCode}
|
||||
/>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
className="">
|
||||
<div className="py-3 pb-10">
|
||||
<div className='w-full flex justify-between items-center gap-2'>
|
||||
<h3 className="text-sm2 font-medium leading-5 inline-block">{t("SectionSummary.Title")}</h3>
|
||||
<button
|
||||
className='text-sm2 text-primary cursor-pointer dark:text-foreground'
|
||||
onClick={toggleCartModal}
|
||||
>
|
||||
{t("SectionSummary.ButtonViewCart")}
|
||||
<ChevronLeft className='inline-block mr-1 mb-0.5 stroke-primary dark:stroke-foreground' size='16' />
|
||||
</button>
|
||||
</div>
|
||||
<div className='mt-6 text-sm2 grid grid-cols-2 gap-4'>
|
||||
<span className=''>{t("SectionSummary.SumOfItemsLabel")}</span>
|
||||
<span className='font-medium place-self-end '>100,000 T</span>
|
||||
<span className=''>{t("SectionSummary.DeliveryLabel")}</span>
|
||||
<span className='font-medium place-self-end '>20,000 T</span>
|
||||
<span className='text-emerald-600'>{t("SectionSummary.DiscountLabel")}</span>
|
||||
<span className='font-medium place-self-end text-emerald-600'>10,000 T</span>
|
||||
<span className='font-medium '>{t("SectionSummary.TotalLabel")}</span>
|
||||
<span className='font-bold place-self-end'>110,000 T</span>
|
||||
</div>
|
||||
<Button className='mt-6'>
|
||||
{t("ButtonSubmit")}
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<AnimatedBottomSheet
|
||||
title={t("CartModal.Title")}
|
||||
visible={cartModal}
|
||||
onClick={toggleCartModal}
|
||||
>
|
||||
<div></div>
|
||||
</AnimatedBottomSheet>
|
||||
<SummarySection
|
||||
cartModal={cartModal}
|
||||
onToggleCartModal={toggleCartModal}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default OrderDetailInex
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getShipmentMethod } from "../service/OrderService";
|
||||
|
||||
export const useGetShipmentMethod = () => {
|
||||
return useQuery({
|
||||
queryKey: ["shipment-method"],
|
||||
queryFn: getShipmentMethod,
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
import { api } from "@/config/axios";
|
||||
|
||||
export const getShipmentMethod = async () => {
|
||||
const { data } = await api.get("/public/shipment-methods/restaurant");
|
||||
return data;
|
||||
};
|
||||
Reference in New Issue
Block a user