Implement remote embedding of guestbooks #25
| @ -5,7 +5,6 @@ import ( | |||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" |  | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| @ -258,11 +257,10 @@ func (app *application) postGuestbookCommentCreateRemote(w http.ResponseWriter, | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if normalizeUrl(r.Header.Get("Origin")) != normalizeUrl(website.SiteUrl) { | 	if !matchOrigin(r.Header.Get("Origin"), website.Url) { | ||||||
| 		app.clientError(w, http.StatusForbidden) | 		app.clientError(w, http.StatusForbidden) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	if !website.Guestbook.CanComment() { | 	if !website.Guestbook.CanComment() { | ||||||
| 		app.clientError(w, http.StatusForbidden) | 		app.clientError(w, http.StatusForbidden) | ||||||
| 		return | 		return | ||||||
| @ -285,13 +283,11 @@ func (app *application) postGuestbookCommentCreateRemote(w http.ResponseWriter, | |||||||
| 	// otherwise redirect to the guestbook by default | 	// otherwise redirect to the guestbook by default | ||||||
| 	redirectUrl := fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(website.ShortId)) | 	redirectUrl := fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(website.ShortId)) | ||||||
| 	if form.Redirect != "" { | 	if form.Redirect != "" { | ||||||
| 		u := url.URL{ | 		u, err := website.Url.Parse(form.Redirect) | ||||||
| 			Scheme: "http", | 		if err == nil { | ||||||
| 			Host:   website.SiteUrl, |  | ||||||
| 			Path:   form.Redirect, |  | ||||||
| 		} |  | ||||||
| 			redirectUrl = u.String() | 			redirectUrl = u.String() | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if !form.Valid() { | 	if !form.Valid() { | ||||||
| 		views.GuestbookCommentCreateRemoteErrorView(redirectUrl, "Invalid Input").Render(r.Context(), w) | 		views.GuestbookCommentCreateRemoteErrorView(redirectUrl, "Invalid Input").Render(r.Context(), w) | ||||||
|  | |||||||
| @ -144,3 +144,88 @@ func TestPostGuestbookCommentCreate(t *testing.T) { | |||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func TestPostGuestbookCommentCreateRemote(t *testing.T) { | ||||||
|  | 	app := newTestApplication(t) | ||||||
|  | 	ts := newTestServer(t, app.routes()) | ||||||
|  | 	defer ts.Close() | ||||||
|  | 
 | ||||||
|  | 	_, _, body := ts.get(t, fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(1))) | ||||||
|  | 	validCSRFToken := extractCSRFToken(t, body) | ||||||
|  | 
 | ||||||
|  | 	const ( | ||||||
|  | 		validAuthorName  = "John Test" | ||||||
|  | 		validAuthorEmail = "test@example.com" | ||||||
|  | 		validAuthorSite  = "example.com" | ||||||
|  | 		validContent     = "This is a comment" | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name        string | ||||||
|  | 		authorName  string | ||||||
|  | 		authorEmail string | ||||||
|  | 		authorSite  string | ||||||
|  | 		content     string | ||||||
|  | 		csrfToken   string | ||||||
|  | 		wantCode    int | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			name:        "Valid input", | ||||||
|  | 			authorName:  validAuthorName, | ||||||
|  | 			authorEmail: validAuthorEmail, | ||||||
|  | 			authorSite:  validAuthorSite, | ||||||
|  | 			content:     validContent, | ||||||
|  | 			csrfToken:   validCSRFToken, | ||||||
|  | 			wantCode:    http.StatusSeeOther, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:        "Blank name", | ||||||
|  | 			authorName:  "", | ||||||
|  | 			authorEmail: validAuthorEmail, | ||||||
|  | 			authorSite:  validAuthorSite, | ||||||
|  | 			content:     validContent, | ||||||
|  | 			csrfToken:   validCSRFToken, | ||||||
|  | 			wantCode:    http.StatusUnprocessableEntity, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:        "Blank email", | ||||||
|  | 			authorName:  validAuthorName, | ||||||
|  | 			authorEmail: "", | ||||||
|  | 			authorSite:  validAuthorSite, | ||||||
|  | 			content:     validContent, | ||||||
|  | 			csrfToken:   validCSRFToken, | ||||||
|  | 			wantCode:    http.StatusSeeOther, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:        "Blank site", | ||||||
|  | 			authorName:  validAuthorName, | ||||||
|  | 			authorEmail: validAuthorEmail, | ||||||
|  | 			authorSite:  "", | ||||||
|  | 			content:     validContent, | ||||||
|  | 			csrfToken:   validCSRFToken, | ||||||
|  | 			wantCode:    http.StatusSeeOther, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:        "Blank content", | ||||||
|  | 			authorName:  validAuthorName, | ||||||
|  | 			authorEmail: validAuthorEmail, | ||||||
|  | 			authorSite:  validAuthorSite, | ||||||
|  | 			content:     "", | ||||||
|  | 			csrfToken:   validCSRFToken, | ||||||
|  | 			wantCode:    http.StatusUnprocessableEntity, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	for _, tt := range tests { | ||||||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||||||
|  | 			form := url.Values{} | ||||||
|  | 			form.Add("authorname", tt.authorName) | ||||||
|  | 			form.Add("authoremail", tt.authorEmail) | ||||||
|  | 			form.Add("authorsite", tt.authorSite) | ||||||
|  | 			form.Add("content", tt.content) | ||||||
|  | 			form.Add("csrf_token", tt.csrfToken) | ||||||
|  | 			code, _, body := ts.postForm(t, fmt.Sprintf("/websites/%s/guestbook/comments/create/remote", shortIdToSlug(1)), form) | ||||||
|  | 			assert.Equal(t, code, tt.wantCode) | ||||||
|  | 			assert.Equal(t, body, body) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -33,16 +33,20 @@ func (app *application) postWebsiteCreate(w http.ResponseWriter, r *http.Request | |||||||
| 	form.CheckField(validator.MaxChars(form.Name, 256), "sitename", "This field cannot exceed 256 characters") | 	form.CheckField(validator.MaxChars(form.Name, 256), "sitename", "This field cannot exceed 256 characters") | ||||||
| 	form.CheckField(validator.NotBlank(form.SiteUrl), "siteurl", "This field cannot be blank") | 	form.CheckField(validator.NotBlank(form.SiteUrl), "siteurl", "This field cannot be blank") | ||||||
| 	form.CheckField(validator.MaxChars(form.SiteUrl, 512), "siteurl", "This field cannot exceed 512 characters") | 	form.CheckField(validator.MaxChars(form.SiteUrl, 512), "siteurl", "This field cannot exceed 512 characters") | ||||||
|  | 	form.CheckField(validator.Matches(form.SiteUrl, validator.WebRX), "siteurl", "This field must be a valid URL (including http:// or https://)") | ||||||
| 
 | 
 | ||||||
| 	u, err := url.Parse(form.SiteUrl) | 	u, err := url.Parse(form.SiteUrl) | ||||||
| 
 | 	if err != nil { | ||||||
| 	if !form.Valid() || err != nil { | 		form.CheckField(false, "siteurl", "This field must be a valid URL") | ||||||
|  | 	} | ||||||
|  | 	if !form.Valid() { | ||||||
| 		data := app.newCommonData(r) | 		data := app.newCommonData(r) | ||||||
| 		w.WriteHeader(http.StatusUnprocessableEntity) | 		w.WriteHeader(http.StatusUnprocessableEntity) | ||||||
| 		views.WebsiteCreate("Add a Website", data, form).Render(r.Context(), w) | 		views.WebsiteCreate("Add a Website", data, form).Render(r.Context(), w) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
| 	websiteShortID := app.createShortId() | 	websiteShortID := app.createShortId() | ||||||
| 	_, err = app.websites.Insert(websiteShortID, userId, form.Name, u.Host, form.AuthorName) | 	_, err = app.websites.Insert(websiteShortID, userId, form.Name, u.String(), form.AuthorName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		app.serverError(w, r, err) | 		app.serverError(w, r, err) | ||||||
| 		return | 		return | ||||||
| @ -78,10 +82,6 @@ func (app *application) getWebsiteList(w http.ResponseWriter, r *http.Request) { | |||||||
| 		app.serverError(w, r, err) | 		app.serverError(w, r, err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if r.Header.Get("HX-Request") == "true" { |  | ||||||
| 		views.HxWebsiteList(websites) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	data := app.newCommonData(r) | 	data := app.newCommonData(r) | ||||||
| 	views.WebsiteList("My Websites", data, websites).Render(r.Context(), w) | 	views.WebsiteList("My Websites", data, websites).Render(r.Context(), w) | ||||||
| } | } | ||||||
|  | |||||||
| @ -5,9 +5,9 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math" | 	"math" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  | 	"net/url" | ||||||
| 	"runtime/debug" | 	"runtime/debug" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" |  | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"git.32bit.cafe/32bitcafe/guestbook/internal/models" | 	"git.32bit.cafe/32bitcafe/guestbook/internal/models" | ||||||
| @ -130,11 +130,13 @@ func (app *application) durationToTime(duration string) (time.Time, error) { | |||||||
| 	return result, nil | 	return result, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func normalizeUrl(url string) string { | func matchOrigin(origin string, u *url.URL) bool { | ||||||
| 	r, f := strings.CutPrefix(url, "http://") | 	o, err := url.Parse(origin) | ||||||
| 	if f { | 	if err != nil { | ||||||
| 		return r | 		return false | ||||||
| 	} | 	} | ||||||
| 	r, _ = strings.CutPrefix(url, "https://") | 	if o.Host != u.Host { | ||||||
| 	return r | 		return false | ||||||
|  | 	} | ||||||
|  | 	return true | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,6 +18,12 @@ var mockGuestbookComment = models.GuestbookComment{ | |||||||
| 	IsPublished: true, | 	IsPublished: true, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | var mockSerializedGuestbookComment = models.GuestbookCommentSerialized{ | ||||||
|  | 	AuthorName:  "John Test", | ||||||
|  | 	CommentText: "Hello, world", | ||||||
|  | 	Created:     time.Now().Format(time.RFC3339), | ||||||
|  | } | ||||||
|  | 
 | ||||||
| type GuestbookCommentModel struct{} | type GuestbookCommentModel struct{} | ||||||
| 
 | 
 | ||||||
| func (m *GuestbookCommentModel) Insert(shortId uint64, guestbookId, parentId int64, authorName, | func (m *GuestbookCommentModel) Insert(shortId uint64, guestbookId, parentId int64, authorName, | ||||||
| @ -45,6 +51,17 @@ func (m *GuestbookCommentModel) GetAll(guestbookId int64) ([]models.GuestbookCom | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (m *GuestbookCommentModel) GetAllSerialized(guestbookId int64) ([]models.GuestbookCommentSerialized, error) { | ||||||
|  | 	switch guestbookId { | ||||||
|  | 	case 1: | ||||||
|  | 		return []models.GuestbookCommentSerialized{mockSerializedGuestbookComment}, nil | ||||||
|  | 	case 2: | ||||||
|  | 		return []models.GuestbookCommentSerialized{}, nil | ||||||
|  | 	default: | ||||||
|  | 		return []models.GuestbookCommentSerialized{}, models.ErrNoRecord | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (m *GuestbookCommentModel) GetDeleted(guestbookId int64) ([]models.GuestbookComment, error) { | func (m *GuestbookCommentModel) GetDeleted(guestbookId int64) ([]models.GuestbookComment, error) { | ||||||
| 	switch guestbookId { | 	switch guestbookId { | ||||||
| 	default: | 	default: | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package mocks | package mocks | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"net/url" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"git.32bit.cafe/32bitcafe/guestbook/internal/models" | 	"git.32bit.cafe/32bitcafe/guestbook/internal/models" | ||||||
| @ -25,7 +26,11 @@ var mockWebsite = models.Website{ | |||||||
| 	ID:      1, | 	ID:      1, | ||||||
| 	ShortId: 1, | 	ShortId: 1, | ||||||
| 	Name:    "Example", | 	Name:    "Example", | ||||||
| 	SiteUrl:    "example.com", | 	// SiteUrl:    "example.com", | ||||||
|  | 	Url: &url.URL{ | ||||||
|  | 		Scheme: "http", | ||||||
|  | 		Host:   "example.com", | ||||||
|  | 	}, | ||||||
| 	AuthorName: "John Test", | 	AuthorName: "John Test", | ||||||
| 	UserId:     1, | 	UserId:     1, | ||||||
| 	Created:    time.Now(), | 	Created:    time.Now(), | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ package models | |||||||
| import ( | import ( | ||||||
| 	"database/sql" | 	"database/sql" | ||||||
| 	"errors" | 	"errors" | ||||||
|  | 	"net/url" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| @ -11,7 +12,8 @@ type Website struct { | |||||||
| 	ID      int64 | 	ID      int64 | ||||||
| 	ShortId uint64 | 	ShortId uint64 | ||||||
| 	Name    string | 	Name    string | ||||||
| 	SiteUrl    string | 	// SiteUrl    string | ||||||
|  | 	Url        *url.URL | ||||||
| 	AuthorName string | 	AuthorName string | ||||||
| 	UserId     int64 | 	UserId     int64 | ||||||
| 	Created    time.Time | 	Created    time.Time | ||||||
| @ -179,7 +181,8 @@ func (m *WebsiteModel) Get(shortId uint64) (Website, error) { | |||||||
| 	} | 	} | ||||||
| 	row := tx.QueryRow(stmt, shortId) | 	row := tx.QueryRow(stmt, shortId) | ||||||
| 	var w Website | 	var w Website | ||||||
| 	err = row.Scan(&w.ID, &w.ShortId, &w.Name, &w.SiteUrl, &w.AuthorName, &w.UserId, &w.Created) | 	var u string | ||||||
|  | 	err = row.Scan(&w.ID, &w.ShortId, &w.Name, &u, &w.AuthorName, &w.UserId, &w.Created) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if errors.Is(err, sql.ErrNoRows) { | 		if errors.Is(err, sql.ErrNoRows) { | ||||||
| 			err = ErrNoRecord | 			err = ErrNoRecord | ||||||
| @ -189,6 +192,10 @@ func (m *WebsiteModel) Get(shortId uint64) (Website, error) { | |||||||
| 		} | 		} | ||||||
| 		return Website{}, err | 		return Website{}, err | ||||||
| 	} | 	} | ||||||
|  | 	w.Url, err = url.Parse(u) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return Website{}, err | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	stmt = `SELECT Id, ShortId, UserId, WebsiteId, Created, IsActive FROM guestbooks | 	stmt = `SELECT Id, ShortId, UserId, WebsiteId, Created, IsActive FROM guestbooks | ||||||
|     WHERE WebsiteId = ? AND Deleted IS NULL` |     WHERE WebsiteId = ? AND Deleted IS NULL` | ||||||
| @ -244,11 +251,16 @@ func (m *WebsiteModel) GetAllUser(userId int64) ([]Website, error) { | |||||||
| 	var websites []Website | 	var websites []Website | ||||||
| 	for rows.Next() { | 	for rows.Next() { | ||||||
| 		var w Website | 		var w Website | ||||||
| 		err := rows.Scan(&w.ID, &w.ShortId, &w.Name, &w.SiteUrl, &w.AuthorName, &w.UserId, &w.Created, | 		var u string | ||||||
|  | 		err := rows.Scan(&w.ID, &w.ShortId, &w.Name, &u, &w.AuthorName, &w.UserId, &w.Created, | ||||||
| 			&w.Guestbook.ID, &w.Guestbook.ShortId, &w.Guestbook.Created, &w.Guestbook.IsActive) | 			&w.Guestbook.ID, &w.Guestbook.ShortId, &w.Guestbook.Created, &w.Guestbook.IsActive) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|  | 		w.Url, err = url.Parse(u) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
| 		websites = append(websites, w) | 		websites = append(websites, w) | ||||||
| 	} | 	} | ||||||
| 	if err = rows.Err(); err != nil { | 	if err = rows.Err(); err != nil { | ||||||
| @ -268,11 +280,16 @@ func (m *WebsiteModel) GetAll() ([]Website, error) { | |||||||
| 	var websites []Website | 	var websites []Website | ||||||
| 	for rows.Next() { | 	for rows.Next() { | ||||||
| 		var w Website | 		var w Website | ||||||
| 		err := rows.Scan(&w.ID, &w.ShortId, &w.Name, &w.SiteUrl, &w.AuthorName, &w.UserId, &w.Created, | 		var u string | ||||||
|  | 		err := rows.Scan(&w.ID, &w.ShortId, &w.Name, &u, &w.AuthorName, &w.UserId, &w.Created, | ||||||
| 			&w.Guestbook.ID, &w.Guestbook.ShortId, &w.Guestbook.Created, &w.Guestbook.IsActive) | 			&w.Guestbook.ID, &w.Guestbook.ShortId, &w.Guestbook.Created, &w.Guestbook.IsActive) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|  | 		w.Url, err = url.Parse(u) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
| 		websites = append(websites, w) | 		websites = append(websites, w) | ||||||
| 	} | 	} | ||||||
| 	if err = rows.Err(); err != nil { | 	if err = rows.Err(); err != nil { | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var EmailRX = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") | var EmailRX = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") | ||||||
|  | var WebRX = regexp.MustCompile("^https?:\\/\\/") | ||||||
| 
 | 
 | ||||||
| type Validator struct { | type Validator struct { | ||||||
| 	NonFieldErrors []string | 	NonFieldErrors []string | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								migrations/000005_normalize_site_urls.down.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								migrations/000005_normalize_site_urls.down.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | UPDATE websites SET SiteUrl = substr(SiteUrl, 8) WHERE substr(SiteUrl, 1, 4) = 'http'; | ||||||
							
								
								
									
										1
									
								
								migrations/000005_normalize_site_urls.up.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								migrations/000005_normalize_site_urls.up.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | UPDATE websites SET SiteUrl = 'http://' || SiteUrl WHERE substr(SiteUrl, 1, 4) <> 'http'; | ||||||
| @ -10,7 +10,7 @@ templ GuestbookDashboardCommentsView(title string, data CommonData, website mode | |||||||
| 		<div id="dashboard"> | 		<div id="dashboard"> | ||||||
| 			@wSidebar(website) | 			@wSidebar(website) | ||||||
| 			<div> | 			<div> | ||||||
| 				<h1>Comments on { website.SiteUrl }</h1> | 				<h1>Comments on { website.Name }</h1> | ||||||
| 				<hr/> | 				<hr/> | ||||||
| 				if len(comments) == 0 { | 				if len(comments) == 0 { | ||||||
| 					<p>No comments yet!</p> | 					<p>No comments yet!</p> | ||||||
|  | |||||||
| @ -59,9 +59,9 @@ func GuestbookDashboardCommentsView(title string, data CommonData, website model | |||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| 			var templ_7745c5c3_Var3 string | 			var templ_7745c5c3_Var3 string | ||||||
| 			templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(website.SiteUrl) | 			templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name) | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 13, Col: 37} | 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 13, Col: 34} | ||||||
| 			} | 			} | ||||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) | 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ templ wSidebar(website models.Website) { | |||||||
| 			<h2>{ website.Name }</h2> | 			<h2>{ website.Name }</h2> | ||||||
| 			<ul> | 			<ul> | ||||||
| 				<li><a href={ templ.URL(dashUrl) }>Dashboard</a></li> | 				<li><a href={ templ.URL(dashUrl) }>Dashboard</a></li> | ||||||
| 				<li><a href={ templ.URL(externalUrl(website.SiteUrl)) } target="_blank">View Website</a></li> | 				<li><a href={ templ.URL(externalUrl(website.Url.String())) } target="_blank">View Website</a></li> | ||||||
| 			</ul> | 			</ul> | ||||||
| 			<h3>Guestbook</h3> | 			<h3>Guestbook</h3> | ||||||
| 			<ul> | 			<ul> | ||||||
| @ -70,7 +70,7 @@ templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) { | |||||||
| 		if exists { | 		if exists { | ||||||
| 			<label class="error">{ err }</label> | 			<label class="error">{ err }</label> | ||||||
| 		} | 		} | ||||||
| 		<input type="text" name="sitename" id="sitename" required/> | 		<input type="text" name="sitename" id="sitename" value={ form.Name } required/> | ||||||
| 	</div> | 	</div> | ||||||
| 	<div> | 	<div> | ||||||
| 		{{ err, exists = form.FieldErrors["siteurl"] }} | 		{{ err, exists = form.FieldErrors["siteurl"] }} | ||||||
| @ -78,7 +78,7 @@ templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) { | |||||||
| 		if exists { | 		if exists { | ||||||
| 			<label class="error">{ err }</label> | 			<label class="error">{ err }</label> | ||||||
| 		} | 		} | ||||||
| 		<input type="text" name="siteurl" id="siteurl" required/> | 		<input type="text" name="siteurl" id="siteurl" value={ form.SiteUrl } required/> | ||||||
| 	</div> | 	</div> | ||||||
| 	<div> | 	<div> | ||||||
| 		{{ err, exists = form.FieldErrors["authorname"] }} | 		{{ err, exists = form.FieldErrors["authorname"] }} | ||||||
| @ -86,22 +86,18 @@ templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) { | |||||||
| 		if exists { | 		if exists { | ||||||
| 			<label class="error">{ err }</label> | 			<label class="error">{ err }</label> | ||||||
| 		} | 		} | ||||||
| 		<input type="text" name="authorname" id="authorname" required/> | 		<input type="text" name="authorname" id="authorname" value={ form.AuthorName } required/> | ||||||
| 	</div> | 	</div> | ||||||
| 	<div> | 	<div> | ||||||
| 		<button type="submit">Submit</button> | 		<button type="submit">Submit</button> | ||||||
| 	</div> | 	</div> | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| templ WebsiteCreateButton() { |  | ||||||
| 	<button hx-get="/websites/create" hx-target="closest div">Add Website</button> |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| templ WebsiteList(title string, data CommonData, websites []models.Website) { | templ WebsiteList(title string, data CommonData, websites []models.Website) { | ||||||
| 	@base(title, data) { | 	@base(title, data) { | ||||||
| 		<h1>My Websites</h1> | 		<h1>My Websites</h1> | ||||||
| 		<div> | 		<div> | ||||||
| 			@WebsiteCreateButton() | 			<a href="/websites/create">Add Website</a> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div> | 		<div> | ||||||
| 			@displayWebsites(websites) | 			@displayWebsites(websites) | ||||||
| @ -171,42 +167,9 @@ templ WebsiteDashboardComingSoon(title string, data CommonData, website models.W | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| templ WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm) { | templ WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm) { | ||||||
| 	<form hx-post="/websites/create" hx-target="closest div"> | 	@base(title, data) { | ||||||
|  | 		<form action="/websites/create" method="post"> | ||||||
| 			@websiteCreateForm(data.CSRFToken, form) | 			@websiteCreateForm(data.CSRFToken, form) | ||||||
| 		</form> | 		</form> | ||||||
| } | 	} | ||||||
| 
 |  | ||||||
| templ embeddableForm(root string, website models.Website) { |  | ||||||
| 	{{ postUrl := fmt.Sprintf("https://%s/websites/%s/guestbook/comments/create/remote", root, shortIdToSlug(website.ShortId)) }} |  | ||||||
| 	{{formStr := |  | ||||||
| 	`<form action="%s" method="post"> |  | ||||||
|         <div> |  | ||||||
|             <label for="authorname">Name</label> |  | ||||||
|             <input type="text" name="authorname" id="authorname"/> |  | ||||||
|         </div> |  | ||||||
|         <div> |  | ||||||
|             <label for="authoremail">Email (Optional) </label> |  | ||||||
|             <input type="text" name="authoremail" id="authoremail"/> |  | ||||||
|         </div> |  | ||||||
|         <div> |  | ||||||
|             <label for="authorsite">Site Url (Optional) </label> |  | ||||||
|             <input type="text" name="authorsite" id="authorsite"/> |  | ||||||
|         </div> |  | ||||||
|         <div> |  | ||||||
|             <label for="content">Comment</label> |  | ||||||
|             <textarea name="content" id="content"></textarea> |  | ||||||
|         </div> |  | ||||||
|         <div> |  | ||||||
|             <input type="submit" value="Submit"/> |  | ||||||
|         </div> |  | ||||||
| </form>` |  | ||||||
| 	}} |  | ||||||
| 	<pre> |  | ||||||
| 		<code> |  | ||||||
| 			{ fmt.Sprintf(formStr, postUrl) } |  | ||||||
| 		</code> |  | ||||||
| 	</pre> |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| templ embedJavaScriptSnippet(root string, website models.Website) { |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -65,7 +65,7 @@ func wSidebar(website models.Website) templ.Component { | |||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			return templ_7745c5c3_Err | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| 		var templ_7745c5c3_Var4 templ.SafeURL = templ.URL(externalUrl(website.SiteUrl)) | 		var templ_7745c5c3_Var4 templ.SafeURL = templ.URL(externalUrl(website.Url.String())) | ||||||
| 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4))) | 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4))) | ||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			return templ_7745c5c3_Err | 			return templ_7745c5c3_Err | ||||||
| @ -271,92 +271,102 @@ func websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) templ.Com | |||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<input type=\"text\" name=\"sitename\" id=\"sitename\" required></div><div>") | 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<input type=\"text\" name=\"sitename\" id=\"sitename\" value=\"") | ||||||
| 		if templ_7745c5c3_Err != nil { |  | ||||||
| 			return templ_7745c5c3_Err |  | ||||||
| 		} |  | ||||||
| 		err, exists = form.FieldErrors["siteurl"] |  | ||||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "<label for=\"siteurl\">Site URL: </label> ") |  | ||||||
| 		if templ_7745c5c3_Err != nil { |  | ||||||
| 			return templ_7745c5c3_Err |  | ||||||
| 		} |  | ||||||
| 		if exists { |  | ||||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<label class=\"error\">") |  | ||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			return templ_7745c5c3_Err | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| 		var templ_7745c5c3_Var18 string | 		var templ_7745c5c3_Var18 string | ||||||
| 			templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(err) | 		templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(form.Name) | ||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 79, Col: 29} | 			return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 73, Col: 68} | ||||||
| 		} | 		} | ||||||
| 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) | 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) | ||||||
| 		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, 26, "</label> ") | 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\" required></div><div>") | ||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			return templ_7745c5c3_Err | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| 		} | 		err, exists = form.FieldErrors["siteurl"] | ||||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<input type=\"text\" name=\"siteurl\" id=\"siteurl\" required></div><div>") | 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<label for=\"siteurl\">Site URL: </label> ") | ||||||
| 		if templ_7745c5c3_Err != nil { |  | ||||||
| 			return templ_7745c5c3_Err |  | ||||||
| 		} |  | ||||||
| 		err, exists = form.FieldErrors["authorname"] |  | ||||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "<label for=\"authorname\">Site Author: </label> ") |  | ||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			return templ_7745c5c3_Err | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| 		if exists { | 		if exists { | ||||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "<label class=\"error\">") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<label class=\"error\">") | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| 			var templ_7745c5c3_Var19 string | 			var templ_7745c5c3_Var19 string | ||||||
| 			templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(err) | 			templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(err) | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 87, Col: 29} | 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 79, Col: 29} | ||||||
| 			} | 			} | ||||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) | 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) | ||||||
| 			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, 30, "</label> ") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "</label> ") | ||||||
| 			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, 31, "<input type=\"text\" name=\"authorname\" id=\"authorname\" required></div><div><button type=\"submit\">Submit</button></div>") | 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "<input type=\"text\" name=\"siteurl\" id=\"siteurl\" value=\"") | ||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			return templ_7745c5c3_Err | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| 		return nil | 		var templ_7745c5c3_Var20 string | ||||||
| 	}) | 		templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(form.SiteUrl) | ||||||
| } | 		if templ_7745c5c3_Err != nil { | ||||||
| 
 | 			return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 81, Col: 69} | ||||||
| func WebsiteCreateButton() 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) | 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) | ||||||
| 		if !templ_7745c5c3_IsBuffer { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			defer func() { | 			return templ_7745c5c3_Err | ||||||
| 				templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) |  | ||||||
| 				if templ_7745c5c3_Err == nil { |  | ||||||
| 					templ_7745c5c3_Err = templ_7745c5c3_BufErr |  | ||||||
| 		} | 		} | ||||||
| 			}() | 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "\" required></div><div>") | ||||||
|  | 		if templ_7745c5c3_Err != nil { | ||||||
|  | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| 		ctx = templ.InitializeContext(ctx) | 		err, exists = form.FieldErrors["authorname"] | ||||||
| 		templ_7745c5c3_Var20 := templ.GetChildren(ctx) | 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "<label for=\"authorname\">Site Author: </label> ") | ||||||
| 		if templ_7745c5c3_Var20 == nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			templ_7745c5c3_Var20 = templ.NopComponent | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| 		ctx = templ.ClearChildren(ctx) | 		if exists { | ||||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "<button hx-get=\"/websites/create\" hx-target=\"closest div\">Add Website</button>") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "<label class=\"error\">") | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 			var templ_7745c5c3_Var21 string | ||||||
|  | 			templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(err) | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 87, Col: 29} | ||||||
|  | 			} | ||||||
|  | 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "</label> ") | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "<input type=\"text\" name=\"authorname\" id=\"authorname\" value=\"") | ||||||
|  | 		if templ_7745c5c3_Err != nil { | ||||||
|  | 			return templ_7745c5c3_Err | ||||||
|  | 		} | ||||||
|  | 		var templ_7745c5c3_Var22 string | ||||||
|  | 		templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(form.AuthorName) | ||||||
|  | 		if templ_7745c5c3_Err != nil { | ||||||
|  | 			return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 89, Col: 78} | ||||||
|  | 		} | ||||||
|  | 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) | ||||||
|  | 		if templ_7745c5c3_Err != nil { | ||||||
|  | 			return templ_7745c5c3_Err | ||||||
|  | 		} | ||||||
|  | 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "\" required></div><div><button type=\"submit\">Submit</button></div>") | ||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			return templ_7745c5c3_Err | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| @ -365,69 +375,6 @@ func WebsiteCreateButton() templ.Component { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func WebsiteList(title string, data CommonData, websites []models.Website) templ.Component { | func WebsiteList(title string, data CommonData, websites []models.Website) 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_Var21 := templ.GetChildren(ctx) |  | ||||||
| 		if templ_7745c5c3_Var21 == nil { |  | ||||||
| 			templ_7745c5c3_Var21 = templ.NopComponent |  | ||||||
| 		} |  | ||||||
| 		ctx = templ.ClearChildren(ctx) |  | ||||||
| 		templ_7745c5c3_Var22 := 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, 33, "<h1>My Websites</h1><div>") |  | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ_7745c5c3_Err |  | ||||||
| 			} |  | ||||||
| 			templ_7745c5c3_Err = WebsiteCreateButton().Render(ctx, templ_7745c5c3_Buffer) |  | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ_7745c5c3_Err |  | ||||||
| 			} |  | ||||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "</div><div>") |  | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ_7745c5c3_Err |  | ||||||
| 			} |  | ||||||
| 			templ_7745c5c3_Err = displayWebsites(websites).Render(ctx, templ_7745c5c3_Buffer) |  | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ_7745c5c3_Err |  | ||||||
| 			} |  | ||||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "</div>") |  | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ_7745c5c3_Err |  | ||||||
| 			} |  | ||||||
| 			return nil |  | ||||||
| 		}) |  | ||||||
| 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var22), templ_7745c5c3_Buffer) |  | ||||||
| 		if templ_7745c5c3_Err != nil { |  | ||||||
| 			return templ_7745c5c3_Err |  | ||||||
| 		} |  | ||||||
| 		return nil |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func WebsiteDashboard(title string, data CommonData, website models.Website) templ.Component { |  | ||||||
| 	return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | 	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 | 		templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||||||
| 		if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { | 		if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { | ||||||
| @ -460,7 +407,62 @@ func WebsiteDashboard(title string, data CommonData, website models.Website) tem | |||||||
| 				}() | 				}() | ||||||
| 			} | 			} | ||||||
| 			ctx = templ.InitializeContext(ctx) | 			ctx = templ.InitializeContext(ctx) | ||||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "<div id=\"dashboard\">") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<h1>My Websites</h1><div><a href=\"/websites/create\">Add Website</a></div><div>") | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 			templ_7745c5c3_Err = displayWebsites(websites).Render(ctx, templ_7745c5c3_Buffer) | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</div>") | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 			return nil | ||||||
|  | 		}) | ||||||
|  | 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var24), templ_7745c5c3_Buffer) | ||||||
|  | 		if templ_7745c5c3_Err != nil { | ||||||
|  | 			return templ_7745c5c3_Err | ||||||
|  | 		} | ||||||
|  | 		return nil | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func WebsiteDashboard(title string, data CommonData, website models.Website) 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_Var25 := templ.GetChildren(ctx) | ||||||
|  | 		if templ_7745c5c3_Var25 == nil { | ||||||
|  | 			templ_7745c5c3_Var25 = templ.NopComponent | ||||||
|  | 		} | ||||||
|  | 		ctx = templ.ClearChildren(ctx) | ||||||
|  | 		templ_7745c5c3_Var26 := 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, 37, "<div id=\"dashboard\">") | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| @ -468,87 +470,87 @@ func WebsiteDashboard(title string, data CommonData, website models.Website) tem | |||||||
| 			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, 37, "<div><h1>") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<div><h1>") | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ_7745c5c3_Err |  | ||||||
| 			} |  | ||||||
| 			var templ_7745c5c3_Var25 string |  | ||||||
| 			templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name) |  | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 117, Col: 22} |  | ||||||
| 			} |  | ||||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) |  | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ_7745c5c3_Err |  | ||||||
| 			} |  | ||||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "</h1><h2>Embed your Guestbook</h2><p>Upload <a href=\"/static/js/guestbook.js\" download>this JavaScript WebComponent</a> to your site and include it in your <code>") |  | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ_7745c5c3_Err |  | ||||||
| 			} |  | ||||||
| 			var templ_7745c5c3_Var26 string |  | ||||||
| 			templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(`<head>`) |  | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 120, Col: 140} |  | ||||||
| 			} |  | ||||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) |  | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ_7745c5c3_Err |  | ||||||
| 			} |  | ||||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "</code> tag.</p><div><pre><code id=\"guestbookSnippet\">") |  | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| 			var templ_7745c5c3_Var27 string | 			var templ_7745c5c3_Var27 string | ||||||
| 			templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs( | 			templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name) | ||||||
| 				`<head> |  | ||||||
|     <script type="module" src="js/guestbook.js"></script> |  | ||||||
| </head>`) |  | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 129, Col: 8} | 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 113, Col: 22} | ||||||
| 			} | 			} | ||||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) | 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) | ||||||
| 			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, 40, "</code></pre><p>Then add the custom elements where you want your form and comments to show up</p>") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "</h1><h2>Embed your Guestbook</h2><p>Upload <a href=\"/static/js/guestbook.js\" download>this JavaScript WebComponent</a> to your site and include it in your <code>") | ||||||
| 			if templ_7745c5c3_Err != nil { |  | ||||||
| 				return templ_7745c5c3_Err |  | ||||||
| 			} |  | ||||||
| 			gbUrl := fmt.Sprintf("https://%s/websites/%s/guestbook", data.RootUrl, shortIdToSlug(website.ShortId)) |  | ||||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<pre><code>") |  | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| 			var templ_7745c5c3_Var28 string | 			var templ_7745c5c3_Var28 string | ||||||
| 			templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`<guestbook-form guestbook="%s"></guestbook-form> | 			templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(`<head>`) | ||||||
| <guestbook-comments guestbook="%s"></guestbook-comments>`, gbUrl, gbUrl)) |  | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 140, Col: 72} | 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 116, Col: 140} | ||||||
| 			} | 			} | ||||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) | 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) | ||||||
| 			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, 42, "</code></pre></div><p>If your web host does not allow CORS requests, use an iframe instead</p><div><pre><code>") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</code> tag.</p><div><pre><code id=\"guestbookSnippet\">") | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| 			var templ_7745c5c3_Var29 string | 			var templ_7745c5c3_Var29 string | ||||||
| 			templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`<iframe src="%s" title="Guestbook"></iframe>`, gbUrl)) | 			templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs( | ||||||
|  | 				`<head> | ||||||
|  |     <script type="module" src="js/guestbook.js"></script> | ||||||
|  | </head>`) | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 150, Col: 75} | 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 125, Col: 8} | ||||||
| 			} | 			} | ||||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) | 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) | ||||||
| 			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, 43, "</code></pre></div></div></div>") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</code></pre><p>Then add the custom elements where you want your form and comments to show up</p>") | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 			gbUrl := fmt.Sprintf("https://%s/websites/%s/guestbook", data.RootUrl, shortIdToSlug(website.ShortId)) | ||||||
|  | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<pre><code>") | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 			var templ_7745c5c3_Var30 string | ||||||
|  | 			templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`<guestbook-form guestbook="%s"></guestbook-form> | ||||||
|  | <guestbook-comments guestbook="%s"></guestbook-comments>`, gbUrl, gbUrl)) | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 136, Col: 72} | ||||||
|  | 			} | ||||||
|  | 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</code></pre></div><p>If your web host does not allow CORS requests, use an iframe instead</p><div><pre><code>") | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 			var templ_7745c5c3_Var31 string | ||||||
|  | 			templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`<iframe src="%s" title="Guestbook"></iframe>`, gbUrl)) | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 146, Col: 75} | ||||||
|  | 			} | ||||||
|  | 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) | ||||||
|  | 			if templ_7745c5c3_Err != nil { | ||||||
|  | 				return templ_7745c5c3_Err | ||||||
|  | 			} | ||||||
|  | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</code></pre></div></div></div>") | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| 			return nil | 			return nil | ||||||
| 		}) | 		}) | ||||||
| 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var24), templ_7745c5c3_Buffer) | 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var26), templ_7745c5c3_Buffer) | ||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			return templ_7745c5c3_Err | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| @ -572,12 +574,12 @@ func WebsiteDashboardComingSoon(title string, data CommonData, website models.We | |||||||
| 			}() | 			}() | ||||||
| 		} | 		} | ||||||
| 		ctx = templ.InitializeContext(ctx) | 		ctx = templ.InitializeContext(ctx) | ||||||
| 		templ_7745c5c3_Var30 := templ.GetChildren(ctx) | 		templ_7745c5c3_Var32 := templ.GetChildren(ctx) | ||||||
| 		if templ_7745c5c3_Var30 == nil { | 		if templ_7745c5c3_Var32 == nil { | ||||||
| 			templ_7745c5c3_Var30 = templ.NopComponent | 			templ_7745c5c3_Var32 = templ.NopComponent | ||||||
| 		} | 		} | ||||||
| 		ctx = templ.ClearChildren(ctx) | 		ctx = templ.ClearChildren(ctx) | ||||||
| 		templ_7745c5c3_Var31 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | 		templ_7745c5c3_Var33 := 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_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||||||
| 			templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | 			templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | ||||||
| 			if !templ_7745c5c3_IsBuffer { | 			if !templ_7745c5c3_IsBuffer { | ||||||
| @ -589,7 +591,7 @@ func WebsiteDashboardComingSoon(title string, data CommonData, website models.We | |||||||
| 				}() | 				}() | ||||||
| 			} | 			} | ||||||
| 			ctx = templ.InitializeContext(ctx) | 			ctx = templ.InitializeContext(ctx) | ||||||
| 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "<div id=\"dashboard\">") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<div id=\"dashboard\">") | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| @ -597,26 +599,26 @@ func WebsiteDashboardComingSoon(title string, data CommonData, website models.We | |||||||
| 			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, 45, "<div><h1>") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "<div><h1>") | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| 			var templ_7745c5c3_Var32 string | 			var templ_7745c5c3_Var34 string | ||||||
| 			templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name) | 			templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name) | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 164, Col: 22} | 				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 160, Col: 22} | ||||||
| 			} | 			} | ||||||
| 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) | 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34)) | ||||||
| 			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, 46, "</h1><p>Coming Soon</p></div></div>") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "</h1><p>Coming Soon</p></div></div>") | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| 			return nil | 			return nil | ||||||
| 		}) | 		}) | ||||||
| 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var31), templ_7745c5c3_Buffer) | 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var33), templ_7745c5c3_Buffer) | ||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			return templ_7745c5c3_Err | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| @ -640,12 +642,24 @@ func WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm) | |||||||
| 			}() | 			}() | ||||||
| 		} | 		} | ||||||
| 		ctx = templ.InitializeContext(ctx) | 		ctx = templ.InitializeContext(ctx) | ||||||
| 		templ_7745c5c3_Var33 := templ.GetChildren(ctx) | 		templ_7745c5c3_Var35 := templ.GetChildren(ctx) | ||||||
| 		if templ_7745c5c3_Var33 == nil { | 		if templ_7745c5c3_Var35 == nil { | ||||||
| 			templ_7745c5c3_Var33 = templ.NopComponent | 			templ_7745c5c3_Var35 = templ.NopComponent | ||||||
| 		} | 		} | ||||||
| 		ctx = templ.ClearChildren(ctx) | 		ctx = templ.ClearChildren(ctx) | ||||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "<form hx-post=\"/websites/create\" hx-target=\"closest div\">") | 		templ_7745c5c3_Var36 := 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, 48, "<form action=\"/websites/create\" method=\"post\">") | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| @ -653,100 +667,16 @@ func WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm) | |||||||
| 			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, 48, "</form>") | 			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "</form>") | ||||||
| 			if templ_7745c5c3_Err != nil { | 			if templ_7745c5c3_Err != nil { | ||||||
| 				return templ_7745c5c3_Err | 				return templ_7745c5c3_Err | ||||||
| 			} | 			} | ||||||
| 			return nil | 			return nil | ||||||
| 		}) | 		}) | ||||||
| } | 		templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var36), templ_7745c5c3_Buffer) | ||||||
| 
 |  | ||||||
