First pass at basic functionality.

This PR introduces the beginnings of Sprint Padawan.

Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
2026-05-02 02:01:53 -06:00
parent 3586be0e14
commit 16bed1b8c0
51 changed files with 4597 additions and 1 deletions
+120
View File
@@ -0,0 +1,120 @@
<!doctype html>
<html lang="en">
{{template "app-head" (dict "Title" "Dashboard" "UseHTMX" true "UseSSE"
false)}}
<body class="app-body">
<div class="app-shell">
<div class="main-content">
<header class="topbar">
<div class="topbar-brand">
{{template "brand-mark" .}}
<span class="topbar-title">Planning Rooms</span>
</div>
<div class="topbar-actions">
<button
class="btn-primary topbar-btn"
hx-get="/rooms/new"
hx-target="body"
hx-swap="beforeend"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="12" y1="5" x2="12" y2="19"></line>
<line x1="5" y1="12" x2="19" y2="12"></line>
</svg>
Create Room
</button>
{{template "session-controls" .}}
</div>
</header>
<main class="page-content">
<div class="welcome-hero">
<p class="welcome-greeting">
Welcome back, <span>{{.Username}}</span>
</p>
<p class="welcome-sub">
Create or join a planning room to start estimating.
</p>
</div>
{{if .Rooms}}
<div class="rooms-grid">
{{range .Rooms}}
<div class="room-card">
<a href="/rooms/{{.ID}}" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 1;"></a>
<div class="room-header" style="position: relative; z-index: 2; pointer-events: none;">
<span class="room-name">{{.Name}}</span>
<div
style="
display: flex;
gap: 0.5rem;
align-items: center;
pointer-events: auto;
"
>
{{if .IsOwner}}
<span
class="room-owner-badge"
style="
position: static;
margin: 0;
padding: 0.2rem 0.5rem;
"
>
Owner
</span>
{{end}}
<span class="room-code">{{.Code}}</span>
{{if .IsOwner}}
<button
type="button"
class="story-action-btn story-action-delete"
hx-post="/rooms/{{.ID}}/delete"
hx-target="closest .room-card"
hx-swap="outerHTML"
hx-confirm="Delete this room?"
title="Delete Room"
aria-label="Delete Room"
>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 6h18" />
<path d="M8 6V4h8v2" />
<path d="M19 6l-1 14H6L5 6" />
<path d="M10 11v6" />
<path d="M14 11v6" />
</svg>
</button>
{{end}}
</div>
</div>
<div class="room-meta" style="position: relative; z-index: 2; pointer-events: none;">
<span class="room-scale">{{.Scale}}</span>
<span class="room-members"
>{{.MemberCount}} members</span
>
</div>
</div>
{{end}}
</div>
{{else}}
<div class="empty-state">
<p>No rooms yet. Create one to get started.</p>
</div>
{{end}}
</main>
</div>
</div>
<div id="modal-container"></div>
</body>
</html>