diff --git a/web/07/labor/loesungen/uebung02/book.go b/web/07/labor/loesungen/uebung02/book.go
new file mode 100644
index 0000000..f72036b
--- /dev/null
+++ b/web/07/labor/loesungen/uebung02/book.go
@@ -0,0 +1,48 @@
+package main
+
+import (
+ "encoding/json"
+ "os"
+)
+
+type Book struct {
+ ID int `json:"id"`
+ Title string `json:"title"`
+ Author string `json:"author"`
+ Read bool `json:"read"`
+}
+
+type Library struct {
+ Books []Book `json:"books"`
+}
+
+func (lib *Library) Add(title, author string) {
+ id := len(lib.Books) + 1
+ lib.Books = append(lib.Books, Book{ID: id, Title: title, Author: author, Read: false})
+}
+
+func (lib *Library) MarkRead(id int) {
+ for i := range lib.Books {
+ if lib.Books[i].ID == id {
+ lib.Books[i].Read = true
+ }
+ }
+}
+
+func (lib *Library) Save(filename string) error {
+ data, err := json.MarshalIndent(lib, "", " ")
+ if err != nil {
+ return err
+ }
+ return os.WriteFile(filename, data, 0644)
+}
+
+func LoadLibrary(filename string) (*Library, error) {
+ data, err := os.ReadFile(filename)
+ if err != nil {
+ return &Library{}, nil
+ }
+ var lib Library
+ err = json.Unmarshal(data, &lib)
+ return &lib, err
+}
diff --git a/web/07/labor/loesungen/uebung02/books.json b/web/07/labor/loesungen/uebung02/books.json
new file mode 100644
index 0000000..882dda5
--- /dev/null
+++ b/web/07/labor/loesungen/uebung02/books.json
@@ -0,0 +1,16 @@
+{
+ "books": [
+ {
+ "id": 1,
+ "title": "Der Steppenwolf",
+ "author": "Hermann Hesse",
+ "read": false
+ },
+ {
+ "id": 2,
+ "title": "Clean Code",
+ "author": "Robert C. Martin",
+ "read": true
+ }
+ ]
+}
\ No newline at end of file
diff --git a/web/07/labor/loesungen/uebung02/main.go b/web/07/labor/loesungen/uebung02/main.go
new file mode 100644
index 0000000..b4ad205
--- /dev/null
+++ b/web/07/labor/loesungen/uebung02/main.go
@@ -0,0 +1,50 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "strconv"
+)
+
+func main() {
+ if len(os.Args) < 2 {
+ fmt.Println("Usage: add
| list | read ")
+ return
+ }
+
+ lib, _ := LoadLibrary("books.json")
+
+ switch os.Args[1] {
+ case "add":
+ if len(os.Args) < 4 {
+ fmt.Println("Usage: add ")
+ return
+ }
+ lib.Add(os.Args[2], os.Args[3])
+ lib.Save("books.json")
+ fmt.Println("Buch hinzugefügt.")
+
+ case "list":
+ for _, b := range lib.Books {
+ status := " "
+ if b.Read {
+ status = "✓"
+ }
+ fmt.Printf("[%s] %d: \"%s\" by %s\n", status, b.ID, b.Title, b.Author)
+ }
+
+ case "read":
+ if len(os.Args) < 3 {
+ fmt.Println("Geben Sie eine Buch-ID ein.")
+ return
+ }
+ id, err := strconv.Atoi(os.Args[2])
+ if err != nil {
+ fmt.Println("Ungültige ID-Eingabe.")
+ return
+ }
+ lib.MarkRead(id)
+ lib.Save("books.json")
+ fmt.Println("Buch als gelesen markiert.")
+ }
+}
diff --git a/web/07/labor/loesungen/uebung03.go b/web/07/labor/loesungen/uebung03.go
new file mode 100644
index 0000000..e484ebf
--- /dev/null
+++ b/web/07/labor/loesungen/uebung03.go
@@ -0,0 +1,92 @@
+package main
+
+import (
+ "errors"
+ "fmt"
+ "log"
+ "net/http"
+)
+
+type workshopHandler int
+
+func parseCheckboxValue(value string) string {
+ if value == "" || (value != "ja" && value != "on") {
+ return "nein"
+ }
+ return "ja"
+}
+
+func parseRadiobuttonValue(value string) (string, error) {
+ if value == "" || (value != "praesenz" && value != "online") {
+ return "", errors.New("Auswahl nicht erlaubt.")
+ }
+ return value, nil
+}
+
+func (worksh workshopHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+
+ if r.Method != http.MethodPost {
+ http.Error(w, "Nur POST-Anfragen erlaubt", http.StatusMethodNotAllowed)
+ return
+ }
+
+ // Formulardaten parsen und Überprüfen, ob ungültige Formulardaten gesendet wurde
+ if err := r.ParseForm(); err != nil {
+ http.Error(w, "Fehler beim Parsen des Formulars", http.StatusBadRequest)
+ return
+ }
+
+ // Überprüfen, ob leeres Formular gesendet wurde
+ if len(r.PostForm) == 0 {
+ http.Error(w, "Kein Formular gesendet", http.StatusBadRequest)
+ return
+ }
+
+ // Formulardaten auslesen und ggf. überprüfen
+ vorname := r.PostForm.Get("vorname")
+ if vorname == "" {
+ http.Error(w, "Pflichtfeld fehlt.", http.StatusBadRequest)
+ return
+ }
+ nachname := r.PostForm.Get("nachname")
+ if nachname == "" {
+ http.Error(w, "Pflichtfeld fehlt.", http.StatusBadRequest)
+ return
+ }
+ email := r.PostForm.Get("email")
+ telefon := r.PostForm.Get("telefon")
+ sessions := r.PostForm["sessions"]
+ agb := parseCheckboxValue(r.PostForm.Get("agb"))
+ if agb == "nein" {
+ http.Error(w, "AGB wurde nicht akzeptiert.", http.StatusBadRequest)
+ return
+ }
+ newsletter := parseCheckboxValue(r.PostForm.Get("newsletter"))
+ equipment := parseCheckboxValue(r.PostForm.Get("equipment"))
+ format, err := parseRadiobuttonValue(r.PostForm.Get("format"))
+ if err != nil {
+ http.Error(w, "Ungültige Auswahl des Formats.", http.StatusBadRequest)
+ return
+ }
+
+ // Ausgabe im Terminal
+ fmt.Fprintf(w, "Neue Registrierung erhalten:\n")
+ fmt.Fprintf(w, "Vorname: %s\n", vorname)
+ fmt.Fprintf(w, "Nachname: %s\n", nachname)
+ fmt.Fprintf(w, "E-Mail: %s\n", email)
+ fmt.Fprintf(w, "Telefon: %s\n", telefon)
+ fmt.Fprintf(w, "Bevorzugte Sessions: \n")
+ for _, session := range sessions {
+ fmt.Fprintf(w, " - %s\n", session)
+ }
+ fmt.Fprintf(w, "AGB: %s\n", agb)
+ fmt.Fprintf(w, "Newsletter: %s\n", newsletter)
+ fmt.Fprintf(w, "Equipment benötigt: %s\n", equipment)
+ fmt.Fprintf(w, "Teilnahmeformat: %s", format)
+}
+
+func main() {
+ var workshop workshopHandler
+ fmt.Println("Server läuft auf localhost:8080...")
+ log.Fatal(http.ListenAndServe(":8080", workshop))
+}
diff --git a/web/07/labor/loesungen/workshop-anmeldung.html b/web/07/labor/loesungen/workshop-anmeldung.html
new file mode 100644
index 0000000..1d2b32e
--- /dev/null
+++ b/web/07/labor/loesungen/workshop-anmeldung.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+ Workshop-Anmeldung
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/07/labor/loesungen/workshop-api.json b/web/07/labor/loesungen/workshop-api.json
new file mode 100644
index 0000000..193a7c0
--- /dev/null
+++ b/web/07/labor/loesungen/workshop-api.json
@@ -0,0 +1,119 @@
+{
+ "openapi": "3.0.0",
+ "info": {
+ "title": "Workshop API",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "http://localhost:8080"
+ }
+ ],
+ "paths": {
+ "/registrierung": {
+ "post": {
+ "summary": "Sends all information needed for registering at a workshop",
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {
+ "$ref": "#/components/schemas/RegistrierungForm"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RegistrierungForm"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Success",
+ "content": {
+ "text/html": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "text/plain": {
+ "schema": {
+ "type": "string",
+ "example": "Kein Formular gesendet"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "RegistrierungForm": {
+ "type": "object",
+ "required": [
+ "vorname",
+ "nachname",
+ "agb",
+ "format"
+ ],
+ "properties": {
+ "vorname": {
+ "type": "string",
+ "example": "Zoya"
+ },
+ "nachname": {
+ "type": "string",
+ "example": "Akhtar"
+ },
+ "email": {
+ "type": "string",
+ "example": "z.akhtar@test.de"
+ },
+ "telefon": {
+ "type": "string",
+ "example": "Zoya"
+ },
+ "sessions": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "example": "vormittag"
+ },
+ "example": [
+ "vormittag",
+ "nachmittag"
+ ]
+ },
+ "agb": {
+ "type": "string",
+ "enum": ["on","ja"],
+ "example": "on"
+ },
+ "newsletter": {
+ "type": "string",
+ "enum": ["on","ja"],
+ "example": "ja"
+ },
+ "equipment": {
+ "type": "string",
+ "enum": ["on","ja"],
+ "example": "ja"
+ },
+ "format": {
+ "type": "string",
+ "enum": ["online","praesenz"],
+ "example": "online"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file