Diff -- /var/www/vhosts/3dshawn.com/repricer.3dshawn.com/TEMPLATES/repricer_team.html

O Operator
Diff

/var/www/vhosts/3dshawn.com/repricer.3dshawn.com/TEMPLATES/repricer_team.html

added on local at 2026-07-01 21:47:27

Added
+237
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 5b2860402fac
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1<div class="page-head">
2 <div>
3 <span class="page-eyebrow"><span class="dot"></span> Account &amp; preferences</span>
4 <h1 class="page-title">Team Members</h1>
5 <p class="page-subtitle">Add teammates who can sign in and help run your store. Their access is scoped by the role you pick &mdash; private billing details stay yours alone.</p>
6 </div>
7</div>
8
9[if:$has_flash]
10<div class="banner [if:$flash_is_success]success[/if][if:$flash_is_error]error[/if] mb-3">
11 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/></svg>
12 <div class="text-sm fw-600">$flash_msg</div>
13</div>
14[/if]
15
16[if:!$has_perm_ready]
17<div class="banner warn mb-3">
18 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/></svg>
19 <div class="text-sm fw-600">Permission tables not installed yet &mdash; run the DB migration to enable team management.</div>
20</div>
21[/if]
22
23[if:$has_perm_ready]
24<div class="module">
25 <div class="module-head">
26 <div class="left">
27 <div class="module-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg></div>
28 <div>
29 <div class="module-title">Your team ($member_count)</div>
30 <div class="module-sub">Owner: $owner_display</div>
31 </div>
32 </div>
33 </div>
34
35 [if:$has_members]
36 <div class="table-wrap" style="border:none;border-radius:0">
37 <table class="table">
38 <thead>
39 <tr>
40 <th>Member</th>
41 <th>Role</th>
42 <th class="num">Added</th>
43 <th class="num">Last seen</th>
44 <th></th>
45 </tr>
46 </thead>
47 <tbody>
48 [loop:@members]
49 <tr>
50 <td>
51 <div class="fw-600" style="color:#fff">$loop1.display_name</div>
52 <div class="text-xs text-dim">$loop1.email</div>
53 </td>
54 <td>
55 <form method="post" action="/team.cgi" style="display:flex;gap:6px;align-items:center;margin:0">
56 <input type="hidden" name="action" value="update_role">
57 <input type="hidden" name="member_id" value="$loop1.id">
58 <select class="select" name="permission_groups_id" style="min-width:140px">
59 [loop:@role_options]<option value="$loop2.value"$loop2.selected_attr>$loop2.label</option>[/loop]
60 </select>
61 <button type="submit" class="btn btn-secondary btn-sm">Save</button>
62 </form>
63 </td>
64 <td class="num text-dim">$loop1.added_on</td>
65 <td class="num text-dim">$loop1.last_seen</td>
66 <td>
67 <form method="post" action="/team.cgi"
68 data-confirm-title="Remove this team member?"
69 data-confirm-message="They will lose access to your store immediately."
70 data-confirm-label="Remove member"
71 data-confirm-style="danger"
72 style="margin:0">
73 <input type="hidden" name="action" value="remove_member">
74 <input type="hidden" name="member_id" value="$loop1.id">
75 <button type="submit" class="text-danger text-xs fw-600" style="background:none;border:0;padding:0;cursor:pointer">Remove</button>
76 </form>
77 </td>
78 </tr>
79 [/loop]
80 </tbody>
81 </table>
82 </div>
83 [/if]
84 [if:!$has_members]
85 <div class="module-body" style="text-align:center;padding:32px 20px">
86 <div class="text-sm fw-600" style="color:#fff;margin-bottom:6px">You're the only member</div>
87 <div class="text-xs text-dim">Add a teammate below to share day-to-day store work.</div>
88 </div>
89 [/if]
90</div>
91
92[if:$has_role_cards]
93<div class="module mt-3">
94 <div class="module-head">
95 <div class="left">
96 <div class="module-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 12l2 2 4-4"/><circle cx="12" cy="12" r="10"/></svg></div>
97 <div>
98 <div class="module-title">Roles</div>
99 <div class="module-sub">Built-in presets (Manager / Editor / Viewer) cover most teams; create custom roles below if you need a narrower or wider grant. Billing, team management, account deletion, and destructive ops (delete models, refund orders) stay owner-only no matter what.</div>
100 </div>
101 </div>
102 </div>
103 <div class="module-body">
104 <div class="dash-grid-3" style="gap:12px">
105 [loop:@role_cards]
106 <div style="border:1px solid var(--border);border-radius:8px;padding:14px;background:rgba(255,255,255,0.02);display:flex;flex-direction:column;gap:8px">
107 <div style="display:flex;align-items:center;justify-content:space-between;gap:8px">
108 <div class="fw-600" style="color:#fff">$loop1.name</div>
109 [if:$loop1.is_preset]<span class="pill" style="font-size:9.5px;letter-spacing:1px;padding:2px 7px;background:rgba(148,163,184,0.18);color:#cbd5e1;text-transform:uppercase;border-radius:999px">Built-in</span>[/if]
110 [if:$loop1.is_custom]<span class="pill" style="font-size:9.5px;letter-spacing:1px;padding:2px 7px;background:rgba(15,118,110,0.18);color:#6ee7b7;text-transform:uppercase;border-radius:999px">Custom</span>[/if]
111 </div>
112 [if:$loop1.has_features]
113 <ul style="margin:0;padding-left:18px">
114 [loop:@features]<li class="text-xs text-dim" style="margin:3px 0">$loop2.label</li>[/loop]
115 </ul>
116 [/if]
117 [if:!$loop1.has_features]
118 <div class="text-xs text-dim" style="font-style:italic">No permissions granted yet.</div>
119 [/if]
120
121 [if:$loop1.is_custom]
122 <details style="margin-top:4px">
123 <summary style="cursor:pointer;font-size:12px;color:var(--accent);user-select:none">Edit role</summary>
124 <form method="POST" action="/team.cgi" style="margin-top:10px;display:flex;flex-direction:column;gap:8px">
125 <input type="hidden" name="action" value="update_role_perms">
126 <input type="hidden" name="role_id" value="$loop1.id">
127 <label class="text-xs text-dim" style="display:block">
128 Name
129 <input class="input" type="text" name="role_name" value="$loop1.name" maxlength="120" required style="margin-top:4px">
130 </label>
131 <div class="text-xs text-dim" style="margin-top:4px">Permissions</div>
132 <div style="display:flex;flex-direction:column;gap:4px;max-height:180px;overflow:auto;padding:6px;background:rgba(15,23,42,0.4);border-radius:6px">
133 [loop:@feature_options]
134 <label class="text-xs" style="display:flex;align-items:center;gap:6px;color:var(--text-2);cursor:pointer">
135 <input type="checkbox" name="feature_ids" value="$loop2.id"$loop2.checked_attr>
136 $loop2.label
137 </label>
138 [/loop]
139 </div>
140 <div style="display:flex;gap:6px;margin-top:6px">
141 <button type="submit" class="btn btn-secondary btn-sm">Save</button>
142 </div>
143 </form>
144 <form method="POST" action="/team.cgi" style="margin-top:8px"
145 data-confirm-title="Delete this role?"
146 data-confirm-message="Members using this role must be reassigned first or this delete will fail."
147 data-confirm-label="Delete role"
148 data-confirm-style="danger">
149 <input type="hidden" name="action" value="delete_role">
150 <input type="hidden" name="role_id" value="$loop1.id">
151 <button type="submit" class="btn btn-danger btn-sm" style="font-size:11px;padding:4px 10px">Delete role</button>
152 </form>
153 </details>
154 [/if]
155 </div>
156 [/loop]
157 </div>
158
159 [if:$has_features_catalog]
160 <details style="margin-top:14px">
161 <summary style="cursor:pointer;color:var(--accent);font-weight:600;user-select:none">+ Create a custom role</summary>
162 <form method="POST" action="/team.cgi" style="margin-top:12px;padding:14px;border:1px solid var(--border);border-radius:8px;background:rgba(255,255,255,0.02);display:flex;flex-direction:column;gap:10px">
163 <input type="hidden" name="action" value="create_role">
164 <label class="text-xs text-dim">
165 Role name
166 <input class="input" type="text" name="role_name" placeholder="e.g. Storefront editor, Reports analyst" maxlength="120" required style="margin-top:4px">
167 </label>
168 <div class="text-xs text-dim" style="margin-top:4px">Pick the permissions this role grants. You can edit the list later.</div>
169 <div style="display:grid;grid-template-columns:1fr 1fr;gap:4px 18px;padding:10px;background:rgba(15,23,42,0.4);border-radius:6px">
170 [loop:@create_feature_options]
171 <label class="text-xs" style="display:flex;align-items:center;gap:6px;color:var(--text-2);cursor:pointer">
172 <input type="checkbox" name="feature_ids" value="$loop1.id">
173 $loop1.label
174 </label>
175 [/loop]
176 </div>
177 <div>
178 <button type="submit" class="btn btn-primary btn-sm">Create role</button>
179 </div>
180 </form>
181 </details>
182 [/if]
183 </div>
184</div>
185[/if]
186
187<div class="module mt-3">
188 <div class="module-head">
189 <div class="left">
190 <div class="module-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg></div>
191 <div>
192 <div class="module-title">Add team member</div>
193 <div class="module-sub">Set their starting password &mdash; they can change it after first login.</div>
194 </div>
195 </div>
196 </div>
197 <div class="module-body">
198 [if:$has_roles]
199 <form method="post" action="/team.cgi">
200 <input type="hidden" name="action" value="add_member">
201 <div class="dash-grid-2" style="gap:12px">
202 <div class="form-group">
203 <label class="form-label">Display name</label>
204 <input class="input" name="display_name" required maxlength="120" placeholder="e.g. Jordan Lee">
205 </div>
206 <div class="form-group">
207 <label class="form-label">Email</label>
208 <input class="input" name="email" type="email" required maxlength="191" placeholder="teammate@example.com">
209 </div>
210 </div>
211 <div class="dash-grid-2" style="gap:12px">
212 <div class="form-group">
213 <label class="form-label">Starting password</label>
214 <input class="input" name="password" type="text" required minlength="8" placeholder="Min 8 chars">
215 <div class="form-help">Hand this to them directly. They can change it from their own settings page.</div>
216 </div>
217 <div class="form-group">
218 <label class="form-label">Role</label>
219 <select class="select" name="permission_groups_id" required>
220 [loop:@add_role_options]<option value="$loop1.value">$loop1.label</option>[/loop]
221 </select>
222 <div class="form-help">Manager = full minus billing. Editor = day-to-day operations. Viewer = read-only.</div>
223 </div>
224 </div>
225 <div style="margin-top:12px">
226 <button type="submit" class="btn btn-primary">Add team member</button>
227 </div>
228 </form>
229 [/if]
230 [if:!$has_roles]
231 <div class="text-xs text-dim">No roles available yet &mdash; run the DB migration to install the default Manager / Editor / Viewer roles.</div>
232 [/if]
233 </div>
234</div>
235[/if]
236
237<div class="page-foot-spacer"></div>