0
Koodi Прогрес
Поточний:0 днів
Рекорд:0 днів
Без активності
Активний день
Сьогодні
🏆 ФІНАЛЬНИЙ УРОК

🚖 Урок 9: Збираємо все разом!

🎉 ВІТАЄМО! Ти пройшов весь курс!

За 9 уроків ти створив повноцінний веб-додаток з нуля!

Тепер ти знаєш як працюють справжні додатки: Uber, Bolt, Uklon...

Цей урок — збираємо всі шматочки в один працюючий проєкт!

🏆
KOODI TAXI MASTER!
Ти опанував 7 Web APIs та створив повноцінний додаток!
+160 KD зароблено за проєкт!
📱 ФІНАЛЬНИЙ ДОДАТОК
Твій Koodi Taxi!
9:41 🔋 100%
🚖 KOODI TAXI

👋 Привіт!

📍 Куди їдемо?

🚖 Таксі їде!

Водій: Олександр ⭐ 4.9

Авто: Білий Peugeot 308

Прибуде: 3 хвилини

🎉

Поїздка завершена!

Дякуємо за поїздку!

👆 Це твій повноцінний додаток! Пройди весь флоу!

📚

Що ти вивчив за цей проєкт:

🖱️
DOM Events
Уроки 1-2
addEventListener() — реагуємо на дії користувача: кліки, введення тексту, submit форми.
💾
LocalStorage
Урок 3
localStorage.setItem() — зберігаємо дані в браузері назавжди (історія поїздок, налаштування).
📍
Geolocation
Уроки 4-5
getCurrentPosition() — визначаємо де зараз користувач (широта, довгота).
🗺️
iframe + Maps
Урок 6
<iframe src="..."> — вбудовуємо Google Maps прямо в сторінку.
🔔
Notifications
Урок 7
new Notification() — показуємо сповіщення "Таксі прибуло!" навіть коли вкладка в фоні.
📋
Clipboard
Урок 8
clipboard.writeText() — копіюємо деталі поїздки одним кліком.
🧩
Як LEGO — збираємо з частинок!
Кожен API — це окремий кубик LEGO.

Events — руки, які керують.
LocalStorage — пам'ять, яка зберігає.
Geolocation — очі, які бачать де ти.
iframe — вікно в інший світ (карту).
Notifications — голос, який повідомляє.
Clipboard — руки, які передають.

Разом вони створюють повноцінний додаток! 🚀
1
HTML структура — скелет додатка
🏗️
HTML — це каркас будинку. Без нього нема де жити!

Ми створюємо екрани (section) — як кімнати в квартирі. Кожен екран має своє призначення.
Структура додатка:
<!-- 1. Екран привітання --> <section id="welcomeScreen"> <h1>🚖 Koodi Taxi</h1> <input id="userName" placeholder="Твоє ім'я"> <button id="startBtn">Почати</button> </section> <!-- 2. Екран замовлення --> <section id="orderScreen" style="display:none"> <button id="findMe">📍 Моя локація</button> <input id="pickup" placeholder="Звідки?"> <input id="destination" placeholder="Куди?"> <select id="carType">...</select> <button id="orderBtn">🚖 Викликати</button> </section> <!-- 3. Екран поїздки --> <section id="tripScreen" style="display:none"> <div id="driverInfo"></div> <iframe id="map"></iframe> <button id="copyBtn">📋 Скопіювати</button> </section>
🔍 ДЕТАЛЬНИЙ РОЗБІР КОДУ:

1. <section id="welcomeScreen">
<section> — тег що групує пов'язаний контент (як папка для файлів)
id="welcomeScreen" — унікальне ім'я (як номер квартири). JavaScript знайде цей елемент через getElementById('welcomeScreen')

2. <input id="userName" placeholder="Твоє ім'я">
<input> — поле для введення тексту
id="userName" — ім'я поля (потім зчитаємо: userName.value)
placeholder="..." — підказка всередині поля (зникає коли пишеш)

