Compare commits
	
		
			12 Commits
		
	
	
		
			fdf68adb0d
			...
			startseite
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 324a1c54d6 | |||
| 15675d5e6c | |||
| 8ae3019b9c | |||
| b13eba8008 | |||
| da77201a93 | |||
| 9acc6711fc | |||
| f570950425 | |||
| 5749739761 | |||
| 1bcfbfd325 | |||
| fcb509c9fe | |||
| 1c39b1e471 | |||
| 71bf8978ac | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| create_tables.sql | ||||
							
								
								
									
										52
									
								
								db.go
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								db.go
									
									
									
									
									
								
							| @@ -1,52 +0,0 @@ | ||||
| package sicherheitsunterweisung | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"database/sql" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/go-sql-driver/mysql" | ||||
| 	"golang.org/x/term" | ||||
| ) | ||||
|  | ||||
| func getCredentials() (string, string, error) { | ||||
| 	fmt.Printf("DB Benutzer: ") | ||||
| 	user, err := bufio.NewReader(os.Stdin).ReadString('\n') | ||||
| 	if err != nil { | ||||
| 		return "", "", fmt.Errorf("getCredentials: bufio.NewReader(os.Stdin).ReadString('\n'): %v", err) | ||||
| 	} | ||||
|  | ||||
| 	fmt.Printf("DB Passwort: ") | ||||
| 	bytePass, err := term.ReadPassword(int(syscall.Stdin)) | ||||
| 	if err != nil { | ||||
| 		return "", "", fmt.Errorf("getCredentials: term.ReadPassword(int(syscall.Stdin)): %v", err) | ||||
| 	} | ||||
| 	fmt.Println() | ||||
| 	pass := string(bytePass) | ||||
|  | ||||
| 	return strings.TrimSpace(user), strings.TrimSpace(pass), nil | ||||
| } | ||||
|  | ||||
| func OpenDB(dbName string) (*sql.DB, error) { | ||||
| 	var err error | ||||
|  | ||||
| 	cfg := mysql.NewConfig() | ||||
| 	cfg.DBName = dbName | ||||
| 	cfg.User, cfg.Passwd, err = getCredentials() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("OpenDB: getCredentials(): %v\n", err) | ||||
| 	} | ||||
|  | ||||
| 	db, err := sql.Open("mysql", cfg.FormatDSN()) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("newDB: sql.Open(\"mysql\", cfg.FormatDSN()): %v\n", err) | ||||
| 	} | ||||
| 	if err := db.Ping(); err != nil { | ||||
| 		return nil, fmt.Errorf("newDB: db.Ping(): %v\n", err) | ||||
| 	} | ||||
|  | ||||
| 	return db, nil | ||||
| } | ||||
							
								
								
									
										64
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								main.go
									
									
									
									
									
								
							| @@ -1,73 +1,29 @@ | ||||
