Quest: The Event

Temat projektu: Strona promująca kilkudniowe wydarzenie

Celem projektu jest stworzenie responsywnej strony internetowej w WordPressie, promującej kilkudniowe wydarzenie (np. konferencję, obóz, wyprawę lub szkolenie). Strona powinna prezentować pełny program imprezy, sylwetki prelegentów oraz dodatkowe elementy multimedialne i interaktywne.

W projekcie warto wykorzystać Custom Post Types oraz wybrane widżety, dzięki czemu powstanie rozbudowany, profesjonalnie wyglądający serwis.

Zakres funkcjoności

  1. Strona główna
    • dynamiczny timeline prezentujący przebieg wydarzenia,
    • liczniki statystyk (np. liczba dni, uczestników, prelegentów),
    • karuzela logotypów partnerów,
    • sekcja z chmurą tagów (tagcloud) prowadzącą do wybranych artykułów.
  2. Program wydarzenia
    • Custom Post Type prezentujący szczegółowy opis każdego dnia,
    • możliwość dodawania galerii, filmów i dodatkowych multimediów.
  3. Lista gości / mówców
    • osobny Custom Post Type dla prelegentów lub bohaterów wydarzenia,
    • indywidualne podstrony z opisem i multimediami.
  4. Kategorie i tagi
    • wykorzystanie stron kategorii do prezentacji tematycznych treści,
    • chmura inspirujących tagów kierująca do powiązanych postów.
  5. Kontakt
    • formularz kontaktowy,
    • interaktywna mapa lokalizacji (bez Google i Apple Maps).
  6. Responsywność
    • poprawne działanie na urządzeniach mobilnych i desktopowych.

Stronę należy wykonać w 2 lub 3 osobowych zespołach (wspólna ocena).

Promowane wydarzenie ma być inspirujące, motywujące i angażujące uczestników do aktywnego działania. Ma być miejscem wymiany wartościowych doświadczeń oraz budowania relacji. Powinno także zachęcać do rozwoju osobistego, przekraczania własnych granic i odkrywania nowych perspektyw.

Quest: Node.js – start

Node.js to środowisko uruchomieniowe JavaScript stworzone po to, aby można było wykonywać kod JS poza przeglądarką — najczęściej na serwerze. Najważniejsze cechy Node.js:

  • Oparte na silniku JavaScript V8, który napędza Google Chrome.
  • Asynchroniczność i model zdarzeniowy: Node działa w jednym wątku, ale obsługuje wiele operacji wejścia/wyjścia asynchronicznie, więc świetnie nadaje się do aplikacji, które muszą obsługiwać np. wielu użytkowników jednocześnie.
  • Dzięki bibliotekom jak Express można szybko tworzyć serwery aplikacji webowych: HTTP, API, aplikacje czasu rzeczywistego.
  • Ekosystem NPM (Node Package Manager) Node posiada największy ekosystem bibliotek na świecie. Są tam gotowe pakiety do niemal wszystkiego.
  • Wieloplatformowy: Działa na Windows, Linux, macOS, a także na serwerach w chmurze i w środowiskach serverless.

Zastosowania Node.js

  1. API oraz backend aplikacji webowych / mobilnych
  2. Aplikacje czasu rzeczywistego (czaty, powiadomienia, WebSocket)
  3. Streaming audio / video i obsługa dużych danych
  4. Narzędzia developerskie: cli, bundlery i build tools (do SCSS, JSX, TypeScript) 1
  5. IoT: sterowanie urządzeniami, komunikacja z sensorami
  6. Serverless i chmura (kod, który działa tylko wtedy, gdy jest potrzebny)
  7. Przetwarzanie asynchroniczne: kolejki zadań, generowanie raportów/plików

Zadanie

