Przejdź do głównej zawartości

19. Symulator zamawiania jedzenia

Zbudujesz symulator aplikacji do zamawiania jedzenia (jak Uber Eats / Pyszne.pl) — przeglądanie restauracji, menu z kategoriami, koszyk i podsumowanie zamówienia.

Czego się nauczycie?

  • Zarządzanie stanem koszyka (globalne)
  • Wielopoziomowa nawigacja (restauracje → menu → koszyk)
  • Warianty pozycji (rozmiar, dodatki) — wariant B/C
  • Symulacja procesu zamówienia (wieloetapowy flow)
  • Praca zespołowa — jeden robi restauracje i menu, drugi koszyk i proces zamówienia
  1. Lista restauracji — karty z logo, nazwą, kuchnią, oceną, czasem dostawy

  2. Menu restauracji — dania pogrupowane w kategorie z cenami i opisami

  3. Koszyk — dodawanie pozycji, zmiana ilości, podsumowanie

  4. Proces zamówienia — formularz z adresem dostawy i sposobem płatności

  5. Potwierdzenie — ekran sukcesu z szacowanym czasem dostawy

{
"restaurants": [
{
"id": "rest-001",
"name": "Pizza Planet",
"cuisine": "Włoska",
"rating": 4.7,
"deliveryTime": "25-35 min",
"deliveryFee": 5.99,
"minOrder": 30,
"menu": [
{
"category": "Pizze",
"items": [
{
"id": "pizza-margherita",
"name": "Margherita",
"description": "Sos pomidorowy, mozzarella, bazylia",
"price": 32.99,
"image": "https://..."
}
]
}
]
}
]
}
  • Lista restauracji (2-3 z lokalnymi danymi)
  • Menu restauracji z kategoriami
  • Koszyk — dodawanie, usuwanie, suma
  • Koszyk dostępny z każdej strony (Context API)
  • Routing: /, /restaurant/:id, /cart
  • Foldersrc/
    • Foldercontext/
      • CartContext.jsx
    • Folderpages/
      • RestaurantListPage.jsx
      • RestaurantMenuPage.jsx
      • CartPage.jsx
    • Foldercomponents/
      • RestaurantCard.jsx
      • MenuItem.jsx
      • CartSummary.jsx
Ocena: 3.0
src/context/CartContext.jsx
function cartReducer(state, action) {
switch (action.type) {
case 'ADD_ITEM': {
// Blokada mieszania restauracji
if (state.restaurantId && state.restaurantId !== action.restaurantId) {
if (!window.confirm('Masz produkty z innej restauracji. Wyczyścić koszyk?')) {
return state;
}
return {
restaurantId: action.restaurantId,
items: [{ ...action.item, quantity: 1 }],
};
}
const existing = state.items.find((i) => i.id === action.item.id);
return {
restaurantId: action.restaurantId,
items: existing
? state.items.map((i) =>
i.id === action.item.id ? { ...i, quantity: i.quantity + 1 } : i
)
: [...state.items, { ...action.item, quantity: 1 }],
};
}
case 'REMOVE_ITEM':
return { ...state, items: state.items.filter((i) => i.id !== action.id) };
case 'CLEAR':
return { restaurantId: null, items: [] };
default:
return state;
}
}
const ORDER_STATUSES = [
{ status: 'confirmed', label: 'Zamówienie przyjęte', delay: 0 },
{ status: 'preparing', label: 'Restauracja przygotowuje', delay: 5000 },
{ status: 'picked-up', label: 'Kurier odebrał zamówienie', delay: 15000 },
{ status: 'delivered', label: 'Zamówienie dostarczone!', delay: 30000 },
];
function useOrderTracking() {
const [statusIndex, setStatusIndex] = useState(0);
useEffect(() => {
const timers = ORDER_STATUSES.slice(1).map((s, i) =>
setTimeout(() => setStatusIndex(i + 1), s.delay)
);
return () => timers.forEach(clearTimeout);
}, []);
return ORDER_STATUSES[statusIndex];
}

Powodzenia!

Symulator zamawiania jedzenia to projekt, który wszyscy znają z codziennego życia — co ułatwia zrozumienie wymagań. Koszyk z obsługą wielu pozycji i mieszania restauracji to klasyczny problem zarządzania stanem. Context API + useReducer jest tutaj idealnym rozwiązaniem!