diff --git a/' b/' deleted file mode 100644 index 51d0fb6..0000000 --- a/' +++ /dev/null @@ -1,130 +0,0 @@ -body { - background: #EEF2FF; -} - -/* INDEX */ - -#clavis { - display: block; - width: 300px; - margin: 10px auto; - margin-bottom: 50px; -} - - -/* BOARD LIST */ - -#boardList { - font-size: 12px; - margin: 5px; -} - -#boardList a { - cursor: pointer; - color: #575F68; -} - -#boardList a:hover { - color: #ff0000; -} - -/* BOARDS */ - -.board-header { - text-align: center; - color: #AF0A0F; -} - -.board-header h1 { - font-weight: bold; - font-size: 1.8rem; - margin: 8px; - margin-top: 12px; -} - -.board-header p { - font-size: .8rem; - margin: 4px; -} - -.board-header img { - width: 300px; -} - -.new-thread-container { - width: max-content; - margin: auto; -} - -.thread-catalog-post { - border: 2px solid rgba(111, 111, 111, 0.34); - min-width: 140px; - max-width: 140px; - max-height: 192px; -} - -.thread-catalog-post h1 { - color: #0F0C5D; - font-weight: bold; -} - -.thread-catalog-post p { - margin-top: 10px; - font-size: 12px; -} - -#newThreadBtn { - margin-top: 12px; - background: none; - border: none; - padding: 0; - font-weight: bold; - font-size: 1.2rem; - color: #34345C; - cursor: pointer; -} - -#newThreadBtn:hover { - color: #ff0000 -} - -.new-thread-form-field {} - -.new-thread-form-field th { - border: 1px solid black; - text-align: left; - vertical-align: middle; - padding: 4px; - background: #98E; - font-weight: bold; - font-size: .8rem; -} - -.new-thread-form-field td { - display: block; - margin: 2px; -} - -/* GENERAL LAYOUT */ - -.container { - width: 600px; - margin: auto; -} - -.box { - font-size: 12px; - border: 1px solid black; - background-color: #eceff6; -} - -.box h2 { - padding: 5px; - margin: 0; - background-color: #00007F; - color: #FFF; -} - -.box p { - padding: 10px; -} diff --git a/internal/database/handlers.go b/internal/database/handlers.go index d296916..8affbc1 100644 --- a/internal/database/handlers.go +++ b/internal/database/handlers.go @@ -73,3 +73,32 @@ 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 { + 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) + if err != nil { + return err + } + + threadId, err := res.LastInsertId() + if err != nil { + return err + } + + _, err = tx.Exec(`INSERT INTO posts (thread_id, body) VALUES (?, ?)`, threadId, body) + if err != nil { + return err + } + + if err = tx.Commit(); err != nil { + return err + } + + return nil +} diff --git a/main.go b/main.go index 5390436..d2d0015 100644 --- a/main.go +++ b/main.go @@ -3,15 +3,14 @@ package main import ( "database/sql" "fmt" - "log" - "net/http" - "strconv" - "github.com/dominicf2001/comfychan/internal/database" "github.com/dominicf2001/comfychan/web/views" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" _ "github.com/mattn/go-sqlite3" + "log" + "net/http" + "strconv" ) var dev = true @@ -59,7 +58,7 @@ func main() { views.Board(board).Render(r.Context(), w) }) - r.Get("/hx/{boardId}/posts/grid", func(w http.ResponseWriter, r *http.Request) { + 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 { @@ -89,7 +88,26 @@ func main() { }) } - views.PostsGrid(vms).Render(r.Context(), w) + 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 + } + + if err := r.ParseForm(); err != nil { + http.Error(w, "Bad form data", http.StatusBadRequest) + return + } + + subject := r.FormValue("subject") + body := r.FormValue("body") + + database.PutBoardThread(db, boardId, subject, body) }) fmt.Println("Listening on :8080") diff --git a/web/static/index.css b/web/static/index.css index b95a808..a5b9aa4 100644 --- a/web/static/index.css +++ b/web/static/index.css @@ -54,21 +54,26 @@ body { .new-thread-container { width: max-content; margin: auto; + margin-top: 16px; } -#threadCatalog { - margin: 0 2rem; +#catalog { + display: grid; + grid-template-columns: auto auto auto auto; + gap: 1rem; + margin: 2rem; } .thread-catalog-post { padding: 10px; border: 2px solid rgba(111, 111, 111, 0.34); min-width: 140px; - max-width: 140px; + max-width: 200px; max-height: 192px; } .thread-catalog-post h1 { + font-size: 14px; color: #0F0C5D; font-weight: bold; } @@ -93,6 +98,11 @@ body { color: #ff0000 } +#newThreadForm button { + display: block; + margin-left: auto; +} + .new-thread-form-field {} .new-thread-form-field th { diff --git a/web/views/board.templ b/web/views/board.templ index 3f995be..f3f2d8b 100644 --- a/web/views/board.templ +++ b/web/views/board.templ @@ -1,43 +1,48 @@ 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() { - + + } templ Board(board database.Board) { -@shared.Layout() { -
- -

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

-

{ board.Tag }

-
-
- - @NewThreadForm() -
-
-} + @shared.Layout() { +
+ +

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

+

{ board.Tag }

+
+
+ + @NewThreadForm(board) +
+
+ } } diff --git a/web/views/posts.templ b/web/views/posts.templ index 40b1af1..494be6f 100644 --- a/web/views/posts.templ +++ b/web/views/posts.templ @@ -3,15 +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 PostsGrid(vms []ThreadGridBoxViewModel) { -for _, vm := range vms { -
-

{ vm.Thread.Subject }

-

{ vm.Posts[0].Body }

-
-} +templ PostsCatalog(vms []ThreadGridBoxViewModel) { +
+ for _, vm := range vms { +
+

{ vm.Thread.Subject }

+

{ vm.Posts[0].Body }

+
+ } +
}