3. <button id="startBtn">Почати</button>
<button> — кнопка на яку можна натиснути
id="startBtn" — ім'я кнопки (потім повісимо обробник: startBtn.addEventListener())

4. style="display:none"
display:none — повністю ховає елемент (його немає на сторінці)
display:block — показує елемент
• Так ми перемикаємо "екрани" — ховаємо один, показуємо інший

5. <iframe id="map"></iframe>
<iframe> — "вікно" для вбудовування іншого сайту (Google Maps)
• Через map.src = "..." завантажуємо карту

💡 ЧОМУ id ВАЖЛИВІ?
Кожен id — це "адреса" елемента. JavaScript шукає елементи за id:
document.getElementById('startBtn') → знаходить кнопку
userName.value → отримує текст з поля (скорочений запис)
🧪 Тест: Для збереження історії поїздок між сесіями використовуємо...
2
JavaScript — мозок додатка
🧠
JavaScript — це мозок. Він приймає рішення!

Коли натиснули кнопку → реагуємо.
Коли треба зберегти → зберігаємо.
Коли треба показати → показуємо.
Основна логіка:
// ===== СТАН ДОДАТКА ===== let currentUser = ''; let currentScreen = 'welcome'; // ===== ФУНКЦІЯ ЗМІНИ ЕКРАНУ ===== function showScreen(screenId) { // Ховаємо всі екрани document.querySelectorAll('section').forEach(s => { s.style.display = 'none'; }); // Показуємо потрібний document.getElementById(screenId).style.display = 'block'; } // ===== СТАРТ ДОДАТКА ===== startBtn.addEventListener('click', function() { currentUser = userName.value; if (currentUser) { localStorage.setItem('userName', currentUser); showScreen('orderScreen'); } }); // ===== ЗАМОВЛЕННЯ ТАКСІ ===== orderBtn.addEventListener('click', function() { showScreen('tripScreen'); showMap(); sendNotification(); saveToHistory(); });
🔍 ДЕТАЛЬНИЙ РОЗБІР КОДУ:

