Did some restyling

This commit is contained in:
Leon Mika 2025-03-29 21:54:14 +11:00
parent d1e212d5e0
commit 2411e64a53
13 changed files with 172 additions and 45 deletions

View file

@ -56,6 +56,23 @@ div.post {
* Post form * Post form
*/ */
form.prefs fieldset {
display: inline-grid;
grid-template-columns: auto 1fr;
column-gap: 1rem;
row-gap: 0.5rem;
align-items: center;
border: none;
}
form.prefs label {
text-align: right;
}
form.prefs input[type=text] {
min-width: 400px;
}
form.post-form { form.post-form {
display: grid; display: grid;
grid-template-columns: auto 23vw; grid-template-columns: auto 23vw;
@ -115,4 +132,29 @@ dialog h3 {
dialog textarea { dialog textarea {
min-height: 10vh !important; min-height: 10vh !important;
width: 100%; width: 100%;
}
@media (max-width: 1000px) {
body.role-site nav.vert {
display: none;
}
form.prefs fieldset {
display: grid;
padding-inline: 0;
margin-block-end: 12px;
grid-template-columns: 1fr;
}
form.prefs label {
margin-block-start: 12px;
display: block;
text-align: left;
}
form.prefs input[type=text] {
width: 100%;
min-width: 50px;
}
} }

View file

@ -95,6 +95,47 @@ func (ns NullPageRole) Value() (driver.Value, error) {
return string(ns.PageRole), nil return string(ns.PageRole), nil
} }
type PostFormat string
const (
PostFormatMarkdown PostFormat = "markdown"
)
func (e *PostFormat) Scan(src interface{}) error {
switch s := src.(type) {
case []byte:
*e = PostFormat(s)
case string:
*e = PostFormat(s)
default:
return fmt.Errorf("unsupported scan type for PostFormat: %T", src)
}
return nil
}
type NullPostFormat struct {
PostFormat PostFormat
Valid bool // Valid is true if PostFormat is not NULL
}
// Scan implements the Scanner interface.
func (ns *NullPostFormat) Scan(value interface{}) error {
if value == nil {
ns.PostFormat, ns.Valid = "", false
return nil
}
ns.Valid = true
return ns.PostFormat.Scan(value)
}
// Value implements the driver Valuer interface.
func (ns NullPostFormat) Value() (driver.Value, error) {
if !ns.Valid {
return nil, nil
}
return string(ns.PostFormat), nil
}
type PostState string type PostState string
const ( const (
@ -233,6 +274,7 @@ type Page struct {
BundleID int64 BundleID int64
Name string Name string
NameProvenance PageNameProvenance NameProvenance PageNameProvenance
Format PostFormat
Title pgtype.Text Title pgtype.Text
PostTypeID pgtype.Int8 PostTypeID pgtype.Int8
Body string Body string
@ -249,6 +291,7 @@ type Post struct {
SiteID int64 SiteID int64
Title pgtype.Text Title pgtype.Text
PostTypeID pgtype.Int8 PostTypeID pgtype.Int8
Format PostFormat
Body string Body string
State PostState State PostState
Props []byte Props []byte

View file

@ -21,7 +21,7 @@ func (q *Queries) DeletePageWithID(ctx context.Context, id int64) error {
} }
const getPageWithID = `-- name: GetPageWithID :one const getPageWithID = `-- name: GetPageWithID :one
SELECT id, site_id, bundle_id, name, name_provenance, title, post_type_id, body, state, props, role, publish_date, created_at, updated_at FROM pages WHERE id = $1 SELECT id, site_id, bundle_id, name, name_provenance, format, title, post_type_id, body, state, props, role, publish_date, created_at, updated_at FROM pages WHERE id = $1
` `
func (q *Queries) GetPageWithID(ctx context.Context, id int64) (Page, error) { func (q *Queries) GetPageWithID(ctx context.Context, id int64) (Page, error) {
@ -33,6 +33,7 @@ func (q *Queries) GetPageWithID(ctx context.Context, id int64) (Page, error) {
&i.BundleID, &i.BundleID,
&i.Name, &i.Name,
&i.NameProvenance, &i.NameProvenance,
&i.Format,
&i.Title, &i.Title,
&i.PostTypeID, &i.PostTypeID,
&i.Body, &i.Body,
@ -101,7 +102,7 @@ func (q *Queries) InsertPage(ctx context.Context, arg InsertPageParams) (int64,
} }
const listPages = `-- name: ListPages :many const listPages = `-- name: ListPages :many
SELECT id, site_id, bundle_id, name, name_provenance, title, post_type_id, body, state, props, role, publish_date, created_at, updated_at FROM pages WHERE site_id = $1 ORDER BY name ASC LIMIT 25 SELECT id, site_id, bundle_id, name, name_provenance, format, title, post_type_id, body, state, props, role, publish_date, created_at, updated_at FROM pages WHERE site_id = $1 ORDER BY name ASC LIMIT 25
` `
func (q *Queries) ListPages(ctx context.Context, siteID int64) ([]Page, error) { func (q *Queries) ListPages(ctx context.Context, siteID int64) ([]Page, error) {
@ -119,6 +120,7 @@ func (q *Queries) ListPages(ctx context.Context, siteID int64) ([]Page, error) {
&i.BundleID, &i.BundleID,
&i.Name, &i.Name,
&i.NameProvenance, &i.NameProvenance,
&i.Format,
&i.Title, &i.Title,
&i.PostTypeID, &i.PostTypeID,
&i.Body, &i.Body,
@ -140,7 +142,7 @@ func (q *Queries) ListPages(ctx context.Context, siteID int64) ([]Page, error) {
} }
const listPublishablePages = `-- name: ListPublishablePages :many const listPublishablePages = `-- name: ListPublishablePages :many
SELECT id, site_id, bundle_id, name, name_provenance, title, post_type_id, body, state, props, role, publish_date, created_at, updated_at SELECT id, site_id, bundle_id, name, name_provenance, format, title, post_type_id, body, state, props, role, publish_date, created_at, updated_at
FROM pages FROM pages
WHERE id > $1 AND site_id = $2 AND state = 'published' WHERE id > $1 AND site_id = $2 AND state = 'published'
ORDER BY id LIMIT 100 ORDER BY id LIMIT 100
@ -166,6 +168,7 @@ func (q *Queries) ListPublishablePages(ctx context.Context, arg ListPublishableP
&i.BundleID, &i.BundleID,
&i.Name, &i.Name,
&i.NameProvenance, &i.NameProvenance,
&i.Format,
&i.Title, &i.Title,
&i.PostTypeID, &i.PostTypeID,
&i.Body, &i.Body,

View file

@ -21,7 +21,7 @@ func (q *Queries) DeletePost(ctx context.Context, id int64) error {
} }
const getPostWithID = `-- name: GetPostWithID :one const getPostWithID = `-- name: GetPostWithID :one
SELECT id, site_id, title, post_type_id, body, state, props, publish_date, created_at, updated_at FROM posts WHERE id = $1 LIMIT 1 SELECT id, site_id, title, post_type_id, format, body, state, props, publish_date, created_at, updated_at FROM posts WHERE id = $1 LIMIT 1
` `
func (q *Queries) GetPostWithID(ctx context.Context, id int64) (Post, error) { func (q *Queries) GetPostWithID(ctx context.Context, id int64) (Post, error) {
@ -32,6 +32,7 @@ func (q *Queries) GetPostWithID(ctx context.Context, id int64) (Post, error) {
&i.SiteID, &i.SiteID,
&i.Title, &i.Title,
&i.PostTypeID, &i.PostTypeID,
&i.Format,
&i.Body, &i.Body,
&i.State, &i.State,
&i.Props, &i.Props,
@ -84,7 +85,7 @@ func (q *Queries) InsertPost(ctx context.Context, arg InsertPostParams) (int64,
} }
const listPosts = `-- name: ListPosts :many const listPosts = `-- name: ListPosts :many
SELECT id, site_id, title, post_type_id, body, state, props, publish_date, created_at, updated_at FROM posts WHERE site_id = $1 ORDER BY publish_date DESC LIMIT 25 SELECT id, site_id, title, post_type_id, format, body, state, props, publish_date, created_at, updated_at FROM posts WHERE site_id = $1 ORDER BY publish_date DESC LIMIT 25
` `
func (q *Queries) ListPosts(ctx context.Context, siteID int64) ([]Post, error) { func (q *Queries) ListPosts(ctx context.Context, siteID int64) ([]Post, error) {
@ -101,6 +102,7 @@ func (q *Queries) ListPosts(ctx context.Context, siteID int64) ([]Post, error) {
&i.SiteID, &i.SiteID,
&i.Title, &i.Title,
&i.PostTypeID, &i.PostTypeID,
&i.Format,
&i.Body, &i.Body,
&i.State, &i.State,
&i.Props, &i.Props,
@ -119,7 +121,7 @@ func (q *Queries) ListPosts(ctx context.Context, siteID int64) ([]Post, error) {
} }
const listPublishablePosts = `-- name: ListPublishablePosts :many const listPublishablePosts = `-- name: ListPublishablePosts :many
SELECT id, site_id, title, post_type_id, body, state, props, publish_date, created_at, updated_at SELECT id, site_id, title, post_type_id, format, body, state, props, publish_date, created_at, updated_at
FROM posts FROM posts
WHERE id > $1 AND site_id = $2 AND state = 'published' AND publish_date <= $3 WHERE id > $1 AND site_id = $2 AND state = 'published' AND publish_date <= $3
ORDER BY id LIMIT 100 ORDER BY id LIMIT 100
@ -145,6 +147,7 @@ func (q *Queries) ListPublishablePosts(ctx context.Context, arg ListPublishableP
&i.SiteID, &i.SiteID,
&i.Title, &i.Title,
&i.PostTypeID, &i.PostTypeID,
&i.Format,
&i.Body, &i.Body,
&i.State, &i.State,
&i.Props, &i.Props,

View file

@ -27,22 +27,35 @@ func (q *Queries) GetSiteWithID(ctx context.Context, id int64) (Site, error) {
return i, err return i, err
} }
const listSites = `-- name: ListSites :one const listSites = `-- name: ListSites :many
SELECT id, owner_user_id, name, title, theme, props FROM sites SELECT id, owner_user_id, name, title, theme, props FROM sites
` `
func (q *Queries) ListSites(ctx context.Context) (Site, error) { func (q *Queries) ListSites(ctx context.Context) ([]Site, error) {
row := q.db.QueryRow(ctx, listSites) rows, err := q.db.Query(ctx, listSites)
var i Site if err != nil {
err := row.Scan( return nil, err
&i.ID, }
&i.OwnerUserID, defer rows.Close()
&i.Name, var items []Site
&i.Title, for rows.Next() {
&i.Theme, var i Site
&i.Props, if err := rows.Scan(
) &i.ID,
return i, err &i.OwnerUserID,
&i.Name,
&i.Title,
&i.Theme,
&i.Props,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
} }
const newSite = `-- name: NewSite :one const newSite = `-- name: NewSite :one

View file

@ -3,9 +3,11 @@ package handlers
import ( import (
"fmt" "fmt"
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3"
"lmika.dev/lmika/hugo-cms/services/sites"
) )
type IndexHandler struct { type IndexHandler struct {
Sites *sites.Service
} }
func (h IndexHandler) Index(c fiber.Ctx) error { func (h IndexHandler) Index(c fiber.Ctx) error {
@ -14,5 +16,12 @@ func (h IndexHandler) Index(c fiber.Ctx) error {
return c.Redirect().To(fmt.Sprintf("/sites/%v/posts", prefs.SiteID)) return c.Redirect().To(fmt.Sprintf("/sites/%v/posts", prefs.SiteID))
} }
return c.Render("index", fiber.Map{}, "layouts/main") sites, err := h.Sites.ListSites(c.Context())
if err != nil {
return err
}
return c.Render("index", fiber.Map{
"sites": sites,
}, "layouts/main")
} }

View file

@ -88,7 +88,7 @@ func main() {
postService := posts.New(dbp, siteBuilderService, jobService) postService := posts.New(dbp, siteBuilderService, jobService)
pageService := pages.New(dbp, siteBuilderService, jobService) pageService := pages.New(dbp, siteBuilderService, jobService)
indexHandlers := handlers.IndexHandler{} indexHandlers := handlers.IndexHandler{Sites: siteService}
siteHandlers := handlers.Site{Site: siteService, Bus: bus} siteHandlers := handlers.Site{Site: siteService, Bus: bus}
postHandlers := handlers.Post{Post: postService} postHandlers := handlers.Post{Post: postService}
pageHandlers := handlers.Pages{Svc: pageService} pageHandlers := handlers.Pages{Svc: pageService}

View file

@ -4,8 +4,18 @@ import (
"context" "context"
"lmika.dev/lmika/hugo-cms/gen/sqlc/dbq" "lmika.dev/lmika/hugo-cms/gen/sqlc/dbq"
"lmika.dev/lmika/hugo-cms/models" "lmika.dev/lmika/hugo-cms/models"
"lmika.dev/pkg/modash/moslice"
) )
func (db *DB) ListSites(ctx context.Context) ([]models.Site, error) {
res, err := db.q.ListSites(ctx)
if err != nil {
return nil, err
}
return moslice.Map(res, dbSiteToSite), nil
}
func (db *DB) InsertSite(ctx context.Context, site *models.Site) error { func (db *DB) InsertSite(ctx context.Context, site *models.Site) error {
id, err := db.q.NewSite(ctx, dbq.NewSiteParams{ id, err := db.q.NewSite(ctx, dbq.NewSiteParams{
Name: site.Name, Name: site.Name,
@ -27,13 +37,7 @@ func (db *DB) GetSite(ctx context.Context, id int64) (models.Site, error) {
return models.Site{}, err return models.Site{}, err
} }
return models.Site{ return dbSiteToSite(site), nil
ID: site.ID,
OwnerUserID: site.OwnerUserID,
Name: site.Name,
Title: site.Title,
Theme: site.Theme,
}, nil
} }
func (db *DB) UpdateSite(ctx context.Context, site models.Site) error { func (db *DB) UpdateSite(ctx context.Context, site models.Site) error {
@ -44,3 +48,13 @@ func (db *DB) UpdateSite(ctx context.Context, site models.Site) error {
Theme: site.Theme, Theme: site.Theme,
}) })
} }
func dbSiteToSite(site dbq.Site) models.Site {
return models.Site{
ID: site.ID,
OwnerUserID: site.OwnerUserID,
Name: site.Name,
Title: site.Title,
Theme: site.Theme,
}
}

View file

@ -38,6 +38,10 @@ func NewService(
} }
} }
func (s *Service) ListSites(ctx context.Context) ([]models.Site, error) {
return s.db.ListSites(ctx)
}
func (s *Service) GetSite(ctx context.Context, id int) (models.Site, error) { func (s *Service) GetSite(ctx context.Context, id int) (models.Site, error) {
return s.db.GetSite(ctx, int64(id)) return s.db.GetSite(ctx, int64(id))
} }

View file

@ -1,4 +1,4 @@
-- name: ListSites :one -- name: ListSites :many
SELECT * FROM sites; SELECT * FROM sites;
-- name: GetSiteWithID :one -- name: GetSiteWithID :one

View file

@ -1,6 +1,10 @@
<h1>Thing</h1> <h1>Sites</h1>
User = {{.user.Email}} <ul>
{{range .sites}}
<li><a href="/sites/{{.ID}}/posts">{{ .Name }}</a></li>
{{end}}
</ul>
<form method="post" action="/sites"> <form method="post" action="/sites">
<input type="submit" value="Create Site"> <input type="submit" value="Create Site">

View file

@ -1,12 +1,10 @@
<form method="post" action="/sites/{{.site.ID}}/posts/new-link"> <form class="prefs" method="post" action="/sites/{{.site.ID}}/posts/new-link">
<p> <fieldset>
<label>Link URL</label> <label>Link URL</label>
<input type="text" name="link_url" value="" /> <input type="text" name="link_url" value="" />
</p>
<p>
<label>Via URL</label> <label>Via URL</label>
<input type="text" name="via_url" value="" /> <input type="text" name="via_url" value="" />
</p> </fieldset>
<div class="bottom-area"> <div class="bottom-area">
<input type="submit" value="Create Post"> <input type="submit" value="Create Post">
</div> </div>

View file

@ -1,9 +1,7 @@
<form method="POST" action="/sites/{{.site.ID}}/settings"> <form class="prefs" method="POST" action="/sites/{{.site.ID}}/settings">
<p> <fieldset>
<label>Title</label> <label>Title</label>
<input type="text" name="site_title" value="{{.site.Title}}" /> <input type="text" name="site_title" value="{{.site.Title}}" />
</p>
<p>
<label>Theme</label> <label>Theme</label>
<select name="site_theme"> <select name="site_theme">
{{range .themes}} {{range .themes}}
@ -14,15 +12,11 @@
{{end}} {{end}}
{{end}} {{end}}
</select> </select>
</p>
<p>
<label>URL</label> <label>URL</label>
<input type="text" name="target_url" value="{{.target.URL}}" /> <input type="text" name="target_url" value="{{.target.URL}}" />
</p>
<p>
<label>Netlify Site ID</label> <label>Netlify Site ID</label>
<input type="text" name="target_ref" value="{{.target.TargetRef}}" /> <input type="text" name="target_ref" value="{{.target.TargetRef}}" />
</p> </fieldset>
<p> <p>
<input type="submit" value="Save" /> <input type="submit" value="Save" />
</p> </p>