From 2014a73c50097e5e7e39f0a207256c3b8700f339 Mon Sep 17 00:00:00 2001 From: Yash-Marathe91 Date: Thu, 11 Jun 2026 23:52:00 +0530 Subject: [PATCH] enhancement(ui): standardize user-facing error feedback across admin workflows --- RestroHub-FrontEnd/src/components/admin/Header.jsx | 3 +++ .../src/components/admin/dashboard/cards/LiveOrders.jsx | 2 ++ .../src/components/admin/dashboard/cards/QuickActions.jsx | 5 +++++ .../src/components/admin/dashboard/cards/RevenueChart.jsx | 2 ++ .../src/components/admin/dashboard/cards/StatsSection.jsx | 2 ++ .../src/components/admin/kds/KitchenDisplaySystem.jsx | 3 +++ RestroHub-FrontEnd/src/components/admin/kds/OrderCard.jsx | 2 ++ .../src/components/admin/marketing/qr/QRHeader.jsx | 2 ++ .../src/components/admin/marketing/qr/QRPreview.jsx | 2 ++ .../src/components/admin/marketing/website/WebsiteHeader.jsx | 1 + RestroHub-FrontEnd/src/components/admin/menu/Menus.jsx | 1 + .../src/components/admin/menu/menuCard/BulkActions.jsx | 4 ++++ .../src/components/admin/menu/menuCard/CategoryFormModal.jsx | 2 ++ .../src/components/admin/menu/menuCard/CategorySidebar.jsx | 2 ++ .../src/components/admin/menu/menuCard/FoodItemsGrid.jsx | 2 ++ .../src/components/admin/menu/menuCard/MenuFormModal.jsx | 2 ++ .../src/components/admin/menu/menuCard/MenusGrid.jsx | 1 + .../components/admin/orders/orderComponents/OrderCard.jsx | 2 ++ .../components/admin/orders/orderComponents/OrdersGrid.jsx | 2 ++ RestroHub-FrontEnd/src/components/admin/profile/Profile.jsx | 3 +++ .../admin/profile/profileComponents/ProfileImageModal.jsx | 2 ++ .../admin/profile/profileComponents/RestaurantInfoCard.jsx | 2 ++ .../src/components/admin/store/branch/BranchCard.jsx | 2 ++ .../src/components/admin/store/branch/BranchFormModal.jsx | 2 ++ .../src/components/admin/store/branch/BranchesGrid.jsx | 1 + .../src/components/admin/store/tables/TableCard.jsx | 2 ++ .../src/components/admin/store/tables/TableFormModal.jsx | 2 ++ .../src/components/admin/store/tables/TableQRModal.jsx | 2 ++ .../src/components/admin/store/tables/TablesGrid.jsx | 2 ++ .../src/components/admin/store/tables/TablesHeader.jsx | 2 ++ RestroHub-FrontEnd/src/components/admin/upi/UPICard.jsx | 3 +++ RestroHub-FrontEnd/src/components/admin/upi/UPIFormModal.jsx | 2 ++ RestroHub-FrontEnd/src/components/admin/upi/UPIGrid.jsx | 2 ++ 33 files changed, 71 insertions(+) diff --git a/RestroHub-FrontEnd/src/components/admin/Header.jsx b/RestroHub-FrontEnd/src/components/admin/Header.jsx index 1a845635..9a59f6f6 100644 --- a/RestroHub-FrontEnd/src/components/admin/Header.jsx +++ b/RestroHub-FrontEnd/src/components/admin/Header.jsx @@ -18,6 +18,7 @@ import { useAdminTheme } from '@context/AdminThemeContext'; import profileService from '../../services/user/profileService'; import useWebSocketNotifications from '@hooks/useWebSocketNotifications'; import api from '../../services/common/api'; +import toast from 'react-hot-toast'; const Header = ({ onMobileMenuClick, collapsed, onCollapseToggle }) => { const [searchOpen, setSearchOpen] = useState(false); @@ -40,6 +41,7 @@ const Header = ({ onMobileMenuClick, collapsed, onCollapseToggle }) => { await api.post('/public/api/v1/auth/logout'); //handles logout on backend and invalidates refresh token } catch (error) { console.error('Logout API failed:', error); //catches errors if API call breaks + toast.error('Logout API failed'); } finally { localStorage.removeItem('accessToken'); localStorage.removeItem('refreshToken'); @@ -79,6 +81,7 @@ const Header = ({ onMobileMenuClick, collapsed, onCollapseToggle }) => { }); } catch (error) { console.error('Failed to fetch user for header:', error); + toast.error('Failed to fetch user for header'); } }; fetchUser(); diff --git a/RestroHub-FrontEnd/src/components/admin/dashboard/cards/LiveOrders.jsx b/RestroHub-FrontEnd/src/components/admin/dashboard/cards/LiveOrders.jsx index 290a2090..89500830 100644 --- a/RestroHub-FrontEnd/src/components/admin/dashboard/cards/LiveOrders.jsx +++ b/RestroHub-FrontEnd/src/components/admin/dashboard/cards/LiveOrders.jsx @@ -11,6 +11,7 @@ import { import api from "@services/common/api"; import AdminSkeleton from '../../AdminSkeleton'; import { useAdminTheme } from '@context/AdminThemeContext'; +import toast from 'react-hot-toast'; // ============================================ // STATUS BADGE (Private to this file) @@ -107,6 +108,7 @@ const LiveOrders = () => { } catch (err) { console.error('Failed to fetch orders:', err); + toast.error('Failed to fetch orders'); setError('Failed to load orders'); setOrders(fallbackOrders); } finally { diff --git a/RestroHub-FrontEnd/src/components/admin/dashboard/cards/QuickActions.jsx b/RestroHub-FrontEnd/src/components/admin/dashboard/cards/QuickActions.jsx index b4c95d64..8b82a461 100644 --- a/RestroHub-FrontEnd/src/components/admin/dashboard/cards/QuickActions.jsx +++ b/RestroHub-FrontEnd/src/components/admin/dashboard/cards/QuickActions.jsx @@ -9,6 +9,7 @@ import { } from 'lucide-react'; import api from "@services/common/api"; import { useAdminTheme } from '@context/AdminThemeContext'; +import toast from 'react-hot-toast'; // import { useNavigate } from 'react-router-dom'; // if using react-router // ============================================ @@ -51,6 +52,7 @@ const QuickActions = () => { console.log('Navigate to new order page'); } catch (err) { console.error('Failed to create order:', err); + toast.error('Failed to create order'); } finally { setLoadingAction(null); } @@ -68,6 +70,7 @@ const QuickActions = () => { console.log('All orders marked ready'); } catch (err) { console.error('Failed to mark orders:', err); + toast.error('Failed to mark orders'); } finally { setLoadingAction(null); } @@ -91,6 +94,7 @@ const QuickActions = () => { console.log('WhatsApp broadcast sent'); } catch (err) { console.error('Failed to send broadcast:', err); + toast.error('Failed to send broadcast'); } finally { setLoadingAction(null); } @@ -112,6 +116,7 @@ const QuickActions = () => { console.log('Report exported'); } catch (err) { console.error('Failed to export report:', err); + toast.error('Failed to export report'); } finally { setLoadingAction(null); } diff --git a/RestroHub-FrontEnd/src/components/admin/dashboard/cards/RevenueChart.jsx b/RestroHub-FrontEnd/src/components/admin/dashboard/cards/RevenueChart.jsx index 08b86e13..78ba1af5 100644 --- a/RestroHub-FrontEnd/src/components/admin/dashboard/cards/RevenueChart.jsx +++ b/RestroHub-FrontEnd/src/components/admin/dashboard/cards/RevenueChart.jsx @@ -12,6 +12,7 @@ import { import api from "@services/common/api"; import AdminSkeleton from '../../AdminSkeleton'; import { useAdminTheme } from '@context/AdminThemeContext'; +import toast from 'react-hot-toast'; // ============================================ // MAIN COMPONENT (Exported) @@ -57,6 +58,7 @@ const RevenueChart = () => { } catch (err) { console.error('Failed to fetch revenue:', err); + toast.error('Failed to fetch revenue'); setError('Failed to load chart'); setData(fallbackData); } finally { diff --git a/RestroHub-FrontEnd/src/components/admin/dashboard/cards/StatsSection.jsx b/RestroHub-FrontEnd/src/components/admin/dashboard/cards/StatsSection.jsx index e1e3b892..51366f25 100644 --- a/RestroHub-FrontEnd/src/components/admin/dashboard/cards/StatsSection.jsx +++ b/RestroHub-FrontEnd/src/components/admin/dashboard/cards/StatsSection.jsx @@ -10,6 +10,7 @@ import { import api from "@services/common/api"; import AdminSkeleton from '../../AdminSkeleton'; import { useAdminTheme } from '@context/AdminThemeContext'; +import toast from 'react-hot-toast'; // ============================================ // STAT CARD (Private to this file) @@ -161,6 +162,7 @@ const StatsSection = () => { } catch (err) { console.error("Failed to fetch stats:", err); + toast.error("Failed to fetch stats"); setError("Failed to load stats"); setStats(fallbackStats); } finally { diff --git a/RestroHub-FrontEnd/src/components/admin/kds/KitchenDisplaySystem.jsx b/RestroHub-FrontEnd/src/components/admin/kds/KitchenDisplaySystem.jsx index 4caf8ae9..f04c6ce9 100644 --- a/RestroHub-FrontEnd/src/components/admin/kds/KitchenDisplaySystem.jsx +++ b/RestroHub-FrontEnd/src/components/admin/kds/KitchenDisplaySystem.jsx @@ -4,6 +4,7 @@ import SockJS from 'sockjs-client'; import api from '@services/common/api'; import KanbanBoard from './KanbanBoard'; import { toast } from 'react-hot-toast'; +import toast from 'react-hot-toast'; const KitchenDisplaySystem = () => { const [orders, setOrders] = useState([]); @@ -54,6 +55,7 @@ const KitchenDisplaySystem = () => { oscillator.stop(audioContextRef.current.currentTime + 1); } catch (e) { console.error("Audio playback failed", e); + toast.error("Audio playback failed"); } }; @@ -92,6 +94,7 @@ const KitchenDisplaySystem = () => { }); }, (error) => { console.error('WebSocket error:', error); + toast.error('WebSocket error'); setIsConnected(false); setTimeout(connectWebSocket, 5000); }); diff --git a/RestroHub-FrontEnd/src/components/admin/kds/OrderCard.jsx b/RestroHub-FrontEnd/src/components/admin/kds/OrderCard.jsx index 339f604b..e3a9c6a9 100644 --- a/RestroHub-FrontEnd/src/components/admin/kds/OrderCard.jsx +++ b/RestroHub-FrontEnd/src/components/admin/kds/OrderCard.jsx @@ -1,6 +1,7 @@ import React, { useState, useEffect } from 'react'; import { Clock, ChefHat, CheckCircle, AlertCircle } from 'lucide-react'; import api from '@services/common/api'; +import toast from 'react-hot-toast'; const OrderCard = ({ order, onStatusUpdate }) => { const [elapsedMinutes, setElapsedMinutes] = useState(0); @@ -25,6 +26,7 @@ const OrderCard = ({ order, onStatusUpdate }) => { onStatusUpdate(order.orderId, newStatus); } catch (error) { console.error('Failed to update order status', error); + toast.error('Failed to update order status'); } finally { setIsUpdating(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/marketing/qr/QRHeader.jsx b/RestroHub-FrontEnd/src/components/admin/marketing/qr/QRHeader.jsx index e6865584..63bb942e 100644 --- a/RestroHub-FrontEnd/src/components/admin/marketing/qr/QRHeader.jsx +++ b/RestroHub-FrontEnd/src/components/admin/marketing/qr/QRHeader.jsx @@ -1,5 +1,6 @@ import { useState } from 'react'; import { Download, QrCode, Loader2 } from 'lucide-react'; +import toast from 'react-hot-toast'; const QRHeader = () => { const [downloading, setDownloading] = useState(false); @@ -12,6 +13,7 @@ const QRHeader = () => { console.log('Download all QRs'); } catch (err) { console.error('Download failed:', err); + toast.error('Download failed'); } finally { setDownloading(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/marketing/qr/QRPreview.jsx b/RestroHub-FrontEnd/src/components/admin/marketing/qr/QRPreview.jsx index 1c83b570..83ef0e64 100644 --- a/RestroHub-FrontEnd/src/components/admin/marketing/qr/QRPreview.jsx +++ b/RestroHub-FrontEnd/src/components/admin/marketing/qr/QRPreview.jsx @@ -1,6 +1,7 @@ import { useState } from 'react'; import { Download, Eye, Loader2 } from 'lucide-react'; import QRCode from 'react-qr-code'; +import toast from 'react-hot-toast'; const QRPreview = ({ qrColor, selectedStyle }) => { const [downloading, setDownloading] = useState(null); @@ -21,6 +22,7 @@ const QRPreview = ({ qrColor, selectedStyle }) => { console.log('Download:', format); } catch (err) { console.error('Download failed:', err); + toast.error('Download failed'); } finally { setDownloading(null); } diff --git a/RestroHub-FrontEnd/src/components/admin/marketing/website/WebsiteHeader.jsx b/RestroHub-FrontEnd/src/components/admin/marketing/website/WebsiteHeader.jsx index 5c2e4ecb..50540f47 100644 --- a/RestroHub-FrontEnd/src/components/admin/marketing/website/WebsiteHeader.jsx +++ b/RestroHub-FrontEnd/src/components/admin/marketing/website/WebsiteHeader.jsx @@ -13,6 +13,7 @@ const WebsiteHeader = ({ onSave }) => { console.log('Saved'); } catch (err) { console.error('Save failed:', err); + toast.error('Save failed'); } finally { setSaving(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/menu/Menus.jsx b/RestroHub-FrontEnd/src/components/admin/menu/Menus.jsx index 0da84c4e..407bf918 100644 --- a/RestroHub-FrontEnd/src/components/admin/menu/Menus.jsx +++ b/RestroHub-FrontEnd/src/components/admin/menu/Menus.jsx @@ -43,6 +43,7 @@ const Menus = () => { setAllBranches(Array.isArray(branchList) ? branchList : []); } catch (err) { console.error('Failed to fetch branches:', err.response?.data || err); + toast.error('Failed to fetch branches'); setAllBranches([]); } }; diff --git a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/BulkActions.jsx b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/BulkActions.jsx index daa90f4f..2a8dd99f 100644 --- a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/BulkActions.jsx +++ b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/BulkActions.jsx @@ -1,6 +1,7 @@ import { useState } from 'react'; import { Copy, EyeOff, RefreshCw, Download, Loader2 } from 'lucide-react'; import api from "@services/common/api"; +import toast from 'react-hot-toast'; const BulkActions = ({ onRefresh }) => { const [loadingAction, setLoadingAction] = useState(null); @@ -21,6 +22,7 @@ const BulkActions = ({ onRefresh }) => { onRefresh?.(); } catch (err) { console.error('Failed to copy menu:', err); + toast.error('Failed to copy menu'); } finally { setLoadingAction(null); } @@ -38,6 +40,7 @@ const BulkActions = ({ onRefresh }) => { onRefresh?.(); } catch (err) { console.error('Failed to hide items:', err); + toast.error('Failed to hide items'); } finally { setLoadingAction(null); } @@ -59,6 +62,7 @@ const BulkActions = ({ onRefresh }) => { console.log('Export menu'); } catch (err) { console.error('Failed to export:', err); + toast.error('Failed to export'); } finally { setLoadingAction(null); } diff --git a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/CategoryFormModal.jsx b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/CategoryFormModal.jsx index e1effa26..21fe20e4 100644 --- a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/CategoryFormModal.jsx +++ b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/CategoryFormModal.jsx @@ -2,6 +2,7 @@ import { useState } from "react"; import { Dialog } from "@headlessui/react"; import { X, Loader2, Tag, Type, FileText } from "lucide-react"; import api from "@services/common/api"; +import toast from 'react-hot-toast'; const CategoryFormModal = ({ isOpen, onClose }) => { const [formData, setFormData] = useState({ @@ -36,6 +37,7 @@ const CategoryFormModal = ({ isOpen, onClose }) => { } catch (err) { console.error("Category create failed:", err.response?.data || err); + toast.error("Category create failed"); } finally { setSubmitting(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/CategorySidebar.jsx b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/CategorySidebar.jsx index 31bb9b91..1cdb4d8d 100644 --- a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/CategorySidebar.jsx +++ b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/CategorySidebar.jsx @@ -3,6 +3,7 @@ import { ChevronRight, RefreshCw, FolderPlus } from 'lucide-react'; import api from "@services/common/api"; import AdminSkeleton from '../../AdminSkeleton'; import { useAdminTheme } from '@context/AdminThemeContext'; +import toast from 'react-hot-toast'; // ============================================ // SKELETON (Private) @@ -58,6 +59,7 @@ const CategorySidebar = ({ selectedCategory, onCategoryChange, onAddCategory, se setAllCategories(response.data.data.content); } catch (err) { console.error('Failed to fetch categories:', err); + toast.error('Failed to fetch categories'); setCategories(fallbackCategories); setAllCategories(fallbackCategories); } finally { diff --git a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/FoodItemsGrid.jsx b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/FoodItemsGrid.jsx index 43b307ab..96eae5fb 100644 --- a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/FoodItemsGrid.jsx +++ b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/FoodItemsGrid.jsx @@ -3,6 +3,7 @@ import { Search, RefreshCw, AlertCircle, UtensilsCrossed, ChevronLeft, ChevronRi import MenuItemCard from './FoodItemCard'; import api from "@services/common/api"; import AdminSkeleton from '../../AdminSkeleton'; +import toast from 'react-hot-toast'; const PAGE_SIZE = 9; @@ -88,6 +89,7 @@ const MenuItemsGrid = forwardRef(({ selectedCategory, onEditItem }, ref) => { }); } catch (err) { console.error('Failed to fetch menu:', err.response?.data || err); + toast.error('Failed to fetch menu'); setError(err.response?.data?.message || 'Failed to load menu items'); setMenuItems([]); setPageInfo({ totalElements: 0, totalPages: 0, first: true, last: true }); diff --git a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/MenuFormModal.jsx b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/MenuFormModal.jsx index 0751bda8..bc0c1e59 100644 --- a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/MenuFormModal.jsx +++ b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/MenuFormModal.jsx @@ -3,6 +3,7 @@ import { useState, useEffect } from 'react'; import { X, Loader2, ChevronDown, Tag, UtensilsCrossed, MapPin, FileText, Type } from 'lucide-react'; import { Dialog } from '@headlessui/react'; import api from "@services/common/api"; +import toast from 'react-hot-toast'; const MenuCreation = ({ isOpen, onClose, editingMenu, allCategories, allBranches }) => { const [categories, setCategories] = useState([]); @@ -119,6 +120,7 @@ const MenuCreation = ({ isOpen, onClose, editingMenu, allCategories, allBranches onClose(); } catch (err) { console.error("Failed to save menu:", err.response?.data || err); + toast.error("Failed to save menu"); const message = err.response?.data?.message || err.response?.data?.error || 'Failed to save menu. Please try again.'; diff --git a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/MenusGrid.jsx b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/MenusGrid.jsx index a52a40c5..0babd6ff 100644 --- a/RestroHub-FrontEnd/src/components/admin/menu/menuCard/MenusGrid.jsx +++ b/RestroHub-FrontEnd/src/components/admin/menu/menuCard/MenusGrid.jsx @@ -989,6 +989,7 @@ const MenusGrid = forwardRef(({ onEditMenu, onCreateMenu }, ref) => { setMenus(Array.isArray(menuList) ? menuList : []); } catch (err) { console.error('Failed to fetch menus:', err.response?.data || err); + toast.error('Failed to fetch menus'); setError('Failed to load menus'); setMenus([]); } finally { diff --git a/RestroHub-FrontEnd/src/components/admin/orders/orderComponents/OrderCard.jsx b/RestroHub-FrontEnd/src/components/admin/orders/orderComponents/OrderCard.jsx index e3ccd9ac..c89b8763 100644 --- a/RestroHub-FrontEnd/src/components/admin/orders/orderComponents/OrderCard.jsx +++ b/RestroHub-FrontEnd/src/components/admin/orders/orderComponents/OrderCard.jsx @@ -13,6 +13,7 @@ import { UtensilsCrossed, } from 'lucide-react'; import api from "@services/common/api"; +import toast from 'react-hot-toast'; const OrderCard = ({ order, onStatusUpdate }) => { const [updating, setUpdating] = useState(false); @@ -164,6 +165,7 @@ const OrderCard = ({ order, onStatusUpdate }) => { onStatusUpdate(order.id, action.next); } catch (err) { console.error('Failed to update order:', err); + toast.error('Failed to update order'); } finally { setUpdating(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/orders/orderComponents/OrdersGrid.jsx b/RestroHub-FrontEnd/src/components/admin/orders/orderComponents/OrdersGrid.jsx index 082b6ebe..f98fb8ba 100644 --- a/RestroHub-FrontEnd/src/components/admin/orders/orderComponents/OrdersGrid.jsx +++ b/RestroHub-FrontEnd/src/components/admin/orders/orderComponents/OrdersGrid.jsx @@ -3,6 +3,7 @@ import { RefreshCw, AlertCircle, ClipboardList } from 'lucide-react'; import OrderCard from './OrderCard'; import api from "@services/common/api"; import AdminSkeleton from '../../AdminSkeleton'; +import toast from 'react-hot-toast'; // ============================================ // MAIN COMPONENT @@ -96,6 +97,7 @@ const OrdersGrid = ({ activeFilter, searchQuery, onOrdersChange }) => { syncOrders(fallbackOrders); } catch (err) { console.error('Failed to fetch orders:', err); + toast.error('Failed to fetch orders'); setError('Failed to load orders'); syncOrders(fallbackOrders); } finally { diff --git a/RestroHub-FrontEnd/src/components/admin/profile/Profile.jsx b/RestroHub-FrontEnd/src/components/admin/profile/Profile.jsx index e021b910..c2b59aa6 100644 --- a/RestroHub-FrontEnd/src/components/admin/profile/Profile.jsx +++ b/RestroHub-FrontEnd/src/components/admin/profile/Profile.jsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from 'react'; +import toast from 'react-hot-toast'; import ProfileHeader from './profileComponents/ProfileHeader'; import ProfileSidebar from './profileComponents/ProfileSidebar'; @@ -70,6 +71,7 @@ const Profile = () => { 'Failed to fetch profile:', error ); + toast.error('Failed to fetch profile'); } finally { @@ -118,6 +120,7 @@ const Profile = () => { 'Failed to update profile:', error ); + toast.error('Failed to update profile'); } }; diff --git a/RestroHub-FrontEnd/src/components/admin/profile/profileComponents/ProfileImageModal.jsx b/RestroHub-FrontEnd/src/components/admin/profile/profileComponents/ProfileImageModal.jsx index 92870721..f68d0902 100644 --- a/RestroHub-FrontEnd/src/components/admin/profile/profileComponents/ProfileImageModal.jsx +++ b/RestroHub-FrontEnd/src/components/admin/profile/profileComponents/ProfileImageModal.jsx @@ -2,6 +2,7 @@ import { useState, useRef } from 'react'; import { X, Upload, Loader2, Camera, Trash2 } from 'lucide-react'; import { Dialog } from '@headlessui/react'; import profileService from '../../../../services/user/profileService'; +import toast from 'react-hot-toast'; const ProfileImageModal = ({ isOpen, onClose, currentImage, onSave }) => { const [preview, setPreview] = useState(null); @@ -32,6 +33,7 @@ const ProfileImageModal = ({ isOpen, onClose, currentImage, onSave }) => { setPreview(null); } catch (err) { console.error('Upload failed:', err); + toast.error('Upload failed'); } finally { setUploading(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/profile/profileComponents/RestaurantInfoCard.jsx b/RestroHub-FrontEnd/src/components/admin/profile/profileComponents/RestaurantInfoCard.jsx index 12002b3a..5ff31d77 100644 --- a/RestroHub-FrontEnd/src/components/admin/profile/profileComponents/RestaurantInfoCard.jsx +++ b/RestroHub-FrontEnd/src/components/admin/profile/profileComponents/RestaurantInfoCard.jsx @@ -9,6 +9,7 @@ import { Facebook, } from 'lucide-react'; import api from '../../../../services/common/api'; +import toast from 'react-hot-toast'; const RestaurantInfoCard = ({ profile, onSave }) => { const [editing, setEditing] = useState(false); @@ -83,6 +84,7 @@ const RestaurantInfoCard = ({ profile, onSave }) => { setEditing(false); } catch (err) { console.error('Save failed:', err); + toast.error('Save failed'); } finally { setSaving(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/store/branch/BranchCard.jsx b/RestroHub-FrontEnd/src/components/admin/store/branch/BranchCard.jsx index da728605..e44db21e 100644 --- a/RestroHub-FrontEnd/src/components/admin/store/branch/BranchCard.jsx +++ b/RestroHub-FrontEnd/src/components/admin/store/branch/BranchCard.jsx @@ -7,6 +7,7 @@ import { UtensilsCrossed, FileText } from 'lucide-react'; import api from '@services/common/api'; +import toast from 'react-hot-toast'; const BranchCard = ({ branch, onEdit, onDelete, onRestore }) => { const [toggling, setToggling] = useState(false); @@ -41,6 +42,7 @@ const BranchCard = ({ branch, onEdit, onDelete, onRestore }) => { } } catch (err) { console.error('Toggle failed:', err); + toast.error('Toggle failed'); } finally { setToggling(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/store/branch/BranchFormModal.jsx b/RestroHub-FrontEnd/src/components/admin/store/branch/BranchFormModal.jsx index 3a342a45..a4463952 100644 --- a/RestroHub-FrontEnd/src/components/admin/store/branch/BranchFormModal.jsx +++ b/RestroHub-FrontEnd/src/components/admin/store/branch/BranchFormModal.jsx @@ -5,6 +5,7 @@ import { } from 'lucide-react'; import { Dialog } from '@headlessui/react'; import api from "@services/common/api"; +import toast from 'react-hot-toast'; const BranchFormModal = ({ isOpen, onClose, editingBranch, restaurantId }) => { const [formData, setFormData] = useState({ @@ -91,6 +92,7 @@ const BranchFormModal = ({ isOpen, onClose, editingBranch, restaurantId }) => { onClose(); } catch (err) { console.error('Save failed:', err); + toast.error('Save failed'); const message = err.response?.data?.message || 'Failed to save branch'; setError(message); } finally { diff --git a/RestroHub-FrontEnd/src/components/admin/store/branch/BranchesGrid.jsx b/RestroHub-FrontEnd/src/components/admin/store/branch/BranchesGrid.jsx index 62ef0024..2f219aea 100644 --- a/RestroHub-FrontEnd/src/components/admin/store/branch/BranchesGrid.jsx +++ b/RestroHub-FrontEnd/src/components/admin/store/branch/BranchesGrid.jsx @@ -43,6 +43,7 @@ const BranchesGrid = forwardRef(({ onEdit, onCountChange, restaurantId }, ref) = onCountChange?.(branchList.length); } catch (err) { console.error('Fetch failed:', err); + toast.error('Fetch failed'); setError('Failed to load branches'); setBranches([]); onCountChange?.(0); diff --git a/RestroHub-FrontEnd/src/components/admin/store/tables/TableCard.jsx b/RestroHub-FrontEnd/src/components/admin/store/tables/TableCard.jsx index db8343ff..210f1e79 100644 --- a/RestroHub-FrontEnd/src/components/admin/store/tables/TableCard.jsx +++ b/RestroHub-FrontEnd/src/components/admin/store/tables/TableCard.jsx @@ -1,6 +1,7 @@ import { useState } from 'react'; import { QrCode, Edit2, Trash2, Users, Loader2 } from 'lucide-react'; import api from '@services/common/api'; +import toast from 'react-hot-toast'; const TableCard = ({ table, onShowQR, onEdit, onDelete }) => { const [saving, setSaving] = useState(false); @@ -45,6 +46,7 @@ const TableCard = ({ table, onShowQR, onEdit, onDelete }) => { onDelete(table.id); } catch (err) { console.error('Delete failed:', err); + toast.error('Delete failed'); alert(err.response?.data?.message || 'Failed to delete table'); } finally { setSaving(false); diff --git a/RestroHub-FrontEnd/src/components/admin/store/tables/TableFormModal.jsx b/RestroHub-FrontEnd/src/components/admin/store/tables/TableFormModal.jsx index c44c2beb..314ca8a4 100644 --- a/RestroHub-FrontEnd/src/components/admin/store/tables/TableFormModal.jsx +++ b/RestroHub-FrontEnd/src/components/admin/store/tables/TableFormModal.jsx @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'; import { X, Loader2, LayoutGrid } from 'lucide-react'; import { Dialog } from '@headlessui/react'; import api from '@services/common/api'; +import toast from 'react-hot-toast'; const TableFormModal = ({ isOpen, onClose, onSaved, branchId, editingTable }) => { const [formData, setFormData] = useState({ @@ -50,6 +51,7 @@ const TableFormModal = ({ isOpen, onClose, onSaved, branchId, editingTable }) => onClose(); } catch (err) { console.error('Failed:', err); + toast.error('Failed'); setError(err.response?.data?.message || 'Failed to save table'); } finally { setSubmitting(false); diff --git a/RestroHub-FrontEnd/src/components/admin/store/tables/TableQRModal.jsx b/RestroHub-FrontEnd/src/components/admin/store/tables/TableQRModal.jsx index 6516a54d..880ad610 100644 --- a/RestroHub-FrontEnd/src/components/admin/store/tables/TableQRModal.jsx +++ b/RestroHub-FrontEnd/src/components/admin/store/tables/TableQRModal.jsx @@ -2,6 +2,7 @@ import { useState } from 'react'; import { X, Download, Loader2, ExternalLink } from 'lucide-react'; import { Dialog } from '@headlessui/react'; import QRCode from 'react-qr-code'; +import toast from 'react-hot-toast'; const TableQRModal = ({ isOpen, onClose, table, branchId }) => { const [downloading, setDownloading] = useState(false); @@ -17,6 +18,7 @@ const TableQRModal = ({ isOpen, onClose, table, branchId }) => { console.log('Download QR:', table.number); } catch (err) { console.error('Download failed:', err); + toast.error('Download failed'); } finally { setDownloading(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/store/tables/TablesGrid.jsx b/RestroHub-FrontEnd/src/components/admin/store/tables/TablesGrid.jsx index 7bb19cc2..7411f01c 100644 --- a/RestroHub-FrontEnd/src/components/admin/store/tables/TablesGrid.jsx +++ b/RestroHub-FrontEnd/src/components/admin/store/tables/TablesGrid.jsx @@ -4,6 +4,7 @@ import api from '@services/common/api'; import TableCard from './TableCard'; import AdminSkeleton from '../../AdminSkeleton'; import { normalizeTable } from './tableMapper'; +import toast from 'react-hot-toast'; const TablesGrid = ({ branchId, onShowQR, onEdit, onTablesLoaded, refreshKey }) => { const [tables, setTables] = useState([]); @@ -32,6 +33,7 @@ const TablesGrid = ({ branchId, onShowQR, onEdit, onTablesLoaded, refreshKey }) onTablesLoaded?.(tableList); } catch (err) { console.error('Fetch failed:', err); + toast.error('Fetch failed'); setError('Failed to load tables'); setTables([]); onTablesLoaded?.([]); diff --git a/RestroHub-FrontEnd/src/components/admin/store/tables/TablesHeader.jsx b/RestroHub-FrontEnd/src/components/admin/store/tables/TablesHeader.jsx index 20481368..4d53ef18 100644 --- a/RestroHub-FrontEnd/src/components/admin/store/tables/TablesHeader.jsx +++ b/RestroHub-FrontEnd/src/components/admin/store/tables/TablesHeader.jsx @@ -1,6 +1,7 @@ import { useState } from 'react'; import { Link } from 'react-router-dom'; import { Plus, ArrowLeft, Download, Loader2, LayoutGrid } from 'lucide-react'; +import toast from 'react-hot-toast'; const TablesHeader = ({ branchId, onAddTable, totalTables = 0 }) => { const [downloading, setDownloading] = useState(false); @@ -13,6 +14,7 @@ const TablesHeader = ({ branchId, onAddTable, totalTables = 0 }) => { console.log('Download all QRs'); } catch (err) { console.error('Download failed:', err); + toast.error('Download failed'); } finally { setDownloading(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/upi/UPICard.jsx b/RestroHub-FrontEnd/src/components/admin/upi/UPICard.jsx index d520cb8a..20c1dde6 100644 --- a/RestroHub-FrontEnd/src/components/admin/upi/UPICard.jsx +++ b/RestroHub-FrontEnd/src/components/admin/upi/UPICard.jsx @@ -1,5 +1,6 @@ import { useState } from 'react'; import { +import toast from 'react-hot-toast'; CreditCard, Check, Copy, @@ -27,6 +28,7 @@ const UPICard = ({ link, onCopy, onSetDefault, onDelete, onTest, copiedId }) => onSetDefault(link.id); } catch (err) { console.error('Failed:', err); + toast.error('Failed'); } finally { setSettingDefault(false); } @@ -41,6 +43,7 @@ const UPICard = ({ link, onCopy, onSetDefault, onDelete, onTest, copiedId }) => onDelete(link.id); } catch (err) { console.error('Failed:', err); + toast.error('Failed'); } finally { setDeleting(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/upi/UPIFormModal.jsx b/RestroHub-FrontEnd/src/components/admin/upi/UPIFormModal.jsx index de65fa8c..315d9237 100644 --- a/RestroHub-FrontEnd/src/components/admin/upi/UPIFormModal.jsx +++ b/RestroHub-FrontEnd/src/components/admin/upi/UPIFormModal.jsx @@ -1,6 +1,7 @@ import { useState } from 'react'; import { X, Loader2, CreditCard, Info } from 'lucide-react'; import { Dialog } from '@headlessui/react'; +import toast from 'react-hot-toast'; const UPIFormModal = ({ isOpen, onClose }) => { const [formData, setFormData] = useState({ name: '', upiId: '' }); @@ -17,6 +18,7 @@ const UPIFormModal = ({ isOpen, onClose }) => { setFormData({ name: '', upiId: '' }); } catch (err) { console.error('Failed:', err); + toast.error('Failed'); } finally { setSubmitting(false); } diff --git a/RestroHub-FrontEnd/src/components/admin/upi/UPIGrid.jsx b/RestroHub-FrontEnd/src/components/admin/upi/UPIGrid.jsx index 5aa815c2..d5f905f6 100644 --- a/RestroHub-FrontEnd/src/components/admin/upi/UPIGrid.jsx +++ b/RestroHub-FrontEnd/src/components/admin/upi/UPIGrid.jsx @@ -2,6 +2,7 @@ import { useState, useEffect } from 'react'; import { RefreshCw, AlertCircle, CreditCard } from 'lucide-react'; import UPICard from './UPICard'; import AdminSkeleton from '../AdminSkeleton'; +import toast from 'react-hot-toast'; // ============================================ // MAIN @@ -39,6 +40,7 @@ const UPIGrid = ({ onTest, onCountChange }) => { onCountChange?.(fallbackLinks.length); } catch (err) { console.error('Fetch failed:', err); + toast.error('Fetch failed'); setError('Failed to load UPI links'); setUpiLinks(fallbackLinks); } finally {