diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3a1daf7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "ui/static/fontawesome"] + path = ui/static/fontawesome + url = https://github.com/FortAwesome/Font-Awesome.git + branch = fa-release-7.0.0 diff --git a/cmd/web/handlers.go b/cmd/web/handlers.go index a72a3b4..f5d5246 100644 --- a/cmd/web/handlers.go +++ b/cmd/web/handlers.go @@ -14,6 +14,10 @@ func (app *application) home(w http.ResponseWriter, r *http.Request) { views.Home("Home", app.newCommonData(r)).Render(r.Context(), w) } +func (app *application) about(w http.ResponseWriter, r *http.Request) { + views.AboutPage("About Webweav.ing", app.newCommonData(r)).Render(r.Context(), w) +} + func (app *application) notImplemented(w http.ResponseWriter, r *http.Request) { views.ComingSoon("Coming Soon", app.newCommonData(r)).Render(r.Context(), w) } diff --git a/cmd/web/handlers_guestbook.go b/cmd/web/handlers_guestbook.go index 4d90132..4128e08 100644 --- a/cmd/web/handlers_guestbook.go +++ b/cmd/web/handlers_guestbook.go @@ -36,7 +36,7 @@ func (app *application) getGuestbook(w http.ResponseWriter, r *http.Request) { return } } - comments, err := app.guestbookComments.GetAll(website.Guestbook.ID) + comments, err := app.guestbookComments.GetVisible(website.Guestbook.ID) if err != nil { app.serverError(w, r, err) return @@ -79,7 +79,7 @@ func (app *application) getGuestbookCommentsSerialized(w http.ResponseWriter, r if !website.Guestbook.Settings.IsVisible || !website.Guestbook.Settings.AllowRemoteHostAccess { app.clientError(w, http.StatusForbidden) } - comments, err := app.guestbookComments.GetAllSerialized(website.Guestbook.ID) + comments, err := app.guestbookComments.GetVisibleSerialized(website.Guestbook.ID) if err != nil { app.serverError(w, r, err) return @@ -151,7 +151,7 @@ func (app *application) postGuestbookCommentCreate(w http.ResponseWriter, r *htt views.EmbeddableGuestbookCommentForm(data, website, form).Render(r.Context(), w) } // TODO: use htmx to avoid getting comments again - comments, err := app.guestbookComments.GetAll(website.Guestbook.ID) + comments, err := app.guestbookComments.GetVisible(website.Guestbook.ID) if err != nil { app.serverError(w, r, err) return @@ -243,7 +243,7 @@ func (app *application) getCommentQueue(w http.ResponseWriter, r *http.Request) return } - comments, err := app.guestbookComments.GetUnpublished(website.Guestbook.ID) + comments, err := app.guestbookComments.GetAll(website.Guestbook.ID) if err != nil { if errors.Is(err, models.ErrNoRecord) { http.NotFound(w, r) @@ -315,6 +315,8 @@ func (app *application) putHideGuestbookComment(w http.ResponseWriter, r *http.R if err != nil { app.serverError(w, r, err) } + data := app.newCommonData(r) + views.GuestbookDashboardUpdateButtonPart(data, website, comment).Render(r.Context(), w) } func (app *application) deleteGuestbookComment(w http.ResponseWriter, r *http.Request) { @@ -349,6 +351,7 @@ func (app *application) deleteGuestbookComment(w http.ResponseWriter, r *http.Re if err != nil { app.serverError(w, r, err) } + views.GuestbookDashboardCommentDeletePart("Comment was successfully deleted").Render(r.Context(), w) } func (app *application) getAllGuestbooks(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/web/middleware.go b/cmd/web/middleware.go index c9d83ec..a2d916e 100644 --- a/cmd/web/middleware.go +++ b/cmd/web/middleware.go @@ -23,7 +23,7 @@ func (app *application) logRequest(next http.Handler) http.Handler { func commonHeaders(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Security-Policy", "default-src 'self'; style-src 'self' fonts.googleapis.com; font-src fonts.gstatic.com") + w.Header().Set("Content-Security-Policy", "default-src 'self'; style-src 'self' fonts.googleapis.com; font-src fonts.gstatic.com 'self'; style-src-elem 'self';") w.Header().Set("Referrer-Policy", "origin-when-cross-origin") w.Header().Set("X-Content-Type-Options", "nosniff") // w.Header().Set("X-Frame-Options", "deny") diff --git a/cmd/web/routes.go b/cmd/web/routes.go index c168a11..e2f6509 100644 --- a/cmd/web/routes.go +++ b/cmd/web/routes.go @@ -35,6 +35,7 @@ func (app *application) routes() http.Handler { mux.Handle("/users/login/oidc", dynamic.ThenFunc(app.userLoginOIDC)) mux.Handle("/users/login/oidc/callback", dynamic.ThenFunc(app.userLoginOIDCCallback)) mux.Handle("GET /help", dynamic.ThenFunc(app.notImplemented)) + mux.Handle("GET /about", dynamic.ThenFunc(app.about)) protected := dynamic.Append(app.requireAuthentication) @@ -43,7 +44,6 @@ func (app *application) routes() http.Handler { mux.Handle("POST /users/logout", protected.ThenFunc(app.postUserLogout)) mux.Handle("GET /users/settings", protected.ThenFunc(app.getUserSettings)) mux.Handle("PUT /users/settings", protected.ThenFunc(app.putUserSettings)) - mux.Handle("GET /users/privacy", protected.ThenFunc(app.notImplemented)) mux.Handle("GET /guestbooks", protected.ThenFunc(app.getAllGuestbooks)) mux.Handle("GET /websites", protected.ThenFunc(app.getWebsiteList)) @@ -51,13 +51,12 @@ func (app *application) routes() http.Handler { mux.Handle("POST /websites/create", protected.ThenFunc(app.postWebsiteCreate)) mux.Handle("GET /websites/{id}/dashboard", protected.ThenFunc(app.getWebsiteDashboard)) mux.Handle("GET /websites/{id}/dashboard/guestbook/comments", protected.ThenFunc(app.getGuestbookComments)) - mux.Handle("GET /websites/{id}/dashboard/guestbook/comments/queue", protected.ThenFunc(app.getCommentQueue)) + mux.Handle("GET /websites/{id}/dashboard/guestbook/comments/hidden", protected.ThenFunc(app.getCommentQueue)) mux.Handle("DELETE /websites/{id}/dashboard/guestbook/comments/{commentId}", protected.ThenFunc(app.deleteGuestbookComment)) mux.Handle("PUT /websites/{id}/dashboard/guestbook/comments/{commentId}", protected.ThenFunc(app.putHideGuestbookComment)) mux.Handle("GET /websites/{id}/dashboard/settings", protected.ThenFunc(app.getWebsiteSettings)) mux.Handle("PUT /websites/{id}/settings", protected.ThenFunc(app.putWebsiteSettings)) mux.Handle("PUT /websites/{id}", protected.ThenFunc(app.deleteWebsite)) - mux.Handle("GET /websites/{id}/dashboard/guestbook/comments/trash", protected.ThenFunc(app.getCommentTrash)) mux.Handle("GET /websites/{id}/dashboard/guestbook/themes", protected.ThenFunc(app.getComingSoon)) mux.Handle("GET /websites/{id}/dashboard/guestbook/customize", protected.ThenFunc(app.getComingSoon)) diff --git a/internal/models/guestbookcomment.go b/internal/models/guestbookcomment.go index d44de26..eb94614 100644 --- a/internal/models/guestbookcomment.go +++ b/internal/models/guestbookcomment.go @@ -33,10 +33,10 @@ type GuestbookCommentModel struct { type GuestbookCommentModelInterface interface { Insert(shortId uint64, guestbookId, parentId int64, authorName, authorEmail, authorSite, commentText, pageUrl string, isPublished bool) (int64, error) Get(shortId uint64) (GuestbookComment, error) - GetAll(guestbookId int64) ([]GuestbookComment, error) - GetAllSerialized(guestbookId int64) ([]GuestbookCommentSerialized, error) + GetVisible(guestbookId int64) ([]GuestbookComment, error) + GetVisibleSerialized(guestbookId int64) ([]GuestbookCommentSerialized, error) GetDeleted(guestbookId int64) ([]GuestbookComment, error) - GetUnpublished(guestbookId int64) ([]GuestbookComment, error) + GetAll(guestbookId int64) ([]GuestbookComment, error) UpdateComment(comment *GuestbookComment) error } @@ -74,7 +74,7 @@ func (m *GuestbookCommentModel) Get(shortId uint64) (GuestbookComment, error) { return c, nil } -func (m *GuestbookCommentModel) GetAll(guestbookId int64) ([]GuestbookComment, error) { +func (m *GuestbookCommentModel) GetVisible(guestbookId int64) ([]GuestbookComment, error) { stmt := `SELECT Id, ShortId, GuestbookId, ParentId, AuthorName, AuthorEmail, AuthorSite, CommentText, PageUrl, Created, IsPublished FROM guestbook_comments @@ -100,7 +100,7 @@ func (m *GuestbookCommentModel) GetAll(guestbookId int64) ([]GuestbookComment, e return comments, nil } -func (m *GuestbookCommentModel) GetAllSerialized(guestbookId int64) ([]GuestbookCommentSerialized, error) { +func (m *GuestbookCommentModel) GetVisibleSerialized(guestbookId int64) ([]GuestbookCommentSerialized, error) { stmt := `SELECT AuthorName, CommentText, Created FROM guestbook_comments WHERE GuestbookId = ? AND IsPublished = TRUE AND DELETED IS NULL @@ -154,11 +154,11 @@ func (m *GuestbookCommentModel) GetDeleted(guestbookId int64) ([]GuestbookCommen return comments, nil } -func (m *GuestbookCommentModel) GetUnpublished(guestbookId int64) ([]GuestbookComment, error) { +func (m *GuestbookCommentModel) GetAll(guestbookId int64) ([]GuestbookComment, error) { stmt := `SELECT Id, ShortId, GuestbookId, ParentId, AuthorName, AuthorEmail, AuthorSite, CommentText, PageUrl, Created, IsPublished FROM guestbook_comments - WHERE GuestbookId = ? AND Deleted IS NULL AND IsPublished = FALSE + WHERE GuestbookId = ? AND Deleted IS NULL ORDER BY Created DESC` rows, err := m.DB.Query(stmt, guestbookId) if err != nil { diff --git a/internal/models/mocks/guestbookcomment.go b/internal/models/mocks/guestbookcomment.go index f8520de..21e755f 100644 --- a/internal/models/mocks/guestbookcomment.go +++ b/internal/models/mocks/guestbookcomment.go @@ -40,7 +40,7 @@ func (m *GuestbookCommentModel) Get(shortId uint64) (models.GuestbookComment, er } } -func (m *GuestbookCommentModel) GetAll(guestbookId int64) ([]models.GuestbookComment, error) { +func (m *GuestbookCommentModel) GetVisible(guestbookId int64) ([]models.GuestbookComment, error) { switch guestbookId { case 1: return []models.GuestbookComment{mockGuestbookComment}, nil @@ -51,7 +51,7 @@ func (m *GuestbookCommentModel) GetAll(guestbookId int64) ([]models.GuestbookCom } } -func (m *GuestbookCommentModel) GetAllSerialized(guestbookId int64) ([]models.GuestbookCommentSerialized, error) { +func (m *GuestbookCommentModel) GetVisibleSerialized(guestbookId int64) ([]models.GuestbookCommentSerialized, error) { switch guestbookId { case 1: return []models.GuestbookCommentSerialized{mockSerializedGuestbookComment}, nil @@ -69,7 +69,7 @@ func (m *GuestbookCommentModel) GetDeleted(guestbookId int64) ([]models.Guestboo } } -func (m *GuestbookCommentModel) GetUnpublished(guestbookId int64) ([]models.GuestbookComment, error) { +func (m *GuestbookCommentModel) GetAll(guestbookId int64) ([]models.GuestbookComment, error) { switch guestbookId { default: return []models.GuestbookComment{}, models.ErrNoRecord diff --git a/ui/static/css/style.css b/ui/static/css/style.css index 29b1844..5b11350 100644 --- a/ui/static/css/style.css +++ b/ui/static/css/style.css @@ -196,6 +196,16 @@ footer { margin-top: auto; } +.footer-links { + padding: 0; + list-style: none; +} + +.footer-links li { + display: inline-block; + padding: 0 1rem; +} + /* Dashboard Layout */ #dashboard { display: grid; @@ -702,15 +712,9 @@ hr { margin: var(--space-lg) 0; } -.htmx-indicator { - opacity: 0; - transition: opacity 200ms ease-in; -} - -.htmx-request .htmx-indicator, -.htmx-request.htmx-indicator { - opacity: 1; -} +.htmx-indicator{opacity:0} +.htmx-request .htmx-indicator{opacity:1; transition: opacity 200ms ease-in;} +.htmx-request.htmx-indicator{opacity:1; transition: opacity 200ms ease-in;} /* Responsive Design */ @media (max-width: 768px) { diff --git a/ui/static/fontawesome b/ui/static/fontawesome new file mode 160000 index 0000000..5a85d8a --- /dev/null +++ b/ui/static/fontawesome @@ -0,0 +1 @@ +Subproject commit 5a85d8a93237e08d9d1f861aa5630f292424cfc0 diff --git a/ui/views/common.templ b/ui/views/common.templ index 9b2b836..666b370 100644 --- a/ui/views/common.templ +++ b/ui/views/common.templ @@ -68,6 +68,10 @@ templ topNav(data CommonData) { templ commonFooter() { } @@ -78,7 +82,10 @@ templ base(title string, data CommonData) {