299 lines
9.3 KiB
Plaintext
299 lines
9.3 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/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 DeleteForm(data CommonData, website models.Website, form forms.WebsiteDeleteForm) {
|
|
{{ putUrl := fmt.Sprintf("/websites/%s", shortIdToSlug(website.ShortId)) }}
|
|
<form hx-put={ putUrl } hx-swap="outerHTML">
|
|
<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>
|
|
{{ err, exists := form.FieldErrors["delete"] }}
|
|
<label for="delete">Type your site name in the form.</label>
|
|
if exists {
|
|
<label class="error">{ err }</label>
|
|
}
|
|
<input type="text" name="delete" id="delete" required/>
|
|
<input type="submit" value="Delete" class="danger"/>
|
|
</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, "")
|
|
@DeleteForm(data, website, forms.WebsiteDeleteForm{})
|
|
</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>
|
|
}
|
|
}
|