add remote client examples and webcomponent script
This commit is contained in:
		
							parent
							
								
									306053b1e3
								
							
						
					
					
						commit
						c3b10ae239
					
				@ -110,6 +110,7 @@ func (app *application) newCommonData(r *http.Request) views.CommonData {
 | 
				
			|||||||
		CSRFToken:       nosurf.Token(r),
 | 
							CSRFToken:       nosurf.Token(r),
 | 
				
			||||||
		CurrentUser:     app.getCurrentUser(r),
 | 
							CurrentUser:     app.getCurrentUser(r),
 | 
				
			||||||
		IsHtmx:          r.Header.Get("Hx-Request") == "true",
 | 
							IsHtmx:          r.Header.Get("Hx-Request") == "true",
 | 
				
			||||||
 | 
							RootUrl:         app.rootUrl,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -28,12 +28,14 @@ type application struct {
 | 
				
			|||||||
	formDecoder       *schema.Decoder
 | 
						formDecoder       *schema.Decoder
 | 
				
			||||||
	debug             bool
 | 
						debug             bool
 | 
				
			||||||
	timezones         []string
 | 
						timezones         []string
 | 
				
			||||||
 | 
						rootUrl           string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	addr := flag.String("addr", ":3000", "HTTP network address")
 | 
						addr := flag.String("addr", ":3000", "HTTP network address")
 | 
				
			||||||
	dsn := flag.String("dsn", "guestbook.db", "data source name")
 | 
						dsn := flag.String("dsn", "guestbook.db", "data source name")
 | 
				
			||||||
	debug := flag.Bool("debug", false, "enable debug mode")
 | 
						debug := flag.Bool("debug", false, "enable debug mode")
 | 
				
			||||||
 | 
						root := flag.String("root", "localhost:3000", "root URL of application")
 | 
				
			||||||
	flag.Parse()
 | 
						flag.Parse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug}))
 | 
						logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug}))
 | 
				
			||||||
