Diff -- /var/www/vhosts/3dshawn.com/ptmatrix.3dshawn.com/TEMPLATES/tf_dashboard.html
Diff
/var/www/vhosts/3dshawn.com/ptmatrix.3dshawn.com/TEMPLATES/tf_dashboard.html
added on local at 2026-07-01 12:34:54
Added
+186
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to de6b7c3940ba
to de6b7c3940ba
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.| 1 | [if:$show_welcome] | |
| 2 | <div class="welcome-card" style="background:linear-gradient(135deg, rgba(90,169,255,0.10) 0%, rgba(168,85,247,0.10) 100%); border:1px solid rgba(90,169,255,0.4); border-radius:12px; padding:24px; margin-bottom:24px; position:relative"> | |
| 3 | <button type="button" onclick="this.parentElement.style.display='none'" style="position:absolute;top:12px;right:14px;background:transparent;border:none;color:var(--col-text-muted);cursor:pointer;font-size:18px;font-weight:700">×</button> | |
| 4 | <h2 style="margin:0 0 6px;font-size:18px;color:#5aa9ff">Welcome to PTMatrix, $display_name! 🎉</h2> | |
| 5 | <p style="margin:0 0 14px;font-size:13px;color:var(--col-text-muted)">Your 14-day trial is active. We've seeded a sample project with example tickets so you can explore right away. Try these next:</p> | |
| 6 | <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px"> | |
| 7 | <a href="/projects.cgi" style="display:block;padding:12px;background:var(--col-bg-2);border:1px solid var(--col-border);border-radius:8px;text-decoration:none;color:var(--col-text);transition:border-color .12s" onmouseover="this.style.borderColor='#5aa9ff'" onmouseout="this.style.borderColor='var(--col-border)'"> | |
| 8 | <div style="font-weight:600;font-size:13px;margin-bottom:4px">📋 Browse sample tickets</div> | |
| 9 | <div style="font-size:11px;color:var(--col-text-muted)">See how tasks, customer tickets, bugs, and feature requests live in one queue.</div> | |
| 10 | </a> | |
| 11 | <a href="/email_inboxes.cgi" style="display:block;padding:12px;background:var(--col-bg-2);border:1px solid var(--col-border);border-radius:8px;text-decoration:none;color:var(--col-text)" onmouseover="this.style.borderColor='#5aa9ff'" onmouseout="this.style.borderColor='var(--col-border)'"> | |
| 12 | <div style="font-weight:600;font-size:13px;margin-bottom:4px">✉️ Connect your support email</div> | |
| 13 | <div style="font-size:11px;color:var(--col-text-muted)">Customer emails become tickets automatically. Gmail, O365, Mailgun, or our forwarding address.</div> | |
| 14 | </a> | |
| 15 | <a href="/api_keys.cgi" style="display:block;padding:12px;background:var(--col-bg-2);border:1px solid var(--col-border);border-radius:8px;text-decoration:none;color:var(--col-text)" onmouseover="this.style.borderColor='#5aa9ff'" onmouseout="this.style.borderColor='var(--col-border)'"> | |
| 16 | <div style="font-weight:600;font-size:13px;margin-bottom:4px">💬 Wire up outbound webhooks</div> | |
| 17 | <div style="font-size:11px;color:var(--col-text-muted)">POST ticket events to Zapier, n8n, your CRM, or any URL. HMAC-signed.</div> | |
| 18 | </a> | |
| 19 | <a href="/team.cgi" style="display:block;padding:12px;background:var(--col-bg-2);border:1px solid var(--col-border);border-radius:8px;text-decoration:none;color:var(--col-text)" onmouseover="this.style.borderColor='#5aa9ff'" onmouseout="this.style.borderColor='var(--col-border)'"> | |
| 20 | <div style="font-weight:600;font-size:13px;margin-bottom:4px">👨‍👩‍👧‍👦 Invite your team</div> | |
| 21 | <div style="font-size:11px;color:var(--col-text-muted)">Add teammates so they can claim tickets and join the conversation.</div> | |
| 22 | </a> | |
| 23 | <a href="/projects.cgi" style="display:block;padding:12px;background:var(--col-bg-2);border:1px solid var(--col-border);border-radius:8px;text-decoration:none;color:var(--col-text)" onmouseover="this.style.borderColor='#5aa9ff'" onmouseout="this.style.borderColor='var(--col-border)'"> | |
| 24 | <div style="font-weight:600;font-size:13px;margin-bottom:4px">📥 Bring your existing tasks</div> | |
| 25 | <div style="font-size:11px;color:var(--col-text-muted)">Open any project → <strong>Import</strong>. Drop in a CSV from Asana, Monday, Jira, or Trello — column names auto-detected.</div> | |
| 26 | </a> | |
| 27 | </div> | |
| 28 | <p style="margin:16px 0 0;font-size:11px;color:var(--col-text-muted)">When you're ready, you can delete the sample project from <a href="/projects.cgi" style="color:#5aa9ff">Projects</a>.</p> | |
| 29 | </div> | |
| 30 | [/if] | |
| 31 | ||
| 32 | <div class="page-header"> | |
| 33 | <div> | |
| 34 | <h1>Dashboard</h1> | |
| 35 | <p class="subtitle">Your work, at a glance.</p> | |
| 36 | </div> | |
| 37 | <div class="flex-end"> | |
| 38 | <a href="/projects.cgi?new=1" class="btn btn-primary"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg> New project</a> | |
| 39 | </div> | |
| 40 | </div> | |
| 41 | ||
| 42 | <div class="kpi-grid"> | |
| 43 | <div class="kpi" data-tip="**Every task currently assigned to you** that isn't done or cancelled. Includes blocked + in review."> | |
| 44 | <div class="kpi-label">My open tasks</div> | |
| 45 | <div class="kpi-value">$kpi_my_open</div> | |
| 46 | <div class="kpi-delta"><a href="/my_tasks.cgi">View all →</a></div> | |
| 47 | </div> | |
| 48 | <div class="kpi warn" data-tip="Tasks assigned to you with a **due date in the next 7 days**. Overdue ones are included."> | |
| 49 | <div class="kpi-label">Due this week</div> | |
| 50 | <div class="kpi-value">$kpi_due_week</div> | |
| 51 | <div class="kpi-delta">Next 7 days</div> | |
| 52 | </div> | |
| 53 | <div class="kpi danger" data-tip="Tasks past their due date that are still open. **Clear these first** — they drag everyone's workload forward."> | |
| 54 | <div class="kpi-label">Overdue</div> | |
| 55 | <div class="kpi-value">$kpi_overdue</div> | |
| 56 | <div class="kpi-delta">Past due date</div> | |
| 57 | </div> | |
| 58 | <div class="kpi success" data-tip="Tasks you closed in the last 7 days. Drives your velocity metric on the per-person report."> | |
| 59 | <div class="kpi-label">Completed this week</div> | |
| 60 | <div class="kpi-value">$kpi_completed_week</div> | |
| 61 | <div class="kpi-delta up">▲ closed in 7d</div> | |
| 62 | </div> | |
| 63 | </div> | |
| 64 | ||
| 65 | [if:$has_digest] | |
| 66 | <div class="card mb-3"> | |
| 67 | <div class="card-header"><h3>What changed today</h3><span class="text-muted" style="font-size:13px">Auto-summary across active projects</span></div> | |
| 68 | <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:12px;padding:6px 14px 14px"> | |
| 69 | [loop:@digest] | |
| 70 | <div style="display:flex;gap:10px;padding:10px 12px;border-radius:8px;background:rgba(255,255,255,.02);border-left:3px solid $loop1.color"> | |
| 71 | <div style="flex:1;min-width:0"> | |
| 72 | <div style="font-weight:600;font-size:14px;margin-bottom:2px"><a href="/project.cgi?id=$loop1.id" style="color:inherit">$loop1.key_prefix · $loop1.name</a></div> | |
| 73 | <div style="font-size:13px;color:var(--col-text-muted)"> | |
| 74 | [if:$loop1.has_today_activity] | |
| 75 | [if:$loop1.done_today]<strong style="color:#22c55e">$loop1.done_today completed</strong>[/if][if:$loop1.done_today][if:$loop1.new_today], [/if][/if][if:$loop1.new_today]<strong>$loop1.new_today new</strong>[/if][if:$loop1.has_today_activity] today[/if][if:$loop1.has_risk]. [/if] | |
| 76 | [/if] | |
| 77 | [if:$loop1.has_risk] | |
| 78 | [if:$loop1.overdue_n]<strong style="color:#ef4444">$loop1.overdue_n overdue</strong>[/if][if:$loop1.overdue_n][if:$loop1.blocked_n], [/if][/if][if:$loop1.blocked_n]<strong style="color:#f59e0b">$loop1.blocked_n blocked</strong>[/if] | |
| 79 | [if:!$loop1.has_today_activity] in flight[/if]. | |
| 80 | [/if] | |
| 81 | [if:$loop1.is_quiet]<span class="text-dim">Quiet day — no changes.</span>[/if] | |
| 82 | </div> | |
| 83 | </div> | |
| 84 | </div> | |
| 85 | [/loop] | |
| 86 | </div> | |
| 87 | </div> | |
| 88 | [/if] | |
| 89 | ||
| 90 | <div class="row" style="gap:24px;align-items:stretch;flex-wrap:wrap"> | |
| 91 | <div class="col" style="min-width:300px;flex:2"> | |
| 92 | <div class="card mb-3"> | |
| 93 | <div class="card-header"><h3>My next tasks</h3><a href="/my_tasks.cgi" class="text-muted" style="font-size:13px">View all</a></div> | |
| 94 | [if:$has_my_tasks] | |
| 95 | <table class="table"> | |
| 96 | <thead> | |
| 97 | <tr><th>Ticket</th><th>Title</th><th>Project</th><th>Priority</th><th>Due</th></tr> | |
| 98 | </thead> | |
| 99 | <tbody> | |
| 100 | [loop:@my_tasks] | |
| 101 | <tr class="clickable" onclick="location.href='/task.cgi?id=$loop1.id'"> | |
| 102 | <td><code>$loop1.display_ticket</code></td> | |
| 103 | <td>$loop1.title</td> | |
| 104 | <td><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:$loop1.project_color;margin-right:6px"></span>$loop1.project_name</td> | |
| 105 | <td><span class="priority-pill priority-$loop1.priority">$loop1.priority</span></td> | |
| 106 | <td>$loop1.due_label</td> | |
| 107 | </tr> | |
| 108 | [/loop] | |
| 109 | </tbody> | |
| 110 | </table> | |
| 111 | [/if] | |
| 112 | [if:!$has_my_tasks] | |
| 113 | <div class="muted-empty"> | |
| 114 | <h3>You're all caught up!</h3> | |
| 115 | <p>No open tasks assigned to you. Nice work.</p> | |
| 116 | </div> | |
| 117 | [/if] | |
| 118 | </div> | |
| 119 | ||
| 120 | <div class="card"> | |
| 121 | <div class="card-header"><h3>Active projects</h3><a href="/projects.cgi" class="text-muted" style="font-size:13px">All projects</a></div> | |
| 122 | [if:$has_projects] | |
| 123 | <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px"> | |
| 124 | [loop:@projects] | |
| 125 | <a href="/project.cgi?id=$loop1.id" style="text-decoration:none;color:inherit;display:block;background:var(--col-bg-1);border:1px solid var(--col-border);border-radius:10px;padding:14px;border-left:3px solid $loop1.color;transition:transform 120ms"> | |
| 126 | <div style="display:flex;justify-content:space-between;align-items:start;gap:10px;margin-bottom:8px"> | |
| 127 | <div style="font-weight:600">$loop1.name</div> | |
| 128 | <span class="badge">$loop1.key_prefix</span> | |
| 129 | </div> | |
| 130 | <div style="font-size:12px;color:var(--col-text-dim);margin-bottom:10px">$loop1.open_count open / $loop1.total_count total</div> | |
| 131 | <div style="background:var(--col-bg-3);height:6px;border-radius:3px;overflow:hidden"><div style="background:$loop1.color;height:100%;width:$loop1.progress_pct%"></div></div> | |
| 132 | <div style="font-size:11px;color:var(--col-text-dim);margin-top:4px">$loop1.progress_pct% complete</div> | |
| 133 | </a> | |
| 134 | [/loop] | |
| 135 | </div> | |
| 136 | [/if] | |
| 137 | [if:!$has_projects] | |
| 138 | <div class="muted-empty"> | |
| 139 | <h3>No projects yet</h3> | |
| 140 | <p>Spin one up to get your team rolling.</p> | |
| 141 | <a href="/projects.cgi?new=1" class="btn btn-primary mt-2">Create your first project</a> | |
| 142 | </div> | |
| 143 | [/if] | |
| 144 | </div> | |
| 145 | </div> | |
| 146 | ||
| 147 | <div class="col" style="min-width:280px;flex:1"> | |
| 148 | <div class="card mb-3"> | |
| 149 | <div class="card-header"><h3>Team workload</h3><a href="/workload.cgi" class="text-muted" style="font-size:13px">Full report</a></div> | |
| 150 | [if:$has_workload] | |
| 151 | [loop:@workload] | |
| 152 | <div style="display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid var(--col-border)"> | |
| 153 | <div class="avatar avatar-sm" style="background:$loop1.avatar_color">$loop1.initials</div> | |
| 154 | <div style="flex:1;min-width:0"> | |
| 155 | <div style="font-size:13px">$loop1.display_name</div> | |
| 156 | <div style="font-size:11px;color:var(--col-text-dim)">$loop1.open_count open | |
| 157 | [if:$loop1.overdue_count > 0] · <span style="color:var(--col-danger)">$loop1.overdue_count overdue</span>[/if] | |
| 158 | </div> | |
| 159 | </div> | |
| 160 | </div> | |
| 161 | [/loop] | |
| 162 | [/if] | |
| 163 | [if:!$has_workload] | |
| 164 | <p class="text-dim" style="font-size:13px">No team members yet. <a href="/team.cgi">Invite your team</a>.</p> | |
| 165 | [/if] | |
| 166 | </div> | |
| 167 | ||
| 168 | <div class="card"> | |
| 169 | <div class="card-header"><h3>Recent activity</h3><a href="/activity.cgi" class="text-muted" style="font-size:13px">Full feed</a></div> | |
| 170 | [if:$has_activity] | |
| 171 | [loop:@activity] | |
| 172 | <div style="display:flex;align-items:start;gap:10px;padding:8px 0;border-bottom:1px solid var(--col-border)"> | |
| 173 | <div class="avatar avatar-sm" style="background:$loop1.avatar_color">!</div> | |
| 174 | <div style="flex:1;font-size:12.5px;color:var(--col-text-muted);line-height:1.4"> | |
| 175 | <strong>$loop1.actor_name</strong> $loop1.action <em>$loop1.target_type</em> | |
| 176 | <div style="color:var(--col-text-dim);font-size:11px">$loop1.occurred_at</div> | |
| 177 | </div> | |
| 178 | </div> | |
| 179 | [/loop] | |
| 180 | [/if] | |
| 181 | [if:!$has_activity] | |
| 182 | <p class="text-dim" style="font-size:13px">Activity will show up here as you and your team work.</p> | |
| 183 | [/if] | |
| 184 | </div> | |
| 185 | </div> | |
| 186 | </div> |