add a bunch of frontend stuff

This commit is contained in:
sam 2023-09-03 04:11:56 +02:00
parent 2586161abd
commit bc85b7c340
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
30 changed files with 1459 additions and 136 deletions

View file

@ -1,8 +1,11 @@
package app
import (
"emperror.dev/errors"
"git.sleepycat.moe/sam/mercury/config"
"git.sleepycat.moe/sam/mercury/internal/database/sql"
"git.sleepycat.moe/sam/mercury/web/templates"
"github.com/flosch/pongo2/v6"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
@ -12,19 +15,27 @@ type App struct {
Config config.Config
Database *sql.Base
tmpl *pongo2.TemplateSet
}
func NewApp(cfg config.Config, db *sql.Base) *App {
func NewApp(cfg config.Config, db *sql.Base) (*App, error) {
app := &App{
Router: chi.NewRouter(),
Config: cfg,
Database: db,
}
tmpl, err := templates.New(cfg.Core.Dev)
if err != nil {
return nil, errors.Wrap(err, "creating templates")
}
app.tmpl = tmpl
app.Router.Use(app.Logger)
app.Router.Use(middleware.Recoverer)
return app
return app, nil
}
func (a *App) Account(q ...sql.Querier) *sql.AccountStore {

52
web/app/template.go Normal file
View file

@ -0,0 +1,52 @@
package app
import (
"net/http"
"time"
"github.com/flosch/pongo2/v6"
)
func (app *App) Template(w http.ResponseWriter, r *http.Request, tmplName string, ctx pongo2.Context) error {
tmpl, err := app.tmpl.FromCache(tmplName)
if err != nil {
return err
}
tctx := pongo2.Context{
"flash_message": app.getFlash(w, r),
}
tctx.Update(ctx)
w.Header().Set("Content-Type", "text/html")
return tmpl.ExecuteWriter(tctx, w)
}
const flashCookieName = "mercury-flash-message"
func (app *App) Flash(w http.ResponseWriter, msg string) {
http.SetCookie(w, &http.Cookie{
Name: flashCookieName,
Value: msg,
Path: "/",
HttpOnly: true,
Expires: time.Now().Add(time.Minute),
})
}
func (app *App) getFlash(w http.ResponseWriter, r *http.Request) string {
cookie, err := r.Cookie(flashCookieName)
if err != nil {
return ""
}
defer http.SetCookie(w, &http.Cookie{
Name: flashCookieName,
Value: "",
Path: "/",
HttpOnly: true,
Expires: time.Now(),
})
return cookie.Value
}

15
web/auth/auth.go Normal file
View file

@ -0,0 +1,15 @@
package auth
import "git.sleepycat.moe/sam/mercury/web/app"
type Auth struct {
*app.App
}
func New(app *app.App) *Auth {
auth := &Auth{
App: app,
}
return auth
}

11
web/auth/login.go Normal file
View file

@ -0,0 +1,11 @@
package auth
import (
"net/http"
"github.com/flosch/pongo2/v6"
)
func (app *Auth) GetLogin(w http.ResponseWriter, r *http.Request) {
app.Template(w, r, "auth/login.tpl", pongo2.Context{})
}

1
web/frontend/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
assets

View file

@ -1,13 +1,13 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.Config.Name}}</title>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{.Config.Name}}</title>
{{.Vue.RenderTags}}
</head>
<body>
<div id="app"></div>
</body>
{{.Vue.RenderTags}}
</head>
<body>
<div id="app"></div>
</body>
</html>

View file

@ -1,22 +1,26 @@
package frontend
import (
"embed"
"html/template"
"net/http"
"os"
"path/filepath"
"git.sleepycat.moe/sam/mercury/frontend"
"git.sleepycat.moe/sam/mercury/internal/database"
"git.sleepycat.moe/sam/mercury/web/app"
"github.com/go-chi/chi/v5"
"github.com/rs/zerolog/log"
vueglue "github.com/torenware/vite-go"
_ "embed"
)
//go:embed app.html
var htmlTemplate string
//go:embed assets
var assets embed.FS
type Frontend struct {
*app.App
glue *vueglue.VueGlue
@ -94,3 +98,14 @@ func (app *Frontend) ServeFrontend(w http.ResponseWriter, r *http.Request) {
log.Err(err).Msg("executing frontend template")
}
}
func (app *Frontend) ServeStaticAssets(w http.ResponseWriter, r *http.Request) {
if app.Config.Core.Dev {
// TODO: this is unsafe
path := filepath.Join("web/frontend/assets/", chi.URLParam(r, "*"))
http.ServeFile(w, r, path)
return
}
_ = assets
}

View file

@ -2,12 +2,23 @@ package web
import (
"git.sleepycat.moe/sam/mercury/web/app"
"git.sleepycat.moe/sam/mercury/web/auth"
"git.sleepycat.moe/sam/mercury/web/frontend"
"github.com/go-chi/chi/v5"
)
func Routes(app *app.App) {
// auth
app.Router.Route("/auth", func(r chi.Router) {
auth := auth.New(app)
r.Get("/login", auth.GetLogin)
})
// web app handlers
// also assets
frontend := frontend.New(app)
app.Router.HandleFunc(frontend.AssetsPath(), frontend.ServeAssets)
app.Router.HandleFunc("/static/*", frontend.ServeStaticAssets)
app.Router.HandleFunc("/web", frontend.ServeFrontend)
app.Router.HandleFunc("/web/*", frontend.ServeFrontend)
}

View file

@ -0,0 +1,19 @@
{% extends 'base.tpl' %}
{% block title %}
Log in
{% endblock %}
{% block content %}
<div class="auth">
<form method="post">
<p>
<label for="username">Username</label>
<input type="text" name="username" />
</p>
<p>
<label for="username">Password</label>
<input type="password" name="password" />
</p>
<input type="submit" value="Log in" />
</form>
</div>
{% endblock %}

13
web/templates/base.tpl Normal file
View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="/static/css/style.css" />
<title>{% block title %}Mercury{% endblock %}</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>

View file

@ -0,0 +1,28 @@
package templates
import (
"embed"
"emperror.dev/errors"
"github.com/flosch/pongo2/v6"
)
//go:embed *
var fs embed.FS
func New(dev bool) (*pongo2.TemplateSet, error) {
if dev {
loader, err := pongo2.NewLocalFileSystemLoader("web/templates")
if err != nil {
return nil, errors.Wrap(err, "creating filesystem loader")
}
ts := pongo2.NewSet("web", loader)
ts.Debug = true
return ts, nil
}
loader := pongo2.NewFSLoader(fs)
ts := pongo2.NewSet("web", loader)
return ts, nil
}