@ -62,6 +64,7 @@ func main() {
 | 
				
			|||||||
		formDecoder:       formDecoder,
 | 
							formDecoder:       formDecoder,
 | 
				
			||||||
		debug:             *debug,
 | 
							debug:             *debug,
 | 
				
			||||||
		timezones:         getAvailableTimezones(),
 | 
							timezones:         getAvailableTimezones(),
 | 
				
			||||||
 | 
							rootUrl:           *root,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = app.users.InitializeSettingsMap()
 | 
						err = app.users.InitializeSettingsMap()
 | 
				
			||||||
 | 
				
			|||||||
@ -58,10 +58,17 @@ div#dashboard {
 | 
				
			|||||||
div#dashboard nav {
 | 
					div#dashboard nav {
 | 
				
			||||||
  flex: 1 1 25%;
 | 
					  flex: 1 1 25%;
 | 
				
			||||||
  margin-top: 2rem;
 | 
					  margin-top: 2rem;
 | 
				
			||||||
 | 
					  min-width: 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
div#dashboard > div {
 | 
					div#dashboard > div {
 | 
				
			||||||
  flex: 10 1 40%;
 | 
					  flex: 10 1 40%;
 | 
				
			||||||
 | 
					  min-width: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div > pre {
 | 
				
			||||||
 | 
					    max-width: 100%;
 | 
				
			||||||
 | 
					    overflow: auto;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
main nav ul {
 | 
					main nav ul {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										105
									
								
								ui/static/js/guestbook.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								ui/static/js/guestbook.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					class CommentList extends HTMLElement {
 | 
				
			||||||
 | 
					    static get observedAttributes() {
 | 
				
			||||||
 | 
					        return ['src'];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor() {
 | 
				
			||||||
 | 
					        super();
 | 
				
			||||||
 | 
					        this.attachShadow({ mode: 'open' });
 | 
				
			||||||
 | 
					        this.comments = [];
 | 
				
			||||||
 | 
					        this.loading = false;
 | 
				
			||||||
 | 
					        this.error = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    connectedCallback() {
 | 
				
			||||||
 | 
					        if (this.hasAttribute('src')) {
 | 
				
			||||||
 | 
					            this.fetchComments();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    attributeChangedCallback(name, oldValue, newValue) {
 | 
				
			||||||
 | 
					        if (name === 'src' && oldValue !== newValue) {
 | 
				
			||||||
 | 
					            this.fetchComments();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async fetchComments() {
 | 
				
			||||||
 | 
					        const src = this.getAttribute('src');
 | 
				
			||||||
 | 
					        if (!src) return;
 | 
				
			||||||
 | 
					        this.loading = true;
 | 
				
			||||||
 | 
					        this.error = null;
 | 
				
			||||||
 | 
					        this.render();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            const response = await fetch(src);
 | 
				
			||||||
 | 
					            if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
 | 
				
			||||||
 | 
					            const data = await response.json();
 | 
				
			||||||
 | 
					            this.comments = Array.isArray(data) ? data : [];
 | 
				
			||||||
 | 
					            this.loading = false;
 | 
				
			||||||
 | 
					            this.render();
 | 
				
			||||||
 | 
					        } catch (err) {
 | 
				
			||||||
 | 
					            this.error = err.message;
 | 
				
			||||||
 | 
					            this.loading = false;
 | 
				
			||||||
 | 
					            this.render();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    formatDate(isoString) {
 | 
				
			||||||
 | 
					        if (!isoString) return '';
 | 
				
			||||||
 | 
					        const date = new Date(isoString);
 | 
				
			||||||
 | 
					        return date.toLocaleString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        this.shadowRoot.innerHTML = `
 | 
				
			||||||
 | 
					      <style>
 | 
				
			||||||
 | 
					        .comment-list {
 | 
				
			||||||
 | 
					          font-family: Arial, sans-serif;
 | 
				
			||||||
 | 
					          border: 1px solid #ddd;
 | 
				
			||||||
 | 
					          border-radius: 6px;
 | 
				
			||||||
 | 
					          padding: 1em;
 | 
				
			||||||
 | 
					          background: #fafafa;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .comment {
 | 
				
			||||||
 | 
					          border-bottom: 1px solid #eee;
 | 
				
			||||||
 | 
					          padding: 0.7em 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .comment:last-child {
 | 
				
			||||||
 | 
					          border-bottom: none;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .author {
 | 
				
			||||||
 | 
					          font-weight: bold;
 | 
				
			||||||
 | 
					          margin-right: 1em;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .timestamp {
 | 
				
			||||||
 | 
					          color: #888;
 | 
				
			||||||
 | 
					          font-size: 0.85em;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .text {
 | 
				
			||||||
 | 
					          margin: 0.2em 0 0 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .error {
 | 
				
			||||||
 | 
					          color: red;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      </style>
 | 
				
			||||||
 | 
					      <div class="comment-list">
 | 
				
			||||||
 | 
					        ${this.loading
 | 
				
			||||||
 | 
					                ? `<div>Loading comments...</div>`
 | 
				
			||||||
 | 
					                : this.error
 | 
				
			||||||
 | 
					                    ? `<div class="error">Error: ${this.error}</div>`
 | 
				
			||||||
 | 
					                    : this.comments.length === 0
 | 
				
			||||||
 | 
					                        ? `<div>No comments found.</div>`
 | 
				
			||||||
 | 
					                        : this.comments.map(comment => `
 | 
				
			||||||
 | 
					                  <div class="comment">
 | 
				
			||||||
 | 
					                    <span class="author">${comment.AuthorName || 'Unknown Author'}</span>
 | 
				
			||||||
 | 
					                    <span class="timestamp">${this.formatDate(comment.Created)}</span>
 | 
				
			||||||
 | 
					                    <div class="text">${comment.CommentText || ''}</div>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                `).join('')
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					customElements.define('comment-list', CommentList);
 | 
				
			||||||
@ -20,6 +20,7 @@ type CommonData struct {
 | 
				
			|||||||
	CSRFToken       string
 | 
						CSRFToken       string
 | 
				
			||||||
	CurrentUser     *models.User
 | 
						CurrentUser     *models.User
 | 
				
			||||||
	IsHtmx          bool
 | 
						IsHtmx          bool
 | 
				
			||||||
 | 
						RootUrl         string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func shortIdToSlug(shortId uint64) string {
 | 
					func shortIdToSlug(shortId uint64) string {
 | 
				
			||||||
 | 
				
			|||||||
@ -115,9 +115,41 @@ templ WebsiteDashboard(title string, data CommonData, website models.Website) {
 | 
				
			|||||||
			@wSidebar(website)
 | 
								@wSidebar(website)
 | 
				
			||||||
			<div>
 | 
								<div>
 | 
				
			||||||
				<h1>{ website.Name }</h1>
 | 
									<h1>{ website.Name }</h1>
 | 
				
			||||||
 | 
									<h2>Embed your Guestbook</h2>
 | 
				
			||||||
 | 
									<h3>Comment form</h3>
 | 
				
			||||||
				<p>
 | 
									<p>
 | 
				
			||||||
					Stats and stuff will go here.
 | 
										Use this form to allow readers of your website to comment on your guestbook!
 | 
				
			||||||
				</p>
 | 
									</p>
 | 
				
			||||||
 | 
									<div>
 | 
				
			||||||
 | 
										//<button>Copy to Clipboard</button>
 | 
				
			||||||
 | 
										@embeddableForm(data.RootUrl, website)
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
									<h3>Embed your comments</h3>
 | 
				
			||||||
 | 
									<p>
 | 
				
			||||||
 | 
										Upload <a href="/static/js/guestbook.js" download>this JavaScript WebComponent</a> to your site and include it in your <code>{ `<head>` }</code> tag.
 | 
				
			||||||
 | 
									</p>
 | 
				
			||||||
 | 
									<div>
 | 
				
			||||||
 | 
										//<button>Copy to Clipboard</button>
 | 
				
			||||||
 | 
										<pre>
 | 
				
			||||||
 | 
											<code id="guestbookSnippet">
 | 
				
			||||||
 | 
												{ 
 | 
				
			||||||
 | 
					`<head>
 | 
				
			||||||
 | 
					    <script type="module" src="js/guestbook.js"></script>
 | 
				
			||||||
 | 
					</head>` }
 | 
				
			||||||
 | 
											</code>
 | 
				
			||||||
 | 
										</pre>
 | 
				
			||||||
 | 
										<p>
 | 
				
			||||||
 | 
											Then add the custom element where you want the comments to show up
 | 
				
			||||||
 | 
										</p>
 | 
				
			||||||
 | 
										{{ getUrl := fmt.Sprintf("https://%s/websites/%s/guestbook/comments", data.RootUrl, shortIdToSlug(website.ShortId)) }}
 | 
				
			||||||
 | 
										//<button>Copy to Clipboard</button>
 | 
				
			||||||
 | 
										<pre>
 | 
				
			||||||
 | 
											<code>
 | 
				
			||||||
 | 
												{ fmt.Sprintf(`<comment-list src="%s"></comment-list>`, getUrl) }
 | 
				
			||||||
 | 
											</code>
 | 
				
			||||||
 | 
										</pre>
 | 
				
			||||||
 | 
										@embedJavaScriptSnippet(data.RootUrl, website)
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -142,3 +174,38 @@ templ WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm)
 | 
				
			|||||||
		@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) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -481,7 +481,70 @@ 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, 38, "</h1><p>Stats and stuff will go here.</p></div></div>")
 | 
								templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "</h1><h2>Embed your Guestbook</h2><h3>Comment form</h3><p>Use this form to allow readers of your website to comment on your guestbook!</p><div>")
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								templ_7745c5c3_Err = embeddableForm(data.RootUrl, website).Render(ctx, templ_7745c5c3_Buffer)
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "</div><h3>Embed your comments</h3><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: 129, 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, 40, "</code> tag.</p><div><pre><code id=\"guestbookSnippet\">")
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								var templ_7745c5c3_Var27 string
 | 
				
			||||||
 | 
								templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(
 | 
				
			||||||
 | 
									`<head>
 | 
				
			||||||
 | 
					    <script type="module" src="js/guestbook.js"></script>
 | 
				
			||||||
 | 
					</head>`)
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 138, Col: 8}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</code></pre><p>Then add the custom element where you want the comments to show up</p>")
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								getUrl := fmt.Sprintf("https://%s/websites/%s/guestbook/comments", 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_Var28 string
 | 
				
			||||||
 | 
								templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`<comment-list src="%s"></comment-list>`, getUrl))
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 148, Col: 70}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</code></pre>")
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								templ_7745c5c3_Err = embedJavaScriptSnippet(data.RootUrl, website).Render(ctx, templ_7745c5c3_Buffer)
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</div></div></div>")
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ_7745c5c3_Err
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -511,12 +574,12 @@ func WebsiteDashboardComingSoon(title string, data CommonData, website models.We
 | 
				
			|||||||
			}()
 | 
								}()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx = templ.InitializeContext(ctx)
 | 
							ctx = templ.InitializeContext(ctx)
 | 
				
			||||||
		templ_7745c5c3_Var26 := templ.GetChildren(ctx)
 | 
							templ_7745c5c3_Var29 := templ.GetChildren(ctx)
 | 
				
			||||||
		if templ_7745c5c3_Var26 == nil {
 | 
							if templ_7745c5c3_Var29 == nil {
 | 
				
			||||||
			templ_7745c5c3_Var26 = templ.NopComponent
 | 
								templ_7745c5c3_Var29 = templ.NopComponent
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx = templ.ClearChildren(ctx)
 | 
							ctx = templ.ClearChildren(ctx)
 | 
				
			||||||
		templ_7745c5c3_Var27 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
							templ_7745c5c3_Var30 := 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 {
 | 
				
			||||||
@ -528,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, 39, "<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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -536,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, 40, "<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_Var28 string
 | 
								var templ_7745c5c3_Var31 string
 | 
				
			||||||
			templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
 | 
								templ_7745c5c3_Var31, 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: 131, Col: 22}
 | 
									return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 163, Col: 22}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
 | 
				
			||||||
			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, 41, "</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_Var27), templ_7745c5c3_Buffer)
 | 
							templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var30), templ_7745c5c3_Buffer)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -579,12 +642,12 @@ func WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm)
 | 
				
			|||||||
			}()
 | 
								}()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx = templ.InitializeContext(ctx)
 | 
							ctx = templ.InitializeContext(ctx)
 | 
				
			||||||
		templ_7745c5c3_Var29 := templ.GetChildren(ctx)
 | 
							templ_7745c5c3_Var32 := templ.GetChildren(ctx)
 | 
				
			||||||
		if templ_7745c5c3_Var29 == nil {
 | 
							if templ_7745c5c3_Var32 == nil {
 | 
				
			||||||
			templ_7745c5c3_Var29 = templ.NopComponent
 | 
								templ_7745c5c3_Var32 = templ.NopComponent
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx = templ.ClearChildren(ctx)
 | 
							ctx = templ.ClearChildren(ctx)
 | 
				
			||||||
		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<form hx-post=\"/websites/create\" hx-target=\"closest div\">")
 | 
							templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "<form hx-post=\"/websites/create\" hx-target=\"closest div\">")
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -592,7 +655,7 @@ 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, 43, "</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
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -600,4 +663,94 @@ func WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm)
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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_Var33 := templ.GetChildren(ctx)
 | 
				
			||||||
 | 
							if templ_7745c5c3_Var33 == nil {
 | 
				
			||||||
 | 
								templ_7745c5c3_Var33 = 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, 50, "<pre><code>")
 | 
				
			||||||
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							var templ_7745c5c3_Var34 string
 | 
				
			||||||
 | 
							templ_7745c5c3_Var34, 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: 205, Col: 34}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
 | 
				
			||||||
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "</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_Var35 := templ.GetChildren(ctx)
 | 
				
			||||||
 | 
							if templ_7745c5c3_Var35 == nil {
 | 
				
			||||||
 | 
								templ_7745c5c3_Var35 = templ.NopComponent
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ctx = templ.ClearChildren(ctx)
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var _ = templruntime.GeneratedTemplate
 | 
					var _ = templruntime.GeneratedTemplate
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user