Utwórzmy prosty serwer, który udostępnia pliki z katalogu /www w formie klikalnej listy, ale ukryje jeden z plików. Serwer będzie też logował aktywność użytkowników.

  1. Zainstaluj Node.js z nodejs.org i sprawdź czy działa
  2. Utwórz folder projektu
  3. Zainicjuj projekt Node
    To utworzy plik package.json.
  4. Zainstaluj Express
  5. Utwórz folder www a w nim pliki: test.txt hello.html tajny.html obrazek.png
  6. Utwórz plik server.js (poza katalogiem /www) i wklej kod serwera:
# 1.
node -v
npm -v

# 2.
mkdir node-express-demo
cd node-express-demo

# 3.
npm init -y

# 4.
npm install express

# 5.
mkdir www

const express = require("express");
const fs = require("fs");
const path = require("path");

const app = express();

// Middleware 1: prosty logger
app.use((req, res, next) => {
  console.log(req.method, req.url);
  next();
});

// Middleware 2: ukrywa tajny.html
app.use((req, res, next) => {
  req.hidden = "tajny.html";
  next();
});

// Trasa główna – lista plików
app.get("/", (req, res) => {
  const files = fs.readdirSync(path.join(__dirname, "www"))
    .filter(f => f !== req.hidden);

  res.send(`
    <h1>Pliki w /www</h1>
    <ul>
      ${files.map(f => `<li><a href="/${f}" target="_blank">${f}</a></li>`).join("")}
    </ul>
  `);
});

// Serwowanie plików z /www
app.use(express.static(path.join(__dirname, "www")));

app.listen(3000, () => console.log("http://localhost:3000"));

Uruchom serwer i sprawdź jak działa w przeglądarce i jak loguje

node server.js

Kilka pojęć które warto rozumieć:

  • Express – lekki framework dla Node.js ułatwiający tworzenie serwerów HTTP i API.
  • Middleware – funkcja pośrednicząca, która może modyfikować żądanie, odpowiedź lub przepływ działania aplikacji Express.
  • Trasa główna – podstawowy endpoint aplikacji (np. / ), który odpowiada na główne żądanie użytkownika.
  • fs i path – moduły Node.js umożliwiające odpowiednio pracę z plikami oraz zarządzanie ścieżkami w systemie plików.
  • npm – menedżer pakietów dla Node.js, który pozwala instalować, aktualizować i zarządzać bibliotekami oraz narzędziami potrzebnymi w projektach JavaScript (jak Express, React czy Vite)
  • Bundlery i build tools – narzędzia, które łączą, optymalizują i przygotowują kod frontendowy do produkcji.

    Bundlery i build tools to narzędzia, które zbierają wiele plików frontendowych (JavaScript, CSS, obrazy) i łączą je w zoptymalizowane pakiety gotowe do uruchomienia w przeglądarce. Usuwają zbędny kod, kompresują pliki, dzielą aplikację na mniejsze części i automatycznie rozwiązują zależności między modułami. Dzięki nim aplikacje wczytują się szybciej, są bardziej wydajne i łatwiejsze do rozwijania.

    W kontekście korzystania z Vite + React to narzędzia, które błyskawicznie uruchamiają środowisko deweloperskie, podając kod Reacta bezpośrednio do przeglądarki dzięki natywnym modułom ES, a jednocześnie generują szybki i zoptymalizowany build produkcyjny. Vite automatycznie łączy i optymalizuje pliki, zarządza zależnościami, kompresuje kod i obsługuje JSX oraz TypeScript, dzięki czemu React działa szybko i wygodnie zarówno podczas developmentu, jak i na produkcji. Dzięki temu deweloper może skupić się na pisaniu komponentów, a nie na konfiguracji narzędzi.

  1. To do tego najczęściej będziemy potrzebować node.js ↩︎

INF.03.drill.9 – MySQL + troszkę PHP

Wykonaj kwerendy z zadania INF.03-11-25.01-SG. Napraw popsute fragmenty kodu MySQL i skrypt PHP (nie zaznaczyłem co zepsułem). Potrzebne pliki są tu.

