diff --git a/my-library/src/App.jsx b/my-library/src/App.jsx index 9bf7291..fa65a5d 100644 --- a/my-library/src/App.jsx +++ b/my-library/src/App.jsx @@ -13,6 +13,7 @@ import Reservations from './pages/Reservations'; import Returns from './pages/Returns'; import Subscription from './pages/Subscription'; import Loans from './pages/Loans'; +import GroupOrders from './pages/GroupOrders'; import { useAuth } from './context/AuthContext'; function RequireAuth({ children }) { @@ -43,6 +44,7 @@ export default function App() { } /> } /> } /> + } /> } /> diff --git a/my-library/src/components/Navbar.jsx b/my-library/src/components/Navbar.jsx index d28da7d..d296850 100644 --- a/my-library/src/components/Navbar.jsx +++ b/my-library/src/components/Navbar.jsx @@ -22,6 +22,7 @@ export default function Navbar() { {user?.role === 'user' &&
  • Mes réservations
  • } {user?.role === 'user' &&
  • Mon abonnement
  • } {user?.role === 'user' &&
  • Mes prêts
  • } + {user &&
  • Commandes groupées
  • } {user &&
  • Mon compte
  • } {user?.role === 'admin' &&
  • Clients
  • } {user?.role === 'admin' &&
  • Retours
  • } diff --git a/my-library/src/context/GroupOrderContext.js b/my-library/src/context/GroupOrderContext.js new file mode 100644 index 0000000..6975698 --- /dev/null +++ b/my-library/src/context/GroupOrderContext.js @@ -0,0 +1,59 @@ +import { createContext, useContext, useState } from 'react'; + +const GroupOrderContext = createContext(null); + +export function GroupOrderProvider({ children }) { + const [groups, setGroups] = useState(() => { + const saved = localStorage.getItem('groupOrders'); + return saved ? JSON.parse(saved) : []; + }); + + function createGroup(creatorPhone) { + const group = { + id: crypto.randomUUID(), + creatorPhone, + orders: [], + status: 'OPEN', + createdAt: new Date().toISOString(), + }; + const updated = [...groups, group]; + setGroups(updated); + localStorage.setItem('groupOrders', JSON.stringify(updated)); + return group; + } + + function addOrderToGroup(groupId, phoneNumber, bookId, bookTitle, quantity) { + const updated = groups.map(g => { + if (g.id !== groupId) return g; + const order = { + orderId: crypto.randomUUID(), + phoneNumber, + bookId, + bookTitle, + quantity: Number(quantity), + addedAt: new Date().toISOString(), + }; + return { ...g, orders: [...g.orders, order] }; + }); + setGroups(updated); + localStorage.setItem('groupOrders', JSON.stringify(updated)); + } + + function closeGroup(groupId) { + const updated = groups.map(g => + g.id === groupId ? { ...g, status: 'CLOSED' } : g + ); + setGroups(updated); + localStorage.setItem('groupOrders', JSON.stringify(updated)); + } + + return ( + + {children} + + ); +} + +export function useGroupOrders() { + return useContext(GroupOrderContext); +} diff --git a/my-library/src/index.js b/my-library/src/index.js index c330510..abfad5a 100644 --- a/my-library/src/index.js +++ b/my-library/src/index.js @@ -7,6 +7,7 @@ import { ReviewProvider } from './context/ReviewContext'; import { ReturnProvider } from './context/ReturnContext'; import { SubscriptionProvider } from './context/SubscriptionContext'; import { LoanProvider } from './context/LoanContext'; +import { GroupOrderProvider } from './context/GroupOrderContext'; import App from './App'; import './styles/global.css'; @@ -20,7 +21,9 @@ root.render( - + + + diff --git a/my-library/src/pages/GroupOrders.jsx b/my-library/src/pages/GroupOrders.jsx new file mode 100644 index 0000000..a87d6ea --- /dev/null +++ b/my-library/src/pages/GroupOrders.jsx @@ -0,0 +1,167 @@ +import { useState } from 'react'; +import { useGroupOrders } from '../context/GroupOrderContext'; +import { useAuth } from '../context/AuthContext'; + +export default function GroupOrders() { + const { groups, createGroup, addOrderToGroup, closeGroup } = useGroupOrders(); + const { user } = useAuth(); + + const [creatorPhone, setCreatorPhone] = useState(''); + const [joinGroupId, setJoinGroupId] = useState(''); + const [joinForm, setJoinForm] = useState({ phoneNumber: '', bookId: '', bookTitle: '', quantity: 1 }); + const [joinStatus, setJoinStatus] = useState({}); + const [createStatus, setCreateStatus] = useState(null); + + function handleCreateGroup(e) { + e.preventDefault(); + const group = createGroup(creatorPhone); + setCreateStatus(`Groupe créé ! ID : ${group.id}`); + setCreatorPhone(''); + } + + function handleJoinGroup(e) { + e.preventDefault(); + const group = groups.find(g => g.id === joinGroupId); + if (!group) { + setJoinStatus(prev => ({ ...prev, [joinGroupId]: 'Groupe introuvable.' })); + return; + } + if (group.status === 'CLOSED') { + setJoinStatus(prev => ({ ...prev, [joinGroupId]: 'Ce groupe est fermé.' })); + return; + } + addOrderToGroup(joinGroupId, joinForm.phoneNumber, joinForm.bookId, joinForm.bookTitle, joinForm.quantity); + setJoinStatus(prev => ({ ...prev, [joinGroupId]: 'Commande ajoutée au groupe !' })); + setJoinForm({ phoneNumber: '', bookId: '', bookTitle: '', quantity: 1 }); + } + + const openGroups = groups.filter(g => g.status === 'OPEN'); + const closedGroups = groups.filter(g => g.status === 'CLOSED'); + + return ( +
    +

    Commandes groupées

    + +
    +

    Créer un groupe

    +
    + + +
    + {createStatus &&

    {createStatus}

    } +
    + +
    +

    Rejoindre un groupe

    +
    + + + + + + +
    + {joinStatus[joinGroupId] && ( +

    + {joinStatus[joinGroupId]} +

    + )} +
    + +
    +

    Groupes ouverts ({openGroups.length})

    + {openGroups.length === 0 ? ( +

    Aucun groupe ouvert.

    + ) : ( +
      + {openGroups.map(g => ( +
    • + Groupe {g.id.slice(0, 8)}… +
      + Créé par : {g.creatorPhone} +
      + Créé le : {new Date(g.createdAt).toLocaleDateString('fr-FR')} +
      + Participants : {g.orders.length} + {g.orders.length > 0 && ( +
        + {g.orders.map(o => ( +
      • + {o.phoneNumber} , {o.bookTitle} (x{o.quantity}) +
      • + ))} +
      + )} + +
    • + ))} +
    + )} +
    + + {closedGroups.length > 0 && ( +
    +

    Groupes fermés ({closedGroups.length})

    +
      + {closedGroups.map(g => ( +
    • + Groupe {g.id.slice(0, 8)}… , {g.orders.length} commande(s) , Fermé ✓ +
    • + ))} +
    +
    + )} +
    + ); +} diff --git a/my-library/src/pages/Orders.jsx b/my-library/src/pages/Orders.jsx index 7b8026d..93a38aa 100644 --- a/my-library/src/pages/Orders.jsx +++ b/my-library/src/pages/Orders.jsx @@ -88,4 +88,4 @@ export default function Orders() { {message &&

    {message}

    } ); -} \ No newline at end of file +}