From 4a6f987bf7f9d73e9dd33d225fd2d73e9bf69a88 Mon Sep 17 00:00:00 2001 From: grm Date: Wed, 16 Sep 2026 19:10:13 +0300 Subject: Merge the Layout and Design tabs into one form with a single Save The look and the layout of a blog were split over two tabs that cross-linked each other, and the Layout tab saved every toggle, move and add straight away through a dozen tiny forms. Now one Design tab holds it all, organised by part of the blog (colours & fonts, header, menu, content, side columns, footer, logo & icon) behind a sticky side index, and one Save stores the theme, every module and the menu atomically (BlogStore.SaveDesign). Module settings are edited inline; Discard changes throws the edits away; a validation error shows the form again exactly as it was sent. The image pickers no longer render the whole library four times over: a select of the newest images, and a script-driven panel that fetches the library page by page (GET /files as JSON) with lazy thumbnails. New options: posts per page, site title size, footer alignment. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A --- internal/store/modules.go | 55 ----------------------------------------------- 1 file changed, 55 deletions(-) (limited to 'internal/store/modules.go') diff --git a/internal/store/modules.go b/internal/store/modules.go index d077975..99aed1a 100644 --- a/internal/store/modules.go +++ b/internal/store/modules.go @@ -48,10 +48,6 @@ func (bs *BlogStore) ListModules(ctx context.Context) ([]Module, error) { return out, rows.Err() } -func (bs *BlogStore) ModuleByID(ctx context.Context, id int64) (*Module, error) { - return scanModule(bs.db.QueryRow(ctx, `SELECT `+moduleCols+` FROM modules WHERE id=$1`, id)) -} - // CreateModule appends a module to the end of its area. func (bs *BlogStore) CreateModule(ctx context.Context, m *Module) (*Module, error) { return scanModule(bs.db.QueryRow(ctx, `INSERT INTO modules (area, kind, title, body, count, sort_order) @@ -59,57 +55,6 @@ func (bs *BlogStore) CreateModule(ctx context.Context, m *Module) (*Module, erro m.Area, m.Kind, m.Title, m.Body, m.Count)) } -// UpdateModule saves the editable settings; area and kind never change. -func (bs *BlogStore) UpdateModule(ctx context.Context, m *Module) error { - _, err := bs.db.Exec(ctx, `UPDATE modules SET title=$2, body=$3, count=$4, updated_at=now() WHERE id=$1`, - m.ID, m.Title, m.Body, m.Count) - return wrap(err) -} - -func (bs *BlogStore) DeleteModule(ctx context.Context, id int64) error { - _, err := bs.db.Exec(ctx, `DELETE FROM modules WHERE id=$1`, id) - return err -} - -// MoveModule swaps sort_order with the neighbouring module of the same area (dir = -1 up, +1 down). -func (bs *BlogStore) MoveModule(ctx context.Context, id int64, dir int) error { - cur, err := bs.ModuleByID(ctx, id) - if err != nil { - return err - } - all, err := bs.ListModules(ctx) - if err != nil { - return err - } - var mods []Module - idx := -1 - for _, m := range all { - if m.Area != cur.Area { - continue - } - if m.ID == id { - idx = len(mods) - } - mods = append(mods, m) - } - j := idx + dir - if idx < 0 || j < 0 || j >= len(mods) { - return nil - } - mods[idx], mods[j] = mods[j], mods[idx] - tx, err := bs.db.Begin(ctx) - if err != nil { - return err - } - defer tx.Rollback(ctx) - for i, m := range mods { // renumber the area; keeps orders dense - if _, err := tx.Exec(ctx, `UPDATE modules SET sort_order=$2 WHERE id=$1`, m.ID, i); err != nil { - return err - } - } - return tx.Commit(ctx) -} - // ResetModules puts the layout back to what a new blog starts with. func (bs *BlogStore) ResetModules(ctx context.Context) error { tx, err := bs.db.Begin(ctx) -- cgit v1.2.3