| package sicherheitsunterweisung | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"html/template" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"streifling.com/jason/sicherheitsunterweisung/packages/db" | ||||
| 	"streifling.com/jason/sicherheitsunterweisung/packages/server" | ||||
| ) | ||||
|  | ||||
| type Person struct { | ||||
| 	FirstName string | ||||
| 	LastName  string | ||||
| } | ||||
|  | ||||
| type Instructor Person | ||||
|  | ||||
| type Participant struct { | ||||
| 	ID int64 | ||||
| 	Person | ||||
| 	Company string | ||||
| } | ||||
|  | ||||
| type Briefing struct { | ||||
| 	Instructor | ||||
| 	Date         string | ||||
| 	Time         string | ||||
| 	State        string | ||||
| 	Location     string | ||||
| 	Participants []Participant | ||||
| } | ||||
|  | ||||
| func main() { | ||||
| 	var i, j int64 | ||||
| 	var b Briefing | ||||
|  | ||||
| 	i, j = 1, 1 | ||||
| 	mux := http.NewServeMux() | ||||
|  | ||||
| 	db, err := OpenDB("sicherheitsunterweisung") | ||||
| 	db, err := db.Open("sicherheitsunterweisung") | ||||
| 	if err != nil { | ||||
| 		log.Fatalln(err) | ||||
| 	} | ||||
|  | ||||
| 	mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static/")))) | ||||
| 	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		template.Must(template.ParseFiles("templates/index.html")).Execute(w, i) | ||||
| 	}) | ||||
| 	mux.HandleFunc("/add-participant/", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		i++ | ||||
| 		template.Must(template.ParseFiles("templates/index.html", "templates/participant.html")).ExecuteTemplate(w, "participant", i) | ||||
| 	}) | ||||
| 	mux.HandleFunc("/submit/", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		b.Instructor.FirstName = r.PostFormValue("instructor-first") | ||||
| 		b.Instructor.LastName = r.PostFormValue("instructor-last") | ||||
| 		b.Date = r.PostFormValue("date") | ||||
| 		b.Time = r.PostFormValue("time") | ||||
| 		b.State = r.PostFormValue("state") | ||||
| 		b.Location = r.PostFormValue("location") | ||||
|  | ||||
| 		for ; j <= i; j++ { | ||||
| 			b.Participants = append(b.Participants, Participant{ | ||||
| 				ID: j, | ||||
| 				Person: Person{ | ||||
| 					FirstName: r.PostFormValue("participant-first-" + fmt.Sprint(j)), | ||||
| 					LastName:  r.PostFormValue(("participant-last-" + fmt.Sprint(j))), | ||||
| 				}, | ||||
| 				Company: r.PostFormValue(("participant-company-" + fmt.Sprint(j))), | ||||
| 			}) | ||||
| 		} | ||||
| 	}) | ||||
| 	mux.HandleFunc("/", server.DisplayTable(db)) | ||||
| 	mux.HandleFunc("/submit/", server.SubmitForm(db, &i, &j)) | ||||
| 	mux.HandleFunc("/search/", server.DisplayResults(db)) | ||||
| 	mux.HandleFunc("/new-briefing/", server.DisplayForm(&i)) | ||||
| 	mux.HandleFunc("/add-participant/", server.AddParticipant(&i)) | ||||
|  | ||||
| 	log.Fatalln(http.ListenAndServe(":8080", mux)) | ||||
| } | ||||
|   | ||||
							
								
								
									
										149
									
								
								packages/db/db.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								packages/db/db.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | ||||