To zadanie ma bardzo standardowy skrypt wyświetlający dane z bazy, ale jeden element jest niestandardowy (pierwsza kolumna). Nie pomijajcie tego elementu.

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WOLONTARIAT SZKOLNY</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <h1>KONKURS - WOLONTARIAT SZKOLNY</h1>
    </header>
    <section class="left">
        <h3>Konkursowe nagrody</h3>
        <form>
            <button type="submit">Losuj nowe nagrody</button>
        </form>
        <table>
            <tr>
                <th>Nr</th>
                <th>Nazwa</th>
                <th>Opis</th>
                <th>Wartość</th>
            </tr>
            <?php
             $id_połączenia = mysqli_connect('localhost','root','','konkurs');
             $zapytanie = "SELECT * FROM nagrody";
             $wynik_zapytania = mysqli_query($id_połączenia,$zapytanie);
             while($wiersz = mysqli_fetch_row($wynik_zapytania)){
                 print "<tr><td>".$wiersz[0]."</td><td>".$wiersz[1]."</td></tr>";
             }
             mysqli_close($id_połączenia);
            ?>
        </table>
    </section>
    <section class="right">
        <img src="puchar.png" alt="Puchar dla wolontariusza">
        <h4>Polecane linki</h4>
        <ul>
            <li><a href="kw1.png">Kwerenda1</a></li>
            <li><a href="kw2.png">Kwerenda2</a></li>
            <li><a href="kw3.png">Kwerenda3</a></li>
            <li><a href="kw4.png">Kwerenda4</a></li>
        </ul>
    </section>
    <footer>
        <p>Numer zdającego: 0000000000</p>
    </footer>
</body>
</html>

INF.03.drill.8 – MySQL + nieco PHP

Wykonaj kwerendy i grafiki z zadania INF.03-12-25.01-SG. Napraw popsute przez Piotrusia fragmenty kodu MySQL i skrypt PHP. Wszystkie popsute miejsca oznaczyłem. Potrzebne pliki są tu. Wykonaj potrzebne zrzuty ekranu.

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PIEKARNIA</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <img src="wypieki.png" alt="Produkty naszej piekarni">
    <nav>
        <a href="kw1.png">KWERENDA1</a>
        <a href="kw2.png">KWERENDA2</a>
        <a href="kw3.png">KWERENDA3</a>
        <a href="kw4.png">KWERENDA4</a>
    </nav>
    <header>
        <H1>WITAMY</H1>
        <h4>NA STRONIE PIEKARNI</h4>
        <p>Od 31 lat oferujemy najwyższej jakości pieczywo.</p>
    </header>
    <main>
        <h4>Wybierz rodzaj wypieków:</h4>
        <form method="post">
            <select name="lista" class="lista"></select> zepsułem
                <?php
                $polaczenie = mysqli_connect('localhost','root','','piekarnia');
                $zapytanie = "SELECT rodzaj FROM wyroby WHERE id LIKE '1%'";  //zepsułem
                $wynik_zapytania = mysqli_query($polaczenie,$zapytanie);
                while($wiersz = mysqli_fetch_row($wynik_zapytania)){
                    print $wiersz[0]."<br>";  //zepsułem
                }
                //zepsułem
                ?>
            </select>
            <button type="submit">Wybierz</button>
        </form>
        <table>
            <tr>
                <th>Rodzaj</th>
                <th>Nazwa</th>
                <th>Gramatura</th>
                <th>Cena</th>
            </tr>
            <?php
                $element = isset($_POST['lista']) ? $_POST['lista'] : '';
                $polaczenie = mysqli_connect('localhost','root','','piekarnia');
                $zapytanie = "SELECT Nazwa, Cena FROM wyroby WHERE Rodzaj='INNE'";  //zepsułem
                $wynik_zapytania = mysqli_query($polaczenie,$zapytanie);
                while($wiersz = mysqli_fetch_row($wynik_zapytania)){
                    echo "<tr><td>".$wiersz[0]." ".$wiersz[1]."</td></tr>";  //zepsułem
                }
                //zepsułem
            ?>
        </table>
    </main>
    <footer>
        <p>AUTOR: 000000000</p>
        <P>25.01.2025</P>
    </footer>
</body>
</html>

