diff --git a/.gitignore b/.gitignore index 7e480e2..51ec17d 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ public *.idx *.sqlite3 webapp +bin diff --git a/api/handlers.go b/api/handlers.go deleted file mode 100644 index 18a56d9..0000000 --- a/api/handlers.go +++ /dev/null @@ -1,20 +0,0 @@ -package api - -import ( - "log" - "time" - - "github.com/gofiber/fiber/v2" -) - -func Setup(app *fiber.App) { - // this forces static pages to reload - app.Static("/", "./public", fiber.Static{ - Compress: false, - CacheDuration: 1 * time.Nanosecond, - }) -} - -func Shutdown() { - log.Println("Shutting down controllers...") -} diff --git a/common/api.go b/common/api.go index ae3fdd5..a558d6b 100644 --- a/common/api.go +++ b/common/api.go @@ -9,16 +9,18 @@ import ( type Failure struct { Message string `json:"message"` + Status int } func IfErrNil(err error, c *fiber.Ctx) error { if err != nil { log.Output(10, err.Error()) - c.SendStatus(fiber.StatusInternalServerError) - return c.JSON(Failure{err.Error()}) - } - - return err + status := fiber.StatusInternalServerError + c.SendStatus(status) + return c.JSON(Failure{err.Error(), status}) + } else { + return err + } } func ReceivePost[T any](c *fiber.Ctx) (*T, error) { diff --git a/common/web.go b/common/web.go index 4fa314a..27d2e1f 100644 --- a/common/web.go +++ b/common/web.go @@ -4,6 +4,9 @@ import ( "strings" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/session" + "io/fs" + "path/filepath" + "fmt" ) var STORE *session.Store @@ -34,3 +37,63 @@ func Page(path string) (func(c *fiber.Ctx) error) { return c.Render(path, fiber.Map{"PageId": page_id}) } } + +func SplitRouteTemplate(path string) (string, string) { + path = filepath.ToSlash(filepath.Clean(path)) + path, found := strings.CutPrefix(path, "views/") + if !found { + fmt.Println("no views/ prefix?", path) + } + + ext := filepath.Ext(path) + source_name, _ := strings.CutSuffix(path, ext) + split_path := strings.Split(source_name, "/") + + var route string + page := strings.Join(split_path, "/") + last := split_path[len(split_path) - 1] + + if last == "index" { + // it's an index.html so route doesn't include it + // WARN: page already has the leading / + route = fmt.Sprintf("/%s/", filepath.Dir(page)) + } else { + route = fmt.Sprintf("/%s", page) + } + + return route, page +} + +func ConfigViews(app *fiber.App, path string) error { + route_map := make(map[string]string, 10) + + for _, route := range app.GetRoutes() { + if route.Method == "GET" { + route_map[route.Path] = route.Method + } + } + + err := filepath.WalkDir(path, + func(path string, d fs.DirEntry, err error) error { + if err != nil { return err } + + if !d.IsDir() && strings.HasSuffix(path, "html") { + route, page := SplitRouteTemplate(path) + _, exists := route_map[route] + + if exists { + fmt.Println("ROUTE ", route, "Already exists, skipping", page) + } else { + fmt.Println("ROUTE ", route, "does not conflict page", page) + AddPage(app, route, page) + + // update the route map to avoid dupes + route_map[route] = "GET" + } + } + + return nil + }) + + return err +} diff --git a/go.mod b/go.mod index 5339ea1..9f3cefa 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/mattn/go-sqlite3 v1.14.32 github.com/stretchr/testify v1.11.1 golang.org/x/crypto v0.43.0 + golang.org/x/net v0.46.0 ) require ( diff --git a/go.sum b/go.sum index 5fe5def..0dcc0d6 100644 --- a/go.sum +++ b/go.sum @@ -105,6 +105,8 @@ github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= +golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= +golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= diff --git a/main.go b/main.go index 9aedef0..b26fc56 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "os" "os/signal" "syscall" + "time" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/template/html/v2" @@ -13,12 +14,12 @@ import ( _ "github.com/mattn/go-sqlite3" recov "github.com/gofiber/fiber/v2/middleware/recover" - "MY/webapp/api" "MY/webapp/data" "MY/webapp/config" "MY/webapp/admin" "MY/webapp/common" "MY/webapp/auth" + "MY/webapp/features" ) func main() { @@ -40,12 +41,17 @@ func main() { app.Use(logger.New()) app.Use(recov.New()) + app.Static("/", "./public", fiber.Static{ + Compress: false, + CacheDuration: 1 * time.Nanosecond, + }) + common.STORE = session.New() data.Setup(config.Settings.Database.Driver, config.Settings.Database.Url) auth.Setup(app) - api.Setup(app) admin.Setup(app) + features.Setup(app) // this sets up graceful shutdown go func() { @@ -61,7 +67,6 @@ func main() { log.Println("Shutdown now...") _ = app.Shutdown() - api.Shutdown() data.Shutdown() log.Println("Done.") diff --git a/static/style.css b/static/style.css index 64be2dc..2e3d29d 100644 --- a/static/style.css +++ b/static/style.css @@ -11,6 +11,7 @@ --color-red-300: oklch(80.8% 0.114 19.571); --color-red-500: oklch(63.7% 0.237 25.331); --color-red-800: oklch(44.4% 0.177 26.899); + --color-red-900: oklch(39.6% 0.141 25.723); --color-orange-500: oklch(70.5% 0.213 47.604); --color-yellow-300: oklch(90.5% 0.182 98.111); --color-green-400: oklch(79.2% 0.209 151.711);