| package db | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"database/sql" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"streifling.com/jason/sicherheitsunterweisung/packages/types" | ||||
|  | ||||
| 	"github.com/go-sql-driver/mysql" | ||||
| 	"golang.org/x/term" | ||||
| ) | ||||
|  | ||||
| type DB struct { | ||||
| 	*sql.DB | ||||
| 	Name string | ||||
| } | ||||
|  | ||||
| func getCredentials() (string, string, error) { | ||||
| 	fmt.Printf("DB Benutzer: ") | ||||
| 	user, err := bufio.NewReader(os.Stdin).ReadString('\n') | ||||
| 	if err != nil { | ||||
| 		return "", "", fmt.Errorf("getCredentials: bufio.NewReader(os.Stdin).ReadString('\n'): %v", err) | ||||
| 	} | ||||
|  | ||||
| 	fmt.Printf("DB Passwort: ") | ||||
| 	bytePass, err := term.ReadPassword(int(syscall.Stdin)) | ||||
| 	if err != nil { | ||||
| 		return "", "", fmt.Errorf("getCredentials: term.ReadPassword(int(syscall.Stdin)): %v", err) | ||||
| 	} | ||||
| 	fmt.Println() | ||||
| 	pass := string(bytePass) | ||||
|  | ||||
| 	return strings.TrimSpace(user), strings.TrimSpace(pass), nil | ||||
| } | ||||
|  | ||||
| func Open(dbName string) (*DB, error) { | ||||
| 	var err error | ||||
| 	db := new(DB) | ||||
|  | ||||
| 	cfg := mysql.NewConfig() | ||||
| 	cfg.DBName = dbName | ||||
| 	cfg.User, cfg.Passwd, err = getCredentials() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("Open: getCredentials(): %v\n", err) | ||||
| 	} | ||||
|  | ||||
| 	db.Name = dbName | ||||
| 	db.DB, err = sql.Open("mysql", cfg.FormatDSN()) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("Open: sql.Open(\"mysql\", cfg.FormatDSN()): %v\n", err) | ||||
| 	} | ||||
| 	if err := db.Ping(); err != nil { | ||||
| 		return nil, fmt.Errorf("Open: db.Ping(): %v\n", err) | ||||
| 	} | ||||
|  | ||||
| 	return db, nil | ||||
| } | ||||
|  | ||||
| func (db *DB) WriteBriefing(b *types.Briefing) error { | ||||
| 	for i := 0; i < len(b.Participants); i++ { | ||||
| 		result, err := db.Exec("INSERT INTO "+db.Name+" (instructor_first,"+ | ||||
| 			"instructor_last, date, time, state, location, participant_first,"+ | ||||
| 			"participant_last, company) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", | ||||
| 			b.FirstName, b.LastName, b.Date, b.Time, b.State, b.Location, | ||||
| 			b.Participants[i].FirstName, b.Participants[i].LastName, | ||||
| 			b.Participants[i].Company) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("*DB.WriteBriefing: db.Exec(\"INSERT INTO"+ | ||||
| 				"\"+db.Name+\" (instructor_first, instructor_last, date, time, state,"+ | ||||
| 				"location, participant_first, participant_last, company) VALUES (?, ?,"+ | ||||
| 				"?, ?, ?, ?, ?, ?, ?)\", b.FirstName, b.LastName, b.Date, b.Time,"+ | ||||
| 				"b.State, b.Location, b.Participants[i].FirstName,"+ | ||||
| 				"b.Participants[i].LastName, b.Participants[i].Company): %v\n", err) | ||||
| 		} | ||||
|  | ||||
| 		_, err = result.LastInsertId() | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("*DB.WriteBriefing: result.LastInsertId(): %v\n", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (db *DB) ReadAll() (*[]types.Briefing, error) { | ||||
| 	bs := make([]types.Briefing, 0) | ||||
|  | ||||
| 	rows, err := db.Query("SELECT *" + " FROM " + db.Name) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("*DB.ReadAll: db.Query(\"SELECT * FROM \"+db.Name): %v\n", err) | ||||
| 	} | ||||
| 	defer rows.Close() | ||||
|  | ||||
| 	for rows.Next() { | ||||
| 		b := new(types.Briefing) | ||||
| 		p := new(types.Participant) | ||||
|  | ||||
| 		if err := rows.Scan(&p.ID, &b.FirstName, &b.LastName, &b.Date, &b.Time, | ||||
| 			&b.State, &b.Location, &p.FirstName, &p.LastName, &p.Company); err != nil { | ||||
| 			return nil, fmt.Errorf("*DB.ReadAll: db.Query(): %v\n", err) | ||||
| 		} | ||||
|  | ||||
| 		b.Participants = append(b.Participants, *p) | ||||
| 		bs = append(bs, *b) | ||||
| 	} | ||||
|  | ||||
| 	return &bs, nil | ||||
| } | ||||
|  | ||||
| func (db *DB) ReadByName(name string) (*[]types.Briefing, error) { | ||||
| 	bs := make([]types.Briefing, 0) | ||||
|  | ||||
| 	rows, err := db.Query("SELECT *"+ | ||||
| 		" FROM "+db.Name+ | ||||
| 		" WHERE instructor_first LIKE ?"+ | ||||
| 		" OR instructor_last LIKE ?"+ | ||||
| 		" OR participant_first LIKE ?"+ | ||||
| 		" OR participant_last LIKE ?", | ||||
| 		"%"+name+"%", "%"+name+"%", "%"+name+"%", "%"+name+"%") | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("*DB.ReadByName: db.Query(\"SELECT *"+ | ||||
| 			" FROM \"+db.Name+"+ | ||||
| 			" WHERE instructor_first LIKE ?"+ | ||||
| 			" OR instructor_last LIKE ?"+ | ||||
| 			" OR participant_first LIKE ?"+ | ||||
| 			" OR participant_last LIKE ?\"): %v\n", err) | ||||
| 	} | ||||
| 	defer rows.Close() | ||||
|  | ||||
| 	for rows.Next() { | ||||
| 		b := new(types.Briefing) | ||||
| 		p := new(types.Participant) | ||||
|  | ||||
| 		if err := rows.Scan(&p.ID, &b.FirstName, &b.LastName, &b.Date, &b.Time, &b.State, | ||||
| 			&b.Location, &p.FirstName, &p.LastName, &p.Company); err != nil { | ||||
| 			return nil, fmt.Errorf("*DB.ReadByName: rows.Scan(&p.ID, &b.FirstName,"+ | ||||
| 				" &b.LastName, &b.Date, &b.Time, &b.State, &b.Location, &p.FirstName,"+ | ||||
| 				" &p.LastName, &p.Company): %v\n", err) | ||||
| 		} | ||||
| 		b.Participants = append(b.Participants, *p) | ||||
| 		bs = append(bs, *b) | ||||
| 	} | ||||
|  | ||||
| 	return &bs, nil | ||||
| } | ||||
							
								
								
									
										76
									
								
								packages/server/server.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								packages/server/server.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| package server | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"html/template" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"streifling.com/jason/sicherheitsunterweisung/packages/db" | ||||
