Skip to content

Commit

Permalink
Merge pull request #679 from Czechitas-podklady-WEB/678-leviexpress-a…
Browse files Browse the repository at this point in the history
…ktualizace-lekce

LeviExpress: aktualizace lekce
  • Loading branch information
podlomar authored Nov 10, 2023
2 parents f1d0697 + 8916313 commit f32ba2c
Show file tree
Hide file tree
Showing 19 changed files with 62 additions and 39 deletions.
3 changes: 0 additions & 3 deletions daweb/react/leviexpress-1/cv-detail-cesty.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,3 @@
::exc[cvlekce/podrobnosti-cesty]
::exc[cvlekce/zobrazeni-sedadla]
::exc[cvlekce/potvrzeni-rezervace]

<!-- ::exc[cvlekce/rady-sedadel]
::exc[cvlekce/vyber-sedadla] -->
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
---
title: Podrobnosti cesty
lead: Vytvoříme komponenty pro zobrazení detailu cesty a zastávek.
demand: 1
solutionAccess: lock
---

V tomto cvičení vytvoříte komponentu pro zobrazení detailu cesty a komponentu pro zobrazení zastávky. Využijí se informace, které vrátilo API pro vyhledání spoje.

::fig[náhled]{src=assets/nahled.png}

1. Ve svém projektu vyvořte komponentu s názvem `JourneyDetail`. Do komponenty `JourneyDetail` zatím zkopírujte HTML kód ze zadání – celý element `div` s třídami `journey-detail` a `container` i s jeho obsahem. Vytvoře v komponentě také soubor `style.css`, do kterého zkopírujte ze zadání styly pro třídy `stops` a `journey-detail`. Naimportujte soubor se styly do komponenty.
1. Použijete komponentu `JourneyDetail` v komponentě `Home` na místě, kde se nyní vypisuje id nalezeného spoje. Komponenta se bude zobrazovat jenom tehdy, když ve stavu `journey` v komponentě `Home` je něco jiného, než `null`. Ověřte, že po vyhledání spojení se na stránce zobrazí podrobnosti cesty s městy 1 až 4.
1. Ve svém projektu vytvořte komponentu s názvem `JourneyDetail`. Do této komponenty zatím zkopírujte HTML kód ze zadání – celý element `div` s třídami `journey-detail` a `container` i s jeho obsahem. Vytvoře v komponentě také soubor `style.css`, do kterého zkopírujte ze zadání styly pro třídy `stops` a `journey-detail`. Naimportujte soubor se styly do komponenty.
1. Použijete komponentu `JourneyDetail` v komponentě `HomePage` na místě, kde se nyní vypisuje id nalezeného spoje. Komponenta se bude zobrazovat jenom tehdy, když ve stavu `journey` v komponentě `HomePage` je něco jiného, než `null`. Ověřte, že po vyhledání spojení se na stránce zobrazí podrobnosti cesty s městy 1 až 4.
1. V samostatné složce vytvořte komponentu s názvem `BusStop`. V komponentě vytvořte také soubor se styly, do kterého ze zadání zkopírujete všechny styly pro třídy začínající `bus-stop`.
1. Do komponenty `BusStop` vložte ze zadání celý element `div`, který má třídu `bus-stop`. Je to jeden prvek ze seznamu zastávek.
1. V komponentě `JourneyDetail` smažte HTML kód se seznamem zastávek. Zbyde tam jen kontejner, v něm `h3` s textem „Podrobnosti cesty“ a pod ním `div` s třídou `stops`. Do tohoto divu vložte komponentu `BusStop`. Zkontrolujte v prohlížeči, že se zobrazí jedna zastávka.
1. Komponenta `BusStop` bude očekávat tři `props``name`, `station` a `time`. Tam, kde používáte komponentu `BusStop`, přidejte komponentě odpovídající atributy a nastavte jim hodnoty „Praha“, „ÚAN Florenc“ a „15:55“. Komponentu `BusStop` upravte tak, aby se tyto hodnoty propsaly na správná místa v HTML. Zkontrolujte, že se v prohlížeči zobrazují správné údaje pro jednu zastávku.
1. Komponenta `JourneyDetail` bude v `props` očekávat property `journey` s údaji o cestě. V property `journey` bude objekt, který má v sobě v property `stops` seznam zastávek. Property `journey` si můžete vypsat do konzole prohlížeče.
1. Místo jedné komponenty `BusStop` použité v komponentě napište kód, který projde všechny zastávky v `journey.stops` a pro každou zastávku vloží jednu komponentu `BusStop`, které předá správné údaje. Můžete si pomoci tak, že nejprve upravíte vloženou komponentu `BusStop`, ve které máte „Praha“, „ÚAN Florenc“ a „15:55“ tak, aby se místo těchto údajů vložily údaje z první zastávky v `journey.stops[0]` a následně kód upravíte tak, aby pomocí funkce `map` prošel všechny zastávky v `journey.stops`. Jako klíč (`key`) pro React můžete použít property `code`, která je uvedená v `journey.stops` u každé zastávky.
1. Nyní už zbývá jen poslat z komponenty `Home` do komponenty `JourneyDetail` údaje o cestě. Vraťte se do komponenty `Home`. Ve stavu `journey` tam jsou uloženy údaje o cestě. Nyní už jen stačí tento stav předat do prop `journey` komponenty `JourneyDetail`.
1. Nyní už zbývá jen poslat z komponenty `HomePage` do komponenty `JourneyDetail` údaje o cestě. Vraťte se do komponenty `HomePage`. Ve stavu `journey` tam jsou uloženy údaje o cestě. Nyní už jen stačí tento stav předat do prop `journey` komponenty `JourneyDetail`.
1. Ověřte v prohlížeči, že funguje vyhledání spojení a že se pod vyhledávacím formulářem zobrazí „jízdní řád“ spoje – seznam zastávek s časy. Zastávek je u spoje víc a když vyhledáte jiné spojení, změní se i seznam zastávek.
1. Commitněte změny.
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
---
title: Potvrzení rezervace
lead: Umožníme uživateli potvrdit rezervaci jízdenky.
demand: 2
solutionAccess: lock
---

