Zbuduj bazę danych zawierającą tabele kierunki i loty, połączone kluczem obcym. Wypełnij minimum 5 rekordami.
Wykonaj następujące kwerendy:
Samolot_2026) i nadaj mu prawa SELECT i DELETE dla tabeli loty.styl_loty.css)Utwórz arkusz stylów. Zadbaj o poniższe wymagania:
<th> tło #2980b9.padding: 8px.Zrealizuj dwa pliki HTML i skrypt JS.
oferta.html: 5‑kolumnowa tabela lotów i lista nieuporządkowana z danymi kontaktowymi, stopka z numerem zdającego.rezerwacja.html: Formularz z polami: Imię/Nazwisko, select (wartość = cena), checkbox Bagaż. Przycisk wywołuje funkcję obliczCene().baza_loty.sql)
/* Plik: baza_loty.sql - Tworzenie struktury, danych i kwerendy */
CREATE DATABASE `airfinder` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8_general_ci;
USE `airfinder`;
CREATE TABLE `kierunki` (
`id_kierunku` int(3) NOT NULL PRIMARY KEY,
`miasto` varchar(50) NOT NULL,
`kod_lotniska` char(3) NOT NULL
);
INSERT INTO `kierunki` (`id_kierunku`, `miasto`, `kod_lotniska`) VALUES
(101, 'Londyn', 'LHR'), (102, 'Paryż', 'CDG'), (103, 'Rzym', 'FCO'), (104, 'Madryt', 'MAD');
CREATE TABLE `loty` (
`id_lotu` int(6) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`numer_lotu` varchar(10) NOT NULL,
`cena_bazowa` float(10,2) NOT NULL,
`data_wylotu` date NOT NULL,
`wolne_miejsca` int(3) NOT NULL,
`id_kierunku` int(3) NOT NULL,
CONSTRAINT `fk_kierunek` FOREIGN KEY (`id_kierunku`) REFERENCES `kierunki` (`id_kierunku`)
);
INSERT INTO `loty` (`numer_lotu`, `cena_bazowa`, `data_wylotu`, `wolne_miejsca`, `id_kierunku`) VALUES
('AF1234', 750.00, '2026-03-10', 50, 102),
('BA5678', 650.00, '2026-03-15', 30, 101),
('LH9012', 920.00, '2026-04-01', 80, 103),
('IB3456', 500.00, '2026-03-05', 100, 104),
('AF7890', 799.99, '2026-03-20', 45, 102);
SELECT l.numer_lotu, l.cena_bazowa, k.miasto
FROM loty l JOIN kierunki k ON l.id_kierunku = k.id_kierunku
WHERE l.cena_bazowa < 800;
SELECT numer_lotu, data_wylotu, cena_bazowa
FROM loty
ORDER BY data_wylotu DESC;
CREATE USER 'Pilot'@'localhost' IDENTIFIED BY 'Samolot_2026';
GRANT SELECT, DELETE ON airfinder.loty TO 'Pilot'@'localhost';
styl_loty.css)
/* Plik: styl_loty.css */
:root {
--color-primary: #3498db;
--color-accent: #e74c3c;
--color-light-bg: #f4f4f9;
--color-dark: #2c3e50;
--color-header-bg: #2980b9;
--color-white: #ffffff;
}
* { font-family: 'Verdana', sans-serif; box-sizing: border-box; }
body { background-color: var(--color-light-bg); color: var(--color-dark); margin:0; line-height: 1.5; text-align: center;}
header, footer { background-color: var(--color-primary); color: var(--color-white); text-align: center; padding: 15px 0; }
nav { background-color: var(--color-primary); padding: 5px 0; margin-bottom: 20px; }
nav a { color: var(--color-white); padding: 8px 12px; text-decoration: none; font-weight: bold; }
nav a:hover { background-color: var(--color-accent); }
table { border: 1px solid var(--color-primary); width: 90%; margin: 20px auto; text-align: left; border-collapse: collapse;}
th { background: var(--color-header-bg); color: var(--color-white); padding: 10px; border: 1px solid #ccc;}
td { border: 1px solid #ccc; padding: 10px;}
.input-pole {
width: 80%; padding: 8px; margin: 5px auto 15px auto;
border: 1px solid var(--color-primary); display: block; box-sizing: border-box;
}
.form-box { background: #ffffff; padding: 20px; border-radius: 8px; max-width: 500px; margin: 20px auto; text-align: left;}
#wynik { margin-top: 20px; padding: 12px; border: 2px solid var(--color-accent); background: #ffe6e6; border-radius: 4px; text-align: center;}
oferta.html
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>AirFinder - Oferty Lotów</title>
<link rel="stylesheet" href="styl_loty.css">
</head>
<body>
<header><h1>✈️ Aktualne Oferty Lotów</h1></header>
<nav>
<a href="oferta.html">Aktualne Loty</a>
<a href="rezerwacja.html">Zarezerwuj / Kalkulator</a>
</nav>
<div class="container">
<h2>Dostępne Połączenia Lotnicze</h2>
<table>
<tr>
<th>Numer Lotu</th><th>Miasto Docelowe</th><th>Data Wylotu</th><th>Cena Bazowa (PLN)</th><th>Wolne Miejsca</th>
</tr>
<tr><td>AF1234</td><td>Paryż</td><td>2026-03-10</td><td>750.00</td><td>50</td></tr>
<tr><td>BA5678</td><td>Londyn</td><td>2026-03-15</td><td>650.00</td><td>30</td></tr>
<tr><td>LH9012</td><td>Rzym</td><td>2026-04-01</td><td>920.00</td><td>80</td></tr>
<tr><td>IB3456</td><td>Madryt</td><td>2026-03-05</td><td>500.00</td><td>100</td></tr>
<tr><td>AF7890</td><td>Paryż</td><td>2026-03-20</td><td>799.99</td><td>45</td></tr>
</table>
<h3>Dane Kontaktowe</h3>
<ul>
<li>Nazwa: AirFinder Sp. z o.o.</li>
<li>Adres: ul. Lotnicza 1, 02-143 Warszawa</li>
<li>Telefon: +48 111 222 333</li>
<li>Email: <a href="mailto:rezerwacja@airfinder.pl">rezerwacja@airfinder.pl</a></li>
</ul>
</div>
<footer><p>Przygotował: [NUMER ZDAJĄCEGO] | INF.03</p></footer>
</body>
</html>
rezerwacja.html (wersja podstawowa)
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>AirFinder - Kalkulator Rezerwacji</title>
<link rel="stylesheet" href="styl_loty.css">
</head>
<body>
<header><h1>🧮 Kalkulator Ceny Biletu</h1></header>
<nav>
<a href="oferta.html">Aktualne Loty</a>
<a href="rezerwacja.html">Zarezerwuj / Kalkulator</a>
</nav>
<div class="container">
<div class="form-box" style="margin: 20px auto; max-width: 500px;">
<h2 style="text-align: center;">Formularz Rezerwacji</h2>
<label for="imie_nazwisko"><strong>Imię i Nazwisko:</strong></label>
<input type="text" id="imie_nazwisko" class="input-pole" required>
<label for="lot_id"><strong>Wybierz Kierunek:</strong></label>
<select id="lot_id" class="input-pole">
<option value="750" data-kierunek="Paryż">AF1234 - Paryż (750 PLN)</option>
<option value="650" data-kierunek="Londyn">BA5678 - Londyn (650 PLN)</option>
<option value="920" data-kierunek="Rzym">LH9012 - Rzym (920 PLN)</option>
<option value="500" data-kierunek="Madryt">IB3456 - Madryt (500 PLN)</option>
<option value="799.99" data-kierunek="Paryż">AF7890 - Paryż (799.99 PLN)</option>
</select>
<label>
<input type="checkbox" id="bagaz">
<strong>Dodaj bagaż rejestrowany (+50 PLN)</strong>
</label>
<button onclick="obliczCene()" style="margin-top: 15px; padding: 10px 20px; background: #3498db; color: white; border: none; cursor: pointer; border-radius: 4px; display: block; width: 100%;">
Oblicz Cenę Biletu
</button>
<p id="wynik">Wynik kalkulacji pojawi się tutaj...</p>
</div>
</div>
<footer><p>Przygotował: [NUMER ZDAJĄCEGO] | INF.03</p></footer>
<script>
function obliczCene() {
const imieNazwisko = document.getElementById('imie_nazwisko').value.trim();
const selectLot = document.getElementById('lot_id');
const cenaBazowa = parseFloat(selectLot.value);
const kierunek = selectLot.options[selectLot.selectedIndex].getAttribute('data-kierunek');
const czyBagaz = document.getElementById('bagaz').checked;
const paragrafWynik = document.getElementById('wynik');
if (imieNazwisko === "") {
paragrafWynik.innerHTML = "❌ BŁĄD: Proszę podać Imię i Nazwisko.";
paragrafWynik.style.backgroundColor = '#ffc0c0';
paragrafWynik.style.borderColor = 'red';
return;
}
let cenaKoncowa = cenaBazowa;
let rabat = 0;
if (czyBagaz) {
cenaKoncowa += 50;
}
if (kierunek === "Paryż") {
rabat = cenaBazowa * 0.20;
cenaKoncowa -= rabat;
}
const statusBagaz = czyBagaz ? "TAK (+50 PLN)" : "NIE";
const statusRabat = rabat > 0 ? `TAK (-${rabat.toFixed(2)} PLN)` : "NIE";
const komunikat = `
✅ Rezerwacja dla <strong>${imieNazwisko}</strong> (Kierunek: ${kierunek})
<br>Cena Bazowa: ${cenaBazowa.toFixed(2)} PLN
<br>Bagaż Rejestrowany: <strong>${statusBagaz}</strong>
<br>Zniżka (Paryż): <strong>${statusRabat}</strong>
<br>***
<br>Cena Końcowa: <strong>${cenaKoncowa.toFixed(2)} PLN</strong>
`;
paragrafWynik.innerHTML = komunikat;
paragrafWynik.style.backgroundColor = '#d4edda';
paragrafWynik.style.borderColor = '#155724';
}
</script>
</body>
</html>
Rozszerz serwis AirFinder o dodatkowe pola oraz obliczenia, pozostając w tym samym projekcie.
rezerwacja.html.Nowy wzór:
rezerwacja.html)
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>AirFinder - Rozszerzony kalkulator</title>
<link rel="stylesheet" href="styl_loty.css">
</head>
<body>
<header><h1>🧮 Kalkulator Ceny Biletu (Rozszerzony)</h1></header>
<nav>
<a href="oferta.html">Aktualne Loty</a>
<a href="rezerwacja.html">Zarezerwuj / Kalkulator</a>
</nav>
<div class="container">
<div class="form-box">
<h2 style="text-align: center;">Formularz Rezerwacji</h2>
<label for="imie_nazwisko"><strong>Imię i Nazwisko:</strong></label>
<input type="text" id="imie_nazwisko" class="input-pole" required>
<label for="lot_id"><strong>Wybierz Kierunek:</strong></label>
<select id="lot_id" class="input-pole">
<option value="750" data-kierunek="Paryż">AF1234 - Paryż (750 PLN)</option>
<option value="650" data-kierunek="Londyn">BA5678 - Londyn (650 PLN)</option>
<option value="920" data-kierunek="Rzym">LH9012 - Rzym (920 PLN)</option>
<option value="500" data-kierunek="Madryt">IB3456 - Madryt (500 PLN)</option>
<option value="799.99" data-kierunek="Paryż">AF7890 - Paryż (799.99 PLN)</option>
</select>
<label>
<input type="checkbox" id="bagaz">
<strong>Dodaj bagaż rejestrowany (+50 PLN)</strong>
</label>
<label for="pasazerowie"><strong>Liczba pasażerów:</strong></label>
<input type="number" id="pasazerowie" class="input-pole" value="1" min="1">
<label>
<input type="checkbox" id="ubezpieczenie">
<strong>Ubezpieczenie podróżne (+30 PLN za osobę)</strong>
</label>
<button onclick="obliczCeneRozszerzona()" style="margin-top: 15px; padding: 10px 20px; background: #3498db; color: white; border: none; cursor: pointer; border-radius: 4px; display: block; width: 100%;">
Oblicz Cenę Rezerwacji
</button>
<p id="wynik">Wynik kalkulacji pojawi się tutaj...</p>
</div>
</div>
<footer><p>Przygotował: [NUMER ZDAJĄCEGO] | INF.03</p></footer>
<script>
function obliczCeneRozszerzona() {
const imieNazwisko = document.getElementById('imie_nazwisko').value.trim();
const selectLot = document.getElementById('lot_id');
const cenaBazowa = parseFloat(selectLot.value);
const kierunek = selectLot.options[selectLot.selectedIndex].getAttribute('data-kierunek');
const czyBagaz = document.getElementById('bagaz').checked;
const liczbaPasazerow = parseInt(document.getElementById('pasazerowie').value, 10);
const czyUbezpieczenie = document.getElementById('ubezpieczenie').checked;
const paragrafWynik = document.getElementById('wynik');
if (imieNazwisko === "" || isNaN(liczbaPasazerow) || liczbaPasazerow < 1) {
paragrafWynik.innerHTML = "❌ BŁĄD: Podaj imię i nazwisko oraz poprawną liczbę pasażerów (min. 1).";
paragrafWynik.style.backgroundColor = "#ffc0c0";
paragrafWynik.style.borderColor = "red";
return;
}
let cenaJednego = cenaBazowa;
let rabat = 0;
if (czyBagaz) {
cenaJednego += 50;
}
if (kierunek === "Paryż") {
rabat = cenaBazowa * 0.20;
cenaJednego -= rabat;
}
let suma = cenaJednego * liczbaPasazerow;
if (czyUbezpieczenie) {
suma += 30 * liczbaPasazerow;
}
const infoBagaz = czyBagaz ? "TAK (+50 PLN/os.)" : "NIE";
const infoUbezp = czyUbezpieczenie ? "TAK (+30 PLN/os.)" : "NIE";
const infoRabat = rabat > 0 ? `TAK (-${rabat.toFixed(2)} PLN/os.)` : "NIE";
paragrafWynik.innerHTML = `
✅ Rezerwacja dla <strong>${imieNazwisko}</strong> (Kierunek: ${kierunek})
<br>Liczba pasażerów: <strong>${liczbaPasazerow}</strong>
<br>Cena bazowa za 1 osobę: ${cenaBazowa.toFixed(2)} PLN
<br>Bagaż rejestrowany: <strong>${infoBagaz}</strong>
<br>Zniżka (Paryż): <strong>${infoRabat}</strong>
<br>Ubezpieczenie: <strong>${infoUbezp}</strong>
<br>***
<br>Cena za 1 osobę po uwzględnieniu opcji: <strong>${cenaJednego.toFixed(2)} PLN</strong>
<br>Łączna kwota do zapłaty: <strong>${suma.toFixed(2)} PLN</strong>
`;
paragrafWynik.style.backgroundColor = "#d4edda";
paragrafWynik.style.borderColor = "#155724";
}
</script>
</body>
</html>
Poniżej znajdują się podglądy docelowego wyglądu stron oferta.html i rezerwacja.html. Pliki muszą być w tym samym folderze co ten arkusz.
oferta.html)rezerwacja.html)