1. let currentUser = '';
let — створюємо змінну (коробку для даних)
currentUser — назва змінної (ім'я коробки)
= '' — спочатку порожній рядок (коробка пуста)

2. function showScreen(screenId) { ... }
function — створюємо функцію (набір команд з іменем)
showScreen — назва функції (що робить? показує екран)
(screenId) — параметр (яку інформацію приймає)

3. document.querySelectorAll('section')
document — вся HTML-сторінка
querySelectorAll('section') — знайди ВСІ елементи <section>
• Повертає список (масив) всіх секцій

4. .forEach(s => { s.style.display = 'none'; })
.forEach() — пройдись по кожному елементу списку
s => — кожен елемент називаємо "s" (section)
s.style.display = 'none' — сховай цей елемент

5. startBtn.addEventListener('click', function() {...})
startBtn — кнопка (знаходиться автоматично по id)
.addEventListener() — "слухай подію"
'click' — яку подію? клік мишкою
function() {...} — що робити коли клікнули?

6. currentUser = userName.value;
userName — поле input (знаходиться по id)
.value — текст який ввів користувач
currentUser = ... — зберігаємо в змінну

7. if (currentUser) { ... }
if — "якщо"
(currentUser) — якщо змінна НЕ порожня
• Порожній рядок '' = false, текст = true

8. localStorage.setItem('userName', currentUser)
localStorage — "сховище" в браузері (дані залишаються назавжди)
.setItem(ключ, значення) — зберегти дані
'userName' — під яким ім'ям зберегти (ключ)
currentUser — що зберегти (значення)

💡 ЯК ЦЕ ВСЕ ПРАЦЮЄ РАЗОМ:
1. Користувач вводить ім'я в поле
2. Натискає кнопку "Почати"
3. addEventListener "чує" клік
4. Зчитуємо текст з поля (.value)
5. Зберігаємо в localStorage (щоб пам'ятати)
6. Перемикаємо на наступний екран
🧪 Тест: Щоб оновити карту з новим маршрутом потрібно...
3.1
📍 Geolocation API — де я зараз?
📍
Geolocation — це як GPS-навігатор в телефоні.

Ти питаєш браузер: "Де я зараз?"
Браузер питає дозвіл у користувача → отримує координати → віддає тобі.
Код Geolocation:
// Кнопка "Моя локація" findMe.addEventListener('click', function() { // Питаємо браузер де користувач navigator.geolocation.getCurrentPosition(function(pos) { // Отримали! Вставляємо в поле pickup.value = `${pos.coords.latitude}, ${pos.coords.longitude}`; }); });
🔍 РОЗБІР КОЖНОГО РЯДКА:

findMe.addEventListener('click', function() {...})
findMe — кнопка з id="findMe" (HTML)
.addEventListener('click', ...) — коли клікнуть → виконай функцію

navigator.geolocation.getCurrentPosition(function(pos) {...})
navigator — об'єкт браузера (доступ до функцій пристрою)
.geolocation — GPS/геолокація
.getCurrentPosition() — "дай поточні координати"
function(pos) — callback: що робити коли отримаємо (pos = position)

pos.coords.latitude / pos.coords.longitude
pos — об'єкт з результатом
.coords — координати
.latitude — широта (напр. 50.4501 для Києва)
.longitude — довгота (напр. 30.5234 для Києва)

`${pos.coords.latitude}, ${pos.coords.longitude}`
` ` — шаблонний рядок (template literal)
${...} — вставляємо значення змінної в текст
• Результат: "50.4501, 30.5234"

pickup.value = ...
pickup — input поле "Звідки?"
.value = ... — записуємо текст в поле
3.2
🗺️ Maps (iframe) — показуємо карту
🗺️
iframe — це як вікно в стіні.

Через нього ти показуєш іншу сторінку (Google Maps) прямо у своєму додатку!
Код для карти:
// Функція показу карти function showMap() { // Беремо значення з полів форми const origin = pickup.value; // Звідки const dest = destination.value; // Куди // Змінюємо src в iframe — карта оновлюється! map.src = `https://maps.google.com/maps?q=${dest}&output=embed`; }
🔍 РОЗБІР КОЖНОГО РЯДКА:

function showMap() {...}
function — оголошуємо функцію
showMap — назва (що робить? показує карту)
() — без параметрів

const origin = pickup.value
const — створюємо константу
pickup — input поле (id="pickup")
.value — текст який там написаний

map.src = `https://maps.google.com/maps?q=${dest}&output=embed`
map — елемент <iframe id="map">
.src — атрибут "джерело" (URL сторінки)
?q=${dest} — параметр q = куди (адреса або координати)
&output=embed — режим вбудовування (без меню Google)

💡 ЯК ЦЕ ПРАЦЮЄ:
Коли змінюєш src в iframe — браузер завантажує нову сторінку в цьому "вікні". Тобто карта оновлюється автоматично!
3.3
🔔 Notification API — сповіщення
🔔
Notification — це як SMS від додатка.

Навіть коли вкладка в фоні — користувач побачить повідомлення!
Важливо: спочатку треба попросити дозвіл.
Код сповіщень:
// Функція відправки сповіщення function sendNotification() { // Перевіряємо чи є дозвіл if (Notification.permission === 'granted') { // Є дозвіл! Показуємо сповіщення new Notification('🚖 Таксі прибуло!', { body: 'Водій чекає на вас!' }); } }
🔍 РОЗБІР КОЖНОГО РЯДКА:

if (Notification.permission === 'granted')
Notification — вбудований об'єкт для сповіщень
.permission — статус дозволу. Може бути:
  — 'granted' — дозволено ✅
  — 'denied' — заборонено ❌
  — 'default' — ще не питали

new Notification('🚖 Таксі прибуло!', {...})
new — створюємо новий об'єкт
Notification(...) — конструктор сповіщення
• Перший параметр: заголовок

{ body: 'Водій чекає на вас!' }
• Другий параметр — об'єкт з опціями
body — текст під заголовком
• Можна також: icon, image, tag

⚠️ ВАЖЛИВО:
Перед використанням треба один раз попросити дозвіл:
Notification.requestPermission()
3.4
📋 Clipboard API — копіювання
📋
Clipboard — це буфер обміну.

Як коли ти натискаєш Ctrl+C — текст копіюється.
Тепер можеш зробити це одним кліком на кнопку!
Код копіювання:
// Кнопка копіювання (async бо clipboard працює з Promise) copyBtn.addEventListener('click', async function() { // Чекаємо поки текст скопіюється await navigator.clipboard.writeText(driverInfo.textContent); // Показуємо підтвердження alert('✅ Скопійовано!'); });
🔍 РОЗБІР КОЖНОГО РЯДКА:

copyBtn.addEventListener('click', async function() {...})
copyBtn — кнопка (id="copyBtn")
async function() — асинхронна функція
Чому async? Бо clipboard.writeText() повертає Promise

await navigator.clipboard.writeText(text)
await — "зачекай результат"
navigator.clipboard — доступ до буфера обміну
.writeText(text) — записати текст в буфер

driverInfo.textContent
driverInfo — div з інформацією про водія
.textContent — текстовий вміст (без HTML тегів)

alert('✅ Скопійовано!')
• Показуємо повідомлення що копіювання успішне
• Краще використовувати свій UI замість alert()

⚠️ ВАЖЛИВО:
Clipboard API потребує HTTPS (localhost — виняток)
3.5
💾 LocalStorage — зберігаємо історію
💾
LocalStorage — це як записник в браузері.

Дані залишаються навіть після закриття браузера!
Ідеально для збереження історії поїздок.
Код збереження історії:
// Функція збереження поїздки в історію function saveToHistory() { // 1. Отримуємо існуючу історію (або пустий масив) const history = JSON.parse( localStorage.getItem('trips') || '[]' ); // 2. Додаємо нову поїздку history.push({ date: new Date().toLocaleString(), from: pickup.value, to: destination.value }); // 3. Зберігаємо назад в localStorage localStorage.setItem('trips', JSON.stringify(history)); }
🔍 РОЗБІР КОЖНОГО РЯДКА:

localStorage.getItem('trips')
localStorage — сховище в браузері
.getItem('trips') — отримати дані за ключем 'trips'
• Повертає текст або null якщо нічого немає

|| '[]'
|| — "або"
• Якщо getItem повернув null → беремо '[]' (пустий масив)

JSON.parse(...)
• Перетворює текст на JavaScript об'єкт/масив
• '["a", "b"]' → ["a", "b"]
• localStorage зберігає тільки текст, тому треба parse

history.push({...})
history — масив поїздок
.push() — додати елемент в кінець масиву
{...} — об'єкт з даними поїздки

new Date().toLocaleString()
new Date() — поточна дата і час
.toLocaleString() — в читабельний формат: "23.01.2026, 15:30"

JSON.stringify(history)
• Перетворює масив/об'єкт на текст
• ["a", "b"] → '["a", "b"]'
• Потрібно бо localStorage зберігає тільки текст

localStorage.setItem('trips', ...)
.setItem(ключ, значення) — зберегти дані
• Дані залишаються назавжди (поки не очистиш)
🧪 Тест: Перед показом Notification потрібно...

🏆 Твої нові навички:

🖱️
Events
Реагування на дії
💾
Storage
Збереження даних
📍
Geolocation
Визначення локації
🗺️
Maps
Інтеграція карт
🔔
Notifications
Сповіщення
📋
Clipboard
Копіювання
async/await
Асинхронність

🚀 Що далі?

📱 React/Vue — створюй складніші інтерфейси
🔌 REST API — працюй з серверами
💾 Firebase — база даних в хмарі

🏆 ФІНАЛ! Натисни "Готово" та отримай сертифікат!

Ти заслужив це! +30 KD!

Потрібна допомога?

💡 Підказка
🤖 AI-KOODI
HTML index.html ✏️
CSS style.css
JS app.js
1 2 3 4 5 6 7 8 9 10
localhost/koodi-taxi.html
🚖

Напиши код і натисни Run ▶