feat(web): add vanilla JS/CSS SPA with embed.FS
Stream view with date grouping, card view sorted by usage, capture bar with client-side grammar parsing, tag rail filter, detail pane with card affordances (template slot fill, checklist toggle, link open), promote modal with auto-detect, keyboard shortcuts (j/k/n/p/ Enter/dd/1/2). Dark theme, responsive layout. Embedded in Go binary.
This commit is contained in:
+21
-1
@@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -8,7 +9,7 @@ import (
|
||||
"github.com/lerko/nib/internal/db"
|
||||
)
|
||||
|
||||
func NewRouter(store *db.Store, devMode bool) chi.Router {
|
||||
func NewRouter(store *db.Store, devMode bool, webFS ...fs.FS) chi.Router {
|
||||
r := chi.NewRouter()
|
||||
|
||||
r.Use(middleware.Logger)
|
||||
@@ -32,9 +33,28 @@ func NewRouter(store *db.Store, devMode bool) chi.Router {
|
||||
r.Get("/tags", listTags(store))
|
||||
})
|
||||
|
||||
if len(webFS) > 0 && webFS[0] != nil {
|
||||
r.Get("/*", spaHandler(webFS[0]))
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func spaHandler(fsys fs.FS) http.HandlerFunc {
|
||||
fileServer := http.FileServer(http.FS(fsys))
|
||||
indexHTML, _ := fs.ReadFile(fsys, "index.html")
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.URL.Path
|
||||
if path == "/" || path == "/cards" {
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
w.Write(indexHTML)
|
||||
return
|
||||
}
|
||||
fileServer.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func jsonContentType(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
Reference in New Issue
Block a user