From 89525fa385db4b8a3dca43a7667b77c9a1db48c8 Mon Sep 17 00:00:00 2001 From: Michael Czechowski Date: Fri, 11 Jul 2025 12:06:56 +0200 Subject: [PATCH] Fix --- README.md | 1278 ++++++++++++++++++++++++++--------------------------- 1 file changed, 639 insertions(+), 639 deletions(-) diff --git a/README.md b/README.md index 5bd9c39..0caf72c 100644 --- a/README.md +++ b/README.md @@ -1,639 +1,639 @@ -# DHBW 2025: Web Engineering Prüfungsleistung -**Maximale Punktzahl: 100 Punkte** - ---- - -## 1. Grundanforderungen (25 Punkte) - -### Projektgrundlagen (15 Punkte) -- **Funktionsfähige Anwendung** (8 Punkte) - - Webapp oder Backend-Anwendung läuft fehlerfrei - - Kernfunktionalitäten sind in der Projektdokumentation beschrieben und testbar -- **Repository** (4 Punkte) - - GitHub/GitLab/CodeBerg Repository ist (öffentlich) zugänglich - - Commit-Historie zeigt kontinuierliche Entwicklung -- **Projektdokumentation** (3 Punkte) - - Aussagekräftiger Projekttitel und Beschreibung - - README.md mit Installation, Verwendung und Technologie-Stack - - Kurze Erklärung der Hauptfunktionen am Anfang relevanter Dateien - -### Präsentation (20 Punkte) -- **Elevator Pitch** (5 Punkte) - - Maximal 1 Minute - - Welches Problem wird gelöst und warum wurde es vorher noch nicht gelöst? - - Zielgruppe definiert -- **Technische Präsentation** (5 Punkte) - - PowerPoint/Folien mit Technologie-Stack - - Live-Demo der Anwendung -- **Projektevolution:** (5 Punkte) - Jedes Projekt verläuft unterschiedlich. - Sofern es zutrifft, beschreibt die unterschiedlichen Phasen des Projekts. - *Wie weit seid ihr gekommen? Wo waren die Stolpersteine? Wie könnte sich eure Anwendung bei fortgesetzter Arbeit entwickeln?* - - 0. (Paper) Prototype - 1. Make it work (PoC) - 2. Make it right (MvP) - 3. Make it fast (Production) - ---- - -## 2. Clean Code Prinzipien (35 Punkte) - -### Projektstruktur (10 Punkte) -- **Ordnerstruktur** (5 Punkte) - ``` - projekt/ - ├── src/ - │ ├── components/ # React Components / UI - │ ├── config/ # Konfigurationen, Hard-coded Strings etc. - │ ├── services/ # Separitiere für-sich-stehende Funktionen Klassen, Clients etc. - │ ├── utils/ # Hilfsfunktionen - │ ├── main.css # Haupteinstieg in CSS Klassen, Variablen, Imports etc. - │ ├── main.js # Die eigentliche Appliktion - │ └── index.js # Haupteinstieg in die gesamte Applikation - ├── public/ # Statische Assets, Ressourcen, Bilder etc. - ├── tests/ # Test-Dateien - ├── .gitignore - ├── package.json - └── README.md - ``` - - Logische Trennung von Funktionalitäten - - Konsistente Benennung - -- **Datei-Organisation** (5 Punkte) - - Ein Konzept pro Datei (Single Responsibility) - - Konsistente Namenskonventionen: `kebab-case` für Dateien, `camelCase` für Variablen, `PascalCase` für Komponenten/Klassen - -### Code-Qualität (15 Punkte) - -#### KISS Prinzip (5 Punkte) - -**❌ Nicht so einfach:** -```javascript -const processData = (d) => d.filter(x => x.status === 'active').map(x => ({...x, processed: true})).reduce((acc, curr) => acc + curr.value, 0); -``` - -**✅ Einfach:** -```javascript -function calculateActiveTotal(data) { - const activeItems = data.filter(item => item.status === 'active'); - const processedItems = activeItems.map(item => ({ - ...item, - processed: true - })); - return processedItems.reduce((total, item) => total + item.value, 0); -} -``` - -**❌ Nicht so einfach:** -```javascript -const u = users.find(u => u.id === id && u.active && !u.deleted) || null; -``` - -**✅ Einfach:** -```javascript -function findActiveUser(users, userId) { - return users.find(user => - user.id === userId && - user.active && - !user.deleted - ) || null; -} -``` - -#### Beschreibende Namen (5 Punkte) - -**❌ Schlecht:** -```javascript -let isActive = true; -let data = []; -function calc(x, y) { return x * y; } -``` - -**✅ Gut:** -```javascript -let isMenuVisible = true; -let userProfiles = []; -function calculateTotalPrice(price, taxRate) { return price * taxRate; } -``` - -**❌ Unklar und uneindeutig:** -```javascript -const btn = document.getElementById('btn'); -let flag = false; -function process(items) { /* ... */ } -``` - -**✅ Sprechende Variablennamen:** -```javascript -const submitButton = document.getElementById('submit-btn'); -let isFormValid = false; -function validateUserInput(formData) { /* ... */ } -``` - -#### Funktionsverantwortlichkeiten (5 Punkte) - -**❌ Zu viele Verantwortlichkeiten:** -```javascript -function handleUser(userData) { - // Validiert Daten - if (!userData.email) return false; - // Speichert in DB - database.save(userData); - // Sendet Email - sendWelcomeEmail(userData.email); - // Updated UI - updateUserList(); - return true; -} -``` - -**✅ Eine klare Verantwortlichkeit pro Funktion:** -```javascript -function validateUserData(userData) { - return userData.email && userData.name; -} - -function saveUser(userData) { - return database.save(userData); -} - -function sendWelcomeEmail(email) { - return emailService.send(email, 'welcome'); -} -``` - -### Kommentierung & Dokumentation (5 Punkte) -**JSDoc ist optional und der beste Code muss nicht kommentiert werden.** - -**❌ Über-/Unterkommentiert:** -```javascript -// Erhöht i um 1 -i++; -// Checked ob user existiert -if (user) { - // Macht irgendwas - doSomething(); -} -``` - -**✅ Sinnvoll kommentiert:** -```javascript -/** - * Handles user authentication and session management - * - * OR - * - * This file manages JWT tokens and user permissions - */ - -function calculateCompoundInterest(principal, rate, time) { - // Using compound interest formula: A = P(1 + r/n)^(nt) - return principal * Math.pow((1 + rate), time); -} -``` - -**❌ Unterkommentiert:** -```javascript -function x(a,b,c,d,e) { - return a*b+c-d/e; -} -``` - -**✅ Mit JSDoc dokumentiert:** -```javascript -/** - * Calculates shipping cost based on weight, distance and priority - * @param {number} weight - Package weight in kg - * @param {number} distance - Delivery distance in km - * @param {boolean} isPriority - Priority delivery flag - * @returns {number} Total shipping cost - */ -function calculateShippingCost(weight, distance, priority) { - const baseCost = weight * 2.5; - const distanceCost = distance * 0.1; - const priorityMultiplier = priority ? 1.5 : 1; - return (baseCost + distanceCost) * priorityMultiplier; -} -``` - -### Live-Demo (10 Punkte) -- **Fehlerfreie Demonstration** (10 Punkte) - - Anwendung läuft während der Präsentation stabil - - Alle Kernfunktionen werden erfolgreich vorgeführt - - Ungefähr 5 Minuten Demo-Zeit - ---- - -## 3. Accessibility & UX (25 Punkte) - -### Web Accessibility (15 Punkte) - -#### Semantisches HTML (5 Punkte) - -**❌ Nicht semantisch:** -```html -
- -
-
-
Welcome
-
Description...
-
-``` - -**✅ Semantisch korrekt:** -```html -
- -
-
-
-

