finish ui redesign

This commit is contained in:
yequari 2025-08-16 20:13:22 -07:00
parent 5e7524196a
commit 17d25da9d4
17 changed files with 1204 additions and 954 deletions

4
.gitmodules vendored Normal file
View File

@ -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

View File

@ -14,6 +14,10 @@ func (app *application) home(w http.ResponseWriter, r *http.Request) {
views.Home("Home", app.newCommonData(r)).Render(r.Context(), w) 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) { func (app *application) notImplemented(w http.ResponseWriter, r *http.Request) {
views.ComingSoon("Coming Soon", app.newCommonData(r)).Render(r.Context(), w) views.ComingSoon("Coming Soon", app.newCommonData(r)).Render(r.Context(), w)
} }

View File

@ -36,7 +36,7 @@ func (app *application) getGuestbook(w http.ResponseWriter, r *http.Request) {
return return
} }
} }
comments, err := app.guestbookComments.GetAll(website.Guestbook.ID) comments, err := app.guestbookComments.GetVisible(website.Guestbook.ID)
if err != nil { if err != nil {
app.serverError(w, r, err) app.serverError(w, r, err)
return return
@ -79,7 +79,7 @@ func (app *application) getGuestbookCommentsSerialized(w http.ResponseWriter, r
if !website.Guestbook.Settings.IsVisible || !website.Guestbook.Settings.AllowRemoteHostAccess { if !website.Guestbook.Settings.IsVisible || !website.Guestbook.Settings.AllowRemoteHostAccess {
app.clientError(w, http.StatusForbidden) app.clientError(w, http.StatusForbidden)
} }
comments, err := app.guestbookComments.GetAllSerialized(website.Guestbook.ID) comments, err := app.guestbookComments.GetVisibleSerialized(website.Guestbook.ID)
if err != nil { if err != nil {
app.serverError(w, r, err) app.serverError(w, r, err)
return return
@ -151,7 +151,7 @@ func (app *application) postGuestbookCommentCreate(w http.ResponseWriter, r *htt
views.EmbeddableGuestbookCommentForm(data, website, form).Render(r.Context(), w) views.EmbeddableGuestbookCommentForm(data, website, form).Render(r.Context(), w)
} }
// TODO: use htmx to avoid getting comments again // 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 { if err != nil {
app.serverError(w, r, err) app.serverError(w, r, err)
return return
@ -243,7 +243,7 @@ func (app *application) getCommentQueue(w http.ResponseWriter, r *http.Request)
return return
} }
comments, err := app.guestbookComments.GetUnpublished(website.Guestbook.ID) comments, err := app.guestbookComments.GetAll(website.Guestbook.ID)
if err != nil { if err != nil {
if errors.Is(err, models.ErrNoRecord) { if errors.Is(err, models.ErrNoRecord) {
http.NotFound(w, r) http.NotFound(w, r)
@ -315,6 +315,8 @@ func (app *application) putHideGuestbookComment(w http.ResponseWriter, r *http.R
if err != nil { if err != nil {
app.serverError(w, r, err) 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) { 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 { if err != nil {
app.serverError(w, r, err) 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) { func (app *application) getAllGuestbooks(w http.ResponseWriter, r *http.Request) {

View File

@ -23,7 +23,7 @@ func (app *application) logRequest(next http.Handler) http.Handler {
func commonHeaders(next http.Handler) http.Handler { func commonHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 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("Referrer-Policy", "origin-when-cross-origin")
w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("X-Content-Type-Options", "nosniff")
// w.Header().Set("X-Frame-Options", "deny") // w.Header().Set("X-Frame-Options", "deny")

View File

@ -35,6 +35,7 @@ func (app *application) routes() http.Handler {
mux.Handle("/users/login/oidc", dynamic.ThenFunc(app.userLoginOIDC)) mux.Handle("/users/login/oidc", dynamic.ThenFunc(app.userLoginOIDC))
mux.Handle("/users/login/oidc/callback", dynamic.ThenFunc(app.userLoginOIDCCallback)) mux.Handle("/users/login/oidc/callback", dynamic.ThenFunc(app.userLoginOIDCCallback))
mux.Handle("GET /help", dynamic.ThenFunc(app.notImplemented)) mux.Handle("GET /help", dynamic.ThenFunc(app.notImplemented))
mux.Handle("GET /about", dynamic.ThenFunc(app.about))
protected := dynamic.Append(app.requireAuthentication) 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("POST /users/logout", protected.ThenFunc(app.postUserLogout))
mux.Handle("GET /users/settings", protected.ThenFunc(app.getUserSettings)) mux.Handle("GET /users/settings", protected.ThenFunc(app.getUserSettings))
mux.Handle("PUT /users/settings", protected.ThenFunc(app.putUserSettings)) 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 /guestbooks", protected.ThenFunc(app.getAllGuestbooks))
mux.Handle("GET /websites", protected.ThenFunc(app.getWebsiteList)) 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("POST /websites/create", protected.ThenFunc(app.postWebsiteCreate))
mux.Handle("GET /websites/{id}/dashboard", protected.ThenFunc(app.getWebsiteDashboard)) 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", 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("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("PUT /websites/{id}/dashboard/guestbook/comments/{commentId}", protected.ThenFunc(app.putHideGuestbookComment))
mux.Handle("GET /websites/{id}/dashboard/settings", protected.ThenFunc(app.getWebsiteSettings)) 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}/settings", protected.ThenFunc(app.putWebsiteSettings))
mux.Handle("PUT /websites/{id}", protected.ThenFunc(app.deleteWebsite)) 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/themes", protected.ThenFunc(app.getComingSoon))
mux.Handle("GET /websites/{id}/dashboard/guestbook/customize", protected.ThenFunc(app.getComingSoon)) mux.Handle("GET /websites/{id}/dashboard/guestbook/customize", protected.ThenFunc(app.getComingSoon))

View File

@ -33,10 +33,10 @@ type GuestbookCommentModel struct {
type GuestbookCommentModelInterface interface { type GuestbookCommentModelInterface interface {
Insert(shortId uint64, guestbookId, parentId int64, authorName, authorEmail, authorSite, commentText, pageUrl string, isPublished bool) (int64, error) Insert(shortId uint64, guestbookId, parentId int64, authorName, authorEmail, authorSite, commentText, pageUrl string, isPublished bool) (int64, error)
Get(shortId uint64) (GuestbookComment, error) Get(shortId uint64) (GuestbookComment, error)
GetAll(guestbookId int64) ([]GuestbookComment, error) GetVisible(guestbookId int64) ([]GuestbookComment, error)
GetAllSerialized(guestbookId int64) ([]GuestbookCommentSerialized, error) GetVisibleSerialized(guestbookId int64) ([]GuestbookCommentSerialized, error)
GetDeleted(guestbookId int64) ([]GuestbookComment, error) GetDeleted(guestbookId int64) ([]GuestbookComment, error)
GetUnpublished(guestbookId int64) ([]GuestbookComment, error) GetAll(guestbookId int64) ([]GuestbookComment, error)
UpdateComment(comment *GuestbookComment) error UpdateComment(comment *GuestbookComment) error
} }
@ -74,7 +74,7 @@ func (m *GuestbookCommentModel) Get(shortId uint64) (GuestbookComment, error) {
return c, nil 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, stmt := `SELECT Id, ShortId, GuestbookId, ParentId, AuthorName, AuthorEmail, AuthorSite,
CommentText, PageUrl, Created, IsPublished CommentText, PageUrl, Created, IsPublished
FROM guestbook_comments FROM guestbook_comments
@ -100,7 +100,7 @@ func (m *GuestbookCommentModel) GetAll(guestbookId int64) ([]GuestbookComment, e
return comments, nil return comments, nil
} }
func (m *GuestbookCommentModel) GetAllSerialized(guestbookId int64) ([]GuestbookCommentSerialized, error) { func (m *GuestbookCommentModel) GetVisibleSerialized(guestbookId int64) ([]GuestbookCommentSerialized, error) {
stmt := `SELECT AuthorName, CommentText, Created stmt := `SELECT AuthorName, CommentText, Created
FROM guestbook_comments FROM guestbook_comments
WHERE GuestbookId = ? AND IsPublished = TRUE AND DELETED IS NULL WHERE GuestbookId = ? AND IsPublished = TRUE AND DELETED IS NULL
@ -154,11 +154,11 @@ func (m *GuestbookCommentModel) GetDeleted(guestbookId int64) ([]GuestbookCommen
return comments, nil 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, stmt := `SELECT Id, ShortId, GuestbookId, ParentId, AuthorName, AuthorEmail, AuthorSite,
CommentText, PageUrl, Created, IsPublished CommentText, PageUrl, Created, IsPublished
FROM guestbook_comments FROM guestbook_comments
WHERE GuestbookId = ? AND Deleted IS NULL AND IsPublished = FALSE WHERE GuestbookId = ? AND Deleted IS NULL
ORDER BY Created DESC` ORDER BY Created DESC`
rows, err := m.DB.Query(stmt, guestbookId) rows, err := m.DB.Query(stmt, guestbookId)
if err != nil { if err != nil {

View File

@ -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 { switch guestbookId {
case 1: case 1:
return []models.GuestbookComment{mockGuestbookComment}, nil 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 { switch guestbookId {
case 1: case 1:
return []models.GuestbookCommentSerialized{mockSerializedGuestbookComment}, nil 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 { switch guestbookId {
default: default:
return []models.GuestbookComment{}, models.ErrNoRecord return []models.GuestbookComment{}, models.ErrNoRecord

View File

@ -196,6 +196,16 @@ footer {
margin-top: auto; margin-top: auto;
} }
.footer-links {
padding: 0;
list-style: none;
}
.footer-links li {
display: inline-block;
padding: 0 1rem;
}
/* Dashboard Layout */ /* Dashboard Layout */
#dashboard { #dashboard {
display: grid; display: grid;
@ -702,15 +712,9 @@ hr {
margin: var(--space-lg) 0; margin: var(--space-lg) 0;
} }
.htmx-indicator { .htmx-indicator{opacity:0}
opacity: 0; .htmx-request .htmx-indicator{opacity:1; transition: opacity 200ms ease-in;}
transition: opacity 200ms ease-in; .htmx-request.htmx-indicator{opacity:1; transition: opacity 200ms ease-in;}
}
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
opacity: 1;
}
/* Responsive Design */ /* Responsive Design */
@media (max-width: 768px) { @media (max-width: 768px) {

1
ui/static/fontawesome Submodule

@ -0,0 +1 @@
Subproject commit 5a85d8a93237e08d9d1f861aa5630f292424cfc0

View File

@ -68,6 +68,10 @@ templ topNav(data CommonData) {
templ commonFooter() { templ commonFooter() {
<footer> <footer>
<p>A <a href="https://32bit.cafe" rel="noopener">32bit.cafe</a> Project</p> <p>A <a href="https://32bit.cafe" rel="noopener">32bit.cafe</a> Project</p>
<ul class="footer-links">
<li><a href="/about">About</a></li>
<li><a href="/help">Help</a></li>
</ul>
</footer> </footer>
} }
@ -78,7 +82,10 @@ templ base(title string, data CommonData) {
<title>{ title } - webweav.ing</title> <title>{ title } - webweav.ing</title>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="htmx-config" content={ `{"includeIndicatorStyles":false}` }/>
<link href="/static/css/style.css" rel="stylesheet"/> <link href="/static/css/style.css" rel="stylesheet"/>
<link href="/static/fontawesome/css/fontawesome.css" rel="stylesheet"/>
<link href="/static/fontawesome/css/solid.css" rel="stylesheet"/>
<script src="/static/js/htmx.min.js"></script> <script src="/static/js/htmx.min.js"></script>
</head> </head>
<body> <body>

View File

@ -174,7 +174,7 @@ func commonFooter() templ.Component {
templ_7745c5c3_Var5 = templ.NopComponent templ_7745c5c3_Var5 = templ.NopComponent
} }
ctx = templ.ClearChildren(ctx) ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<footer><p>A <a href=\"https://32bit.cafe\" rel=\"noopener\">32bit.cafe</a> Project</p></footer>") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<footer><p>A <a href=\"https://32bit.cafe\" rel=\"noopener\">32bit.cafe</a> Project</p><ul class=\"footer-links\"><li><a href=\"/about\">About</a></li><li><a href=\"/help\">Help</a></li></ul></footer>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -210,13 +210,26 @@ func base(title string, data CommonData) templ.Component {
var templ_7745c5c3_Var7 string var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(title) templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(title)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/common.templ`, Line: 78, Col: 17} return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/common.templ`, Line: 82, Col: 17}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " - webweav.ing</title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><link href=\"/static/css/style.css\" rel=\"stylesheet\"><script src=\"/static/js/htmx.min.js\"></script></head><body>") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " - webweav.ing</title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><meta name=\"htmx-config\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(`{"includeIndicatorStyles":false}`)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/common.templ`, Line: 85, Col: 72}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\"><link href=\"/static/css/style.css\" rel=\"stylesheet\"><link href=\"/static/fontawesome/css/fontawesome.css\" rel=\"stylesheet\"><link href=\"/static/fontawesome/css/solid.css\" rel=\"stylesheet\"><script src=\"/static/js/htmx.min.js\"></script></head><body>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -228,25 +241,25 @@ func base(title string, data CommonData) templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<main role=\"main\">") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<main role=\"main\">")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
if data.Flash != "" { if data.Flash != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<div class=\"notice flash\">") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<div class=\"notice flash\">")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var8 string var templ_7745c5c3_Var9 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(data.Flash) templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(data.Flash)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/common.templ`, Line: 89, Col: 43} return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/common.templ`, Line: 96, Col: 43}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</div>") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</div>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -255,7 +268,7 @@ func base(title string, data CommonData) templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</main>") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</main>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -263,7 +276,7 @@ func base(title string, data CommonData) templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</body></html>") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</body></html>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }

View File

@ -12,15 +12,15 @@ templ GuestbookDashboardCommentsView(title string, data CommonData, website mode
<div> <div>
<section aria-labelledby="comments-management-heading"> <section aria-labelledby="comments-management-heading">
<header class="section-header"> <header class="section-header">
<h1 id="comments-management-heading">Comments on yq</h1> <h1 id="comments-management-heading">Comments on { website.Name }</h1>
<p class="section-description">Manage, moderate, and organize comments on your guestbook</p> <p class="section-description">Manage, moderate, and organize comments on your guestbook</p>
</header> </header>
<hr role="separator"/> <hr role="separator"/>
if len(comments) == 0 { if len(comments) == 0 {
<p>No comments yet!</p> <p>No comments yet!</p>
} }
for _, c := range comments { for i, c := range comments {
@GuestbookDashboardCommentView(data, website, c) @GuestbookDashboardCommentView(data, website, c, i)
} }
</section> </section>
</div> </div>
@ -28,40 +28,77 @@ templ GuestbookDashboardCommentsView(title string, data CommonData, website mode
} }
} }
templ GuestbookDashboardCommentView(data CommonData, w models.Website, c models.GuestbookComment) { templ GuestbookDashboardCommentDeletePart(text string) {
<div class="comment-update-msg">
<p>{ text }</p>
</div>
}
templ GuestbookDashboardUpdateButtonPart(data CommonData, w models.Website, c models.GuestbookComment) {
{{ hxHeaders := fmt.Sprintf("{\"X-CSRF-Token\": \"%s\"}", data.CSRFToken) }}
{{ commentUrl := fmt.Sprintf("%s/dashboard/guestbook/comments/%s", wUrl(w), shortIdToSlug(c.ShortId)) }}
<button
type="button"
class="outline"
hx-put={ commentUrl }
hx-headers={ hxHeaders }
hx-swap="outerHTML"
>
if !c.IsPublished {
Publish
} else {
Hide
}
</button>
}
templ GuestbookDashboardCommentView(data CommonData, w models.Website, c models.GuestbookComment, i int) {
{{ commentUrl := fmt.Sprintf("%s/dashboard/guestbook/comments/%s", wUrl(w), shortIdToSlug(c.ShortId)) }} {{ commentUrl := fmt.Sprintf("%s/dashboard/guestbook/comments/%s", wUrl(w), shortIdToSlug(c.ShortId)) }}
{{ hxHeaders := fmt.Sprintf("{\"X-CSRF-Token\": \"%s\"}", data.CSRFToken) }} {{ hxHeaders := fmt.Sprintf("{\"X-CSRF-Token\": \"%s\"}", data.CSRFToken) }}
<div class="comment"> {{ authorClass := fmt.Sprintf("comment-author-%d", i) }}
<div> <article class="comment" role="article" aria-labelledby={ authorClass }>
if c.Deleted.IsZero() { <div class="comment-update-msg"></div>
<button class="danger" hx-delete={ commentUrl } hx-target="closest div.comment" hx-headers={ hxHeaders }>Delete</button> <header class="comment-header">
<button class="outline" hx-put={ commentUrl } hx-target="closest div.comment" hx-headers={ hxHeaders }> <div class="comment-meta">
if !c.IsPublished { <h3 id={ authorClass } class="comment-author">{ c.AuthorName }</h3>
Publish <time datetime={ c.Created.In(data.CurrentUser.Settings.LocalTimezone).Format("01-02-2006 03:04PM") }>{ c.Created.In(data.CurrentUser.Settings.LocalTimezone).Format("01-02-2006 03:04PM") }</time>
} else { if len(c.AuthorEmail) > 0 {
Hide <div class="comment-contact">
} {{ email := "mailto:" + c.AuthorEmail }}
</button> <i class="fa-solid fa-envelope"></i>
} <a href={ templ.URL(email) } target="_blank">{ c.AuthorEmail }</a>
</div> </div>
<div> }
<strong>{ c.AuthorName }</strong> if len(c.AuthorSite) > 0 {
if len(c.AuthorEmail) > 0 { <div class="comment-contact">
{{ email := "mailto:" + c.AuthorEmail }} <i class="fa-solid fa-house"></i>
| <a href={ templ.URL(email) } target="_blank">{ c.AuthorEmail }</a> <a href={ templ.URL(externalUrl(c.AuthorSite)) } target="_blank">{ c.AuthorSite }</a>
} </div>
if len(c.AuthorSite) > 0 { }
| <a href={ templ.URL(externalUrl(c.AuthorSite)) } target="_blank">{ c.AuthorSite }</a> </div>
} <div class="comment-actions" role="group" aria-label={ fmt.Sprintf("Actions for comment by %s", c.AuthorName) }>
if c.Deleted.IsZero() {
<button
type="button"
class="danger"
hx-delete={ commentUrl }
hx-target="closest article.comment"
hx-confirm="Are you sure you want to delete this comment? This action cannot be undone."
hx-headers={ hxHeaders }
>
Delete
</button>
@GuestbookDashboardUpdateButtonPart(data, w, c)
}
</div>
</header>
<div class="comment-content">
<p> <p>
{ c.Created.In(data.CurrentUser.Settings.LocalTimezone).Format("01-02-2006 03:04PM") } { c.CommentText }
</p> </p>
</div> </div>
<p> <hr role="separator"/>
{ c.CommentText } </article>
</p>
<hr/>
</div>
} }
templ commentForm(form forms.CommentCreateForm) { templ commentForm(form forms.CommentCreateForm) {
@ -83,7 +120,7 @@ templ commentForm(form forms.CommentCreateForm) {
<label class="error">{ error }</label> <label class="error">{ error }</label>
} }
<input type="email" name="authoremail" id="authoremail" aria-describedby="authoremail-help"/> <input type="email" name="authoremail" id="authoremail" aria-describedby="authoremail-help"/>
<small id="authoremail-help">We won't share your email address, except with the guestbook's owner</small> <small id="authoremail-help">Your email address will only be shared with the guestbook's owner</small>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="authorsite">Website URL (Optional)</label> <label for="authorsite">Website URL (Optional)</label>

File diff suppressed because it is too large Load Diff

View File

@ -18,3 +18,11 @@ templ ComingSoon(title string, data CommonData) {
<h2>Coming Soon</h2> <h2>Coming Soon</h2>
} }
} }
templ AboutPage(title string, data CommonData) {
@base(title, data) {
<section aria-labelledby="about-heading">
<h2 id="about-heading">About Webweav.ing</h2>
</section>
}
}

View File

@ -102,4 +102,51 @@ func ComingSoon(title string, data CommonData) templ.Component {
}) })
} }
func AboutPage(title string, data CommonData) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<section aria-labelledby=\"about-heading\"><h2 id=\"about-heading\">About Webweav.ing</h2></section>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate var _ = templruntime.GeneratedTemplate

View File

@ -30,15 +30,9 @@ templ wSidebar(website models.Website) {
<h3 id="guestbook-nav-heading">Guestbook</h3> <h3 id="guestbook-nav-heading">Guestbook</h3>
<ul role="list"> <ul role="list">
<li><a href={ templ.URL(gbUrl) } target="_blank">View Guestbook</a></li> <li><a href={ templ.URL(gbUrl) } target="_blank">View Guestbook</a></li>
<li><a href={ templ.URL(dashUrl + "/guestbook/comments") }>Manage messages</a></li> <li><a href={ templ.URL(dashUrl + "/guestbook/comments") }>Manage Comments</a></li>
<li><a href={ templ.URL(dashUrl + "/guestbook/comments/queue") }>Review message queue</a></li>
<li><a href={ templ.URL(dashUrl + "/guestbook/comments/trash") }>Trash</a></li>
</ul> </ul>
</section> </section>
//<ul>
//<li><a href={ templ.URL(dashUrl + "/guestbook/themes") }>Themes</a></li>
//<li><a href={ templ.URL(dashUrl + "/guestbook/customize") }>Custom CSS</a></li>
//</ul>
</div> </div>
<div> <div>
<section aria-labelledby="feeds-nav-heading"> <section aria-labelledby="feeds-nav-heading">

File diff suppressed because it is too large Load Diff