aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/context
diff options
context:
space:
mode:
authorLibravatarLibravatar Biswa Kalyan Bhuyan <[email protected]> 2025-04-29 10:47:43 +0530
committerLibravatarLibravatar Biswa Kalyan Bhuyan <[email protected]> 2025-04-29 10:47:43 +0530
commita2e0a65b2599267efe94d665d6305f59b225bbd5 (patch)
treee2cef2031e3f7655e0c5f419020a3f1064c3b7b8 /frontend/src/context
parent570bf0f3f065d583d6f94ecfc61aae93ba3e43de (diff)
downloadrestaurant-master.tar.gz
restaurant-master.tar.bz2
restaurant-master.zip
feat: added initlaized the frontend and backendHEADmaster
Diffstat (limited to 'frontend/src/context')
-rw-r--r--frontend/src/context/auth-context.js126
-rw-r--r--frontend/src/context/cart-context.js120
-rw-r--r--frontend/src/context/theme-context.js54
3 files changed, 300 insertions, 0 deletions
diff --git a/frontend/src/context/auth-context.js b/frontend/src/context/auth-context.js
new file mode 100644
index 0000000..d67b345
--- /dev/null
+++ b/frontend/src/context/auth-context.js
@@ -0,0 +1,126 @@
+import { createContext, useContext, useState, useEffect } from 'react';
+import { useRouter } from 'next/navigation';
+import { Sonner, toast } from 'sonner';
+import * as authApi from '@/lib/api/auth';
+
+// Create auth context
+const AuthContext = createContext();
+
+export const AuthProvider = ({ children }) => {
+ const [user, setUser] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const router = useRouter();
+
+ // Check if user is logged in on initial load
+ useEffect(() => {
+ const checkAuth = async () => {
+ try {
+ const currentUser = authApi.getCurrentUser();
+ if (currentUser) {
+ setUser(currentUser);
+ }
+ } catch (error) {
+ console.error('Authentication check failed:', error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ checkAuth();
+ }, []);
+
+ // Login user
+ const login = async (credentials) => {
+ try {
+ setLoading(true);
+ const data = await authApi.login(credentials);
+ setUser(data.user);
+
+ toast.success('Login successful!');
+
+ // Redirect based on role
+ if (data.user.role === 'admin') {
+ router.push('/admin');
+ } else if (data.user.role === 'staff') {
+ router.push('/staff');
+ } else {
+ router.push('/');
+ }
+
+ return data;
+ } catch (error) {
+ toast.error(error.message || 'Login failed');
+ throw error;
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ // Register user
+ const register = async (userData) => {
+ try {
+ setLoading(true);
+ const data = await authApi.register(userData);
+ setUser(data.user);
+
+ toast.success('Registration successful!');
+ router.push('/');
+
+ return data;
+ } catch (error) {
+ toast.error(error.message || 'Registration failed');
+ throw error;
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ // Logout user
+ const logout = () => {
+ authApi.logout();
+ setUser(null);
+ router.push('/login');
+ toast.success('Logged out successfully');
+ };
+
+ // Get user profile
+ const getProfile = async () => {
+ try {
+ setLoading(true);
+ const data = await authApi.getProfile();
+ setUser(data.user);
+ return data.user;
+ } catch (error) {
+ console.error('Failed to get user profile:', error);
+ throw error;
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+ <AuthContext.Provider
+ value={{
+ user,
+ loading,
+ isAuthenticated: !!user,
+ login,
+ register,
+ logout,
+ getProfile,
+ }}
+ >
+ {children}
+ <Sonner position="top-right" />
+ </AuthContext.Provider>
+ );
+};
+
+// Custom hook to use auth context
+export const useAuth = () => {
+ const context = useContext(AuthContext);
+ if (!context) {
+ throw new Error('useAuth must be used within an AuthProvider');
+ }
+ return context;
+}; \ No newline at end of file
diff --git a/frontend/src/context/cart-context.js b/frontend/src/context/cart-context.js
new file mode 100644
index 0000000..8d173b7
--- /dev/null
+++ b/frontend/src/context/cart-context.js
@@ -0,0 +1,120 @@
+import { createContext, useContext, useState, useEffect } from 'react';
+import { toast } from 'sonner';
+
+const CartContext = createContext();
+
+export const CartProvider = ({ children }) => {
+ const [items, setItems] = useState([]);
+ const [total, setTotal] = useState(0);
+
+ // Load cart from localStorage on initial load
+ useEffect(() => {
+ if (typeof window !== 'undefined') {
+ const savedCart = localStorage.getItem('cart');
+ if (savedCart) {
+ try {
+ const parsedCart = JSON.parse(savedCart);
+ setItems(parsedCart);
+ calculateTotal(parsedCart);
+ } catch (error) {
+ console.error('Failed to parse cart from localStorage:', error);
+ }
+ }
+ }
+ }, []);
+
+ // Save cart to localStorage whenever it changes
+ useEffect(() => {
+ if (typeof window !== 'undefined') {
+ localStorage.setItem('cart', JSON.stringify(items));
+ calculateTotal(items);
+ }
+ }, [items]);
+
+ // Calculate total price
+ const calculateTotal = (cartItems) => {
+ const sum = cartItems.reduce((acc, item) => acc + item.price * item.quantity, 0);
+ setTotal(sum);
+ };
+
+ // Add item to cart
+ const addItem = (item) => {
+ setItems((prevItems) => {
+ // Check if item already exists in cart
+ const existingItemIndex = prevItems.findIndex((i) => i.id === item.id);
+
+ if (existingItemIndex !== -1) {
+ // Item exists, update quantity
+ const updatedItems = [...prevItems];
+ updatedItems[existingItemIndex] = {
+ ...updatedItems[existingItemIndex],
+ quantity: updatedItems[existingItemIndex].quantity + 1,
+ };
+ toast.success(`Added another ${item.name} to your cart`);
+ return updatedItems;
+ } else {
+ // Item doesn't exist, add new item
+ toast.success(`Added ${item.name} to your cart`);
+ return [...prevItems, { ...item, quantity: 1 }];
+ }
+ });
+ };
+
+ // Remove item from cart
+ const removeItem = (itemId) => {
+ setItems((prevItems) => {
+ const itemToRemove = prevItems.find((item) => item.id === itemId);
+ if (itemToRemove) {
+ toast.success(`Removed ${itemToRemove.name} from your cart`);
+ }
+ return prevItems.filter((item) => item.id !== itemId);
+ });
+ };
+
+ // Update item quantity
+ const updateQuantity = (itemId, quantity) => {
+ if (quantity < 1) return;
+
+ setItems((prevItems) =>
+ prevItems.map((item) =>
+ item.id === itemId ? { ...item, quantity } : item
+ )
+ );
+ };
+
+ // Clear cart
+ const clearCart = () => {
+ setItems([]);
+ toast.success('Cart cleared');
+ };
+
+ // Get cart item count
+ const getItemCount = () => {
+ return items.reduce((count, item) => count + item.quantity, 0);
+ };
+
+ return (
+ <CartContext.Provider
+ value={{
+ items,
+ total,
+ addItem,
+ removeItem,
+ updateQuantity,
+ clearCart,
+ getItemCount,
+ }}
+ >
+ {children}
+ </CartContext.Provider>
+ );
+};
+
+// Custom hook to use cart context
+export const useCart = () => {
+ const context = useContext(CartContext);
+ if (!context) {
+ throw new Error('useCart must be used within a CartProvider');
+ }
+ return context;
+}; \ No newline at end of file
diff --git a/frontend/src/context/theme-context.js b/frontend/src/context/theme-context.js
new file mode 100644
index 0000000..655d1b9
--- /dev/null
+++ b/frontend/src/context/theme-context.js
@@ -0,0 +1,54 @@
+import { createContext, useContext, useState, useEffect } from 'react';
+
+const ThemeContext = createContext();
+
+export const ThemeProvider = ({ children }) => {
+ const [theme, setTheme] = useState('light');
+
+ // Initialize theme from localStorage or system preference
+ useEffect(() => {
+ // Check if we're in a browser environment
+ if (typeof window !== 'undefined') {
+ const savedTheme = localStorage.getItem('theme');
+
+ // Use saved theme or system preference
+ if (savedTheme) {
+ setTheme(savedTheme);
+ document.documentElement.classList.toggle('dark', savedTheme === 'dark');
+ } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
+ setTheme('dark');
+ document.documentElement.classList.add('dark');
+ }
+ }
+ }, []);
+
+ // Update theme in localStorage and toggle dark class
+ const updateTheme = (newTheme) => {
+ if (typeof window !== 'undefined') {
+ localStorage.setItem('theme', newTheme);
+ document.documentElement.classList.toggle('dark', newTheme === 'dark');
+ setTheme(newTheme);
+ }
+ };
+
+ // Toggle between light and dark theme
+ const toggleTheme = () => {
+ const newTheme = theme === 'light' ? 'dark' : 'light';
+ updateTheme(newTheme);
+ };
+
+ return (
+ <ThemeContext.Provider value={{ theme, toggleTheme }}>
+ {children}
+ </ThemeContext.Provider>
+ );
+};
+
+// Custom hook to use theme context
+export const useTheme = () => {
+ const context = useContext(ThemeContext);
+ if (!context) {
+ throw new Error('useTheme must be used within a ThemeProvider');
+ }
+ return context;
+}; \ No newline at end of file