290 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			290 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
package views
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"git.32bit.cafe/32bitcafe/guestbook/internal/forms"
 | 
						|
	"git.32bit.cafe/32bitcafe/guestbook/internal/models"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
func wUrl(w models.Website) string {
 | 
						|
	return fmt.Sprintf("/websites/%s", shortIdToSlug(w.ShortId))
 | 
						|
}
 | 
						|
 | 
						|
templ wSidebar(website models.Website) {
 | 
						|
	{{ dashUrl := wUrl(website) + "/dashboard" }}
 | 
						|
	{{ gbUrl := wUrl(website) + "/guestbook" }}
 | 
						|
	<nav>
 | 
						|
		<div>
 | 
						|
			<ul>
 | 
						|
				<li><a href={ templ.URL(dashUrl) }>Dashboard</a></li>
 | 
						|
				<li><a href={ templ.URL(dashUrl + "/settings") }>Settings</a></li>
 | 
						|
				<li><a href={ templ.URL(externalUrl(website.Url.String())) } target="_blank">View Website</a></li>
 | 
						|
			</ul>
 | 
						|
			<h3>Guestbook</h3>
 | 
						|
			<ul>
 | 
						|
				<li><a href={ templ.URL(gbUrl) } target="_blank">View Guestbook</a></li>
 | 
						|
			</ul>
 | 
						|
			<ul>
 | 
						|
				<li><a href={ templ.URL(dashUrl + "/guestbook/comments") }>Manage messages</a></li>
 | 
						|
				<li><a href={ templ.URL(dashUrl + "/guestbook/comments/queue") }>Review message queue</a></li>
 | 
						|
				<li><a href={ templ.URL(dashUrl + "/guestbook/comments/trash") }>Trash</a></li>
 | 
						|
			</ul>
 | 
						|
			<ul>
 | 
						|
				//<li><a href={ templ.URL(dashUrl + "/guestbook/themes") }>Themes</a></li>
 | 
						|
				//<li><a href={ templ.URL(dashUrl + "/guestbook/customize") }>Custom CSS</a></li>
 | 
						|
			</ul>
 | 
						|
		</div>
 | 
						|
		<div>
 | 
						|
			<h3>Feeds</h3>
 | 
						|
			<p>Coming Soon</p>
 | 
						|
		</div>
 | 
						|
		<div>
 | 
						|
			<h3>Account</h3>
 | 
						|
			<ul>
 | 
						|
				<li><a href="/users/settings">Settings</a></li>
 | 
						|
				<li><a href="/users/privacy">Privacy</a></li>
 | 
						|
				<li><a href="/help">Help</a></li>
 | 
						|
			</ul>
 | 
						|
		</div>
 | 
						|
	</nav>
 | 
						|
}
 | 
						|
 | 
						|
templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) {
 | 
						|
	<input type="hidden" name="csrf_token" value={ csrfToken }/>
 | 
						|
	<div>
 | 
						|
		{{ err, exists := form.FieldErrors["sitename"] }}
 | 
						|
		<label for="sitename">Site Name: </label>
 | 
						|
		if exists {
 | 
						|
			<label class="error">{ err }</label>
 | 
						|
		}
 | 
						|
		<input type="text" name="sitename" id="sitename" value={ form.Name } required/>
 | 
						|
	</div>
 | 
						|
	<div>
 | 
						|
		{{ err, exists = form.FieldErrors["siteurl"] }}
 | 
						|
		<label for="siteurl">Site URL: </label>
 | 
						|
		if exists {
 | 
						|
			<label class="error">{ err }</label>
 | 
						|
		}
 | 
						|
		<input type="text" name="siteurl" id="siteurl" value={ form.SiteUrl } required/>
 | 
						|
	</div>
 | 
						|
	<div>
 | 
						|
		{{ err, exists = form.FieldErrors["authorname"] }}
 | 
						|
		<label for="authorname">Site Author: </label>
 | 
						|
		if exists {
 | 
						|
			<label class="error">{ err }</label>
 | 
						|
		}
 | 
						|
		<input type="text" name="authorname" id="authorname" value={ form.AuthorName } required/>
 | 
						|
	</div>
 | 
						|
	<div>
 | 
						|
		<button type="submit">Submit</button>
 | 
						|
	</div>
 | 
						|
}
 | 
						|
 | 
						|
