Add markdown event descriptions for hosts to provide context

Hosts can now add a free-form description (with markdown rendering via
goldmark) when creating or editing events. Descriptions render safely
with no raw HTML passthrough. Includes ALTER TABLE migration for
existing databases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-17 08:02:24 -04:00
parent 4fc79d4491
commit 7b0efb3c45
13 changed files with 189 additions and 35 deletions
+14
View File
@@ -26,6 +26,9 @@
{{if .Event.Time}}<span>&#128338; {{.Event.Time}}</span>{{end}}
{{if .Event.Location}}<span>&#128205; {{.Event.Location}}</span>{{end}}
</div>
{{if .DescriptionHTML}}
<div class="event-description">{{.DescriptionHTML}}</div>
{{end}}
</div>
<div id="slots-container"
@@ -87,6 +90,17 @@
{{end}}
{{if .IsAdmin}}
<div class="section-label" style="margin-top:40px">Admin: Description</div>
<div class="claim-form-wrapper">
<form method="POST" action="/e/{{.Event.Slug}}/admin/{{.Event.AdminToken}}/description">
<div class="form-row">
<label>Event description (markdown supported)</label>
<textarea name="description" rows="5" style="border:var(--border-w) solid var(--border);background:var(--cream);padding:10px 14px;font-family:'Bricolage Grotesque',sans-serif;font-size:0.95rem;resize:vertical;outline:none;">{{.Event.Description}}</textarea>
</div>
<button class="btn-submit" type="submit">Save description</button>
</form>
</div>
<div class="section-label" style="margin-top:40px">Admin: Add slot</div>
<div class="claim-form-wrapper">
<form hx-post="/e/{{.Event.Slug}}/admin/{{.Event.AdminToken}}/slot"
+4
View File
@@ -29,6 +29,10 @@
<label>Location</label>
<input type="text" name="location" placeholder="e.g. Long Meadow, entrance at 9th St">
</div>
<div class="form-row">
<label>Description (optional, markdown supported)</label>
<textarea name="description" rows="4" placeholder="e.g. Bring your own blanket! We'll have a grill set up near the big oak tree." style="border:var(--border-w) solid var(--border);background:var(--cream);padding:10px 14px;font-family:'Bricolage Grotesque',sans-serif;font-size:0.95rem;resize:vertical;outline:none;"></textarea>
</div>
<div class="section-label" style="margin:24px 0 16px">Slots</div>
+36 -1
View File
@@ -97,6 +97,41 @@
font-size: 0.78rem;
color: #555;
}
.event-description {
margin-top: 16px;
padding-top: 16px;
border-top: 1px solid #ddd;
font-size: 0.92rem;
line-height: 1.6;
}
.event-description h1 { font-size: 1.3rem; margin: 16px 0 8px; }
.event-description h2 { font-size: 1.15rem; margin: 14px 0 6px; }
.event-description h3 { font-size: 1.05rem; margin: 12px 0 4px; }
.event-description p { margin: 8px 0; }
.event-description ul, .event-description ol { margin: 8px 0; padding-left: 24px; }
.event-description li { margin: 4px 0; }
.event-description a { color: var(--ink); text-decoration: underline; }
.event-description code {
font-family: 'DM Mono', monospace;
background: var(--cream);
padding: 2px 6px;
font-size: 0.85em;
border: 1px solid #ddd;
}
.event-description pre {
background: var(--cream);
border: 1px solid #ddd;
padding: 12px;
overflow-x: auto;
margin: 8px 0;
}
.event-description pre code { background: none; border: none; padding: 0; }
.event-description blockquote {
border-left: 3px solid var(--ink);
padding-left: 12px;
margin: 8px 0;
color: #555;
}
.section-label {
font-family: 'DM Mono', monospace;
font-size: 0.7rem;
@@ -230,7 +265,7 @@
transition: box-shadow 0.1s;
appearance: none;
}
.form-row input:focus, .form-row select:focus {
.form-row input:focus, .form-row select:focus, .form-row textarea:focus {
box-shadow: 3px 3px 0 var(--ink);
}
.btn-submit {