| 	"streifling.com/jason/sicherheitsunterweisung/packages/types" | ||||
| ) | ||||
|  | ||||
| func DisplayTable(db *db.DB) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		bs, err := db.ReadAll() | ||||
| 		if err != nil { | ||||
| 			_ = fmt.Errorf("DisplayTable: %v\n", err) | ||||
| 		} | ||||
| 		template.Must(template.ParseFiles("templates/index.html", "templates/table.html")).Execute(w, bs) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func DisplayResults(db *db.DB) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		bs, err := db.ReadByName(r.PostFormValue("search")) | ||||
| 		if err != nil { | ||||
| 			_ = fmt.Errorf("DisplayResults: db.ReadByName(r.PostFormValue()): %v\n", err) | ||||
| 		} | ||||
| 		template.Must(template.ParseFiles("templates/table.html")).ExecuteTemplate(w, "rows", bs) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func DisplayForm(i *int64) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		template.Must(template.ParseFiles("templates/form.html")).ExecuteTemplate(w, "content", i) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func AddParticipant(i *int64) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		*i++ | ||||
| 		template.Must(template.ParseFiles("templates/form.html")).ExecuteTemplate(w, "participant", i) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SubmitForm(db *db.DB, i, j *int64) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		b := new(types.Briefing) | ||||
|  | ||||
| 		b.FirstName = r.PostFormValue("instructor-first") | ||||
| 		b.LastName = r.PostFormValue("instructor-last") | ||||
| 		b.Date = r.PostFormValue("date") | ||||
| 		b.Time = r.PostFormValue("time") | ||||
| 		b.State = r.PostFormValue("state") | ||||
| 		b.Location = r.PostFormValue("location") | ||||
|  | ||||
| 		for ; *j <= *i; *j++ { | ||||
| 			b.Participants = append(b.Participants, types.Participant{ | ||||
| 				ID: *j, | ||||
| 				Person: types.Person{ | ||||
| 					FirstName: r.PostFormValue("participant-first-" + fmt.Sprint(*j)), | ||||
| 					LastName:  r.PostFormValue(("participant-last-" + fmt.Sprint(*j))), | ||||
| 				}, | ||||
| 				Company: r.PostFormValue(("participant-company-" + fmt.Sprint(*j))), | ||||
| 			}) | ||||
| 		} | ||||
|  | ||||
| 		log.Println(b) | ||||
| 		db.WriteBriefing(b) | ||||
| 		bs, err := db.ReadAll() | ||||
| 		if err != nil { | ||||
| 			_ = fmt.Errorf("SubmitForm: db.ReadAll(): %v\n", err) | ||||
| 		} | ||||
| 		template.Must(template.ParseFiles("templates/index.html", "templates/table.html")).Execute(w, bs) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										23
									
								
								packages/types/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								packages/types/types.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| package types | ||||
|  | ||||
| type Person struct { | ||||
| 	FirstName string | ||||
| 	LastName  string | ||||
| } | ||||
|  | ||||
| type Instructor Person | ||||
|  | ||||
| type Participant struct { | ||||
| 	ID int64 | ||||
| 	Person | ||||
| 	Company string | ||||
| } | ||||
|  | ||||
| type Briefing struct { | ||||
| 	Instructor | ||||
| 	Date         string | ||||
| 	Time         string | ||||
| 	State        string | ||||
| 	Location     string | ||||
| 	Participants []Participant | ||||
| } | ||||
							
								
								
									
										56
									
								
								templates/form.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								templates/form.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| {{ define "participant" }} | ||||