Nyn již máme ve stavu `journey` uložené všechny potřebné informace k tomu, abychom mohli provést rezervaci jizdenky. V tomto cvičení potvrdíme rezervaci kliknutím na tlačíko, zpracujeme odpověď ze serveru a přesměrujeme uživatele na detail rezervované jízdenky.

1. Vložte do komponenty `Home` oddíl s tlačítkem „Rezervovat". Stále v komponentě `Home` vytvořte funkci `handleBuy` a zařiďte, aby byla tato funkce volána při kliknutí na tlačítko „Rezervovat". Ve funkci si zatím můžete vypsat nějakou zprávu do konzole `('Funguju!')`.
1. Vložte do komponenty `HomePage` oddíl s tlačítkem „Rezervovat". Stále v komponentě `HomePage` vytvořte funkci `handleBuy` a zařiďte, aby byla tato funkce volána při kliknutí na tlačítko „Rezervovat". Ve funkci si zatím můžete vypsat nějakou zprávu do konzole `('Funguju!')`.
1. Podle [dokumentace](https://reactrouter.com/en/main/hooks/use-navigate) React Routeru se podívejte, jak lze pomocí hooku `useNavigate` přímo v kódu změnit stránka, na které se uživatel nachází. Tedy jak uživatele přesměrovat.
1. Na začátku komponenty `Home` vytvořte proměnnou `navigate` s použitím hooku `useNavigate()`, nezapomeňte hook naimportovat z `react-router-dom`. Za moment tuto proměnnou použijeme.
1. Na začátku komponenty `HomePage` vytvořte proměnnou `navigate` s použitím hooku `useNavigate()`, nezapomeňte hook naimportovat z `react-router-dom`. Za moment tuto proměnnou použijeme.
1. Nákup jízdenky se ve funkci `handleBuy` provede tak, že metodou POST zavoláte API endpoint

```
Expand Down Expand Up @@ -38,7 +40,7 @@ Nyn již máme ve stavu `journey` uložené všechny potřebné informace k tomu
1. Zkontrolujte, že po kliknutí na tlačíko „Rezervovat" se stránka přesměruje například na adresu

```
http://localhost:8080/reservation/HAQBAQASf7M
http://localhost:5173/reservation/HAQBAQASf7M
```

kde záhy vytvoříme detail jízdenky!
Expand Down
10 changes: 6 additions & 4 deletions daweb/react/leviexpress-1/cvlekce/routovani.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
---
title: Routování
lead: Rozběhněte základní routování.
demand: 2
solutionAccess: lock
---

Hned na začátku rozběháme routování, abychom ho pak nemuseli složitě roubovat do již rozpracovaného projektu. Knihovna `react-router` už je v naklonovaném projektu nainstalovaná, můžete ji rovnou začít používat.
Hned na začátku rozběháme routování, abychom ho pak nemuseli složitě včlenňovat do již rozpracovaného projektu. Knihovna `react-router` už je v naklonovaném projektu nainstalovaná, můžete ji rovnou začít používat.

Naše aplikace bude mít dvě hlavní stránky: :i[Home] a :i[Reservation]. Obě obsahují stejnou hlavičku i patičku. Stránka :i[Home] bude pod routou `/`, stránka s detaily rezervace bude mít adresu `/reservation`.

1. Uvnitř komponenty `App` již máte připravenou strukturu s hlavičkou a patičkou stránky. Dále máte již hotovou kostru komponenty `Home`. Setavte router tak, aby komponenty `Header` a `Footer` byly na stránce zobrazeny vždy. Mezi ně vložte prvek `RouterProvider` z React Routeru a předejte do něho konfigurační objekt, ve kterém budete mít vytvořené dvě routy: `/` a `/reservation`. V první routě zobrazte komponentu `Home`, ve druhé zatím necháme jen nadpis `h2` s textem "Detail jízdenky". Vyzkoušejte, že vaše stránka správně zobrazuje obě stránky. Odkazy (`Link`) na stránku nedávejte – uživatel přijde vždy na hlavní stránku `/`. Na stránku `/reservation` se dostane až po kliknutí na tlačítko pro objednání, které zprovozníte až později.
1. Vytvořte komponentu `Reservation`. Tuto komponentu zobrazte na adrese `/reservation`. Zatím může vracet pouze nadpis `h2`, abychom viděli, že se na stránce něco děje. Obsah komponenty vytvoříme později.
1. Vyzkoušejte, že vaše stránka správně funguje (adresu `/reservation` vyzkoušejte tak, že ji napíšete do adresního řádku prohlížeče).
1. Uvnitř komponenty `App` již máte připravenou strukturu s hlavičkou a patičkou stránky. Mezi ně budeme pomocí `Outlet` vkládat naše stránky. Stránku `HomePage` již míte připravenou. Vložte ji do routeru jako dítě routy `/` v hlavním `index.jsx`. Stránku `HomePage` chceme umístit na adresu: `/`. Vyzkoušejte, že se vaše stránka správně zobrazuje. Měli byste vidět formulář pro vyhledání spojení.
1. Dále vytvořte komponentu `ReservationPage`. Tuto komponentu zobrazte na adrese `/reservation`. Zatím může také vracet pouze nadpis `h2`, abychom viděli, že se na stránce něco děje. Obsah komponenty vytvoříme později.
1. Vyzkoušejte, že vaše stránka správně funguje (adresu `/reservation` vyzkoušejte tak, že ji prostě napíšete do adresního řádku prohlížeče).
1. Proveďte commit změn se smysluplnou commit zprávou.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
title: Seznámení s projektem
lead: Začneme pracovat na projektu, který již obsahuje nějaký kód.
demand: 2
solutionAccess: lock
---

V praxi často začnete pracovat na projektu, na kterém už pracoval někdo před vámi. V tomto cvičení tomu nebude jinak a také začneme s projektem, který již obsahuje nějaký kód.
Expand All @@ -10,5 +12,5 @@ V praxi často začnete pracovat na projektu, na kterém už pracoval někdo př
1. Nejprve si prohlédněte dopředu připravený [design webu LeviExpress](https://czechitas-podklady.cz/leviexpress-design/), ze kterého budeme vycházet. V připraveném designu najdete kromě úvodní stránky taky stránku s [detailem jízdenky](https://czechitas-podklady-web.github.io/leviexpress-design/reservation). Jde o statické stránky, které nemají žádnou funkčnost. Obsahují pouze HTML a CSS. Zdrojové kódy najdete v [leviexpress-design](https://github.com/Czechitas-podklady-WEB/leviexpress-design) (tento repositář si klonovat nemusíte, slouží hlavně pro inspiraci). Odsud můžete vzít všechny potřebné styly, HTML a obrázky pro váš projekt.
1. Vytvořte si repozitář ze šablony [leviexpress-starter](https://github.com/Czechitas-podklady-WEB/leviexpress-starter). V tomto repozitáři najdete již rozpracovaný základ aplikace.
1. Svůj repozitář si naklonujte do počítače a otevřete ve VS Code.
1. Nainstalujte všechny závislosti pomocí `npm install` a spusťte projekt pomocí `npm run start`.
1. Nainstalujte všechny závislosti pomocí `npm install` a spusťte projekt pomocí `npm run dev`.
1. Prohlédněte si strukturu projektu a projděte si kód připravených komponent.
4 changes: 3 additions & 1 deletion daweb/react/leviexpress-1/cvlekce/udaje-o-ceste/exercise.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
---
title: Údaje o cestě
lead: Propojte výběr měst a data se příslušnými stavy.
demand: 2
solutionAccess: lock
---

Ve svém projektu již máte vytvořen základy komponenty s názvem `JourneyPicker`. Ta je součástí komponenty `Home` a zatím vrací pouze statické JSX
Ve svém projektu již máte vytvořen základy komponenty s názvem `JourneyPicker`. Ta je součástí komponenty `HomePage` a zatím vrací pouze statické JSX. V tomto cvičení propojíme výběr měst a data se stavem komponenty.

::fig[náhled]{src=assets/nahled.png}

Expand Down
2 changes: 2 additions & 0 deletions daweb/react/leviexpress-1/cvlekce/vyber-datumu.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
title: Výběr data cesty
lead: Zprovizníme výběr data cesty.
demand: 2
solutionAccess: lock
---

Na konci tohoto cvičení bude uživatel schopen vybrat datum cesty podle dat stažených z API. Budeme postupovat obdobně jako s komponentou `CityOptions`. Tentokrát však vytvoříme komponentu `DatesOptions`, která vygeneruje elementy `option` do výběru termínů cesty. Termíny cest se budou získávat z API endpointu [/api/dates](https://apps.kodim.cz/daweb/leviexpress/api/dates). Prohlédněte si strukturu dat, která tento endpoint vrací.
Expand Down
2 changes: 2 additions & 0 deletions daweb/react/leviexpress-1/cvlekce/vyber-mesta.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
title: Výběr města
lead: Zprovozněte výběr města ze seznamu.
demand: 2
solutionAccess: lock
---

Na konci tohoto cvičení si uživatel bude schopen vybrat startovní a cílové město ze seznamu měst stažených z API. Vytvoříte komponentu `CityOptions`, která dostane na vstupu pole se seznamem destinací a vytvoří z něj elementy `<option>` do `select`ů pro výběr výchozího a cílového města. Seznam měst se bude stahovat v komponentě `JourneyPicker` z API endpointu [/api/cities](https://apps.kodim.cz/daweb/leviexpress/api/cities). Prohlédněte si strukturu dat, která endpoint vrací.
Expand Down
12 changes: 7 additions & 5 deletions daweb/react/leviexpress-1/cvlekce/vyhledat-spoj.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
title: Vyhledání spoje
lead: Dokončíme komponentu pro vyhledání spojení.
demand: 3
solutionAccess: lock
---

V tomto cvičení dokončíte komponentu pro vyhledání spojení. V komponentě už funguje výběr výchozího a cílového města a také data cesty. Nyní napojíte komponentu
Expand All @@ -15,12 +17,12 @@ na API pro vyhledávání spojení.

1. Volání tohoto API vrací JSON s nalezenými spoji. Vypište si výstup do konzole prohlížeče.
1. Nalezená spojení budeme potřebovat zobrazit v další komponentě na stránce. Potřebujeme je tedy poslat z komponenty `JourneyPicker` jejímu rodiči – to uděláme v následujících krocích.
1. V komponentě `Home` si připravte funkci `handleJourneyChange`. Funkce `handleJourneyChange` bude očekávat jeden parametr – objekt s údaji o nalezeném spojení. Nazvěte jej třeba `journey`. Ve funkci zatím vypište tento parametr do konzole. Funkce se zatím nebude nikde volat – volání zajistíme v následujících krocích, kde bude funkce `handleJourneyChange` sloužit jako callback předaný do komponenty `JourneyPicker`.
1. V komponentě `Home` používáte komponentu `JourneyPicker`. Této komponentě předejte property jménem `onJourneyChange`, jako hodnotu jí předejte funkci (callback) `handleJourneyChange`.
1. V komponentě `JourneyPicker` bude property `onJourneyChange`, do které rodič (`Home`) vkládá funkci, která se zavolá s údaji nalezeném spoji. Všimněte si, že v hlavičce komponenty `JourneyPicker` už je property `onJourneyChange` připravená.
1. V komponentě `HomePage` si připravte funkci `handleJourneyChange`. Funkce `handleJourneyChange` bude očekávat jeden parametr – objekt s údaji o nalezeném spojení. Nazvěte jej třeba `journey`. Ve funkci zatím vypište tento parametr do konzole. Funkce se zatím nebude nikde volat – volání zajistíme v následujících krocích, kde bude funkce `handleJourneyChange` sloužit jako callback předaný do komponenty `JourneyPicker`.
1. V komponentě `HomePage` používáte komponentu `JourneyPicker`. Této komponentě předejte property jménem `onJourneyChange`, jako hodnotu jí předejte funkci (callback) `handleJourneyChange`.
1. V komponentě `JourneyPicker` bude property `onJourneyChange`, do které rodič (`HomePage`) vkládá funkci, která se zavolá s údaji nalezeném spoji. Všimněte si, že v hlavičce komponenty `JourneyPicker` už je property `onJourneyChange` připravená.
1. Ve funkci `handleSubmit` v komponentě `JourneyPicker` máte nyní výpis nalezených spojení do konzole prohlížeče. Tento výpis nahraďte voláním funkce uložené v property `onJourneyChange`, které jako paramter předáte data získaná z volání API pod klíčem `results`.
1. Vraťte se do komponenty `Home`, ze které se volá komponenta `JourneyPicker`. V komponentě `Home` vytvořte pomocí `useState` nový stav `journey`, výchozí hodnota bude `null`.
1. Vraťte se do komponenty `HomePage`, ze které se volá komponenta `JourneyPicker`. V komponentě `HomePage` vytvořte pomocí `useState` nový stav `journey`, výchozí hodnota bude `null`.
1. Propojte komponentu `JourneyPicker` se stavem `journey` – když je volán callback `handleJourneyChange` s údaji o nalezeném spoji, nastaví se toto spojení do stavu `journey`.
1. Upravte komponentu `Home` tak, aby v případě, kdy ve stavu `journey` je nějaké spojení, vypsala pod vyhledávací formulář text „Nalezeno spojení s id …“. Místo tří teček bude `journeyId` z dat o nalezeném spojení.
1. Upravte komponentu `HomePage` tak, aby v případě, kdy ve stavu `journey` je nějaké spojení, vypsala pod vyhledávací formulář text „Nalezeno spojení s id …“. Místo tří teček bude `journeyId` z dat o nalezeném spojení.
1. Ověřte, že funguje výběr měst a data, že po zadání všech třech údajů můžete kliknout na „Vyhledat spoj“ a že se po kliknutí vyhledá nějaké spojení a vypíše se do stránky jeho id.
1. Commitněte změny.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
title: Zobrazení sedadla
lead: Zobrazíme uživateli sedadlo, které mu bylo automaticky přiděleno.
demand: 2
solutionAccess: lock
---

V první fázi projektu bude sedadlo pro cestujícího přidělovat automaticky backend. Jistě jste si všimli, že API endpoint `/journey` vrací JSON s vlastností `autoSeat`. Tato vlastnost obsahuje automaticky vybrané volné sedadlo. V tomto cvičení jej zobrazíme uživateli na stránce.
Expand All @@ -10,4 +12,4 @@ V první fázi projektu bude sedadlo pro cestujícího přidělovat automaticky
1. Na vzorové stránce vidíte sekci s nadpisem „Vaše sedadlo“. Vytvořte pro tuto sekci React komponentu s názvem `SelectedSeat`. Její obsah vyplňte dle vzorové stránky. Všimněte si, že obrázek sedadla je vytvořen pomocí SVG.
1. Najděte, kde se ve struktuře SVG nastavuje číslo sedadlo. Zařiďte, aby šlo komponentě `SelectedSeat` nastavit číslo sedadla skrze prop `number`.
1. Zkontrolujte v prohlížeči, že se správně zobrazuje sekce se sedadlem a že je možné pomocí prop `number` měnit číslo sedadla.
1. V komponentě `Home` máme ve stavu `journey` uložen výsledek vyhledané cesty. Stačí tedy vlastnost `autoSeat` předat komponentě `SelectedSeat`. Dejte však pozor na to, že při načtení stránky je ve stavu `journey` hodnota `null`. V takovém případě komponentu `SelectedSeat` vůbec nezobrazujte.
1. V komponentě `HomePage` máme ve stavu `journey` uložen výsledek vyhledané cesty. Stačí tedy vlastnost `autoSeat` předat komponentě `SelectedSeat`. Dejte však pozor na to, že při načtení stránky je ve stavu `journey` hodnota `null`. V takovém případě komponentu `SelectedSeat` vůbec nezobrazujte.
4 changes: 1 addition & 3 deletions daweb/react/leviexpress-1/entry.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
title: 'Opakování: LeviExpress, první část'
title: 'Projekt: LeviExpress, první část'
lead: Všechno, co jsme se v Reactu naučili, si procvičíme na projektu takzvaně „ze života“.
access: 'claim'
sections:
- zadani
- cv-zalozeni
- cv-vyber-lokace
- cv-detail-cesty
# - cv-rezervace
# - cv-jizdenka
Loading

0 comments on commit f32ba2c

Please sign in to comment.