INF.03.drill.7 – MySQL

Wykonaj kwerendy i grafiki z zadania INF.03-10-25.01-SG i uzupełnij wykropkowane fragmenty w skrypcie PHP. Potrzebne pliki są tu. Wykonaj potrzebne zrzuty ekranu.

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>KOŁO SZACHOWE</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <h2>Koło szachowe <em>gambit piona</em></h2>
    </header>
    <section class="left">
        <h4>Polecane linki</h4>
        <ul>
            <li><a href="kw1.png">Kwerenda 1</a></li>
            <li><a href="kw2.png">Kwerenda 2</a></li>
            <li><a href="kw3.png">Kwerenda 3</a></li>
            <li><a href="kw4.png">Kwerenda 4</a></li>
        </ul>
        <img src="logo.png" alt="Logo koła">
    </section>
    <section class="right">
        <h3>Najlepsi gracze naszego koła</h3>
        <table>
            <tr>
                <th>Pozycja</th>
                <th>Pseudonim</th>
                <th>Tytuł</th>
                <th>Ranking</th>
                <th>Klasa</th>
            </tr>
            <?php
                $id_połączenia = mysqli_connect('localhost','root','','szachy');
                $zapytanie = " :::::::::::::::::::::::::";
                $wynik_zapytania = mysqli_query($id_połączenia,$zapytanie);
                $pozycja = 1;
                while($wiersz = mysqli_fetch_row($wynik_zapytania)){
                    print "<tr><td>".$pozycja."</td><td>".$wiersz[0]."</td><td>".$wiersz[1]."</td>      <td>".$wiersz[2]."</td><td>".$wiersz[3]."</td></tr>";
                    $pozycja ++;
                }
                mysqli_close($id_połączenia);
            ?>
        </table>
        <form>
            <button type="submit">Losuj nową parę graczy</button>
        </form>
        <h4>
        <?php
            $id_połączenia = mysqli_connect('localhost','root','','szachy');
            $zapytanie = "::::::::::::::::::::::::::::::";
            $wynik_zapytania = mysqli_query($id_połączenia,$zapytanie);
            
                while($wiersz = mysqli_fetch_row($wynik_zapytania)){
                    print $wiersz[0]." ".$wiersz[1]." ";
            }
            mysqli_close($id_połączenia);
        ?>
        <p>Legenda: AM - Absolutny Mistrz, SM - Szkolny Mistrz, PM - Mistrz Poziomu, KM - Mistrz Klasowy</p>
    </section>
    <footer>
        <p>Stronę wykonał: 0000000000</p>
    </footer>
</body>
</html>

Quest: NTFS

System plików ewoluuje od wielu lat. Dziś obsługuje on między innymi:

  1. Uprawnienia (ACL) – precyzyjna kontrola dostępu do plików i folderów (kto i w jaki sposób).
  2. Szyfrowanie (EFS) – wbudowane szyfrowanie na poziomie systemu plików.
  3. Kompresja plików i folderów – transparentna, bez użycia zewnętrznych narzędzi.
  4. Transakcyjność (journaling) – rejestrowanie zmian, większa odporność na utratę danych po awarii.
  5. Obsługa bardzo dużych plików i partycji – pliki powyżej 4 GB i partycje wielu terabajtów.
  6. Twarde linki, dowiązania symboliczne, punkty montowania – bardziej zaawansowane odnośniki do plików. W Linux były dostępne od dekad 🙂
  7. Uprawnienia na poziomie plików dla domen/AD – integracja z systemami bezpieczeństwa Windows.
  8. Strumienie alternatywne (ADS) – możliwość dopisywania ukrytych danych do plików (np. plik.ext:Zone.Identifier=3 – plik z Internetu).
  9. Kwanty czasu i dodatkowe metadane – dokładniejsze znaczniki czasu, więcej informacji o pliku.
  10. Limitowanie i zarządzanie przestrzenią (quota) – kontrola zużycia miejsca przez użytkowników.
  11. Samonaprawa (self-healing) w nowszych wersjach – automatyczne korekty uszkodzeń logicznych.

