💥 Aktywne Polecenia Twórcze INF.03 – ECOFARM

Instrukcja z pełnym opisem wymagań – Wymaga pisania kodu, nie kopiowania.

1. Plan Działania – 10 Kroków

Wykonaj zadanie krok po kroku, pamiętając, że polecenia 3, 5 i 6 zawierają aktywne modyfikacje.

  1. Utwórz folder: Stwórz folder o nazwie `ecofarm`.
  2. Uruchom serwer i phpMyAdmin: Włącz moduły Apache i MySQL. Otwórz `http://localhost/phpmyadmin`.
  3. Utwórz bazę danych (SQL): W phpMyAdmin utwórz bazę danych `ecofarm`.
  4. Wprowadź strukturę i dane: W zakładce SQL, napisz i wykonaj kwerendy tworzące tabele i dane zgodnie z sekcją 3.1.
  5. Stwórz plik z kwerendami: Napisz cztery kwerendy SQL zgodnie z sekcją 3.2 i zapisz plik jako `kwerendy_ecofarm.txt`.
  6. Utwórz plik stylów CSS: Utwórz `styl_ecofarm.css` i napisz kod CSS zgodnie z sekcją 4.
  7. Utwórz plik PHP: Napisz kod PHP i HTML, który łączy się z bazą, pobiera i wyświetla dane zgodnie z sekcją 5. Zapisz jako `oferta_farmy.php`.
  8. Utwórz plik HTML/JS: Napisz kod HTML formularza oraz funkcję JavaScript do walidacji i obliczeń zgodnie z sekcją 6. Zapisz jako `koszyk.html`.
  9. Przenieś na serwer: Przenieś folder `ecofarm` do katalogu XAMPP: `C:\xampp\htdocs\`.
  10. Przetestuj: Zweryfikuj działanie stron: `oferta_farmy.php` i `koszyk.html`.

3. Baza danych i Kwerendy SQL (Aktywne pisanie)

3.1. Aktywne Zadanie SQL – Utworzenie tabel i danych

Polecenie:

W środowisku phpMyAdmin napisz i wykonaj kod SQL. Pamiętaj o uwzględnieniu DODATKOWYCH wymagań dotyczących kategorii i produktów:

ElementPełne Polecenie do wykonania (Wymaga pisania kodu)
Tabela `kategorie`Napisz kwerendę `CREATE TABLE` zawierającą pole `id_kategorii` (klucz główny, `AUTO_INCREMENT`) i pole `nazwa_kategorii` (VARCHAR, NOT NULL). Po jej utworzeniu, DODAJ do danych startowych czwartą kategorię: 'Owoce'.
Tabela `produkty`Napisz kwerendę `CREATE TABLE` zawierającą pola: `id_produktu` (klucz główny), `nazwa_produktu`, `cena`, `waga_kg`, `data_dostawy` oraz klucz obcy `id_kategorii`. Następnie DODAJ nowy produkt: 'Mleko Kozie' (22.50, 1.00 kg) do kategorii 'Nabiał'.
Rozwiązanie do Aktywnego Zadania 3.1 (Tworzenie i uzupełnianie tabel)
CREATE DATABASE IF NOT EXISTS ecofarm CHARACTER SET utf8 COLLATE utf8_general_ci;USE ecofarm;

CREATE TABLE kategorie (    id_kategorii INT AUTO_INCREMENT PRIMARY KEY,    nazwa_kategorii VARCHAR(50) NOT NULL);

CREATE TABLE produkty (    id_produktu INT AUTO_INCREMENT PRIMARY KEY,    nazwa_produktu VARCHAR(100) NOT NULL,    cena DECIMAL(6,2) NOT NULL,    waga_kg DECIMAL(5,2) NOT NULL,    data_dostawy DATE NOT NULL,    id_kategorii INT NOT NULL,    FOREIGN KEY (id_kategorii) REFERENCES kategorie(id_kategorii));

INSERT INTO kategorie (nazwa_kategorii) VALUES('Warzywa'),('Nabiał'),('Pieczywo'),('Owoce');

INSERT INTO produkty (nazwa_produktu, cena, waga_kg, data_dostawy, id_kategorii) VALUES('Pomidor Maliniak', 8.99, 1.00, '2025-11-20', 1),('Ser Kozi Wędzony', 25.50, 0.30, '2025-11-18', 2),('Mleko Kozie', 22.50, 1.00, '2025-12-10', 2);

3.2. Aktywne Zadanie: plik `kwerendy_ecofarm.txt`

Polecenie:

Utwórz plik tekstowy `kwerendy_ecofarm.txt`. Napisz do niego cztery kwerendy, uwzględniając podane, zmodyfikowane warunki:

KwerendaPełne Polecenie do wykonania (Wymaga aktywnej zmiany logiki)
Kw1 (SELECT + JOIN)Wybierz nazwy, ceny i kategorie produktów. Ogranicz wyniki do produktów z kategorii „Nabiał”, których cena jest wyższa niż 20.00 zł.
Kw2 (SELECT + ORDER BY)Wybierz nazwy i wagi produktów ze wszystkich kategorii. Wyniki posortuj po kolumnie `waga_kg` malejąco (DESC).
Kw3 (INSERT)Wstaw do tabeli `produkty` nowy rekord: „Jabłko Szampion” o cenie 1.50 zł i wadze 0.25 kg. Przypisz mu nowo utworzoną kategorię Owoce (ID 4).
Kw4 (UPDATE)Zastosuj kwerendę `UPDATE`, aby zmniejszyć ceny wszystkich produktów należących do kategorii „Warzywa” o 10%.
Rozwiązanie do Aktywnego Zadania 3.2 (kwerendy_ecofarm.txt)
-- Kw1 (SELECT + JOIN): Nabiał, cena > 20.00 PLN
SELECT p.nazwa_produktu, p.cena, k.nazwa_kategorii
FROM produkty p JOIN kategorie k ON p.id_kategorii = k.id_kategorii
WHERE k.nazwa_kategorii = 'Nabiał' AND p.cena > 20.00;

-- Kw2 (SELECT + ORDER BY): Nazwa produktu i waga, waga malejąco
SELECT nazwa_produktu, waga_kg FROM produkty ORDER BY waga_kg DESC;

-- Kw3 (INSERT): Dodanie nowego produktu (Jabłko, kategoria 4)
INSERT INTO produkty (nazwa_produktu, cena, waga_kg, data_dostawy, id_kategorii)
VALUES ('Jabłko Szampion', 1.50, 0.25, '2025-12-05', 4);

-- Kw4 (UPDATE): Zmniejszenie ceny Warzyw o 10%
UPDATE produkty SET cena = cena * 0.90 WHERE id_kategorii = 1;

4. Styl strony – plik styl_ecofarm.css

Polecenie:

Utwórz plik styl_ecofarm.css. Napisz kod CSS, który zapewni odpowiednią prezentację wizualną, zgodnie z poniższymi wytycznymi:

ElementPełne Polecenie do wykonania
Całe ciało dokumentu (`body`)Użycie czcionki Tahoma, kolor tła: jasnoszary (`#f2f2f2`).
Nagłówek i Stopka (`header`, `footer`)Kolor tła: ciemny granat (`#1e3a5f`), biały tekst, wyśrodkowanie tekstu.
TabelaSzerokość 90%, wyśrodkowana, granica. Nagłówki komórek (`th`) z tłem `#4a7cff` (niebieski).
FormularzMaksymalna szerokość 450px, wyśrodkowany, tło jasnoszare/kremowe (`#e9ecef`), zaokrąglone rogi (8px).
Przycisk (`.przycisk-akcja`)Zielone tło (`#28a745`), biały tekst, pełna szerokość w kontenerze.
Rozwiązanie CSS (styl_ecofarm.css)
* {
    font-family: Tahoma, sans-serif;
    box-sizing: border-box;
    margin: 0;
    padding: 0;}

