Spaces:
Running
Running
AuthorBot commited on
Commit Β·
0c80c73
1
Parent(s): ea890f6
Add: Create Author UI modal in SuperAdmin panel with plan selection
Browse files
app/superadmin/templates/superadmin.html
CHANGED
|
@@ -254,7 +254,8 @@
|
|
| 254 |
<div class="search-bar"><span>π</span><input type="text" placeholder="Search authors..." id="author-search" oninput="filterAuthors()"></div>
|
| 255 |
<div class="toolbar-spacer"></div>
|
| 256 |
<span class="text-xs text-muted" id="author-count">β authors</span>
|
| 257 |
-
<button class="btn btn-primary btn-sm" onclick="
|
|
|
|
| 258 |
</div>
|
| 259 |
<div class="card" style="padding:0;"><div class="table-wrap"><table><thead><tr><th>Author</th><th>Email</th><th>Role</th><th>Status</th><th>Books</th><th>Joined</th><th>Actions</th></tr></thead><tbody id="authors-body"><tr><td colspan="7" class="text-muted" style="text-align:center;padding:40px;">Loading...</td></tr></tbody></table></div></div>
|
| 260 |
</div>
|
|
@@ -637,6 +638,53 @@ function viewAuthorDetail(id) {
|
|
| 637 |
`<button class="btn btn-secondary" onclick="closeModal()">Close</button>`);
|
| 638 |
}
|
| 639 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 640 |
/* SUBSCRIPTIONS β now powered by /super/grants */
|
| 641 |
let allGrants = [];
|
| 642 |
async function loadSubscriptions() {
|
|
|
|
| 254 |
<div class="search-bar"><span>π</span><input type="text" placeholder="Search authors..." id="author-search" oninput="filterAuthors()"></div>
|
| 255 |
<div class="toolbar-spacer"></div>
|
| 256 |
<span class="text-xs text-muted" id="author-count">β authors</span>
|
| 257 |
+
<button class="btn btn-primary btn-sm" onclick="showCreateAuthorModal()">+ Create Author</button>
|
| 258 |
+
<button class="btn btn-secondary btn-sm" onclick="nav('grant')">π Grant Access</button>
|
| 259 |
</div>
|
| 260 |
<div class="card" style="padding:0;"><div class="table-wrap"><table><thead><tr><th>Author</th><th>Email</th><th>Role</th><th>Status</th><th>Books</th><th>Joined</th><th>Actions</th></tr></thead><tbody id="authors-body"><tr><td colspan="7" class="text-muted" style="text-align:center;padding:40px;">Loading...</td></tr></tbody></table></div></div>
|
| 261 |
</div>
|
|
|
|
| 638 |
`<button class="btn btn-secondary" onclick="closeModal()">Close</button>`);
|
| 639 |
}
|
| 640 |
|
| 641 |
+
/* CREATE AUTHOR */
|
| 642 |
+
function showCreateAuthorModal() {
|
| 643 |
+
showModal('Create New Author',
|
| 644 |
+
`<div class="modal-sub">Register a new author account. Optionally assign a subscription plan immediately.</div>
|
| 645 |
+
<div class="form-group"><label class="form-label">Full Name</label><input type="text" class="form-input" id="ca-name" placeholder="Jane Author"></div>
|
| 646 |
+
<div class="form-group"><label class="form-label">Email</label><input type="email" class="form-input" id="ca-email" placeholder="author@example.com"></div>
|
| 647 |
+
<div class="form-group"><label class="form-label">Password</label><input type="password" class="form-input" id="ca-pass" placeholder="Min 8 chars, uppercase, digit, special char"></div>
|
| 648 |
+
<div class="grid-2">
|
| 649 |
+
<div class="form-group"><label class="form-label">Plan (optional)</label>
|
| 650 |
+
<select class="form-input" id="ca-plan">
|
| 651 |
+
<option value="">No plan β register only</option>
|
| 652 |
+
<option value="monthly">Monthly</option>
|
| 653 |
+
<option value="quarterly">Quarterly</option>
|
| 654 |
+
<option value="semi_annual">Semi-Annual</option>
|
| 655 |
+
<option value="annual">Annual</option>
|
| 656 |
+
</select>
|
| 657 |
+
</div>
|
| 658 |
+
<div class="form-group"><label class="form-label">Auto-Renew</label>
|
| 659 |
+
<select class="form-input" id="ca-renew"><option value="false">No</option><option value="true">Yes</option></select>
|
| 660 |
+
</div>
|
| 661 |
+
</div>`,
|
| 662 |
+
`<button class="btn btn-secondary" onclick="closeModal()">Cancel</button><button class="btn btn-primary" onclick="executeCreateAuthor()">Create Author</button>`);
|
| 663 |
+
}
|
| 664 |
+
|
| 665 |
+
async function executeCreateAuthor() {
|
| 666 |
+
const name = document.getElementById('ca-name').value.trim();
|
| 667 |
+
const email = document.getElementById('ca-email').value.trim();
|
| 668 |
+
const pass = document.getElementById('ca-pass').value;
|
| 669 |
+
const plan = document.getElementById('ca-plan').value || null;
|
| 670 |
+
const autoRenew = document.getElementById('ca-renew').value === 'true';
|
| 671 |
+
|
| 672 |
+
if (!name || !email || !pass) { toast('Please fill in all required fields', 'error'); return; }
|
| 673 |
+
if (pass.length < 8) { toast('Password must be at least 8 characters', 'error'); return; }
|
| 674 |
+
|
| 675 |
+
try {
|
| 676 |
+
const body = { email, password: pass, full_name: name };
|
| 677 |
+
if (plan) { body.plan = plan; body.auto_renew = autoRenew; }
|
| 678 |
+
const result = await apiPost('/super/authors', body);
|
| 679 |
+
closeModal();
|
| 680 |
+
let msg = `Author "${name}" created successfully`;
|
| 681 |
+
if (result.subscription) msg += ` with ${plan} plan`;
|
| 682 |
+
toast(msg, 'success');
|
| 683 |
+
loadAuthors();
|
| 684 |
+
loadOverview();
|
| 685 |
+
} catch(e) { toast(e.message || 'Failed to create author', 'error'); }
|
| 686 |
+
}
|
| 687 |
+
|
| 688 |
/* SUBSCRIPTIONS β now powered by /super/grants */
|
| 689 |
let allGrants = [];
|
| 690 |
async function loadSubscriptions() {
|