| <div id="participant-{{ . }}"> | ||||
|   <label for="participant-first-input-{{ . }}">Vorname</label> | ||||
|   <input type="text" name="participant-first-{{ . }}" id="participant-first-input-{{ . }}" /> | ||||
|  | ||||
|   <label for="participant-last-input-{{ . }}">Nachname</label> | ||||
|   <input type="text" name="participant-last-{{ . }}" id="participant-last-input-{{ . }}" /> | ||||
|  | ||||
|   <label for="participant-company-input-{{ . }}">Firma</label> | ||||
|   <input type="text" name="participant-company-{{ . }}" id="participant-company-input-{{ . }}" /> | ||||
| </div> | ||||
| {{ end }} | ||||
|  | ||||
| {{ define "content" }} | ||||
| <form> | ||||
|   <div id="instructor"> | ||||
|     <label for="instructor-first-input">Unterweiser Vorname</label> | ||||
|     <input type="text" name="instructor-first" id="instructor-first-input" /> | ||||
|  | ||||
|     <label for="instructor-last-input">Unterweiser Nachname</label> | ||||
|     <input type="text" name="instructor-last" id="instructor-last-input" /> | ||||
|   </div> | ||||
|  | ||||
|   <div id="date"> | ||||
|     <label for="date-input">Datum</label> | ||||
|     <input type="date" name="date" id="date-input" /> | ||||
|   </div> | ||||
|  | ||||
|   <div id="time"> | ||||
|     <label for="time-input">Uhrzeit</label> | ||||
|     <input type="time" name="time" id="time-input" /> | ||||
|   </div> | ||||
|  | ||||
|   <div id="state"> | ||||
|     <label for="state-input">Stand vom</label> | ||||
|     <input type="date" name="state" id="state-input" /> | ||||
|   </div> | ||||
|  | ||||
|   <div id="location"> | ||||
|     <label for="location-input">Ort</label> | ||||
|     <input type="text" name="location" id="location-input" /> | ||||
|   </div> | ||||
|  | ||||
|   <div id="participants"> | ||||
|     <button type="button" hx-post="/add-participant/" hx-target="#participants" hx-swap="beforeend" hx-trigger="click"> | ||||
|       + | ||||
|     </button> | ||||
|  | ||||
|     {{ template "participant" . }} | ||||
|   </div> | ||||
|  | ||||
|   <button type="submit" hx-post="/submit/" hx-target="#content" hx-swap="innerHTML"> | ||||
|     Senden | ||||
|   </button> | ||||
| </form> | ||||
| {{ end }} | ||||
| @@ -11,57 +11,9 @@ | ||||
| <body> | ||||
|   <h1>Sicherheitsunterweisung</h1> | ||||
|  | ||||
|   <form> | ||||
|     <div id="instructor"> | ||||
|       <label for="instructor-first-input">Unterweiser Vorname</label> | ||||
|       <input type="text" name="instructor-first" id="instructor-first-input" /> | ||||
|  | ||||
|       <label for="instructor-last-input">Unterweiser Nachname</label> | ||||
|       <input type="text" name="instructor-last" id="instructor-last-input" /> | ||||
|     </div> | ||||
|  | ||||
|     <div id="date"> | ||||
|       <label for="date-input">Datum</label> | ||||
|       <input type="date" name="date" id="date-input" /> | ||||
|     </div> | ||||
|  | ||||
|     <div id="time"> | ||||
|       <label for="time-input">Uhrzeit</label> | ||||
|       <input type="time" name="time" id="time-input" /> | ||||
|     </div> | ||||
|  | ||||
|     <div id="state"> | ||||
|       <label for="state-input">Stand vom</label> | ||||
|       <input type="date" name="state" id="state-input" /> | ||||
|     </div> | ||||
|  | ||||
|     <div id="location"> | ||||
|       <label for="location-input">Ort</label> | ||||
|       <input type="text" name="location" id="location-input" /> | ||||
|     </div> | ||||
|  | ||||
|     <div id="participants"> | ||||
|       <button type="button" hx-post="/add-participant/" hx-target="#participants" hx-swap="beforeend" | ||||
|         hx-trigger="click"> | ||||
|         + | ||||
|       </button> | ||||
|  | ||||
|       <div id="participant-{{ . }}"> | ||||
|         <label for="participant-first-input-{{ . }}">Vorname</label> | ||||
|         <input type="text" name="participant-first-{{ . }}" id="participant-first-input-{{ . }}" /> | ||||
|  | ||||
|         <label for="participant-last-input-{{ . }}">Nachname</label> | ||||
|         <input type="text" name="participant-last-{{ . }}" id="participant-last-input-{{ . }}" /> | ||||
|  | ||||
|         <label for="participant-company-input-{{ . }}">Firma</label> | ||||
|         <input type="text" name="participant-company-{{ . }}" id="participant-company-input-{{ . }}" /> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <button type="submit" hx-post="/submit/"> | ||||
|       Senden | ||||
|     </button> | ||||
|   </form> | ||||
|   <div id="content"> | ||||
|     {{ template "content" . }} | ||||
|   </div> | ||||
|  | ||||
|   <script src="/static/js/htmx.min.js" type="text/javascript"></script> | ||||
| </body> | ||||
|   | ||||
| @@ -1,12 +0,0 @@ | ||||
| {{ define "participant" }} | ||||
| <div id="participant-{{ . }}"> | ||||
|   <label for="participant-first-input-{{ . }}">Vorname</label> | ||||
|   <input type="text" name="participant-first-{{ . }}" id="participant-first-input-{{ . }}" /> | ||||
|  | ||||
|   <label for="participant-last-input-{{ . }}">Nachname</label> | ||||
|   <input type="text" name="participant-last-{{ . }}" id="participant-last-input-{{ . }}" /> | ||||
|  | ||||
|   <label for="participant-company-input-{{ . }}">Firma</label> | ||||
|   <input type="text" name="participant-company-{{ . }}" id="participant-company-input-{{ . }}" /> | ||||
| </div> | ||||
| {{ end }} | ||||
							
								
								
									
										51
									
								
								templates/table.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								templates/table.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| {{ define "rows" }} | ||||