Wykonaj zadania:

  1. Zaloguj się jako administrator i utwórz pięciu użytkowników standardowych: Student1 – Student5.
  2. Utwórz dwie grupy: Grupa1 i Grupa2.
    • Do Grupa1 dodaj Student1, Student2, Student3.
    • Do Grupa2 dodaj Student3, Student4, Student5.
  3. Utwórz folder C:\Dane_grup. Usuń z listy uprawnień grupę Wszyscy.
    Czy jest to możliwe? Uzasadnij.
  4. Wyłącz dziedziczenie uprawnień folderu Dane_grup.
    Spróbuj ponownie usunąć grupę Wszyscy. Opisz różnicę.
  5. Przyznaj uprawnienia:
    • Grupie1 – Odczyt i Zapis
    • Grupie2 – Odczyt i Wyświetlanie a następnie odmów prawa do zapisu
      Określ efektywne uprawnienia wszystkich studentów, zwłaszcza Student3.
  6. Nadaj grupie Administratorzy pełną kontrolę do folderu Dane_grup.
    Utwórz plik Admin.txt.
  7. Zaloguj się jako Student1, Student3 i Student5.
    Spróbuj otworzyć, zmienić, zapisać i usunąć plik Admin.txt.
    Zapisz, co było możliwe.
  8. Obejrzyj zaawansowane uprawnienia NTFS i porównaj je ze standardowymi.
  9. Włącz w Eksploratorze wyświetlanie skompresowanych plików w innym kolorze.
    Utwórz folder C:\Kompresja i skopiuj do niego ok. 10 MB danych.
    Sprawdź „Rozmiar” i „Rozmiar na dysku”.
  10. Skompresuj folder Kompresja.
    Odczytaj ponownie oba parametry i oblicz współczynnik kompresji.
  11. Skonfiguruj przydziały dyskowe (Quota) dla dysku C:
    Limit 10 MB, ostrzeżenie 6 MB.
    Sprawdź dostępne miejsce dla administratora i Student1–Student5.
  12. Zaloguj się jako Student1 i sprawdź dostępne miejsce.
    Porównaj z poprzednim punktem i skomentuj.
  13. Spróbuj skopiować folder C:\Windows\System32 do folderu Moje_dane.
    Podaj jego rozmiar i wyjaśnij, czy kopiowanie było możliwe i dlaczego.
  14. Wyłącz przydziały dyskowe dla dysku C:.
    Ustal, który użytkownik ma prawo tego dokonać.
  15. Jako administrator wyeksportuj certyfikat EFS (pfx).
    Utwórz folder Szyfrowane i plik Confidential.txt.
  16. Zaloguj się jako Student3 i zaszyfruj plik Confidential.txt.
  17. Zaloguj się jako adm i spróbuj odczytać zaszyfrowany plik.
    Wyjaśnij wynik.
  18. Zaimportuj certyfikat agenta odzyskiwania i spróbuj odczytać plik ponownie.
    Wyjaśnij, dlaczego jest to możliwe lub nie.
  19. Usuń wszystkich użytkowników, grupy i foldery utworzone podczas ćwiczenia.

INF.03.drill.6 – JS

Proponuję wykonanie samego skryptu do zadania z 2024. Gotowy kod HTML i CSS jest poniżej.
Treść zadania: INF.03-08-24.06-SG

Przydatna linijka do skryptu (2 warianty)

document.getElementById("bla_bla").style.display = "none";
document.getElementById("ble_ble").style.display = "block";

rejestracja.html

<!DOCTYPE html>
<html lang="pl">
	<head>
		<meta charset="UTF-8">
		<title> Sklep - rejestracja </title>
		<link rel="stylesheet" href="styl.css">
	</head>
