From af8cc95beef75b56cc41a6dd3b6feea15f968b2a Mon Sep 17 00:00:00 2001 From: TanishqMehrunkarIIPSDAVV Date: Thu, 29 Jan 2026 19:24:03 +0530 Subject: [PATCH] somewhat ui improvement --- client/src/features/home/FeaturedItems.jsx | 82 ++------ client/src/features/home/TrendingItems.jsx | 19 +- client/src/hooks/useDebounce.js | 23 +++ client/src/pages/Order/OrderSession.jsx | 206 ++++++++++++++++----- 4 files changed, 204 insertions(+), 126 deletions(-) create mode 100644 client/src/hooks/useDebounce.js diff --git a/client/src/features/home/FeaturedItems.jsx b/client/src/features/home/FeaturedItems.jsx index 35cf0b2..9bbdd2f 100644 --- a/client/src/features/home/FeaturedItems.jsx +++ b/client/src/features/home/FeaturedItems.jsx @@ -2,12 +2,14 @@ import React, { useEffect, useMemo, useState } from 'react'; import MenuCard from '../../components/ui/MenuCard'; import api from '../../lib/axios'; -const FeaturedItems = ({ outletId, showAll = false }) => { +const FeaturedItems = ({ outletId, showAll = false, searchQuery = '', categoryFilter = 'all', dietFilter = 'all' }) => { const [items, setItems] = useState([]); - const [searchTerm, setSearchTerm] = useState(''); - const [category, setCategory] = useState('all'); - const [diet, setDiet] = useState('all'); // 'all' | 'veg' | 'non-veg' - const [tag, setTag] = useState('all'); + const [tag] = useState('all'); + + // Use external filters if provided + const activeSearch = searchQuery; + const activeCategory = categoryFilter; + const activeDiet = dietFilter; useEffect(() => { const fetchMenu = async () => { @@ -34,31 +36,16 @@ const FeaturedItems = ({ outletId, showAll = false }) => { const filteredItems = useMemo(() => { if (!outletId) return []; - const term = searchTerm.trim().toLowerCase(); + const term = activeSearch.trim().toLowerCase(); return items.filter((item) => { - const matchesCategory = category === 'all' || item.category === category; - const matchesDiet = diet === 'all' || (diet === 'veg' ? item.isVeg === true : item.isVeg === false); + const matchesCategory = activeCategory === 'all' || item.category === activeCategory; + const matchesDiet = activeDiet === 'all' || (activeDiet === 'veg' ? item.isVeg === true : item.isVeg === false); const matchesTag = tag === 'all' || (Array.isArray(item.tags) && item.tags.includes(tag)); const matchesSearch = !term || item.name.toLowerCase().includes(term) || (item.description || '').toLowerCase().includes(term); return matchesCategory && matchesDiet && matchesTag && matchesSearch; }); - }, [items, searchTerm, category, diet, tag, outletId]); - - const categories = useMemo(() => { - const unique = Array.from(new Set(items.map((item) => item.category).filter(Boolean))); - return ['all', ...unique]; - }, [items]); - - const tags = useMemo(() => { - const unique = new Set(); - items.forEach((item) => { - if (Array.isArray(item.tags)) { - item.tags.forEach((t) => t && unique.add(t)); - } - }); - return ['all', ...Array.from(unique)]; - }, [items]); + }, [items, activeSearch, activeCategory, activeDiet, tag, outletId]); const displayItems = showAll ? filteredItems : filteredItems.slice(0, 8); @@ -66,53 +53,6 @@ const FeaturedItems = ({ outletId, showAll = false }) => { return (
-
-
- setSearchTerm(e.target.value)} - placeholder="Search dishes..." - className="w-full sm:w-1/2 bg-zinc-800 text-white text-sm rounded-lg px-3 py-2 border border-white/10 focus:border-amber-500 focus:outline-none" - /> -
- - -
-
-
- -
-
-
{displayItems.map((item) => ( diff --git a/client/src/features/home/TrendingItems.jsx b/client/src/features/home/TrendingItems.jsx index eef7377..36cade3 100644 --- a/client/src/features/home/TrendingItems.jsx +++ b/client/src/features/home/TrendingItems.jsx @@ -4,7 +4,7 @@ import api from '../../lib/axios'; import { Flame } from 'lucide-react'; import MenuCard from '../../components/ui/MenuCard'; -const TrendingItems = ({ outletId }) => { +const TrendingItems = ({ outletId, searchQuery = '', categoryFilter = 'all', dietFilter = 'all' }) => { const { addToCart } = useCart(); const [trendingItems, setTrendingItems] = useState([]); @@ -26,8 +26,19 @@ const TrendingItems = ({ outletId }) => { fetchTrendingItems(); }, [outletId]); - // Don't show section if no trending items found - if (trendingItems.length === 0) { + // Filter trending items based on search and filters + const filteredTrendingItems = trendingItems.filter((item) => { + const matchesSearch = + !searchQuery || + item.name.toLowerCase().includes(searchQuery.toLowerCase()) || + (item.description || '').toLowerCase().includes(searchQuery.toLowerCase()); + const matchesCategory = categoryFilter === 'all' || item.category === categoryFilter; + const matchesDiet = dietFilter === 'all' || (dietFilter === 'veg' ? item.isVeg === true : item.isVeg === false); + return matchesSearch && matchesCategory && matchesDiet; + }); + + // Don't show section if no trending items found after filtering + if (filteredTrendingItems.length === 0) { return null; } @@ -40,7 +51,7 @@ const TrendingItems = ({ outletId }) => {
- {trendingItems.map((item) => ( + {filteredTrendingItems.map((item) => ( { + const timer = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + return () => { + clearTimeout(timer); + }; + }, [value, delay]); + + return debouncedValue; +} diff --git a/client/src/pages/Order/OrderSession.jsx b/client/src/pages/Order/OrderSession.jsx index 1328d76..ea267a8 100644 --- a/client/src/pages/Order/OrderSession.jsx +++ b/client/src/pages/Order/OrderSession.jsx @@ -3,6 +3,8 @@ import { useParams, useNavigate } from 'react-router-dom'; import ClassicLoader from '@/components/ui/loader'; import { useOutlet } from '../../context/OutletContextValues'; import { useCart } from '../../context/CartContextValues'; +import { useTheme } from '../../context/useTheme'; +import { useDebounce } from '../../hooks/useDebounce'; import api from '../../lib/axios'; import toast from 'react-hot-toast'; import { AnimatePresence, motion } from 'framer-motion'; // eslint-disable-line no-unused-vars @@ -14,9 +16,11 @@ import { ChevronDown, Search, Menu as MenuIcon, - X, + Sun, + Moon, } from 'lucide-react'; import { Button } from '@/components/ui/button'; +import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import CartDrawer from '../../components/cart/CartDrawer'; import FeaturedItems from '../../features/home/FeaturedItems'; @@ -28,6 +32,7 @@ const OrderSession = () => { const navigate = useNavigate(); const { setOutlet, selectedOutlet } = useOutlet(); const { setTableInfo, tableInfo, setIsCartOpen, cartItems } = useCart(); + const { isDarkMode, toggleTheme } = useTheme(); const initializationRef = useRef(false); const [activeTab, setActiveTab] = useState('menu'); // 'menu' | 'orders' | 'bill' @@ -36,6 +41,15 @@ const OrderSession = () => { const [orders, setOrders] = useState([]); const [isOrdersLoading, setIsOrdersLoading] = useState(false); const [expandedOrders, setExpandedOrders] = useState([]); + const [isMenuOpen, setIsMenuOpen] = useState(false); + + // Search and filter states + const [searchQuery, setSearchQuery] = useState(''); + const [categoryFilter, setCategoryFilter] = useState('all'); + const [dietFilter, setDietFilter] = useState('all'); + + // Debounced search query + const debouncedSearch = useDebounce(searchQuery, 500); // --- 1. Session Initialization --- useEffect(() => { @@ -134,37 +148,86 @@ const OrderSession = () => {
{/* 1. Header (Sticky) */} -
-
-

{selectedOutlet?.name || 'Indo Cafe'}

- - - Table {tableInfo?.tableName} - +
+
+ + + + + +
+ + + +
+
+
+
+

+ {selectedOutlet?.name || 'Indo Cafe'} +

+ + + Table {tableInfo?.tableName} + +
+
+
+
-
- {/* 2. Content Tabs */} + {/* 2. Content */}
- {/* Simple Tab Switcher */} -
- setActiveTab('menu')} - label="Menu" - icon={} - /> - setActiveTab('orders')} - label="My Orders" - icon={} - /> -
- {/* Tab Content */} {activeTab === 'menu' && ( @@ -175,18 +238,68 @@ const OrderSession = () => { exit={{ opacity: 0, y: -10 }} className="space-y-6" > -
-

Hungry? 😋

-

Select items to add to your table order.

+
+
+

Dine-in

+

Hungry? Let's find your cravings.

+

Browse popular picks, then add to your table.

+
+
+
+ + setSearchQuery(e.target.value)} + placeholder="Search dishes..." + className="flex-1 bg-transparent text-xs sm:text-sm text-text placeholder:text-zinc-400 dark:placeholder:text-zinc-500 outline-none min-w-0" + /> + +
+
+ + +
+
{/* Trending Items Section - only show when not viewing full menu */} - {!showFullMenu && } + {!showFullMenu && ( + + )} {/* All Menu Items */}
-

+

{showFullMenu ? 'Full Menu' : 'Our Menu'}

- +
)} @@ -213,8 +332,8 @@ const OrderSession = () => { >
-

My Orders

-

Most recent first

+

Past Orders

+

Most recent first

-); - export default OrderSession;