Files
dmenu-plus-front/src/app/[name]/page.tsx
T
Mahyar Khanbolooki 5edba125a9 chore: update 2 icons
2025-07-11 22:30:22 +03:30

299 lines
9.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useCallback, useMemo, useState } from "react";
import SearchBox from "@/components/input/SearchBox";
import CategoryItemRenderer from "@/components/listview/CategoryItemRenderer";
import HorizontalScrollView from "@/components/listview/HorizontalScrollView";
import Image from "next/image";
import EqualizerIcon from "@/components/icons/EqualizerIcon";
import TextAlignIcon from "@/components/icons/TextAlignIcon";
import VerticalScrollView from "@/components/listview/VerticalScrollView";
import MenuItemRenderer from "@/components/listview/MenuItemRenderer";
import React from "react";
import MenuItem from "@/components/listview/MenuItem";
import Button from "@/components/button/PrimaryButton";
import AnimatedBottomSheet from "@/components/bottomsheet/AnimatedBottomSheet";
import MultiOption from "@/components/combobox/MultiOption";
import { DropdownOption } from "@/components/combobox/Combobox";
import { Switch } from "@/components/ui/switch";
import { LucideMedal, Medal, MedalIcon, StarHalf, StarIcon, Stars, TicketPercentIcon } from "lucide-react";
import TicketDiscountIcon from "@/components/icons/TickerDiscountIcon";
const categories = new Array(13).fill({ title: "خوراک", icon: "" });
const foods = [
{
id: 1,
category: 0,
price: "69.000",
name: "کباب چوبی ژیوان )سیخ چوبی(",
contains: "فیله گوساله / سس سفید / قارچ و سیب زمینی/ پنیر پارمزان"
},
{
id: 2,
category: 1,
price: "49.000",
name: "برگر گوشت گوساله",
contains: "گوشت گوساله / پنیر چدار / کاهو / گوجه"
},
{
id: 3,
category: 2,
price: "29.000",
name: "ساندویچ مرغ",
contains: "مرغ / کاهو / گوجه / سس مایونز"
},
{
id: 4,
category: 0,
price: "89.000",
name: "کباب ماهی",
contains: "ماهی / سس لیمو / قارچ و سیب زمینی"
},
{
id: 5,
category: 1,
price: "39.000",
name: "سالاد فصل",
contains: "کاهو / گوجه / خیار / پنیر فتا"
},
{
id: 6,
category: 3,
price: "59.000",
name: "پاستا گوشت",
contains: "گوشت گوساله / پاستا / سس گوجه"
},
{
id: 7,
category: 2,
price: "49.000",
name: "ساندویچ تن ماهی",
contains: "تن ماهی / کاهو / گوجه / سس مایونز"
},
{
id: 8,
category: 0,
price: "79.000",
name: "کباب گوشت گوسفندی",
contains: "گوشت گوسفندی / سس سفید / قارچ و سیب زمینی"
},
{
id: 9,
category: 1,
price: "29.000",
name: "برگر مرغ",
contains: "مرغ / پنیر چدار / کاهو / گوجه"
},
{
id: 10,
category: 3,
price: "69.000",
name: "سالاد میگو",
contains: "میگو / کاهو / گوجه / خیار"
},
{
id: 11,
category: 2,
price: "39.000",
name: "ساندویچ شاورما",
contains: "مرغ / کاهو / گوجه / سس تارتار"
},
{
id: 12,
category: 0,
price: "99.000",
name: "کباب گوشت بوقلمون",
contains: "گوشت بوقلمون / سس سفید / قارچ و سیب زمینی"
},
{
id: 13,
category: 1,
price: "59.000",
name: "برگر ماهی",
contains: "ماهی / پنیر چدار / کاهو / گوجه"
},
{
id: 14,
category: 3,
price: "49.000",
name: "سالاد مرغ",
contains: "مرغ / کاهو / گوجه / خیار"
}
];
const sortings = [
'محبوب ترین',
'بالاترین امتیاز',
'جدید ترین',
'ارزان ترین',
'گران ترین',
]
const contents: Array<DropdownOption> = [
{ id: '0', title: 'گیاهی' },
{ id: '1', title: 'حیوانی' }
]
const shippings: Array<DropdownOption> = [
{ id: '0', title: 'ارسال با پیک', label: '' },
]
const MenuIndex = () => {
const [search, setSearch] = useState("");
const [selectedCategory, setSelectedCategory] = useState(0);
const [filterModal, setFilterModal] = useState(false);
const [sortingModal, setSortingModal] = useState(false);
const [, setSorting] = useState(0);
const [selectedContentId, setSelectedContentId] = useState('0');
const [selectedShippingId, setSelectedShippingId] = useState('0');
const updateSearch = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value);
}, []);
const updateCategory = useCallback((id: number) => {
setSelectedCategory(id);
}, []);
const toggleFilterModal = useCallback(() => {
setFilterModal((state) => !state);
}, []);
const toggleSortingModal = useCallback(() => {
setSortingModal((state) => !state);
}, []);
const changeSorting = (index: number) => {
setSorting(() => index);
}
const changeSelectedContent = (e: React.MouseEvent<HTMLDivElement, MouseEvent>, index: number) => {
setSelectedContentId(() => contents[index]?.id || contents[0].id);
}
const changeSelectedShipping = (e: React.MouseEvent<HTMLDivElement, MouseEvent>, index: number) => {
setSelectedShippingId(() => contents[index]?.id || contents[0].id);
}
const filteredReceiptItems = useMemo(() => {
const lowerSearch = search.toLowerCase();
return foods.filter(
(item) =>
item.category === selectedCategory &&
item.name.toLowerCase().includes(lowerSearch)
);
}, [selectedCategory, search]);
return (
<div className="flex flex-col gap-4 pt-4 items-center">
<SearchBox value={search} onChange={updateSearch} />
<HorizontalScrollView className="w-full noscrollbar py-4!">
{categories.map((item, index) => (
<CategoryItemRenderer
key={index}
className={`${index === selectedCategory ? "bg-white!" : ""}`}
onClick={() => updateCategory(index)}
>
<Image
priority
src="/assets/images/food-image.png"
width={32}
height={32}
alt="category image"
/>
<span className="text-xs text-black">{item.title}</span>
</CategoryItemRenderer>
))}
</HorizontalScrollView>
<section className="w-full">
<div className="flex justify-between items-center">
<span className="text-base font-semibold">
{categories[selectedCategory]?.title}
</span>
<div className="inline-flex gap-2 justify-around items-center">
<button onClick={toggleFilterModal} className="rounded-xl h-8 bg-white ps-4 pe-2 py-1.5 inline-flex items-center justify-between gap-[7px]">
<EqualizerIcon />
<span className="text-xs leading-5">فیلتر بر اساس</span>
</button>
<button onClick={toggleSortingModal} className="rounded-lg h-8 bg-white p-1.5">
<TextAlignIcon />
</button>
</div>
</div>
<VerticalScrollView className="mt-5! overflow-y-auto h-full">
{filteredReceiptItems.map((food) => (
<MenuItemRenderer key={food.id}>
<MenuItem food={food} />
</MenuItemRenderer>
))}
</VerticalScrollView>
</section>
<AnimatedBottomSheet title="فیلتر ها" visible={filterModal} changeDelay="150" onClick={toggleFilterModal}>
<div className="ps-8.5 pe-[31px] mt-[89px]">
<MultiOption
title="محتویات"
options={contents}
selectedId={selectedContentId}
onSelectionChange={changeSelectedContent} />
<MultiOption
className="relative mt-9.5"
title="روش ارسال"
options={shippings}
selectedId={selectedShippingId}
onSelectionChange={changeSelectedShipping} />
<div
className="flex w-full mt-[23px] h-11 items-center justify-between gap-2 px-3 py-4 relative bg-white/29 rounded-xl border border-solid border-neutral-200 cursor-pointer focus:outline-none focus:ring-2 focus:ring-black"
>
<span className="inline-flex items-center gap-2.5 text-sm2">
<Medal size={16} />
دارای امتیاز پس از خرید
</span>
<Switch className="w-12 h-6" />
</div>
<div
className="flex w-full mt-[23px] h-11 items-center justify-between gap-2 px-3 py-4 relative bg-white/29 rounded-xl border border-solid border-neutral-200 cursor-pointer focus:outline-none focus:ring-2 focus:ring-black"
>
<span className="inline-flex items-center gap-2.5 text-sm2">
<TicketPercentIcon size={16} />
دارای کد تخفیف
</span>
<Switch />
</div>
</div>
<hr className="text-white/40 mt-12" />
<div className="px-9 pt-6 flex justify-between gap-[22px]">
<div className="w-full">
<Button>اعمال فیلتر</Button>
</div>
<div className="w-full">
<Button className="bg-disabled! text-disabled-text!">حذف فیلتر</Button>
</div>
</div>
</AnimatedBottomSheet>
<AnimatedBottomSheet title="مرتب کردن بر اساس" visible={sortingModal} changeDelay="150" onClick={toggleSortingModal}>
<div className="px-8.5 py-10 justify-between">
{sortings.map((v, i) => {
return (
<div key={i}>
<div onClick={() => changeSorting(i)} className="text-sm2 font-medium cursor-pointer">
{v}
</div>
{i < sortings.length - 1 && <hr className="text-white/40 mb-4 mt-4" />}
</div>
)
})}
</div>
</AnimatedBottomSheet>
</div>
);
};
export default MenuIndex;