diff --git a/assets/css/main.css b/assets/css/main.css index 3f52e1e..dc1baf1 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -56,6 +56,23 @@ div.post { * 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 { display: grid; grid-template-columns: auto 23vw; @@ -115,4 +132,29 @@ dialog h3 { dialog textarea { min-height: 10vh !important; 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; + } } \ No newline at end of file diff --git a/gen/sqlc/dbq/models.go b/gen/sqlc/dbq/models.go index e027f2d..2735cc1 100644 --- a/gen/sqlc/dbq/models.go +++ b/gen/sqlc/dbq/models.go @@ -95,6 +95,47 @@ func (ns NullPageRole) Value() (driver.Value, error) { 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 const ( @@ -233,6 +274,7 @@ type Page struct { BundleID int64 Name string NameProvenance PageNameProvenance + Format PostFormat Title pgtype.Text PostTypeID pgtype.Int8 Body string @@ -249,6 +291,7 @@ type Post struct { SiteID int64 Title pgtype.Text PostTypeID pgtype.Int8 + Format PostFormat Body string State PostState Props []byte diff --git a/gen/sqlc/dbq/pages.sql.go b/gen/sqlc/dbq/pages.sql.go index 89c3376..b01390e 100644 --- a/gen/sqlc/dbq/pages.sql.go +++ b/gen/sqlc/dbq/pages.sql.go @@ -21,7 +21,7 @@ func (q *Queries) DeletePageWithID(ctx context.Context, id int64) error { } 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) { @@ -33,6 +33,7 @@ func (q *Queries) GetPageWithID(ctx context.Context, id int64) (Page, error) { &i.BundleID, &i.Name, &i.NameProvenance, + &i.Format, &i.Title, &i.PostTypeID, &i.Body, @@ -101,7 +102,7 @@ func (q *Queries) InsertPage(ctx context.Context, arg InsertPageParams) (int64, } 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) { @@ -119,6 +120,7 @@ func (q *Queries) ListPages(ctx context.Context, siteID int64) ([]Page, error) { &i.BundleID, &i.Name, &i.NameProvenance, + &i.Format, &i.Title, &i.PostTypeID, &i.Body, @@ -140,7 +142,7 @@ func (q *Queries) ListPages(ctx context.Context, siteID int64) ([]Page, error) { } 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 WHERE id > $1 AND site_id = $2 AND state = 'published' ORDER BY id LIMIT 100 @@ -166,6 +168,7 @@ func (q *Queries) ListPublishablePages(ctx context.Context, arg ListPublishableP &i.BundleID, &i.Name, &i.NameProvenance, + &i.Format, &i.Title, &i.PostTypeID, &i.Body, diff --git a/gen/sqlc/dbq/posts.sql.go b/gen/sqlc/dbq/posts.sql.go index 0500cce..fb50671 100644 --- a/gen/sqlc/dbq/posts.sql.go +++ b/gen/sqlc/dbq/posts.sql.go @@ -21,7 +21,7 @@ func (q *Queries) DeletePost(ctx context.Context, id int64) error { } 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) { @@ -32,6 +32,7 @@ func (q *Queries) GetPostWithID(ctx context.Context, id int64) (Post, error) { &i.SiteID, &i.Title, &i.PostTypeID, + &i.Format, &i.Body, &i.State, &i.Props, @@ -84,7 +85,7 @@ func (q *Queries) InsertPost(ctx context.Context, arg InsertPostParams) (int64, } 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) { @@ -101,6 +102,7 @@ func (q *Queries) ListPosts(ctx context.Context, siteID int64) ([]Post, error) { &i.SiteID, &i.Title, &i.PostTypeID, + &i.Format, &i.Body, &i.State, &i.Props, @@ -119,7 +121,7 @@ func (q *Queries) ListPosts(ctx context.Context, siteID int64) ([]Post, error) { } 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 WHERE id > $1 AND site_id = $2 AND state = 'published' AND publish_date <= $3 ORDER BY id LIMIT 100 @@ -145,6 +147,7 @@ func (q *Queries) ListPublishablePosts(ctx context.Context, arg ListPublishableP &i.SiteID, &i.Title, &i.PostTypeID, + &i.Format, &i.Body, &i.State, &i.Props, diff --git a/gen/sqlc/dbq/sites.sql.go b/gen/sqlc/dbq/sites.sql.go index 432289b..5ad5f25 100644 --- a/gen/sqlc/dbq/sites.sql.go +++ b/gen/sqlc/dbq/sites.sql.go @@ -27,22 +27,35 @@ func (q *Queries) GetSiteWithID(ctx context.Context, id int64) (Site, error) { return i, err } -const listSites = `-- name: ListSites :one +const listSites = `-- name: ListSites :many SELECT id, owner_user_id, name, title, theme, props FROM sites ` -func (q *Queries) ListSites(ctx context.Context) (Site, error) { - row := q.db.QueryRow(ctx, listSites) - var i Site - err := row.Scan( - &i.ID, - &i.OwnerUserID, - &i.Name, - &i.Title, - &i.Theme, - &i.Props, - ) - return i, err +func (q *Queries) ListSites(ctx context.Context) ([]Site, error) { + rows, err := q.db.Query(ctx, listSites) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Site + for rows.Next() { + var i Site + if err := rows.Scan( + &i.ID, + &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 diff --git a/handlers/index.go b/handlers/index.go index 354614e..cded18e 100644 --- a/handlers/index.go +++ b/handlers/index.go @@ -3,9 +3,11 @@ package handlers import ( "fmt" "github.com/gofiber/fiber/v3" + "lmika.dev/lmika/hugo-cms/services/sites" ) type IndexHandler struct { + Sites *sites.Service } 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.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") } diff --git a/main.go b/main.go index eeececc..09934ae 100644 --- a/main.go +++ b/main.go @@ -88,7 +88,7 @@ func main() { postService := posts.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} postHandlers := handlers.Post{Post: postService} pageHandlers := handlers.Pages{Svc: pageService} diff --git a/providers/db/sites.go b/providers/db/sites.go index 75c2c88..9bc0d95 100644 --- a/providers/db/sites.go +++ b/providers/db/sites.go @@ -4,8 +4,18 @@ import ( "context" "lmika.dev/lmika/hugo-cms/gen/sqlc/dbq" "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 { id, err := db.q.NewSite(ctx, dbq.NewSiteParams{ 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{ - ID: site.ID, - OwnerUserID: site.OwnerUserID, - Name: site.Name, - Title: site.Title, - Theme: site.Theme, - }, nil + return dbSiteToSite(site), nil } 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, }) } + +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, + } +} diff --git a/services/sites/service.go b/services/sites/service.go index 8ad2bd7..ba5e561 100644 --- a/services/sites/service.go +++ b/services/sites/service.go @@ -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) { return s.db.GetSite(ctx, int64(id)) } diff --git a/sql/queries/sites.sql b/sql/queries/sites.sql index d858afa..33aef5c 100644 --- a/sql/queries/sites.sql +++ b/sql/queries/sites.sql @@ -1,4 +1,4 @@ --- name: ListSites :one +-- name: ListSites :many SELECT * FROM sites; -- name: GetSiteWithID :one diff --git a/templates/index.html b/templates/index.html index 614290c..d700d6b 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,6 +1,10 @@ -