Merge branch 'dev'

This commit is contained in:
Jeff Emmett 2026-03-03 11:35:05 -08:00
commit 9a28ae8cf0
2 changed files with 30 additions and 8 deletions

View File

@ -17,6 +17,7 @@ class FolkInboxClient extends HTMLElement {
private filter: "all" | "open" | "snoozed" | "closed" = "all";
private helpOpen = false;
private composeOpen = false;
private showingSampleData = false;
private demoApprovals: any[] = [
{
id: "a1", subject: "Re: Q1 Budget approval for rSpace infrastructure", status: "PENDING",
@ -92,11 +93,17 @@ class FolkInboxClient extends HTMLElement {
this.mailboxes = data.mailboxes || [];
}
} catch { /* ignore */ }
if (this.mailboxes.length === 0) {
this.showingSampleData = true;
this.loadDemoData();
return;
}
this.render();
}
private async loadThreads(slug: string) {
if (this.space === "demo") {
if (this.space === "demo" || this.showingSampleData) {
this.threads = this.demoThreads[slug] || [];
if (this.filter !== "all") this.threads = this.threads.filter(t => t.status === this.filter);
this.render();
@ -115,7 +122,7 @@ class FolkInboxClient extends HTMLElement {
}
private async loadThread(id: string) {
if (this.space === "demo") {
if (this.space === "demo" || this.showingSampleData) {
const all = [...(this.demoThreads.team || []), ...(this.demoThreads.support || [])];
this.currentThread = all.find(t => t.id === id) || null;
if (this.currentThread) {
@ -135,7 +142,7 @@ class FolkInboxClient extends HTMLElement {
}
private async loadApprovals() {
if (this.space === "demo") { this.approvals = this.demoApprovals; this.render(); return; }
if (this.space === "demo" || this.showingSampleData) { this.approvals = this.demoApprovals; this.render(); return; }
try {
const base = window.location.pathname.replace(/\/$/, "");
const q = this.currentMailbox ? `?mailbox=${this.currentMailbox.slug}` : "";
@ -306,6 +313,8 @@ class FolkInboxClient extends HTMLElement {
.help-step-text { font-size: 0.8rem; color: #cbd5e1; line-height: 1.5; }
.help-cta { display: inline-block; padding: 0.6rem 1.5rem; background: linear-gradient(135deg, #6366f1, #0891b2); color: white; border-radius: 8px; text-decoration: none; font-size: 0.85rem; font-weight: 600; }
.sample-banner { padding: 8px 16px; background: rgba(99,102,241,0.12); border: 1px solid rgba(99,102,241,0.25); border-radius: 8px; color: #a5b4fc; font-size: 13px; text-align: center; margin-bottom: 12px; }
@media (max-width: 600px) {
.mailbox-grid { grid-template-columns: 1fr; }
.thread-from { max-width: 100px; }
@ -315,6 +324,7 @@ class FolkInboxClient extends HTMLElement {
</style>
<div class="container">
${this.renderNav()}
${this.showingSampleData ? '<div class="sample-banner">Showing sample data — create a mailbox to get started</div>' : ''}
${this.renderView()}
${this.helpOpen ? this.renderHelp() : ""}
</div>
@ -699,7 +709,7 @@ class FolkInboxClient extends HTMLElement {
const submitCompose = this.shadow.querySelector("[data-action='submit-compose']");
if (submitCompose) {
submitCompose.addEventListener("click", async () => {
if (this.space === "demo") {
if (this.space === "demo" || this.showingSampleData) {
alert("Compose is disabled in demo mode. In a live space, this would submit the email for team approval.");
return;
}
@ -724,7 +734,7 @@ class FolkInboxClient extends HTMLElement {
// Approval actions
this.shadow.querySelectorAll("[data-approve]").forEach((btn) => {
btn.addEventListener("click", async () => {
if (this.space === "demo") { alert("Approvals are disabled in demo mode."); return; }
if (this.space === "demo" || this.showingSampleData) { alert("Approvals are disabled in demo mode."); return; }
const id = (btn as HTMLElement).dataset.approve!;
const base = window.location.pathname.replace(/\/$/, "");
await fetch(`${base}/api/approvals/${id}/sign`, {
@ -737,7 +747,7 @@ class FolkInboxClient extends HTMLElement {
});
this.shadow.querySelectorAll("[data-reject]").forEach((btn) => {
btn.addEventListener("click", async () => {
if (this.space === "demo") { alert("Approvals are disabled in demo mode."); return; }
if (this.space === "demo" || this.showingSampleData) { alert("Approvals are disabled in demo mode."); return; }
const id = (btn as HTMLElement).dataset.reject!;
const base = window.location.pathname.replace(/\/$/, "");
await fetch(`${base}/api/approvals/${id}/sign`, {

View File

@ -43,6 +43,7 @@ class FolkPhotoGallery extends HTMLElement {
private lightboxAsset: Asset | null = null;
private loading = false;
private error = "";
private showingSampleData = false;
constructor() {
super();
@ -108,7 +109,7 @@ class FolkPhotoGallery extends HTMLElement {
}
private isDemo(): boolean {
return this.space === "demo";
return this.space === "demo" || this.showingSampleData;
}
private getApiBase(): string {
@ -136,7 +137,14 @@ class FolkPhotoGallery extends HTMLElement {
this.albums = albumsData.albums || [];
this.assets = assetsData.assets || [];
} catch {
this.error = "Could not connect to photo service. Make sure Immich is running.";
// Fall through to empty check below
}
if (this.albums.length === 0 && this.assets.length === 0) {
this.showingSampleData = true;
this.loading = false;
this.loadDemoData();
return;
}
this.loading = false;
@ -330,6 +338,8 @@ class FolkPhotoGallery extends HTMLElement {
text-shadow: 0 2px 6px rgba(0,0,0,0.5);
}
.sample-banner { padding: 8px 16px; background: rgba(99,102,241,0.12); border: 1px solid rgba(99,102,241,0.25); border-radius: 8px; color: #a5b4fc; font-size: 13px; text-align: center; margin-bottom: 12px; }
@media (max-width: 480px) {
.albums-grid { grid-template-columns: 1fr; }
.photo-grid { grid-template-columns: repeat(2, 1fr); }
@ -363,6 +373,8 @@ class FolkPhotoGallery extends HTMLElement {
</div>
</div>
${this.showingSampleData ? '<div class="sample-banner">Showing sample data — connect Immich to see your photos</div>' : ''}
${!hasContent ? `
<div class="empty">
<div class="empty-icon">📸</div>