diff --git a/internal/database/handlers.go b/internal/database/handlers.go index 8affbc1..0e6b5da 100644 --- a/internal/database/handlers.go +++ b/internal/database/handlers.go @@ -33,9 +33,9 @@ func GetBoard(db *sql.DB, slug string) (Board, error) { return result, row.Err() } -func GetBoardThreads(db *sql.DB, board_id int) ([]Thread, error) { +func GetBoardThreads(db *sql.DB, slug string) ([]Thread, error) { rows, err := db.Query( - `SELECT id, board_id, subject, created_at, bumped_at FROM threads WHERE board_id = ?`, board_id) + `SELECT id, board_slug, subject, created_at, bumped_at FROM threads WHERE board_slug = ?`, slug) if err != nil { return nil, err } @@ -44,7 +44,7 @@ func GetBoardThreads(db *sql.DB, board_id int) ([]Thread, error) { var result []Thread for rows.Next() { var t Thread - err := rows.Scan(&t.Id, &t.BoardId, &t.Subject, &t.CreatedAt, &t.BumpedAt) + err := rows.Scan(&t.Id, &t.BoardSlug, &t.Subject, &t.CreatedAt, &t.BumpedAt) if err != nil { return nil, err } @@ -74,14 +74,14 @@ func GetThreadPosts(db *sql.DB, thread_id int) ([]Post, error) { return result, rows.Err() } -func PutBoardThread(db *sql.DB, boardId int, subject string, body string) error { +func PutBoardThread(db *sql.DB, board_slug string, subject string, body string) error { tx, err := db.Begin() if err != nil { return err } defer tx.Rollback() - res, err := tx.Exec(`INSERT INTO threads (board_id, subject) VALUES (?, ?) RETURNING id`, boardId, subject) + res, err := tx.Exec(`INSERT INTO threads (board_slug, subject) VALUES (?, ?) RETURNING id`, board_slug, subject) if err != nil { return err } diff --git a/internal/database/models.go b/internal/database/models.go index 2cf6c46..42ee5ea 100644 --- a/internal/database/models.go +++ b/internal/database/models.go @@ -11,7 +11,7 @@ type Board struct { type Thread struct { Id int - BoardId int + BoardSlug string Subject string CreatedAt time.Time BumpedAt time.Time diff --git a/internal/database/seed.sql b/internal/database/seed.sql index 97abe33..7565f53 100644 --- a/internal/database/seed.sql +++ b/internal/database/seed.sql @@ -13,11 +13,11 @@ CREATE TABLE IF NOT EXISTS boards ( CREATE TABLE IF NOT EXISTS threads ( id INTEGER PRIMARY KEY AUTOINCREMENT, - board_id INTEGER NOT NULL, + board_slug TEXT NOT NULL, subject TEXT NOT NULL DEFAULT '', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, bumped_at DATETIME DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (board_id) REFERENCES boards(id) ON DELETE CASCADE + FOREIGN KEY (board_slug) REFERENCES boards(slug) ON DELETE CASCADE ON UPDATE CASCADE ); CREATE TABLE IF NOT EXISTS posts ( @@ -42,8 +42,8 @@ INSERT INTO boards (slug, name, tag) VALUES -- Welcome threads -- /comfy/ - INSERT INTO threads (board_id, subject) VALUES ( - (SELECT id FROM boards WHERE slug='comfy'), + INSERT INTO threads (board_slug, subject) VALUES ( + 'comfy', 'Welcome to /comfy/.' ); INSERT INTO posts (thread_id, body) VALUES ( diff --git a/main.go b/main.go index d2d0015..2c7c8bc 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,6 @@ import ( _ "github.com/mattn/go-sqlite3" "log" "net/http" - "strconv" ) var dev = true @@ -58,15 +57,24 @@ func main() { views.Board(board).Render(r.Context(), w) }) - r.Get("/hx/boards/{boardId}/catalog", func(w http.ResponseWriter, r *http.Request) { - boardIdStr := chi.URLParam(r, "boardId") - boardId, err := strconv.Atoi(boardIdStr) - if err != nil { - http.Error(w, "invalid board id", http.StatusBadRequest) - return - } + // r.Get("/{slug}/{threadId}/posts", func(w http.ResponseWriter, r *http.Request) { + // slug := chi.URLParam(r, "slug") + // threadIdStr := chi.URLParam(r, "postId") + // threadId, err := strconv.Atoi(threadIdStr) + // if err != nil { + // http.Error(w, "Invalid thread id", http.StatusBadRequest) + // return + // } + // + // posts, err := database.GetThreadPosts(db, threadId) + // if err != nil { + // http.Error(w, "Failed to get thread posts", http.StatusInternalServerError) + // } + // }) - threads, err := database.GetBoardThreads(db, boardId) + r.Get("/hx/{slug}/catalog", func(w http.ResponseWriter, r *http.Request) { + slug := chi.URLParam(r, "slug") + threads, err := database.GetBoardThreads(db, slug) if err != nil { http.Error(w, "Failed to get board threads", http.StatusInternalServerError) log.Printf("GetBoardThreads: %v", err) @@ -91,13 +99,8 @@ func main() { views.PostsCatalog(vms).Render(r.Context(), w) }) - r.Post("/boards/{boardId}/threads", func(w http.ResponseWriter, r *http.Request) { - boardIdStr := chi.URLParam(r, "boardId") - boardId, err := strconv.Atoi(boardIdStr) - if err != nil { - http.Error(w, "invalid board id", http.StatusBadRequest) - return - } + r.Post("/{slug}/threads", func(w http.ResponseWriter, r *http.Request) { + slug := chi.URLParam(r, "slug") if err := r.ParseForm(); err != nil { http.Error(w, "Bad form data", http.StatusBadRequest) @@ -107,7 +110,7 @@ func main() { subject := r.FormValue("subject") body := r.FormValue("body") - database.PutBoardThread(db, boardId, subject, body) + database.PutBoardThread(db, slug, subject, body) }) fmt.Println("Listening on :8080") diff --git a/web/static/index.css b/web/static/index.css index a5b9aa4..ff2129a 100644 --- a/web/static/index.css +++ b/web/static/index.css @@ -64,7 +64,7 @@ body { margin: 2rem; } -.thread-catalog-post { +.catalog-post { padding: 10px; border: 2px solid rgba(111, 111, 111, 0.34); min-width: 140px; @@ -72,17 +72,21 @@ body { max-height: 192px; } -.thread-catalog-post h1 { +.catalog-post h1 { font-size: 14px; color: #0F0C5D; font-weight: bold; } -.thread-catalog-post p { +.catalog-post p { margin-top: 10px; font-size: 12px; } +.catalog-post-link { + cursor: pointer; +} + #newThreadBtn { margin-top: 12px; background: none; @@ -103,8 +107,6 @@ body { margin-left: auto; } -.new-thread-form-field {} - .new-thread-form-field th { border: 1px solid black; text-align: left; diff --git a/web/views/board.templ b/web/views/board.templ index f3f2d8b..cb08aac 100644 --- a/web/views/board.templ +++ b/web/views/board.templ @@ -1,48 +1,51 @@ package views import ( - "fmt" - database "github.com/dominicf2001/comfychan/internal/database" - "github.com/dominicf2001/comfychan/web/views/shared" +"fmt" +database "github.com/dominicf2001/comfychan/internal/database" +"github.com/dominicf2001/comfychan/web/views/shared" ) templ NewThreadForm(board database.Board) { - + +} + +templ BoardHeader(board database.Board) { +
+ +

+ { fmt.Sprintf("/%s/ - %s", board.Slug, board.Name) } +

+

{ board.Tag }

+
} templ Board(board database.Board) { - @shared.Layout() { -
- -

- { fmt.Sprintf("/%s/ - %s", board.Slug, board.Name) } -

-

{ board.Tag }

-
-
- - @NewThreadForm(board) -
-
- } +@shared.Layout() { +@BoardHeader(board) +
+ + @NewThreadForm(board) +
+
+} } diff --git a/web/views/post.templ b/web/views/post.templ new file mode 100644 index 0000000..4c5909a --- /dev/null +++ b/web/views/post.templ @@ -0,0 +1,7 @@ +package views + +import "github.com/dominicf2001/comfychan/internal/database" + +templ Post(board database.Board) { +BoardHeader(board) +} diff --git a/web/views/posts.templ b/web/views/posts.templ index 494be6f..4f3b124 100644 --- a/web/views/posts.templ +++ b/web/views/posts.templ @@ -3,17 +3,17 @@ package views import "github.com/dominicf2001/comfychan/internal/database" type ThreadGridBoxViewModel struct { - Thread database.Thread - Posts []database.Post +Thread database.Thread +Posts []database.Post } templ PostsCatalog(vms []ThreadGridBoxViewModel) { -
- for _, vm := range vms { -
-

{ vm.Thread.Subject }

-

{ vm.Posts[0].Body }

-
- } +
+ for _, vm := range vms { +
+

{ vm.Thread.Subject }

+

{ vm.Posts[0].Body }

+ } +
}