| func embeddableForm(root string, website models.Website) 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_Var34 := templ.GetChildren(ctx) |  | ||||||
| 		if templ_7745c5c3_Var34 == nil { |  | ||||||
| 			templ_7745c5c3_Var34 = templ.NopComponent |  | ||||||
| 		} |  | ||||||
| 		ctx = templ.ClearChildren(ctx) |  | ||||||
| 		postUrl := fmt.Sprintf("https://%s/websites/%s/guestbook/comments/create/remote", root, shortIdToSlug(website.ShortId)) |  | ||||||
| 		formStr := |  | ||||||
| 			`<form action="%s" method="post"> |  | ||||||
|         <div> |  | ||||||
|             <label for="authorname">Name</label> |  | ||||||
|             <input type="text" name="authorname" id="authorname"/> |  | ||||||
|         </div> |  | ||||||
|         <div> |  | ||||||
|             <label for="authoremail">Email (Optional) </label> |  | ||||||
|             <input type="text" name="authoremail" id="authoremail"/> |  | ||||||
|         </div> |  | ||||||
|         <div> |  | ||||||
|             <label for="authorsite">Site Url (Optional) </label> |  | ||||||
|             <input type="text" name="authorsite" id="authorsite"/> |  | ||||||
|         </div> |  | ||||||
|         <div> |  | ||||||
|             <label for="content">Comment</label> |  | ||||||
|             <textarea name="content" id="content"></textarea> |  | ||||||
|         </div> |  | ||||||
|         <div> |  | ||||||
|             <input type="submit" value="Submit"/> |  | ||||||
|         </div> |  | ||||||
| </form>` |  | ||||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "<pre><code>") |  | ||||||
| 		if templ_7745c5c3_Err != nil { | 		if templ_7745c5c3_Err != nil { | ||||||
| 			return templ_7745c5c3_Err | 			return templ_7745c5c3_Err | ||||||
| 		} | 		} | ||||||
| 		var templ_7745c5c3_Var35 string |  | ||||||
| 		templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(formStr, postUrl)) |  | ||||||
| 		if templ_7745c5c3_Err != nil { |  | ||||||
| 			return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 206, Col: 34} |  | ||||||
| 		} |  | ||||||
| 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35)) |  | ||||||
| 		if templ_7745c5c3_Err != nil { |  | ||||||
| 			return templ_7745c5c3_Err |  | ||||||
| 		} |  | ||||||
| 		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</code></pre>") |  | ||||||
| 		if templ_7745c5c3_Err != nil { |  | ||||||
| 			return templ_7745c5c3_Err |  | ||||||
| 		} |  | ||||||
| 		return nil |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func embedJavaScriptSnippet(root string, website models.Website) 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_Var36 := templ.GetChildren(ctx) |  | ||||||
| 		if templ_7745c5c3_Var36 == nil { |  | ||||||
| 			templ_7745c5c3_Var36 = templ.NopComponent |  | ||||||
| 		} |  | ||||||
| 		ctx = templ.ClearChildren(ctx) |  | ||||||
| 		return nil | 		return nil | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user