diff options
Diffstat (limited to 'tidsreg.go')
-rw-r--r-- | tidsreg.go | 223 |
1 files changed, 213 insertions, 10 deletions
@@ -4,34 +4,237 @@ import ( "fmt" "log" "net/http" + "strconv" "text/template" + "time" + + "github.com/gorilla/mux" ) type Server struct { template *template.Template + srv *Service +} + +func funcMapFormatTime(t *time.Time) string { + if t == nil { + return "" + } + return t.Format("15:04") +} + +func parseStringTime(str string) (*time.Time, error) { + if str == "" { + return nil, nil + } + t, err := time.Parse("15:04", str) + return &t, err } -func (c *Server) rootHandle(w http.ResponseWriter, r * http.Request) { - tmpl, err := template.ParseFiles("templates/index.html") +func parseTaskFromForm(r *http.Request) (*Task, error) { + err := r.ParseForm() + if err != nil { + return nil, err + } + + from, err := parseStringTime(r.PostFormValue("from")) + if err != nil { + return nil, err + } + to, err := parseStringTime(r.PostFormValue("to")) + if err != nil { + return nil, err + } + var id int64 + if r.PostFormValue("id") == "" { + id = -1 + } else { + id, err = strconv.ParseInt(r.PostFormValue("id"), 10, 32) + if err != nil { + return nil, err + } + } + + task := &Task { + Id: int(id), + From: from, + To: to, + Comment: r.PostFormValue("comment"), + } + return task, nil +} + +func (s *Server) renderTemplate(w http.ResponseWriter, name string, page interface{}) { + tmpl := template.New("").Funcs(template.FuncMap { + "formatTime": funcMapFormatTime, + }) + tmpl, err := tmpl.ParseFiles("templates/index.html", "templates/parts/entry.html", "templates/parts/entryRows.html") + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + err = tmpl.ExecuteTemplate(w, name, page) if err != nil { log.Println(err) + fmt.Fprintf(w, "RENDER ERROR: %s\n", err.Error()) + } +} + +func writeError(w http.ResponseWriter, err string, code int) { + log.Println(err) + w.WriteHeader(code) + fmt.Fprintf(w, "%d: %s\n", code, err) + return +} + +func (s *Server) rootHandle(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" { + w.WriteHeader(http.StatusNotFound) + fmt.Fprintln(w, "Not found 404") return } - tmpl.Execute(w, nil) + + page, err := s.srv.GetRootPage() + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + s.renderTemplate(w, "index.html", page) } -func main() { - fmt.Println("Hello world!") - template, err := template.ParseFS(templates, "templates/*.html") +func (s *Server) postStart(w http.ResponseWriter, r *http.Request) { + now := time.Now() + + task, err := parseTaskFromForm(r) if err != nil { - log.Fatal(err) + writeError(w, err.Error(), http.StatusBadRequest) + return } - s := Server { - template: template, + _, err = s.srv.Db.StartNewEntry(now, task) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + page, err := s.srv.GetEntryPage(nil) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Add("HX-Trigger", "changedTasks") + + s.renderTemplate(w, "entry.html", page) +} + +func (s *Server) postStop(w http.ResponseWriter, r *http.Request) { + now := time.Now() + task, err := parseTaskFromForm(r) + if err != nil { + writeError(w, err.Error(), http.StatusBadRequest) + return + } + _, err = s.srv.Db.SaveEntry(task) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return } + err = s.srv.Db.StopEntry(now) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Add("HX-Trigger", "changedTasks") + + s.getTracking(w, r) +} + +func (s *Server) getTracking(w http.ResponseWriter, _ *http.Request) { + page, err := s.srv.GetEntryPage(nil) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + s.renderTemplate(w, "entry.html", page) +} + +func (s *Server) putSave(w http.ResponseWriter, r *http.Request) { + task, err := parseTaskFromForm(r) + if err != nil { + writeError(w, err.Error(), http.StatusBadRequest) + return + } + + task, err = s.srv.Db.SaveEntry(task) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + var detached *Task = nil + if r.URL.Query().Get("detached") == "true" { + detached = task + } + + page, err := s.srv.GetEntryPage(detached) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Add("HX-Trigger", "changedTasks") + + s.renderTemplate(w, "entry.html", page) +} + +func (s *Server) getNew(w http.ResponseWriter, _ *http.Request) { + task := &Task { + Id: -1, + From: nil, + To: nil, + Tag: nil, + Comment: "", + } + + page, err := s.srv.GetEntryPage(task) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + s.renderTemplate(w, "entry.html", page) +} + +func (s *Server) getEntries(w http.ResponseWriter, _ *http.Request) { + page, err := s.srv.GetRootPage() + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + s.renderTemplate(w, "entryRows.html", page) +} + +func main() { + fmt.Println("Hello world!") + + s := Server{ + template: nil, + srv: NewService(NewInMemDb()), + } + + r := mux.NewRouter() + r.HandleFunc("/start", s.postStart).Methods("POST") + r.HandleFunc("/newDetached", s.getNew).Methods("GET") + r.HandleFunc("/tracking", s.getTracking).Methods("GET") + r.HandleFunc("/stop", s.postStop).Methods("POST") + r.HandleFunc("/save", s.putSave).Methods("PUT") + r.HandleFunc("/entryRows", s.getEntries).Methods("GET") + r.HandleFunc("/", s.rootHandle) - http.HandleFunc("/", s.rootHandle) + http.Handle("/", r) log.Fatal(http.ListenAndServe(":8080", nil)) } |