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="nav('grant')">+ Grant Access</button>
 
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() {