templ WebsiteList(title string, data CommonData, websites []models.Website) {
 | 
						|
	@base(title, data) {
 | 
						|
		<div>
 | 
						|
			<a href="/websites/create">Add Website</a>
 | 
						|
		</div>
 | 
						|
		<div>
 | 
						|
			if len(websites) == 0 {
 | 
						|
				<p>No Websites yet. <a href="">Register a website.</a></p>
 | 
						|
			} else {
 | 
						|
				<ul id="websites" hx-get="/websites" hx-trigger="newWebsite from:body" hx-swap="outerHTML">
 | 
						|
					for _, w := range websites {
 | 
						|
						<li>
 | 
						|
							<a href={ templ.URL(wUrl(w) + "/dashboard") }>{ w.Name }</a>
 | 
						|
						</li>
 | 
						|
					}
 | 
						|
				</ul>
 | 
						|
			}
 | 
						|
		</div>
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
templ WebsiteDashboard(title string, data CommonData, website models.Website) {
 | 
						|
	@base(title, data) {
 | 
						|
		<div id="dashboard">
 | 
						|
			@wSidebar(website)
 | 
						|
			<div>
 | 
						|
				<h1>Embed your Guestbook</h1>
 | 
						|
				<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 elements where you want your form and comments to show up
 | 
						|
					</p>
 | 
						|
					{{ gbUrl := fmt.Sprintf("https://%s/websites/%s/guestbook", data.RootUrl, shortIdToSlug(website.ShortId)) }}
 | 
						|
					//<button>Copy to Clipboard</button>
 | 
						|
					<pre>
 | 
						|
						<code>
 | 
						|
							{ fmt.Sprintf(`<guestbook-form guestbook="%s"></guestbook-form>
 | 
						|
<guestbook-comments guestbook="%s"></guestbook-comments>`, gbUrl, gbUrl) }
 | 
						|
						</code>
 | 
						|
					</pre>
 | 
						|
				</div>
 | 
						|
				<p>
 | 
						|
					If your web host does not allow CORS requests, use an iframe instead
 | 
						|
				</p>
 | 
						|
				<div>
 | 
						|
					<pre>
 | 
						|
						<code>
 | 
						|
							{ fmt.Sprintf(`<iframe src="%s" title="Guestbook"></iframe>`, gbUrl) }
 | 
						|
						</code>
 | 
						|
					</pre>
 | 
						|
				</div>
 | 
						|
			</div>
 | 
						|
		</div>
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
templ websiteSettingsForm(data CommonData, website models.Website, form forms.WebsiteSettingsForm) {
 | 
						|
	<h3>Website Settings</h3>
 | 
						|
	<div>
 | 
						|
		{{ err, exists := form.FieldErrors["ws_name"] }}
 | 
						|
		<label for="ws_name">Site Name: </label>
 | 
						|
		if exists {
 | 
						|
			<label class="error">{ err }</label>
 | 
						|
		}
 | 
						|
		if form.SiteName != "" {
 | 
						|
			<input type="text" name="ws_name" id="sitename" value={ form.SiteName } required/>
 | 
						|
		} else {
 | 
						|
			<input type="text" name="ws_name" id="sitename" value={ website.Name } required/>
 | 
						|
		}
 | 
						|
	</div>
 | 
						|
	<div>
 | 
						|
		{{ err, exists = form.FieldErrors["ws_url"] }}
 | 
						|
		<label for="ws_url">Site URL: </label>
 | 
						|
		if exists {
 | 
						|
			<label class="error">{ err }</label>
 | 
						|
		}
 | 
						|
		if form.SiteUrl != "" {
 | 
						|
			<input type="text" name="ws_url" id="ws_url" value={ form.SiteUrl } required/>
 | 
						|
		} else {
 | 
						|
			<input type="text" name="ws_url" id="ws_url" value={ website.Url.String() } required/>
 | 
						|
		}
 | 
						|
	</div>
 | 
						|
	<div>
 | 
						|
		{{ err, exists = form.FieldErrors["ws_author"] }}
 | 
						|
		<label for="ws_author">Site Author: </label>
 | 
						|
		if exists {
 | 
						|
			<label class="error">{ err }</label>
 | 
						|
		}
 | 
						|
		if form.AuthorName != "" {
 | 
						|
			<input type="text" name="ws_author" id="authorname" value={ form.AuthorName } required/>
 | 
						|
		} else {
 | 
						|
			<input type="text" name="ws_author" id="authorname" value={ website.AuthorName } required/>
 | 
						|
		}
 | 
						|
	</div>
 | 
						|
}
 | 
						|
 | 
						|
templ guestbookSettingsForm(data CommonData, website models.Website, gb models.Guestbook, form forms.WebsiteSettingsForm) {
 | 
						|
	<h3>Guestbook Settings</h3>
 | 
						|
	<div>
 | 
						|
		<label>Guestbook Visibility</label>
 | 
						|
		<label for="gb_visible_true">
 | 
						|
			<input type="radio" name="gb_visible" id="gb_visible_true" value="true" checked?={ gb.Settings.IsVisible }/>
 | 
						|
			Public
 | 
						|
		</label>
 | 
						|
		<label for="gb_visible_false">
 | 
						|
			<input type="radio" name="gb_visible" id="gb_visible_false" value="false" checked?={ !gb.Settings.IsVisible }/>
 | 
						|
			Private
 | 
						|
		</label>
 | 
						|
	</div>
 | 
						|
	<div>
 | 
						|
		<label>Guestbook Commenting</label>
 | 
						|
		<select name="gb_commenting" id="gb-commenting">
 | 
						|
			<option value="true" selected?={ gb.Settings.IsCommentingEnabled }>Enabled</option>
 | 
						|
			<option value="1h">Disabled for 1 Hour</option>
 | 
						|
			<option value="4h">Disabled for 4 Hours</option>
 | 
						|
			<option value="8h">Disabled for 8 Hours</option>
 | 
						|
			<option value="24h">Disabled for 1 Day</option>
 | 
						|
			<option value="72h">Disabled for 3 Days</option>
 | 
						|
			<option value="168h">Disabled for 7 Days</option>
 | 
						|
			<option value="false" selected?={ !gb.Settings.IsCommentingEnabled }>Disabled</option>
 | 
						|
		</select>
 | 
						|
		if !website.Guestbook.CanComment() {
 | 
						|
			{{ localtime := gb.Settings.ReenableCommenting.In(data.CurrentUser.Settings.LocalTimezone) }}
 | 
						|
			<label>Commenting re-enabled on <time value={ localtime.Format(time.RFC3339) }>{ localtime.Format("2 January 2006") } at { localtime.Format("3:04PM MST") }</time></label>
 | 
						|
		}
 | 
						|
	</div>
 | 
						|
	<div>
 | 
						|
		<label>Enable Widgets</label>
 | 
						|
		<label for="gb_remote_true">
 | 
						|
			<input type="radio" name="gb_remote" id="gb_remote_true" value="true" checked?={ gb.Settings.AllowRemoteHostAccess }/>
 | 
						|
			Yes
 | 
						|
		</label>
 | 
						|
		<label for="gb_remote_false">
 | 
						|
			<input type="radio" name="gb_remote" id="gb_remote_false" value="false" checked?={ !gb.Settings.AllowRemoteHostAccess }/>
 | 
						|
			No
 | 
						|
		</label>
 | 
						|
	</div>
 | 
						|
}
 | 
						|
 | 
						|
templ SettingsForm(data CommonData, website models.Website, form forms.WebsiteSettingsForm, msg string) {
 | 
						|
	{{ putUrl := fmt.Sprintf("/websites/%s/dashboard/settings", shortIdToSlug(website.ShortId)) }}
 | 
						|
	{{ gb := website.Guestbook }}
 | 
						|
	<form hx-put={ putUrl } hx-swap="outerHTML">
 | 
						|
		<p>
 | 
						|
			{ msg }
 | 
						|
		</p>
 | 
						|
		<input type="hidden" name="csrf_token" value={ data.CSRFToken }/>
 | 
						|
		<div id="settings_form">
 | 
						|
			@websiteSettingsForm(data, website, form)
 | 
						|
			@guestbookSettingsForm(data, website, gb, form)
 | 
						|
		</div>
 | 
						|
		<input type="submit" value="Submit"/>
 | 
						|
	</form>
 | 
						|
}
 | 
						|
 | 
						|
templ WebsiteDashboardSettings(data CommonData, website models.Website, form forms.WebsiteSettingsForm) {
 | 
						|
	{{ title := fmt.Sprintf("%s - Settings", website.Name) }}
 | 
						|
	@base(title, data) {
 | 
						|
		<div id="dashboard">
 | 
						|
			@wSidebar(website)
 | 
						|
			<div>
 | 
						|
				@SettingsForm(data, website, form, "")
 | 
						|
				<form>
 | 
						|
					<input type="hidden" name="csrf_token" value={ data.CSRFToken }/>
 | 
						|
					<h3>Delete Website</h3>
 | 
						|
					<p>Deleting a website is permanent. Be absolutely sure before proceeding.</p>
 | 
						|
					<label for="delete">Type your site name in the form.</label>
 | 
						|
					<input type="text" name="delete" required/>
 | 
						|
					<input type="submit" value="Delete" class="danger"/>
 | 
						|
				</form>
 | 
						|
			</div>
 | 
						|
		</div>
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
templ WebsiteDashboardComingSoon(title string, data CommonData, website models.Website) {
 | 
						|
	@base(title, data) {
 | 
						|
		<div id="dashboard">
 | 
						|
			@wSidebar(website)
 | 
						|
			<div>
 | 
						|
				<p>
 | 
						|
					Coming Soon
 | 
						|
				</p>
 | 
						|
			</div>
 | 
						|
		</div>
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
templ WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm) {
 | 
						|
	@base(title, data) {
 | 
						|
		<form action="/websites/create" method="post">
 | 
						|
			@websiteCreateForm(data.CSRFToken, form)
 | 
						|
		</form>
 | 
						|
	}
 | 
						|
}
 |