<body>
    <section id="left">
        <img src="obraz.png" alt="promocje">
        <h2>Sprawdź promocje</h2>
        <table>
            <tr><th>co?</th><th> ile taniej?</th></tr>
            <tr><td> ubrania</td><td>15%</td></tr>
            <tr><td> buty</td><td>25%</td></tr>
        </table>
    </section>
    <section id="baner">
        <h1>Zarejestruj się w sklepie</h1>
    </section>
    <section id="main">
        <button id="but_klient" onclick="blok1()">Klient</button>
        <button id="but_adres" onclick="blok2()">Adres</button>
        <button id="but_kontakt" onclick="blok3()">Kontakt</button>
        <div id="klient_div" onload="postep()">
            <p>Imię</p>
            <input type="text" id="imie" placeholder="Wpisz dane...">
            <p>nazwisko</p>
            <input type="text" id="nazwisko">
            <p>Data urodzenia</p>
            <input type="date" id="data">
        </div>
        <div id="adres_div">
            <p>Ulica</p>
            <input type="text" id="ulica">
            <p>Numer</p>
            <input type="number" id="numer">
            <p>Miasto</p>
            <input type="text" id="miasto">
        </div>
        <div id="kontakt_div">
            <p>Numer komórkowy</p>
            <input type="number" id="tel">
            <input type="checkbox" id="akceptuje">Akceptuje RODO <br>
            <button id="zatwierdz" onclick="zatwierdz()">Zatwierdź dane</button> 
        </div>
    </section>
    <section id="progressbar">
        <section id="empty" onresize="postep()"></section>
    </section>
    <footer id="footer">
			<h4>Rejestrację do sklepu wykonał: 0000000000</h4>
    </footer>
		<script>

    </script>
</body>
</html>

styl.css

*{
    font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
}

body{
    background-color: linen;
}

#left, #baner, #footer{
    background-color: steelblue;
    color: white;
    text-align: center;
}

#left{
    width: 25%;
    height: 510px;
    margin-top: 0;
    margin-bottom: 0;
    margin-left: 1%;
    margin-right: 1%;
    box-shadow: 4px blur dimgray;
    float: left;
    clear: both;
    
}

#baner{
    width: 73%;
    height: 80px;
    float: left;
}

#main{
    width: 73%;
    height: 400px;
    float: left;
}

#footer{
    clear: both;
}

button{
    background-color: steelblue;
    color: white;
    width: 20%;
    padding: 15px;
    margin-top: 30px;
    font-size: 130%;
    border: none;
}

button:hover{
    background-color: navy;
}

#klient_div, #adres_div, #kontakt_div{
    background-color: lightblue;
    margin-right: 80px;
    padding: 10px;
}

#adres_div, #kontakt_div{
    display:none;
}

#progressbar{
    background-color: lightgrey;
    width: 73%;
    margin-bottom: 10px;
    float: left;
}

#empty{
    background-color: navy;
    width: 4%;
    height: 30px;
}

table{
    width: 100%;
    border: dotted 1px navy;
    float: left;
}

Podobne zadanie do rozwiązania samodzielnie

INF.03-10-24.06-SG

Quest: HTML + CSS bez JS

CSS się zmienia, ewoluuje. To co kiedyś wymagało JS dziś już często go nie potrzebuje.

Demo 1 – basic

<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo 1 – Podstawy HTML i CSS</title>
<style>
  body {
    font-family: "Segoe UI", sans-serif;
    margin: 40px;
    background: #f9f9fb;
    color: #333;
  }

  h1 {
    text-align: center;
  }

  section {
    background: white;
    border-radius: 16px;
    box-shadow: 0 4px 10px rgba(0,0,0,0.1);
    padding: 20px;
    margin-bottom: 30px;
  }

  h2 {
    color: #444;
    border-bottom: 2px solid #eee;
    padding-bottom: 4px;
  }

  /* Efekt najechania i animacja */
  .btn {
    display: inline-block;
    background: #0078d7;
    color: white;
    padding: 10px 18px;
    border-radius: 8px;
    transition: background 0.3s, transform 0.2s;
    text-decoration: none;
  }
  .btn:hover {
    background: #005fa3;
    transform: scale(1.05);
  }

  /* Styl paska postępu */
  progress {
    width: 100%;
    height: 20px;
  }

  /* Przykład z box-shadow i border-radius */
  .card {
    width: 250px;
    padding: 20px;
    border-radius: 12px;
    box-shadow: 0 6px 12px rgba(0,0,0,0.15);
    text-align: center;
    margin: auto;
    background: #fafafa;
  }
  .card img {
    width: 80px;
    border-radius: 50%;
  }