Welcome

-

Description...

-
-
-``` - -#### ARIA Labels & Alt-Texte (5 Punkte) - -**❌ Schlecht:** -```html -chart - - -
We don't send spam
-``` - -**✅ Gut:** -```html -Verkaufszahlen 2024: 40% Steigerung gegenüber Vorjahr - - -
Wir versenden keine Spam-Mails
-``` - -#### Tastaturnavigation (5 Punkte) -- Alle interaktiven Elemente per Tab erreichbar -- Sichtbarer Focus-Indikator -- Logische Tab-Reihenfolge - -**❌ Nicht tastaturzugänglich:** -```html -
🍔
-``` - -```css -div.clickable { - cursor: pointer; -} -``` - -**✅ Tastaturzugänglich:** -```css -div.clickable:focus { - outline: 2px solid #007acc; -} -``` - -```html -
🍔
-``` - -### Responsive Design (10 Punkte) - -#### Mobile First Approach (5 Punkte - mindestens 1 Breakpoint) -```css -/* Mobile First */ -.container { - width: 100%; - padding: 1rem; -} - -/* Desktop */ -@media (min-width: 768px) { - .container { - max-width: 1200px; - margin: 0 auto; - padding: 2rem; - } -} -``` - -#### Flexbox/Grid Layout (5 Punkte) - -**❌ Veraltete Layouts:** -```css -.container { - float: left; - width: 33.33%; -} -.clearfix::after { - content: ""; - display: table; - clear: both; -} -``` - -**✅ Moderne Layouts:** -```css -.card-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 1.5rem; -} -.navigation { - display: flex; - justify-content: space-between; - align-items: center; -} -``` - ---- - -## 4. Erweiterte Technologien & Innovation (15 Punkte) - -### Plattformunabhängigkeit (5 Punkte) -- Funktioniert auf macOS, Windows, GNU/Linux -- Browser-Kompatibilität (Chrome, Firefox, Safari, Edge) - -**❌ Plattformspezifisch:** -```javascript -// Nur Chrome -navigator.clipboard.writeText(text); -``` - -**✅ Plattformunabhängig:** - -In aller Regel sind solche sog. Polyfills kaum noch eigenhändig zu implementieren. -Nichtsdestotrotz gilt es die Plattformunabhängig zu prüfen und ggf. Alternativen für die Implementierung zu finden wie im folgenden Beispiel für die Zwischenablage: - -```javascript -// Fallback für ältere Browser -function copyToClipboard(text) { - if (navigator.clipboard) { - return navigator.clipboard.writeText(text); - } else { - const textArea = document.createElement('textarea'); - textArea.value = text; - document.body.appendChild(textArea); - textArea.select(); - document.execCommand('copy'); - document.body.removeChild(textArea); - } -} -``` - -### Entwicklungs-Tools (10 Punkte) - -#### Package Management (4 Punkte) - -Sämtliche nodeJS/JavaScript Projekte sollten eine `package.json` beinhalten. -`npm init` und ein Dialog öffnet sich. - -```json -{ - "name": "my-project", - "scripts": { - "start": "vite", - "build": "vite build", - "test": "jest", - "lint": "eslint src/" - }, - "dependencies": { - "react": "^18.0.0" - }, - "devDependencies": { - "vite": "^4.0.0", - "jest": "^29.0.0" - } -} -``` - -#### Build Tools & Optimierung (6 Punkte) -- Vite, Webpack, oder ähnliche Tools -- Optimierte Produktions-Builds - - Debugger und unnötige console.log()'s entfernen - - Code-Splitting - - Nur Teile statt gesamte Bibliotheken importieren - - Bspw. PostCSS für Entfernung von überschüssigem CSS - -**❌ Entwicklungs-Build:** -```javascript -// Unminified, alle Dependencies geladen -import * as _ from 'lodash'; -// Debugging -console.log('Debug info:', data); -debugger; -``` - -**✅ Produktions-Build:** -```javascript -// Minified, nur benötigte Funktionen -import { debounce } from 'lodash'; - -// Debug-Code entfernt in Production -``` - -### Zusätzliche Features (Bonus: bis zu 10 Punkte) -**Wähle mindestens 2 Bereiche:** - -#### API Integration (5 Punkte) - -**❌ Ohne Error Handling:** -```javascript -async function getUser(id) { - const response = await fetch(`/api/users/${id}`); - return response.json(); -} -``` - -**✅ Mit Error Handling:** -```javascript -async function fetchUserData(userId) { - try { - const response = await fetch(`/api/users/${userId}`); - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - return await response.json(); - } catch (error) { - console.error('Fehler beim Laden der Benutzerdaten:', error); - throw new Error('Benutzerdaten konnten nicht geladen werden'); - } -} -``` - -#### Local Storage / State Management (5 Punkte) - -**❌ Ohne Error Handling:** -```javascript -function saveData(data) { - localStorage.setItem('data', JSON.stringify(data)); -} -function loadData() { - return JSON.parse(localStorage.getItem('data')); -} -``` - -**✅ Mit Error Handling:** -```javascript -function saveUserPreferences(prefs) { - try { - localStorage.setItem('userPrefs', JSON.stringify(prefs)); - return true; - } catch (error) { - console.warn('Local Storage nicht verfügbar:', error); - return false; - } -} - -function loadUserPreferences() { - try { - const data = localStorage.getItem('userPrefs'); - return data ? JSON.parse(data) : getDefaultPreferences(); - } catch (error) { - console.warn('Fehler beim Laden der Einstellungen:', error); - return getDefaultPreferences(); - } -} -``` - -#### Progressive Web App Features (5 Punkte) -- Service Worker für Offline-Funktionalität -- Manifest.json für App-Installation -- Caching-Strategien - -**❌ Ohne PWA:** -```html - -``` - -**✅ Mit PWA Features:** -```html - - - - -``` - -#### Testing (10 Punkte) - -Von Vornherein mitgedachte Tests helfen beim Code-Splitting. -Um beim Testen jene Funktionen eindeutig referenzieren zu können, hilft es sie in einzelne Dateien zu verteilen und Ordnern zu gruppieren. - -**❌ Ohne Tests:** -```javascript -// Keine Tests vorhanden -function calculateTotal(price, tax) { - return price + (price * tax); -} -``` - -**✅ Mit Tests:** -```javascript -// calculate.js -export function calculateTotal(price, tax) { - if (typeof price !== 'number' || typeof tax !== 'number') { - throw new Error('Price and tax must be numbers'); - } - return price + (price * tax); -} - -// calculate.test.js -import { calculateTotal } from './calculate.js'; - -test('calculateTotal should return correct sum', () => { - expect(calculateTotal(100, 0.19)).toBeCloseTo(119); -}); - -test('calculateTotal should throw error for invalid input', () => { - expect(() => calculateTotal('100', 0.19)).toThrow(); -}); -``` - -#### Responsive Design Erweitert (5 Punkte - 2 oder mehr Breakpoints) -```css -/* Mobile */ -.grid { display: block; } - -/* Tablet */ -@media (min-width: 768px) { - .grid { - display: grid; - grid-template-columns: 1fr 1fr; - } -} - -/* Desktop */ -@media (min-width: 1024px) { - .grid { - grid-template-columns: repeat(3, 1fr); - } -} - -/* Large Desktop */ -@media (min-width: 1440px) { - .grid { - grid-template-columns: repeat(4, 1fr); - } -} -``` - -#### Security Features (5 Punkte) - -**❌ Unsicher:** -```javascript -// XSS anfällig -element.innerHTML = userInput; -// Unvalidierte Eingabe -function search(query) { - return database.query(`SELECT * FROM users WHERE name = '${query}'`); -} -``` - -**✅ Sicher:** -```javascript -// XSS-sicher durch HTML-Escaping -function escapeHtml(text) { - const div = document.createElement('div'); - div.textContent = text; - return div.innerHTML; -} -element.innerHTML = escapeHtml(userInput); - -// SQL-Injection sicher -function search(query) { - const sanitizedQuery = query.replace(/[^\w\s]/gi, ''); - return database.query('SELECT * FROM users WHERE name = ?', [sanitizedQuery]); -} -``` - ---- - -## Abgabe - -- **Deadline:** 20.07.2025 -- **Format:** GitHub/GitLab Repository Link + Live-Demo URL (falls gehostet) -- **Präsentation:** 11.07.2025 - 10-15 Minuten pro Gruppe + ~5 Minuten Demo - -## Tipps - -1. **Beginnt früh** mit der Eingrenzung des Funktionsumfangs -2. **Testet eure Anwendung** auf verschiedenen Geräten, Betriebssystemen und Browsern -3. **Fragt bei Unklarheiten** rechtzeitig nach -4. **Fokussiert euch** auf Qualität statt Quantität -5. **Behaltet Barrieren im Blick** und vermeidet sie rechtzeitig -5. **Verwendet gute Struktur** um eure Code-Beispiele zu organisieren +# DHBW 2025: Web Engineering Prüfungsleistung +**Maximale Punktzahl: 100 Punkte** + +--- + +## 1. Grundanforderungen (25 Punkte) + +### Projektgrundlagen (15 Punkte) +- **Funktionsfähige Anwendung** (8 Punkte) + - Webapp oder Backend-Anwendung läuft fehlerfrei + - Kernfunktionalitäten sind in der Projektdokumentation beschrieben und testbar +- **Repository** (4 Punkte) + - GitHub/GitLab/CodeBerg Repository ist (öffentlich) zugänglich + - Commit-Historie zeigt kontinuierliche Entwicklung +- **Projektdokumentation** (3 Punkte) + - Aussagekräftiger Projekttitel und Beschreibung + - README.md mit Installation, Verwendung und Technologie-Stack + - Kurze Erklärung der Hauptfunktionen am Anfang relevanter Dateien + +### Präsentation (20 Punkte) +- **Elevator Pitch** (5 Punkte) + - Maximal 1 Minute + - Welches Problem wird gelöst und warum wurde es vorher noch nicht gelöst? + - Zielgruppe definiert +- **Technische Präsentation** (5 Punkte) + - PowerPoint/Folien mit Technologie-Stack + - Live-Demo der Anwendung +- **Projektevolution:** (5 Punkte) + Jedes Projekt verläuft unterschiedlich. + Sofern es zutrifft, beschreibt die unterschiedlichen Phasen des Projekts. + *Wie weit seid ihr gekommen? Wo waren die Stolpersteine? Wie könnte sich eure Anwendung bei fortgesetzter Arbeit entwickeln?* + + 0. (Paper) Prototype + 1. Make it work (PoC) + 2. Make it right (MvP) + 3. Make it fast (Production) + +--- + +## 2. Clean Code Prinzipien (35 Punkte) + +### Projektstruktur (10 Punkte) +- **Ordnerstruktur** (5 Punkte) + ``` + projekt/ + ├── src/ + │ ├── components/ # React Components / UI + │ ├── config/ # Konfigurationen, Hard-coded Strings etc. + │ ├── services/ # Separitiere für-sich-stehende Funktionen Klassen, Clients etc. + │ ├── utils/ # Hilfsfunktionen + │ ├── main.css # Haupteinstieg in CSS Klassen, Variablen, Imports etc. + │ ├── main.js # Die eigentliche Appliktion + │ └── index.js # Haupteinstieg in die gesamte Applikation + ├── public/ # Statische Assets, Ressourcen, Bilder etc. + ├── tests/ # Test-Dateien + ├── .gitignore + ├── package.json + └── README.md + ``` + - Logische Trennung von Funktionalitäten + - Konsistente Benennung + +- **Datei-Organisation** (5 Punkte) + - Ein Konzept pro Datei (Single Responsibility) + - Konsistente Namenskonventionen: `kebab-case` für Dateien, `camelCase` für Variablen, `PascalCase` für Komponenten/Klassen + +### Code-Qualität (15 Punkte) + +#### KISS Prinzip (5 Punkte) + +**❌ Nicht so einfach:** +```javascript +const processData = (d) => d.filter(x => x.status === 'active').map(x => ({...x, processed: true})).reduce((acc, curr) => acc + curr.value, 0); +``` + +**✅ Einfach:** +```javascript +function calculateActiveTotal(data) { + const activeItems = data.filter(item => item.status === 'active'); + const processedItems = activeItems.map(item => ({ + ...item, + processed: true + })); + return processedItems.reduce((total, item) => total + item.value, 0); +} +``` + +**❌ Nicht so einfach:** +```javascript +const u = users.find(u => u.id === id && u.active && !u.deleted) || null; +``` + +**✅ Einfach:** +```javascript +function findActiveUser(users, userId) { + return users.find(user => + user.id === userId && + user.active && + !user.deleted + ) || null; +} +``` + +#### Beschreibende Namen (5 Punkte) + +**❌ Schlecht:** +```javascript +let isActive = true; +let data = []; +function calc(x, y) { return x * y; } +``` + +**✅ Gut:** +```javascript +let isMenuVisible = true; +let userProfiles = []; +function calculateTotalPrice(price, taxRate) { return price * taxRate; } +``` + +**❌ Unklar und uneindeutig:** +```javascript +const btn = document.getElementById('btn'); +let flag = false; +function process(items) { /* ... */ } +``` + +**✅ Sprechende Variablennamen:** +```javascript +const submitButton = document.getElementById('submit-btn'); +let isFormValid = false; +function validateUserInput(formData) { /* ... */ } +``` + +#### Funktionsverantwortlichkeiten (5 Punkte) + +**❌ Zu viele Verantwortlichkeiten:** +```javascript +function handleUser(userData) { + // Validiert Daten + if (!userData.email) return false; + // Speichert in DB + database.save(userData); + // Sendet Email + sendWelcomeEmail(userData.email); + // Updated UI + updateUserList(); + return true; +} +``` + +**✅ Eine klare Verantwortlichkeit pro Funktion:** +```javascript +function validateUserData(userData) { + return userData.email && userData.name; +} + +function saveUser(userData) { + return database.save(userData); +} + +function sendWelcomeEmail(email) { + return emailService.send(email, 'welcome'); +} +``` + +### Kommentierung & Dokumentation (5 Punkte) +**JSDoc ist optional und der beste Code muss nicht kommentiert werden.** + +**❌ Über-/Unterkommentiert:** +```javascript +// Erhöht i um 1 +i++; +// Checked ob user existiert +if (user) { + // Macht irgendwas + doSomething(); +} +``` + +**✅ Sinnvoll kommentiert:** +```javascript +/** + * Handles user authentication and session management + * + * OR + * + * This file manages JWT tokens and user permissions + */ + +function calculateCompoundInterest(principal, rate, time) { + // Using compound interest formula: A = P(1 + r/n)^(nt) + return principal * Math.pow((1 + rate), time); +} +``` + +**❌ Unterkommentiert:** +```javascript +function x(a,b,c,d,e) { + return a*b+c-d/e; +} +``` + +**✅ Mit JSDoc dokumentiert:** +```javascript +/** + * Calculates shipping cost based on weight, distance and priority + * @param {number} weight - Package weight in kg + * @param {number} distance - Delivery distance in km + * @param {boolean} isPriority - Priority delivery flag + * @returns {number} Total shipping cost + */ +function calculateShippingCost(weight, distance, priority) { + const baseCost = weight * 2.5; + const distanceCost = distance * 0.1; + const priorityMultiplier = priority ? 1.5 : 1; + return (baseCost + distanceCost) * priorityMultiplier; +} +``` + +### Live-Demo (10 Punkte) +- **Fehlerfreie Demonstration** (10 Punkte) + - Anwendung läuft während der Präsentation stabil + - Alle Kernfunktionen werden erfolgreich vorgeführt + - Ungefähr 5 Minuten Demo-Zeit + +--- + +## 3. Accessibility & UX (25 Punkte) + +### Web Accessibility (15 Punkte) + +#### Semantisches HTML (5 Punkte) + +**❌ Nicht semantisch:** +```html +
+ +
+
+
Welcome
+
Description...
+
+``` + +**✅ Semantisch korrekt:** +```html +
+ +
+
+
+

