all repos — todo.txt-web @ 444af8de3198d8a4fe86de9e24c8c4dcac920ee4

Minimalist Web interface for todo.txt file management

main.go (view raw)

 1package main
 2
 3import (
 4	"embed"
 5	"html/template"
 6	"net/http"
 7	"strconv"
 8
 9	"github.com/charmbracelet/log"
10	"github.com/gin-gonic/gin"
11
12	todo "github.com/1set/todotxt"
13)
14
15//go:embed static/* templates/*
16var fs embed.FS
17
18func main() {
19
20	// TODO Use config for todo path
21	// configPath := flag.String("config", "config.yaml", "Path to config file")
22	// flag.Parse()
23	// config := getConfig(*configPath)
24	router := gin.Default()
25
26	templ := template.Must(template.New("").ParseFS(fs, "templates/*.html"))
27	router.SetHTMLTemplate(templ)
28
29	router.StaticFS("/public", http.FS(fs))
30
31	router.GET("/", loadTasksList)
32	router.POST("/", loadTasksList)
33
34	router.Run()
35}
36
37func loadTasksList(c *gin.Context) {
38	taskList := getTaskList("todo.txt")
39
40	id := c.PostForm("taskId")
41	content := c.PostForm("taskContent")
42
43	if id != "" {
44		taskId, err := strconv.Atoi(id)
45		if err != nil {
46			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
47			return
48		}
49
50		if updatedTask, err := taskList.GetTask(taskId); err != nil {
51			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(), "taskId": taskId})
52			return
53		} else {
54			if c.PostForm("checked") == "on" {
55				updatedTask.Complete()
56			} else {
57				updatedTask.Reopen()
58			}
59		}
60		taskList.WriteToPath("todo.txt")
61	} else if content != "" {
62		newTask, _ := todo.ParseTask(content)
63		taskList.AddTask(newTask)
64		taskList.WriteToPath("todo.txt")
65	}
66
67	c.HTML(http.StatusOK, "tasks-list.html", gin.H{
68		"tasks": taskList,
69	})
70}
71
72func getTaskList(todoFilePath string) todo.TaskList {
73	if tasklist, err := todo.LoadFromPath(todoFilePath); err != nil {
74		log.Fatalf("Can't load file %s", todoFilePath)
75		return nil
76	} else {
77		return tasklist
78	}
79}