Files
farmcal/cmd/server/handlers_pages.go

215 lines
6.0 KiB
Go

package main
import (
"html/template"
"net/http"
)
func (a *App) renderTemplate(w http.ResponseWriter, path string, data any) {
tmpl, err := template.ParseFiles(path)
if err != nil {
http.Error(w, "template parse failed", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
if err := tmpl.Execute(w, data); err != nil {
http.Error(w, "template render failed", http.StatusInternalServerError)
}
}
func (a *App) handleDashboard(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
settings, err := a.getSettings()
if err != nil {
http.Error(w, "settings read failed", http.StatusInternalServerError)
return
}
plans, err := a.listPlans()
if err != nil {
http.Error(w, "plans read failed", http.StatusInternalServerError)
return
}
crops, err := a.listCrops()
if err != nil {
http.Error(w, "crops read failed", http.StatusInternalServerError)
return
}
products, err := a.listProducts()
if err != nil {
http.Error(w, "products read failed", http.StatusInternalServerError)
return
}
stepMap, err := a.listCropStepsMap()
if err != nil {
http.Error(w, "steps read failed", http.StatusInternalServerError)
return
}
customTasks, err := a.listCustomTasks()
if err != nil {
http.Error(w, "custom tasks read failed", http.StatusInternalServerError)
return
}
doneMap, err := a.listTaskCompletionsMap()
if err != nil {
http.Error(w, "completions read failed", http.StatusInternalServerError)
return
}
data := DashboardPage{
BasePage: BasePage{
ActivePath: "/",
Error: r.URL.Query().Get("error"),
Info: r.URL.Query().Get("info"),
},
Settings: settings,
CurrentMonth: monthNames[settings.CurrentMonth-1],
TodayTasks: buildTasksForDay(plans, crops, products, stepMap, customTasks, doneMap, (settings.CurrentCycle*12)+(settings.CurrentMonth-1), settings.CurrentDay),
Calendar: buildCalendar(plans, crops, products, stepMap, customTasks, doneMap, (settings.CurrentCycle*12)+(settings.CurrentMonth-1), settings.CurrentDay, settings.DaysPerMonth, 14),
PlanningCount: len(plans),
}
if a.matrix != nil {
data.MatrixEnabled = true
data.MatrixRoomID = a.matrix.RoomID
msgs, err := a.matrix.FetchRecentMessages(r.Context())
if err != nil {
data.MatrixError = err.Error()
} else {
data.MatrixMessages = msgs
}
}
data.TodayGroups = groupTasksByField(data.TodayTasks)
a.renderTemplate(w, "templates/dashboard.html", data)
}
func (a *App) handleFieldsPage(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
fields, err := a.listFields()
if err != nil {
http.Error(w, "fields read failed", http.StatusInternalServerError)
return
}
data := FieldsPage{
BasePage: BasePage{
ActivePath: "/fields",
Error: r.URL.Query().Get("error"),
Info: r.URL.Query().Get("info"),
},
Fields: fields,
Groups: buildFieldGroups(fields),
}
a.renderTemplate(w, "templates/fields.html", data)
}
func (a *App) handleCropsPage(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
crops, err := a.listCrops()
if err != nil {
http.Error(w, "crops read failed", http.StatusInternalServerError)
return
}
steps, err := a.listCropSteps()
if err != nil {
http.Error(w, "steps read failed", http.StatusInternalServerError)
return
}
products, err := a.listProducts()
if err != nil {
http.Error(w, "products read failed", http.StatusInternalServerError)
return
}
data := CropsPage{
BasePage: BasePage{
ActivePath: "/crops",
Error: r.URL.Query().Get("error"),
Info: r.URL.Query().Get("info"),
},
Crops: crops,
CropSteps: steps,
Products: products,
}
a.renderTemplate(w, "templates/crops.html", data)
}
func (a *App) handlePlanningPage(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
settings, err := a.getSettings()
if err != nil {
http.Error(w, "settings read failed", http.StatusInternalServerError)
return
}
crops, err := a.listCrops()
if err != nil {
http.Error(w, "crops read failed", http.StatusInternalServerError)
return
}
fields, err := a.listFields()
if err != nil {
http.Error(w, "fields read failed", http.StatusInternalServerError)
return
}
plans, err := a.listPlans()
if err != nil {
http.Error(w, "plans read failed", http.StatusInternalServerError)
return
}
taskTemplates, err := a.listCustomTaskTemplates()
if err != nil {
http.Error(w, "templates read failed", http.StatusInternalServerError)
return
}
customTasks, err := a.listCustomTasks()
if err != nil {
http.Error(w, "custom tasks read failed", http.StatusInternalServerError)
return
}
data := PlanningPage{
BasePage: BasePage{
ActivePath: "/planning",
Error: r.URL.Query().Get("error"),
Info: r.URL.Query().Get("info"),
},
Settings: settings,
Months: monthOptions(),
CycleOffsets: cycleOffsetOptions(8),
Crops: crops,
Plans: plans,
PlanningTargets: buildPlanningTargets(fields),
TaskTemplates: taskTemplates,
CustomTasks: customTasks,
}
a.renderTemplate(w, "templates/planning.html", data)
}
func (a *App) handleGeneralPage(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
settings, err := a.getSettings()
if err != nil {
http.Error(w, "settings read failed", http.StatusInternalServerError)
return
}
data := GeneralPage{
BasePage: BasePage{
ActivePath: "/general",
Error: r.URL.Query().Get("error"),
Info: r.URL.Query().Get("info"),
},
Settings: settings,
Months: monthOptions(),
}
a.renderTemplate(w, "templates/general.html", data)
}