| {{ range . }} | ||||
| <tr> | ||||
|   <td>{{ .FirstName }}</td> | ||||
|   <td>{{ .LastName }}</td> | ||||
|   <td>{{ .Date }}</td> | ||||
|   <td>{{ .Time }}</td> | ||||
|   <td>{{ .State }}</td> | ||||
|   <td>{{ .Location }}</td> | ||||
|   {{ range .Participants }} | ||||
|   <td>{{ .FirstName }}</td> | ||||
|   <td>{{ .LastName }}</td> | ||||
|   <td>{{ .Company }}</td> | ||||
|   {{ end }} | ||||
| </tr> | ||||
| {{ end }} | ||||
| {{ end }} | ||||
|  | ||||
| {{ define "content" }} | ||||
| <form> | ||||
|   <label for="search-input">Suche</label> | ||||
|   <input type="text" name="search" id="search-input" /> | ||||
|   <button type="submit" hx-post="/search/" hx-target="#results" hx-swap="innerHTML"> | ||||
|     Suchen | ||||
|   </button> | ||||
| </form> | ||||
|  | ||||
| <form> | ||||
|   <button type="submit" hx-post="/new-briefing/" hx-target="#content" hx-swap="innerHTML"> | ||||
|     Neue Unterweisung | ||||
|   </button> | ||||
| </form> | ||||
|  | ||||
| <table> | ||||
|   <thead> | ||||
|     <tr> | ||||
|       <th colspan="2">Name Unterweiser</th> | ||||
|       <th>Datum</th> | ||||
|       <th>Uhrzeit</th> | ||||
|       <th>Stand</th> | ||||
|       <th>Ort</th> | ||||
|       <th colspan="2">Name Teilnehmer</th> | ||||
|       <th>Firma</th> | ||||
|     </tr> | ||||
|   </thead> | ||||
|  | ||||
|   <tbody id="results"> | ||||
|     {{ template "rows" . }} | ||||
|   </tbody> | ||||
| </table> | ||||
| {{ end }} | ||||
		Reference in New Issue
	
	Block a user