</style>
</head>
<body>

<h1>Demo 1 – Podstawy HTML i CSS</h1>

<section>
  <h2>1. <details> i <summary></h2>
  <p>Elementy HTML, które pozwalają ukrywać/rozwijać treść bez JavaScript.</p>
  <details>
    <summary>Kliknij, by rozwinąć szczegóły</summary>
    <p>To działa tylko dzięki HTML! Możesz w środku mieć tekst, obrazki, a nawet inne elementy.</p>
  </details>
</section>

<section>
  <h2>2. <meter> i <progress></h2>
  <p>Natywne elementy pokazujące wartość liczbową w graficzny sposób:</p>
  <p>Poziom baterii: <meter value="0.65">65%</meter></p>
  <p>Postęp ładowania:</p>
  <progress value="70" max="100">70%</progress>
</section>

<section>
  <h2>3. Efekty wizualne: box-shadow, border-radius</h2>
  <div class="card">
    <img src="https://picsum.photos/100" alt="avatar">
    <h3>Jan Kowalski</h3>
    <p>Uczeń klasy 3B</p>
  </div>
</section>

<section>
  <h2>4. Efekty interakcji: :hover i transition</h2>
  <p>Prosty efekt po najechaniu na przycisk:</p>
  <a href="#" class="btn">Najedź na mnie</a>
</section>

</body>
</html>

Demo 2 – intermediate

<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo 2 – Efekty CSS średnio zaawansowane</title>
<style>
  body {
    font-family: "Segoe UI", sans-serif;
    background: #f3f4f8;
    margin: 40px;
    color: #333;
  }

  section {
    background: white;
    border-radius: 16px;
    box-shadow: 0 4px 10px rgba(0,0,0,0.1);
    padding: 20px;
    margin-bottom: 30px;
  }

  h1, h2 { text-align: center; }

  /* clip-path – wycinanie kształtów */
  .clip-demo {
    width: 200px; height: 200px;
    background: url('https://picsum.photos/300') center/cover;
    clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
    margin: 10px auto;
  }

  /* filter – efekty graficzne */
  .filter-demo img {
    width: 250px;
    filter: grayscale(80%) blur(1px);
    transition: filter 0.3s;
  }
  .filter-demo img:hover {
    filter: none;
  }

  /* transform – obrót i skalowanie */
  .transform-demo {
    display: inline-block;
    background: #0078d7;
    color: white;
    padding: 15px;
    border-radius: 8px;
    transition: transform 0.3s;
  }
  .transform-demo:hover {
    transform: rotate(8deg) scale(1.1);
  }

  /* nth-child – kolorowanie co drugiego wiersza */
  ul:nth-child(odd) { background: none; }
  li:nth-child(even) {
    background: #e8f0fe;
  }

  /* before/after – pseudo-elementy */
  .quote {
    position: relative;
    padding: 10px 30px;
  }
  .quote::before {
    content: "“";
    font-size: 40px;
    position: absolute;
    left: 5px;
    top: -10px;
    color: #ccc;
  }

</style>
</head>
<body>

<h1>Demo 2 – Efekty CSS średnio zaawansowane</h1>

<section>
  <h2>1. clip-path</h2>
  <p>Wycinanie obrazu w dowolny kształt:</p>
  <div class="clip-demo"></div>
</section>

<section class="filter-demo">
  <h2>2. filter</h2>
  <p>Efekt „starego zdjęcia” po najechaniu:</p>
  <img src="https://picsum.photos/250" alt="obraz">
</section>

<section>
  <h2>3. transform</h2>
  <p>Obrót i powiększenie przy najechaniu:</p>
  <div class="transform-demo">Najedź na mnie</div>