Welcome

+

Description...

+
+
+``` + +#### ARIA Labels & Alt-Texte (5 Punkte) + +**❌ Schlecht:** +```html +chart + + +
We don't send spam
+``` + +**✅ Gut:** +```html +Verkaufszahlen 2024: 40% Steigerung gegenüber Vorjahr + + +
Wir versenden keine Spam-Mails
+``` + +#### Tastaturnavigation (5 Punkte) +- Alle interaktiven Elemente per Tab erreichbar +- Sichtbarer Focus-Indikator +- Logische Tab-Reihenfolge + +**❌ Nicht tastaturzugänglich:** +```html +
🍔
+``` + +```css +div.clickable { + cursor: pointer; +} +``` + +**✅ Tastaturzugänglich:** +```css +div.clickable:focus { + outline: 2px solid #007acc; +} +``` + +```html +
🍔
+``` + +### Responsive Design (10 Punkte) + +#### Mobile First Approach (5 Punkte - mindestens 1 Breakpoint) +```css +/* Mobile First */ +.container { + width: 100%; + padding: 1rem; +} + +/* Desktop */ +@media (min-width: 768px) { + .container { + max-width: 1200px; + margin: 0 auto; + padding: 2rem; + } +} +``` + +#### Flexbox/Grid Layout (5 Punkte) + +**❌ Veraltete Layouts:** +```css +.container { + float: left; + width: 33.33%; +} +.clearfix::after { + content: ""; + display: table; + clear: both; +} +``` + +**✅ Moderne Layouts:** +```css +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 1.5rem; +} +.navigation { + display: flex; + justify-content: space-between; + align-items: center; +} +``` + +--- + +## 4. Erweiterte Technologien & Innovation (15 Punkte) + +### Plattformunabhängigkeit (5 Punkte) +- Funktioniert auf macOS, Windows, GNU/Linux +- Browser-Kompatibilität (Chrome, Firefox, Safari, Edge) + +**❌ Plattformspezifisch:** +```javascript +// Nur Chrome +navigator.clipboard.writeText(text); +``` + +**✅ Plattformunabhängig:** + +In aller Regel sind solche sog. Polyfills kaum noch eigenhändig zu implementieren. +Nichtsdestotrotz gilt es die Plattformunabhängig zu prüfen und ggf. Alternativen für die Implementierung zu finden wie im folgenden Beispiel für die Zwischenablage: + +```javascript +// Fallback für ältere Browser +function copyToClipboard(text) { + if (navigator.clipboard) { + return navigator.clipboard.writeText(text); + } else { + const textArea = document.createElement('textarea'); + textArea.value = text; + document.body.appendChild(textArea); + textArea.select(); + document.execCommand('copy'); + document.body.removeChild(textArea); + } +} +``` + +### Entwicklungs-Tools (10 Punkte) + +#### Package Management (4 Punkte) + +Sämtliche nodeJS/JavaScript Projekte sollten eine `package.json` beinhalten. +`npm init` und ein Dialog öffnet sich. + +```json +{ + "name": "my-project", + "scripts": { + "start": "vite", + "build": "vite build", + "test": "jest", + "lint": "eslint src/" + }, + "dependencies": { + "react": "^18.0.0" + }, + "devDependencies": { + "vite": "^4.0.0", + "jest": "^29.0.0" + } +} +``` + +#### Build Tools & Optimierung (6 Punkte) +- Vite, Webpack, oder ähnliche Tools +- Optimierte Produktions-Builds + - Debugger und unnötige console.log()'s entfernen + - Code-Splitting + - Nur Teile statt gesamte Bibliotheken importieren + - Bspw. PostCSS für Entfernung von überschüssigem CSS + +**❌ Entwicklungs-Build:** +```javascript +// Unminified, alle Dependencies geladen +import * as _ from 'lodash'; +// Debugging +console.log('Debug info:', data); +debugger; +``` + +**✅ Produktions-Build:** +```javascript +// Minified, nur benötigte Funktionen +import { debounce } from 'lodash'; + +// Debug-Code entfernt in Production +``` + +### Zusätzliche Features (Bonus: bis zu 10 Punkte) +**Wähle mindestens 2 Bereiche:** + +#### API Integration (5 Punkte) + +**❌ Ohne Error Handling:** +```javascript +async function getUser(id) { + const response = await fetch(`/api/users/${id}`); + return response.json(); +} +``` + +**✅ Mit Error Handling:** +```javascript +async function fetchUserData(userId) { + try { + const response = await fetch(`/api/users/${userId}`); + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + return await response.json(); + } catch (error) { + console.error('Fehler beim Laden der Benutzerdaten:', error); + throw new Error('Benutzerdaten konnten nicht geladen werden'); + } +} +``` + +#### Local Storage / State Management (5 Punkte) + +**❌ Ohne Error Handling:** +```javascript +function saveData(data) { + localStorage.setItem('data', JSON.stringify(data)); +} +function loadData() { + return JSON.parse(localStorage.getItem('data')); +} +``` + +**✅ Mit Error Handling:** +```javascript +function saveUserPreferences(prefs) { + try { + localStorage.setItem('userPrefs', JSON.stringify(prefs)); + return true; + } catch (error) { + console.warn('Local Storage nicht verfügbar:', error); + return false; + } +} + +function loadUserPreferences() { + try { + const data = localStorage.getItem('userPrefs'); + return data ? JSON.parse(data) : getDefaultPreferences(); + } catch (error) { + console.warn('Fehler beim Laden der Einstellungen:', error); + return getDefaultPreferences(); + } +} +``` + +#### Progressive Web App Features (5 Punkte) +- Service Worker für Offline-Funktionalität +- Manifest.json für App-Installation +- Caching-Strategien + +**❌ Ohne PWA:** +```html + +``` + +**✅ Mit PWA Features:** +```html + + + + +``` + +#### Testing (10 Punkte) + +Von Vornherein mitgedachte Tests helfen beim Code-Splitting. +Um beim Testen jene Funktionen eindeutig referenzieren zu können, hilft es sie in einzelne Dateien zu verteilen und Ordnern zu gruppieren. + +**❌ Ohne Tests:** +```javascript +// Keine Tests vorhanden +function calculateTotal(price, tax) { + return price + (price * tax); +} +``` + +**✅ Mit Tests:** +```javascript +// calculate.js +export function calculateTotal(price, tax) { + if (typeof price !== 'number' || typeof tax !== 'number') { + throw new Error('Price and tax must be numbers'); + } + return price + (price * tax); +} + +// calculate.test.js +import { calculateTotal } from './calculate.js'; + +test('calculateTotal should return correct sum', () => { + expect(calculateTotal(100, 0.19)).toBeCloseTo(119); +}); + +test('calculateTotal should throw error for invalid input', () => { + expect(() => calculateTotal('100', 0.19)).toThrow(); +}); +``` + +#### Responsive Design Erweitert (5 Punkte - 2 oder mehr Breakpoints) +```css +/* Mobile */ +.grid { display: block; } + +/* Tablet */ +@media (min-width: 768px) { + .grid { + display: grid; + grid-template-columns: 1fr 1fr; + } +} + +/* Desktop */ +@media (min-width: 1024px) { + .grid { + grid-template-columns: repeat(3, 1fr); + } +} + +/* Large Desktop */ +@media (min-width: 1440px) { + .grid { + grid-template-columns: repeat(4, 1fr); + } +} +``` + +#### Security Features (5 Punkte) + +**❌ Unsicher:** +```javascript +// XSS anfällig +element.innerHTML = userInput; +// Unvalidierte Eingabe +function search(query) { + return database.query(`SELECT * FROM users WHERE name = '${query}'`); +} +``` + +**✅ Sicher:** +```javascript +// XSS-sicher durch HTML-Escaping +function escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; +} +element.innerHTML = escapeHtml(userInput); + +// SQL-Injection sicher +function search(query) { + const sanitizedQuery = query.replace(/[^\w\s]/gi, ''); + return database.query('SELECT * FROM users WHERE name = ?', [sanitizedQuery]); +} +``` + +--- + +## Abgabe + +- **Deadline:** 27.07.2025 +- **Format:** GitHub/GitLab Repository Link + Live-Demo URL (falls gehostet) +- **Präsentation:** 18.07.2025 - 10-15 Minuten pro Gruppe + ~5 Minuten Demo + +## Tipps + +1. **Beginnt früh** mit der Eingrenzung des Funktionsumfangs +2. **Testet eure Anwendung** auf verschiedenen Geräten, Betriebssystemen und Browsern +3. **Fragt bei Unklarheiten** rechtzeitig nach +4. **Fokussiert euch** auf Qualität statt Quantität +5. **Behaltet Barrieren im Blick** und vermeidet sie rechtzeitig +5. **Verwendet gute Struktur** um eure Code-Beispiele zu organisieren