Czego się nauczycie?
- Walidacji formularzy z różnymi typami pól
- Kontroli limitów i warunków biznesowych
- Obsługi zgód (checkbox) i danych osobowych
- Generowania raportów i list uczestników
- Praca zespołowa - podział zadań, współpraca, integracja kodu
Stworzycie System zapisów na wydarzenie - aplikację webową do rejestracji uczestników na wydarzenia szkolne lub firmowe. System pozwala na zbieranie zgłoszeń z danymi uczestników, kontrolę limitu miejsc oraz zarządzanie listą zapisanych osób. To praktyczny projekt odzwierciedlający rzeczywiste potrzeby organizatorów.
Czego się nauczycie?
W prawdziwej firmie...
Systemy rejestracji to podstawa organizacji wydarzeń - od konferencji IT, przez szkolenia firmowe, po zapisy na kursy. Eventbrite, Meetup, systemy szkolne - wszystkie działają na podobnej zasadzie. Umiejętność tworzenia takich systemów jest bardzo praktyczna.
Umiejętności rynkowe
Nauczycie się obsługi limitów i warunków brzegowych - co gdy miejsca się kończą? Jak obsłużyć listę rezerwową? To typowe problemy w systemach produkcyjnych, których rozwiązanie wymaga przemyślanej logiki.
Formularz rejestracji Użytkownik wypełnia formularz z danymi: imię, nazwisko, klasa/firma, email, telefon oraz akceptuje wymagane zgody. System waliduje wszystkie pola przed zapisem.
Kontrola limitu miejsc System sprawdza, czy są jeszcze wolne miejsca. Jeśli limit został osiągnięty, formularz jest blokowany lub użytkownik trafia na listę rezerwową (wariant B+).
Zapis do pliku JSON Poprawne zgłoszenia są zapisywane z unikalnym ID, znacznikiem czasu i statusem. Dane są bezpiecznie przechowywane w strukturze JSON.
Lista uczestników Organizator może przeglądać listę zapisanych osób z możliwością sortowania i filtrowania. W wyższych wariantach dostępny jest eksport do HTML.
Formularz zapisu
Potwierdzenie
Lista uczestników
Panel organizatora (C)
Przykładowa struktura pliku JSON:
{ "event": { "name": "Wycieczka do Krakowa", "date": "2026-04-15", "max_participants": 40, "registration_deadline": "2026-04-01" }, "registrations": [ { "id": 1, "first_name": "Jan", "last_name": "Kowalski", "class": "3TI", "email": "jan.kowalski@szkola.pl", "phone": "123456789", "consent_data": true, "consent_photo": false, "status": "confirmed", "created_at": "2026-02-13 10:30:00" }, { "id": 2, "first_name": "Anna", "last_name": "Nowak", "class": "3TI", "email": "anna.nowak@szkola.pl", "phone": "987654321", "consent_data": true, "consent_photo": true, "status": "confirmed", "created_at": "2026-02-13 11:15:00" } ]}Wymagane funkcjonalności:
Struktura plików:
Wszystko z wariantu A, plus:
htmlspecialchars() na wszystkich danych wyjściowychStruktura plików:
Wszystko z wariantu B, plus:
Sprawdzanie limitu miejsc:
<?phpfunction getRemainingSlots(array $data): int { $maxParticipants = $data['event']['max_participants']; $confirmed = array_filter( $data['registrations'], fn($r) => $r['status'] === 'confirmed' ); return $maxParticipants - count($confirmed);}
function canRegister(array $data): bool { return getRemainingSlots($data) > 0;}
// Użycie:$data = json_decode(file_get_contents('data/registrations.json'), true);
if (!canRegister($data)) { $errors[] = 'Brak wolnych miejsc. Możesz zapisać się na listę rezerwową.'; $status = 'waitlist';} else { $status = 'confirmed';}Walidacja zgód (checkbox):
<?phpfunction validateConsents(array $post): array { $errors = [];
// Zgoda na dane jest wymagana if (empty($post['consent_data'])) { $errors[] = 'Musisz wyrazić zgodę na przetwarzanie danych osobowych'; }
// Zgoda na zdjęcia jest opcjonalna - tylko zapisujemy wartość $consentPhoto = !empty($post['consent_photo']);
return $errors;}Sprawdzanie duplikatów:
<?phpfunction isDuplicate(string $email, array $registrations): bool { foreach ($registrations as $reg) { if (strtolower($reg['email']) === strtolower($email)) { return true; } } return false;}
// Użycie:if (isDuplicate($_POST['email'], $data['registrations'])) { $errors[] = 'Ten adres email jest już zarejestrowany';}Walidacja terminu zapisów:
<?phpfunction isRegistrationOpen(array $event): bool { $deadline = strtotime($event['registration_deadline']); $now = time(); return $now <= $deadline;}
// Użycie:if (!isRegistrationOpen($data['event'])) { $errors[] = 'Termin zapisów już minął';}JavaScript - walidacja formularza:
document.getElementById('registrationForm').addEventListener('submit', function(e) { const email = document.getElementById('email').value.trim(); const consentData = document.getElementById('consent_data').checked;
// Walidacja email const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { e.preventDefault(); alert('Podaj prawidłowy adres email'); return false; }
// Walidacja zgody if (!consentData) { e.preventDefault(); alert('Musisz wyrazić zgodę na przetwarzanie danych'); return false; }});
// Licznik pozostałych miejsc (AJAX)async function updateSlotsCounter() { const response = await fetch('api/slots.php'); const data = await response.json();
const counter = document.getElementById('slotsCounter'); counter.textContent = `Pozostało ${data.remaining} miejsc`;
if (data.remaining === 0) { counter.classList.add('no-slots'); document.getElementById('submitBtn').disabled = true; }}Eksport do HTML (wariant C):
<?phpfunction exportToHtml(array $registrations, array $event): string { $html = '<!DOCTYPE html><html><head>'; $html .= '<meta charset="UTF-8">'; $html .= '<title>Lista uczestników - ' . htmlspecialchars($event['name']) . '</title>'; $html .= '<style> table { border-collapse: collapse; width: 100%; } th, td { border: 1px solid #000; padding: 8px; text-align: left; } th { background-color: #f0f0f0; } </style>'; $html .= '</head><body>'; $html .= '<h1>' . htmlspecialchars($event['name']) . '</h1>'; $html .= '<p>Data: ' . $event['date'] . '</p>'; $html .= '<table><tr><th>Lp.</th><th>Imię</th><th>Nazwisko</th><th>Klasa</th><th>Email</th></tr>';
$i = 1; foreach ($registrations as $reg) { if ($reg['status'] === 'confirmed') { $html .= '<tr>'; $html .= '<td>' . $i++ . '</td>'; $html .= '<td>' . htmlspecialchars($reg['first_name']) . '</td>'; $html .= '<td>' . htmlspecialchars($reg['last_name']) . '</td>'; $html .= '<td>' . htmlspecialchars($reg['class']) . '</td>'; $html .= '<td>' . htmlspecialchars($reg['email']) . '</td>'; $html .= '</tr>'; } }
$html .= '</table></body></html>'; return $html;}To prawdziwy projekt zespołowy!
System zapisów to praktyczny projekt, który możecie od razu wykorzystać w szkole! Nauczycie się obsługi limitów i warunków biznesowych - umiejętności niezbędne w każdym systemie produkcyjnym.
Pracujcie iteracyjnie - lepiej mieć działający wariant A niż niedziałający C!