</section>

<section>
  <h2>4. nth-child</h2>
  <p>Stylowanie co drugiego elementu listy:</p>
  <ul>
    <li>Jabłko</li>
    <li>Gruszka</li>
    <li>Śliwka</li>
    <li>Banan</li>
  </ul>
</section>

<section>
  <h2>5. ::before i ::after</h2>
  <p>Dodawanie dekoracyjnych znaków bez zmiany HTML:</p>
  <blockquote class="quote">To jest przykład cytatu z pseudo-elementem.</blockquote>
</section>

</body>
</html>

cdn…

Quest: CzatoNotatnik lekcyjny PHP API + JS + Bootstrap

Cel projektu

Stworzyć w zespole prostą aplikację webową umożliwiającą:

  • wspólny czat dla wszystkich uczestników lekcji,
  • prywatną notatkę dla każdego ucznia,
  • tablicę tekstową edytowaną tylko przez belfra.

Aplikacja działa w przeglądarce, z backendem w PHP i bazą danych MySQL.

Założenia techniczne

Backend (API – PHP)

  • Serwer API w PHP
  • Komunikacja w formacie JSON (REST).
  • Główne endpointy:
    • GET /messages?last_id=X – pobiera nowe wiadomości (polling co 2s).
    • POST /messages – dodaje nową wiadomość.
    • GET /board / POST /board – odczyt/zapis tablicy nauczyciela.
    • GET /notes / POST /notes – odczyt/zapis prywatnych notatek.
  • Autoryzacja (role: teacher / student).

Frontend (JS + Bootstrap)

  • Jednostronicowa aplikacja (index.html).
  • 3 główne sekcje UI:
    1. Tablica nauczyciela – widoczna dla wszystkich, edytowalna tylko przez belfra.
    2. Czat grupowy – wszyscy mogą pisać i widzieć wiadomości w czasie rzeczywistym (polling co 2s).
    3. Prywatne notatki – widoczne tylko dla zalogowanego użytkownika.
  • Komunikacja z API za pomocą fetch().

Baza danych (MySQL)

Tabele przykładowe:

  • users(id, name, role)
  • messages(id, user_id, text, created_at)
  • board(id, content, updated_at)
  • notes(id, user_id, content, updated_at)

Działanie aplikacji

  1. Użytkownik loguje się
  2. Co 2 sekundy frontend pobiera nowe wiadomości (polling).
  3. Nauczyciel może edytować tablicę tekstową → zapis przez API.
  4. Każdy użytkownik może:
    • pisać na czacie,
    • zapisywać własną notatkę (przez API lub dodatkowo lokalnie).

Organizacja pracy zespołowej

Role w zespole (przykład podziału)

  • Frontend Developer – interfejs użytkownika (Bootstrap, JS).
  • Backend Developer – API i baza danych (PHP + MySQL).
  • UX/UI Designer – układ strony, użyteczność, style.
  • Tester / Dokumentalista – README, testy, opisy endpointów.

Praca na github.com

Oceniane elementy projektu

Wystawiam dwie oceny:

  • Zespołową ocenę jakości współpracy (ocena wagi 3) – taką samą dla wszystkich
  • Indywidualną ocenę jakości dodawanego kodu (ocena wagi 1) – może być różna dla wszystkich

W ocenie zespołowej zwracam uwagę na:

  • Widoczność w repozytorium eksperymentów dotyczących działania gita (na początkowym etapie)
  • Naturalność wprowadzanych ulepszeń w kodzie (jeśli jedna osoba doda większość kodu w krótkim czasie to źle)
  • Praca widoczna w repozytorium obejmuje cały czas trwania projektu
  • Czy praca nad projektem odbywa się również z domu 🙂

Dodatkowe punkty za:

  • Rejestrację/logowanie z rolami (uczeń/nauczyciel),
  • Pokazywanie, kto jest online,
  • Responsywny wygląd (mobile-friendly),
  • Dokumentację API w pliku api-docs.md.