Split app into subpages, persist ingame time, and add 14-month dashboard calendar
This commit is contained in:
119
cmd/server/domain.go
Normal file
119
cmd/server/domain.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func buildPlanningTargets(fields []Field) []PlanningTarget {
|
||||
groupMap := make(map[string][]Field)
|
||||
var out []PlanningTarget
|
||||
for _, f := range fields {
|
||||
if !f.Owned {
|
||||
continue
|
||||
}
|
||||
if f.GroupKey == "" {
|
||||
out = append(out, PlanningTarget{Ref: fmt.Sprintf("f:%d", f.ID), Label: fieldLabel(f)})
|
||||
continue
|
||||
}
|
||||
groupMap[f.GroupKey] = append(groupMap[f.GroupKey], f)
|
||||
}
|
||||
groupKeys := make([]string, 0, len(groupMap))
|
||||
for k := range groupMap {
|
||||
groupKeys = append(groupKeys, k)
|
||||
}
|
||||
sort.Strings(groupKeys)
|
||||
for _, k := range groupKeys {
|
||||
members := groupMap[k]
|
||||
sort.Slice(members, func(i, j int) bool { return members[i].Number < members[j].Number })
|
||||
name := members[0].GroupName
|
||||
if strings.TrimSpace(name) == "" {
|
||||
name = autoGroupName(members)
|
||||
}
|
||||
out = append(out, PlanningTarget{Ref: "g:" + k, Label: name})
|
||||
}
|
||||
sort.Slice(out, func(i, j int) bool { return out[i].Label < out[j].Label })
|
||||
return out
|
||||
}
|
||||
|
||||
func buildFieldGroups(fields []Field) []FieldGroup {
|
||||
groupMap := make(map[string][]Field)
|
||||
for _, f := range fields {
|
||||
if strings.TrimSpace(f.GroupKey) == "" {
|
||||
continue
|
||||
}
|
||||
groupMap[f.GroupKey] = append(groupMap[f.GroupKey], f)
|
||||
}
|
||||
|
||||
var out []FieldGroup
|
||||
for key, members := range groupMap {
|
||||
sort.Slice(members, func(i, j int) bool { return members[i].Number < members[j].Number })
|
||||
nums := make([]string, 0, len(members))
|
||||
for _, m := range members {
|
||||
nums = append(nums, strconv.Itoa(m.Number))
|
||||
}
|
||||
name := members[0].GroupName
|
||||
if strings.TrimSpace(name) == "" {
|
||||
name = autoGroupName(members)
|
||||
}
|
||||
out = append(out, FieldGroup{Key: key, Name: name, Numbers: strings.Join(nums, "+")})
|
||||
}
|
||||
sort.Slice(out, func(i, j int) bool { return out[i].Name < out[j].Name })
|
||||
return out
|
||||
}
|
||||
|
||||
func autoGroupName(fields []Field) string {
|
||||
sort.Slice(fields, func(i, j int) bool { return fields[i].Number < fields[j].Number })
|
||||
parts := make([]string, 0, len(fields))
|
||||
for _, f := range fields {
|
||||
parts = append(parts, strconv.Itoa(f.Number))
|
||||
}
|
||||
return "Feld " + strings.Join(parts, "+")
|
||||
}
|
||||
|
||||
func fieldLabel(f Field) string {
|
||||
base := fmt.Sprintf("Feld %d", f.Number)
|
||||
if strings.TrimSpace(f.Name) != "" {
|
||||
base += " (" + f.Name + ")"
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
func monthOptions() []MonthOption {
|
||||
out := make([]MonthOption, 0, 12)
|
||||
for i, m := range monthNames {
|
||||
out = append(out, MonthOption{Value: i + 1, Label: m})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func monthInWindow(month, start, end int) bool {
|
||||
if start <= end {
|
||||
return month >= start && month <= end
|
||||
}
|
||||
return month >= start || month <= end
|
||||
}
|
||||
|
||||
func wrapMonth(v int) int {
|
||||
m := v % 12
|
||||
if m == 0 {
|
||||
return 12
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func validateCropInput(name string, start, end, grow int) error {
|
||||
if name == "" {
|
||||
return errors.New("Name der Feldfrucht fehlt")
|
||||
}
|
||||
if start < 1 || start > 12 || end < 1 || end > 12 {
|
||||
return errors.New("Aussaatmonat muss 1-12 sein")
|
||||
}
|
||||
if grow < 1 || grow > 24 {
|
||||
return errors.New("Wachstumsdauer muss 1-24 sein")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user