body {
    background-color: #f2f2f2;
    color: #343a40;}

.container {
    max-width: 1100px;
    margin: 0 auto;
    padding: 20px 10px;}

header, footer {
    background: #1e3a5f;
    color: #ffffff;
    text-align: center;
    padding: 16px 0;
    margin: 20px 0;}

header h1 {
    font-size: 2.2em;
    margin: 0;}

table {
    width: 90%;
    margin: 20px auto;
    border-collapse: collapse;
    border: 1px solid #343a40;}
td, th {
    border: 1px solid #ccc;
    padding: 10px;}
th {
    background: #4a7cff;
    color: #ffffff;
    font-weight: bold;}

.form-container {
    max-width: 450px;
    margin: 20px auto;
    padding: 20px;
    background: #e9ecef;
    border-radius: 8px;
    border: 1px solid #ccc;}

.kontrolka {
    display: block;
    width: 100%;
    margin: 10px 0;
    padding: 8px;
    border-radius: 4px;
    border: 1px solid #ccc;}

.przycisk-akcja {
    background: #28a745;
    color: #ffffff;
    padding: 10px 20px;
    border-radius: 5px;
    border: none;
    font-weight: bold;
    cursor: pointer;
    margin-top: 15px;
    width: 100%;}

#wynik_wyceny {
    margin-top: 18px;
    padding: 10px;
    background: #ffffff;
    border: 1px solid #28a745;
    border-radius: 4px;
    font-weight: bold;}

5. Aktywne Zadanie: plik oferta_farmy.php

Polecenie:

Utwórz plik oferta_farmy.php. Napisz w nim kompletny kod PHP i HTML. Zastosuj następujące, zmienione wymagania:

SekcjaPełne Polecenie do wykonania (Wymaga modyfikacji logiki)
PołączenieNapisz poprawny kod PHP do nawiązania połączenia z bazą danych `ecofarm` przy użyciu rozszerzenia `mysqli`. Zapewnij obsługę błędu połączenia.
ZapytanieNapisz zapytanie `SELECT` z instrukcją `JOIN` (produkty i kategorie). Zapytanie musi posortować wyniki według kolumny `cena` malejąco (`DESC`).
WyświetlanieW pętli `while`, zmodyfikuj instrukcję `echo` tak, aby dane z bazy były wyświetlane w tabeli HTML, a w kolumnie Cena kwoty były wyświetlane z dopiskiem PLN/kg.
Rozwiązanie do Aktywnego Zadania 5 (oferta_farmy.php)
<?php
    // 1. Połączenie z bazą danych ecofarm
    $conn = new mysqli("localhost", "root", "", "ecofarm");

    if ($conn->connect_error) {
        die("Błąd połączenia z bazą danych: " . $conn->connect_error);
    }

    // 2. Zapytanie z JOIN: sortowanie po CENIE MALEJĄCO (DESC)
    $sql = "SELECT p.nazwa_produktu, k.nazwa_kategorii, p.waga_kg, p.cena, p.data_dostawy
            FROM produkty p
            JOIN kategorie k ON p.id_kategorii = k.id_kategorii
            ORDER BY p.cena DESC"; 

    $result = $conn->query($sql);
?>
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>EcoFarm - Oferta Farmy</title>
    <link rel="stylesheet" href="styl_ecofarm.css">
</head>
<body>
<header>
    <h1>ECOFARM – NASZA OFERTA (SORTOWANIE PO CENIE)</h1>
</header>

<main class="container">
    <h2>Katalog produktów ekologicznych</h2>
    <table>
        <tr>
            <th>Nazwa produktu</th>
            <th>Kategoria</th>
            <th>Waga (kg)</th>
            <th>Cena (PLN/kg)</th>
            <th>Data dostawy</th>
        </tr>
        <?php
            if ($result && $result->num_rows > 0) {
                while ($row = $result->fetch_assoc()) {
                    echo "<tr>";
                    echo "<td>" . $row['nazwa_produktu'] . "</td>";
                    echo "<td>" . $row['nazwa_kategorii'] . "</td>";
                    echo "<td>" . $row['waga_kg'] . "</td>";
                    // 3. Dodanie sufiksu PLN/kg
                    echo "<td>" . number_format($row['cena'], 2) . " PLN/kg</td>"; 
                    echo "<td>" . $row['data_dostawy'] . "</td>";
                    echo "</tr>";
                }
            } else {
                echo "<tr><td colspan='5'>Brak produktów w bazie.</td></tr>";
            }
            $conn->close();
        ?>
    </table>
</main>

<footer>
    <p>Przygotował: [NUMER ZDAJĄCEGO]</p>
</footer>
</body>
</html>

6. Aktywne Zadanie: plik koszyk.html

Polecenie:

Utwórz plik koszyk.html. Napisz w nim kompletny kod HTML formularza oraz funkcję JavaScript (`obliczKoszt()`) obsługującą walidację i obliczenia. Zastosuj następujące, zmienione wymagania:

SekcjaPełne Polecenie do wykonania (Wymaga dodania i zmiany logiki)
HTML: FormularzDODAJ do formularza nowy element interaktywny: pole typu `checkbox` dla opcji Opakowanie Ekologiczne (+3 PLN).
JS: WalidacjaZmień walidację, aby pole Nazwa Klienta (`nazwa_klienta`) było niepuste i miało MINIMUM 5 ZNAKÓW. Sprawdź też, czy liczba sztuk jest > 0.
JS: ObliczeniaZmodyfikuj funkcję `obliczKoszt()`, aby poprawnie pobierała i sumowała koszt opakowania (3 PLN) do całkowitej wyceny, jeśli checkbox jest zaznaczony.
JS: WynikZmień komunikat końcowy, aby wyświetlał koszt netto (tylko koszt produktów) oraz koszt brutto (produkty + dostawa + opakowanie).
Rozwiązanie do Aktywnego Zadania 6 (koszyk.html - HTML + JS)
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>EcoFarm - Koszyk</title>
    <link rel="stylesheet" href="styl_ecofarm.css">
</head>
<body>
<header>
    <h1>ECOFARM – OBLICZANIE KOSZYKA</h1>
</header>

<main class="container">
    <div class="form-container">
        <h2>Formularz wyceny zamówienia</h2>

        <label for="nazwa_klienta"><strong>Nazwa klienta (min. 5 znaków):</strong></label>
        <input type="text" id="nazwa_klienta" class="kontrolka" placeholder="Wpisz nazwę klienta">

        <label for="produkt"><strong>Wybierz produkt:</strong></label>
        <select id="produkt" class="kontrolka">
            <option value="8.99" data-nazwa="Pomidor Maliniak">Pomidor Maliniak (8.99 PLN)</option>
            <option value="25.50" data-nazwa="Ser Kozi Wędzony">Ser Kozi Wędzony (25.50 PLN)</option>
        </select>

        <label for="liczba_sztuk"><strong>Liczba sztuk:</strong></label>
        <input type="number" id="liczba_sztuk" class="kontrolka" min="1" value="1">

        <h3>Sposób dostawy i opcje</h3>
        <!-- Dodatkowa opcja Opakowanie Ekologiczne -->
        <label style="display:block; margin-bottom: 10px;">
            <input type="checkbox" id="opakowanie" value="3">
            Opakowanie Ekologiczne (+3 PLN)
        </label>

        <label>
            <input type="radio" name="dostawa" value="15" checked>
            Paczkomat (+15 PLN)
        </label><br>
        <label>
            <input type="radio" name="dostawa" value="25">
            Kurier (+25 PLN)
        </label>

        <button class="przycisk-akcja" onclick="obliczKoszt()">
            Oblicz koszt
        </button>

        <div id="wynik_wyceny">
            Tutaj pojawi się wynik wyceny (netto/brutto).
        </div>
    </div>
</main>

<footer>
    <p>Przygotował: [NUMER ZDAJĄCEGO]</p>
</footer>

<script>
function obliczKoszt() {
    const nazwaKlienta = document.getElementById('nazwa_klienta').value.trim();
    const selectProdukt = document.getElementById('produkt');
    const cenaJednostkowa = parseFloat(selectProdukt.value);
    const nazwaProduktu = selectProdukt.options[selectProdukt.selectedIndex].getAttribute('data-nazwa');
    const liczbaSztuk = parseInt(document.getElementById('liczba_sztuk').value);
    
    const dostawaElement = document.querySelector('input[name="dostawa"]:checked');
    const kosztDostawy = dostawaElement ? parseFloat(dostawaElement.value) : 0;
    
    // Pobranie wartości opakowania
    const kosztOpakowania = document.getElementById('opakowanie').checked ? 3.00 : 0.00;
    
    const wynikDiv = document.getElementById('wynik_wyceny');

    // Walidacja danych (min. 5 znaków)
    if (nazwaKlienta === "" || nazwaKlienta.length < 5 || isNaN(liczbaSztuk) || liczbaSztuk < 1) {
        wynikDiv.innerHTML = "<strong style='color: red;'>BŁĄD: Nazwa klienta musi mieć min. 5 znaków, a ilość min. 1.</strong>";
        return;
    }

    // Obliczenie kosztu NETTO (tylko produkty)
    const kosztNetto = cenaJednostkowa * liczbaSztuk;

    // Obliczenie kosztu BRUTTO (produkty + dostawa + opakowanie)
    const kosztCalkowityBrutto = kosztNetto + kosztDostawy + kosztOpakowania;

    // Komunikat wynikowy (wyświetlanie Netto/Brutto)
    const komunikat =
        "Klient <strong>" + nazwaKlienta + "</strong>. Wybrano " +
        "<strong>" + nazwaProduktu + "</strong> (x " + liczbaSztuk +
        "). <br>Koszt NETTO (produkty): <strong>" + kosztNetto.toFixed(2) +
        "</strong> PLN. <br>Opakowanie + Dostawa: <strong>" + (kosztDostawy + kosztOpakowania).toFixed(2) +
        "</strong> PLN. <br>Całkowity koszt BRUTTO: <strong>" +
        kosztCalkowityBrutto.toFixed(2) + "</strong> PLN.";

    wynikDiv.innerHTML = komunikat;
}
</script>
</body>
</html>

7. Narzędzia i Weryfikacja

Poniżej znajduje się podglądowy formularz i funkcja JavaScript do przełączania kodów.

Przełączanie kodów źródłowych (Weryfikacja):

Kliknij "POKAŻ KOD" w odpowiedniej sekcji, aby zweryfikować poprawność swojego rozwiązania z wymaganiami aktywnymi.