diff --git a/cmd/web/handlers_website.go b/cmd/web/handlers_website.go index d1c8d7c..add16a1 100644 --- a/cmd/web/handlers_website.go +++ b/cmd/web/handlers_website.go @@ -113,6 +113,7 @@ func (app *application) getWebsiteSettings(w http.ResponseWriter, r *http.Reques } else { app.serverError(w, r, err) } + return } var form forms.WebsiteSettingsForm data := app.newCommonData(r) @@ -128,6 +129,7 @@ func (app *application) putWebsiteSettings(w http.ResponseWriter, r *http.Reques } else { app.serverError(w, r, err) } + return } var form forms.WebsiteSettingsForm @@ -185,3 +187,39 @@ func (app *application) putWebsiteSettings(w http.ResponseWriter, r *http.Reques views.SettingsForm(data, website, forms.WebsiteSettingsForm{}, "Settings changed successfully").Render(r.Context(), w) } + +func (app *application) deleteWebsite(w http.ResponseWriter, r *http.Request) { + slug := r.PathValue("id") + website, err := app.websites.Get(slugToShortId(slug)) + if err != nil { + if errors.Is(err, models.ErrNoRecord) { + http.NotFound(w, r) + } else { + app.serverError(w, r, err) + } + return + } + var form forms.WebsiteDeleteForm + err = app.decodePostForm(r, &form) + if err != nil { + app.serverError(w, r, err) + return + } + + form.CheckField(validator.Equals(website.Name, form.Delete), "delete", "Input must match site name exactly") + if !form.Valid() { + data := app.newCommonData(r) + views.DeleteForm(data, website, form).Render(r.Context(), w) + return + } + + err = app.websites.Delete(website.ID) + if err != nil { + app.serverError(w, r, err) + return + } + + app.sessionManager.Put(r.Context(), "flash", "Website Deleted") + w.Header().Add("HX-Redirect", "/websites") + w.WriteHeader(http.StatusOK) +} diff --git a/cmd/web/routes.go b/cmd/web/routes.go index 0528c63..89884d5 100644 --- a/cmd/web/routes.go +++ b/cmd/web/routes.go @@ -50,7 +50,8 @@ func (app *application) routes() http.Handler { 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}/dashboard/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("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/forms/forms.go b/internal/forms/forms.go index 99d8d1c..ebb7b25 100644 --- a/internal/forms/forms.go +++ b/internal/forms/forms.go @@ -31,6 +31,11 @@ type WebsiteCreateForm struct { validator.Validator `schema:"-"` } +type WebsiteDeleteForm struct { + Delete string `schema:"delete"` + validator.Validator `schema:"-"` +} + type UserSettingsForm struct { LocalTimezone string `schema:"timezones"` validator.Validator `schema:"-"` diff --git a/internal/models/mocks/website.go b/internal/models/mocks/website.go index 21f2800..bc50020 100644 --- a/internal/models/mocks/website.go +++ b/internal/models/mocks/website.go @@ -72,6 +72,9 @@ func (m *WebsiteModel) GetAll() ([]models.Website, error) { func (m *WebsiteModel) Update(w models.Website) error { return nil } +func (m *WebsiteModel) Delete(websiteId int64) error { + return nil +} func (m *WebsiteModel) InitializeSettingsMap() error { return nil diff --git a/internal/models/website.go b/internal/models/website.go index cdc4102..6385530 100644 --- a/internal/models/website.go +++ b/internal/models/website.go @@ -101,6 +101,7 @@ type WebsiteModelInterface interface { InitializeSettingsMap() error UpdateGuestbookSettings(guestbookId int64, settings GuestbookSettings) error UpdateSetting(guestbookId int64, setting Setting, value string) error + Delete(websiteId int64) error } func (m *WebsiteModel) Insert(shortId uint64, userId int64, siteName, siteUrl, authorName string) (int64, error) { @@ -244,7 +245,7 @@ func (m *WebsiteModel) GetAllUser(userId int64) ([]Website, error) { stmt := `SELECT w.Id, w.ShortId, w.Name, w.SiteUrl, w.AuthorName, w.UserId, w.Created, g.Id, g.ShortId, g.Created, g.IsActive FROM websites AS w INNER JOIN guestbooks AS g ON w.Id = g.WebsiteId - WHERE w.UserId = ?` + WHERE w.UserId = ? AND w.Deleted IS NULL` rows, err := m.DB.Query(stmt, userId) if err != nil { return nil, err @@ -273,7 +274,7 @@ func (m *WebsiteModel) GetAllUser(userId int64) ([]Website, error) { func (m *WebsiteModel) GetAll() ([]Website, error) { stmt := `SELECT w.Id, w.ShortId, w.Name, w.SiteUrl, w.AuthorName, w.UserId, w.Created, g.Id, g.ShortId, g.Created, g.IsActive - FROM websites AS w INNER JOIN guestbooks AS g ON w.Id = g.WebsiteId` + FROM websites AS w INNER JOIN guestbooks AS g ON w.Id = g.WebsiteId WHERE w.Deleted IS NULL` rows, err := m.DB.Query(stmt) if err != nil { return nil, err @@ -314,6 +315,21 @@ func (m *WebsiteModel) Update(w Website) error { return nil } +func (m *WebsiteModel) Delete(websiteId int64) error { + stmt := `UPDATE websites SET Deleted = ? WHERE ID = ?` + r, err := m.DB.Exec(stmt, time.Now().UTC(), websiteId) + if err != nil { + return err + } + if rows, err := r.RowsAffected(); rows != 1 { + if err != nil { + return err + } + return errors.New("Failed to update website") + } + return nil +} + func (m *WebsiteModel) getGuestbookSettings(tx *sql.Tx, guestbookId int64) (GuestbookSettings, error) { stmt := `SELECT g.SettingId, a.ItemValue, g.UnconstrainedValue FROM guestbook_settings AS g LEFT JOIN allowed_setting_values AS a ON g.AllowedSettingValueId = a.Id diff --git a/internal/validator/validator.go b/internal/validator/validator.go index 62037b2..5991605 100644 --- a/internal/validator/validator.go +++ b/internal/validator/validator.go @@ -57,3 +57,7 @@ func MinChars(value string, n int) bool { func Matches(value string, rx *regexp.Regexp) bool { return rx.MatchString(value) } + +func Equals(expected, actual string) bool { + return expected == actual +} diff --git a/ui/views/websites.templ b/ui/views/websites.templ index 03b9168..fab8123 100644 --- a/ui/views/websites.templ +++ b/ui/views/websites.templ @@ -232,7 +232,7 @@ templ guestbookSettingsForm(data CommonData, website models.Website, gb models.G } templ SettingsForm(data CommonData, website models.Website, form forms.WebsiteSettingsForm, msg string) { - {{ putUrl := fmt.Sprintf("/websites/%s/dashboard/settings", shortIdToSlug(website.ShortId)) }} + {{ putUrl := fmt.Sprintf("/websites/%s/settings", shortIdToSlug(website.ShortId)) }} {{ gb := website.Guestbook }}
} +templ DeleteForm(data CommonData, website models.Website, form forms.WebsiteDeleteForm) { + {{ putUrl := fmt.Sprintf("/websites/%s", shortIdToSlug(website.ShortId)) }} + +} + templ WebsiteDashboardSettings(data CommonData, website models.Website, form forms.WebsiteSettingsForm) { {{ title := fmt.Sprintf("%s - Settings", website.Name) }} @base(title, data) { @@ -254,14 +270,7 @@ templ WebsiteDashboardSettings(data CommonData, website models.Website, form for @wSidebar(website)Coming Soon
Coming Soon