Portfolio
Projekt: E‑Shop

Projekt: E‑Shop

Březen 2026

Po Pokémon Memory Game přišel další větší milník z The Odin Project – jednoduchý, ale plnohodnotný e‑shop. Cílem nebylo jen něco „naklikat v Reactu“, ale propojit více témat najednou: routing, globální stav (košík), práci s API a moderní UI.

Repozitář projektu: Basic Fake e‑shop

Co projekt dělá

Aplikace simuluje klasický malý e‑shop:

  • Zobrazuje produkty z FakeStore API v přehledné mřížce.
  • U každého produktu ukazuje název, cenu, kategorii a obrázek.
  • Umožňuje přidávat a odebírat položky z košíku.
  • Košík je dostupný z každé stránky díky hornímu Headeru.
  • Obsahuje základní stránky: Home, Products a Cart.

Technologie a struktura

Projekt běží na:

  • Reactu (funkcionální komponenty, hooks),
  • Vite pro rychlý vývoj,
  • React Router DOM pro navigaci mezi stránkami,
  • Tailwind CSS pro rychlé a moderní stylování.

Struktura aplikace je rozdělená na components a pages, podobně jako u větších React projektů:

  • Header, Footer, Hero, Features – znovupoužitelné komponenty UI.
  • Home, Products, Cart – stránky, které se mění podle URL.

Práce s API a stavem

Produkty se načítají z FakeStore API pomocí fetch/axios a useEffect. Po načtení se uloží do stavu a z nich se renderují karty produktů.

Jednoduché schéma pro načtení produktů může vypadat třeba takto:

useEffect(() => {
	const loadProducts = async () => {
		try {
			const response = await fetch("https://fakestoreapi.com/products");
			const data = await response.json();
			setProducts(data);
		} catch (error) {
			console.error("Chyba při načítání produktů:", error);
		}
	};

	loadProducts();
}, []);

Pro košík jsem použil Context API, aby bylo možné z jakékoliv komponenty přidat/odebrat položku a zároveň aktualizovat počet položek v Headeru i obsah stránky Cart:

const CartContext = createContext();

const CartProvider = ({ children }) => {
	const [cartItems, setCartItems] = useState([]);

	const addToCart = (product) => {
		setCartItems((prev) => [...prev, product]);
	};

	const removeFromCart = (id) => {
		setCartItems((prev) => prev.filter((item) => item.id !== id));
	};

	return (
		<CartContext.Provider value={{ cartItems, addToCart, removeFromCart }}>
			{children}
		</CartContext.Provider>
	);
};

Routing a uživatelská zkušenost

Pomocí React Routeru má aplikace klasickou SPA strukturu – stránka se nepřenačítá, mění se jen obsah:

  • / – úvodní stránka s hero sekcí a základními informacemi o shopu.
  • /products – hlavní katalog s produkty z API.
  • /cart – přehled košíku s možností položky odebírat.

Header obsahuje odkazy na všechny tři sekce a zároveň ukazuje počet položek v košíku, takže uživatel má neustále přehled, co už přidal.

Co mě potrápilo

  • Práce s globálním stavem: Zvyk z menších projektů byl všechno řešit přes useState v jedné komponentě. Tady jsem se musel naučit přemýšlet nad tím, co má být globální (košík) a jak to zpřístupnit z různých částí aplikace.
  • Synchronizace UI a dat: Ujistit se, že UI vždy odráží aktuální stav košíku (např. po odebrání položky z Cart stránky se ihned aktualizuje i číslo v Headeru).
  • Tailwind a design: Tailwind je extrémně rychlý, ale na začátku jsem měl tendenci ztrácet se v nekonečném řetězení tříd. Postupně jsem si ale začal vytvářet konzistentní patterny pro karty, tlačítka a layout.

Co jsem se naučil

  • React Router: Jak definovat jednotlivé routy, propojit je s komponentami stránek a jak funguje <BrowserRouter>, <Routes> a <Route>.
  • Context API: Jak vytvořit poskytovatele (Provider), který obalí celou aplikaci, a jak z kontextu číst a zapisovat data v různých komponentách.
  • Lepší práce s API: Opakování práce s asynchronním kódem, ošetření chyb a zobrazení UI až ve chvíli, kdy jsou data načtená.
  • UX e‑shopu: Jak důležité je mít konzistentní layout, viditelné CTA tlačítko „Přidat do košíku“ a okamžitou zpětnou vazbu pro uživatele.

Kam to chci posunout dál

Do budoucna bych chtěl přidat:

  • Filtrování podle kategorií a řazení podle ceny.
  • Detail produktu na vlastní stránce.
  • Uložení košíku do localStorage, aby nákup „přežil“ obnovení stránky.
  • Základ falešného checkout flow (rekapitulace objednávky, formulář, potvrzení).

GitHub: Basic Fake e‑shop