Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions RestroHub-FrontEnd/src/components/admin/EmptyState.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const EmptyState = ({
icon: Icon,
title,
description,
actionLabel,
onAction,
className = "",
}) => (
<div
className={`bg-white rounded-2xl border border-gray-100 text-center p-8 sm:p-12 shadow-sm ${className}`}
>
{Icon ? (
<div className="w-16 h-16 sm:w-20 sm:h-20 bg-blue-50 rounded-3xl flex items-center justify-center mx-auto mb-4 sm:mb-5">
<Icon className="w-8 h-8 sm:w-10 sm:h-10 text-blue-300" />
</div>
) : null}
<p className="text-gray-700 font-semibold text-base sm:text-lg mb-1">{title}</p>
{description ? (
<p className="text-gray-500 text-sm mb-5 max-w-md mx-auto">{description}</p>
) : null}
{actionLabel && onAction ? (
<button
type="button"
onClick={onAction}
className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-600 to-indigo-600 text-white rounded-xl hover:from-blue-700 hover:to-indigo-700 transition-all font-semibold shadow-lg shadow-blue-600/25"
>
{actionLabel}
</button>
) : null}
</div>
);

export default EmptyState;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import { Search, RefreshCw, AlertCircle, UtensilsCrossed } from 'lucide-react';
import MenuItemCard from './FoodItemCard';
import EmptyState from '../../EmptyState';
import api from "@services/common/api";


Expand Down Expand Up @@ -258,40 +259,15 @@ const MenuItemsGrid = forwardRef(({ selectedCategory, onEditItem }, ref) => {
</div>

) : filteredItems.length === 0 ? (
// ------------------------------------
// EMPTY STATE - Responsive
// ------------------------------------
<div
className="
bg-white rounded-2xl border border-gray-100 text-center

/* MOBILE */
p-8

/* TABLET+ */
sm:p-12
"
>
<UtensilsCrossed
className="
text-blue-200 mx-auto mb-3

/* MOBILE */
w-12 h-12

/* TABLET+ */
sm:w-16 sm:h-16 sm:mb-4
"
/>
<p className="text-gray-700 font-medium mb-1 text-sm sm:text-base">
No items found
</p>
<p className="text-gray-500 text-xs sm:text-sm">
{searchQuery
<EmptyState
icon={UtensilsCrossed}
title={searchQuery ? 'No items found' : 'No menu items yet'}
description={
searchQuery
? `No results for "${searchQuery}"`
: 'Add your first menu item to get started'}
</p>
</div>
: 'Add your first menu item to get started.'
}
/>

) : (
// ------------------------------------
Expand Down
32 changes: 11 additions & 21 deletions RestroHub-FrontEnd/src/components/admin/menu/menuCard/MenusGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
BadgePercent,
} from 'lucide-react';
import { Dialog } from '@headlessui/react';
import EmptyState from '../../EmptyState';
import api from "@services/common/api";

// ============================================
Expand Down Expand Up @@ -1143,28 +1144,17 @@ const MenusGrid = forwardRef(({ onEditMenu, onCreateMenu }, ref) => {
</button>
</div>
) : filteredMenus.length === 0 ? (
<div className="bg-white rounded-2xl border border-gray-100 text-center p-10 sm:p-16 shadow-sm">
<div className="w-20 h-20 bg-blue-50 rounded-3xl flex items-center justify-center mx-auto mb-5">
<UtensilsCrossed className="w-10 h-10 text-blue-300" />
</div>
<p className="text-gray-700 font-bold text-lg mb-1">
{searchQuery ? 'No menus found' : 'No menus yet'}
</p>
<p className="text-gray-400 text-sm mb-6 max-w-md mx-auto">
{searchQuery
<EmptyState
icon={UtensilsCrossed}
title={searchQuery ? 'No menus found' : 'No menus yet'}
description={
searchQuery
? `No results for "${searchQuery}"`
: 'Create your first menu to organize your food items.'}
</p>
{!searchQuery && (
<button onClick={onCreateMenu}
className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-600
to-indigo-600 text-white rounded-xl hover:from-blue-700 hover:to-indigo-700
transition-all font-semibold shadow-lg shadow-blue-600/25">
<Plus className="w-5 h-5" />
Create Your First Menu
</button>
)}
</div>
: 'Create your first menu to organize your food items.'
}
actionLabel={!searchQuery ? 'Create Your First Menu' : undefined}
onAction={!searchQuery ? onCreateMenu : undefined}
/>
) : (
<div className="grid gap-5 grid-cols-1 lg:grid-cols-2 xl:grid-cols-3">
{filteredMenus.map((menu) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useState, useEffect } from 'react';
import { RefreshCw, AlertCircle, ClipboardList } from 'lucide-react';
import OrderCard from './OrderCard';
import EmptyState from '../../EmptyState';
import api from "@services/common/api";

// ============================================
Expand Down Expand Up @@ -203,17 +204,17 @@ const OrdersGrid = ({ activeFilter, searchQuery, onOrdersChange }) => {

if (filteredOrders.length === 0) {
return (
<div className="bg-white rounded-2xl p-12 border border-gray-100 text-center">
<ClipboardList className="w-16 h-16 text-blue-200 mx-auto mb-4" />
<p className="text-gray-700 font-medium mb-1">No orders found</p>
<p className="text-gray-500 text-sm">
{searchQuery
<EmptyState
icon={ClipboardList}
title={searchQuery ? 'No orders found' : 'No orders yet'}
description={
searchQuery
? `No results for "${searchQuery}"`
: activeFilter !== 'all'
? `No ${activeFilter} orders right now`
: 'No orders yet. They will appear here.'}
</p>
</div>
: 'New orders will appear here once customers place them.'
}
/>
);
}

Expand Down