Add task completion toggle, custom task templates, and umlaut UI updates

This commit is contained in:
Kai
2026-02-16 13:40:02 +01:00
parent a1c1ef31a3
commit 723e9142b2
13 changed files with 548 additions and 118 deletions

View File

@@ -53,6 +53,32 @@ func ensureSchema(db *sql.DB) error {
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_crop_steps_crop FOREIGN KEY(crop_id) REFERENCES crops(id) ON DELETE CASCADE
)`,
`CREATE TABLE IF NOT EXISTS custom_task_templates(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(140) NOT NULL UNIQUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)`,
`CREATE TABLE IF NOT EXISTS custom_tasks(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
template_id BIGINT NULL,
title VARCHAR(140) NOT NULL,
month TINYINT NOT NULL,
day TINYINT NOT NULL,
year_offset SMALLINT NOT NULL DEFAULT 0,
target_name VARCHAR(120) NOT NULL DEFAULT '',
notes VARCHAR(255) NOT NULL DEFAULT '',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_custom_tasks_template FOREIGN KEY(template_id) REFERENCES custom_task_templates(id) ON DELETE SET NULL
)`,
`CREATE TABLE IF NOT EXISTS task_completions(
task_uid VARCHAR(190) NOT NULL,
month TINYINT NOT NULL,
day TINYINT NOT NULL,
year_offset SMALLINT NOT NULL DEFAULT 0,
done TINYINT(1) NOT NULL DEFAULT 1,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(task_uid,month,day,year_offset)
)`,
`CREATE TABLE IF NOT EXISTS plans(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
@@ -199,6 +225,67 @@ func (a *App) listCropStepsMap() (map[int64][]CropStep, error) {
return m, nil
}
func (a *App) listCustomTaskTemplates() ([]CustomTaskTemplate, error) {
rows, err := a.db.Query(`SELECT id,title FROM custom_task_templates ORDER BY title`)
if err != nil {
return nil, err
}
defer rows.Close()
var out []CustomTaskTemplate
for rows.Next() {
var t CustomTaskTemplate
if err := rows.Scan(&t.ID, &t.Title); err != nil {
return nil, err
}
out = append(out, t)
}
return out, rows.Err()
}
func (a *App) listCustomTasks() ([]CustomTask, error) {
rows, err := a.db.Query(`
SELECT id,template_id,title,month,day,year_offset,COALESCE(target_name,''),COALESCE(notes,'')
FROM custom_tasks
ORDER BY year_offset, month, day, title`)
if err != nil {
return nil, err
}
defer rows.Close()
var out []CustomTask
for rows.Next() {
var t CustomTask
if err := rows.Scan(&t.ID, &t.TemplateID, &t.Title, &t.Month, &t.Day, &t.YearOffset, &t.TargetName, &t.Notes); err != nil {
return nil, err
}
out = append(out, t)
}
return out, rows.Err()
}
func (a *App) listTaskCompletionsMap() (map[string]bool, error) {
rows, err := a.db.Query(`SELECT task_uid,month,day,year_offset,done FROM task_completions WHERE done=1`)
if err != nil {
return nil, err
}
defer rows.Close()
out := make(map[string]bool)
for rows.Next() {
var uid string
var month, day, yearOffset int
var done bool
if err := rows.Scan(&uid, &month, &day, &yearOffset, &done); err != nil {
return nil, err
}
if done {
out[completionKey(uid, month, day, yearOffset)] = true
}
}
return out, rows.Err()
}
func seedCrops(db *sql.DB) error {
items := []Crop{
{Name: "Weizen", SowStartMonth: 9, SowEndMonth: 11, GrowMonths: 10},