finish ui redesign
This commit is contained in:
		
							parent
							
								
									5e7524196a
								
							
						
					
					
						commit
						17d25da9d4
					
				
							
								
								
									
										4
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal 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 | ||||||
| @ -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) | ||||||
| } | } | ||||||
|  | |||||||
| @ -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) { | ||||||
|  | |||||||
| @ -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") | ||||||
|  | |||||||
| @ -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)) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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 { | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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
									
								
							
							
								
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								ui/static/fontawesome
									
									
									
									
									
										Submodule
									
								
							| @ -0,0 +1 @@ | |||||||
|  | Subproject commit 5a85d8a93237e08d9d1f861aa5630f292424cfc0 | ||||||
| @ -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> | ||||||
|  | |||||||
| @ -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 | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -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
											
										
									
								
							| @ -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> | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user