feat(admin): mobile-friendly admin shell + promote-on-social MVP

Mobile admin chrome
- New <AdminShell> component: sticky dark top bar w/ hamburger that opens
  a right-side drawer listing every admin section grouped by area
  (Content / Editorial / Companies / Newsletter / AdOps / Accounting /
  People). Closes on route change, Esc, or backdrop tap. Body scroll
  locks while open.
- Wrapped /admin (dashboard) and /admin/articles with the shell. Other
  admin pages still render their own layouts — they'll get the wrapper
  in follow-ups; the shell sits ABOVE them so nothing breaks today.

Promote-story MVP (share URLs, no OAuth yet)
- New /admin/promote/[slug] page: per-article promote sheet w/ one button
  per platform. Each uses that platform's standard share URL:
    • LinkedIn  → /sharing/share-offsite/?url=
    • X         → /intent/tweet?text=…&url=…&hashtags=…
    • Facebook  → /sharer/sharer.php?u=…
    • Instagram → copies caption to clipboard + opens instagram:// camera
    • Email     → mailto: with subject + body pre-filled
  On iPhone each button opens the platform's native app via universal
  link. No OAuth, no API keys, works tonight.
- New "Promote" action button on every published article row in
  /admin/articles — links to /admin/promote/<slug>.

Next session
- Meta OAuth (Facebook Page + IG Business) — Ryan to register the Meta
  App in Business Suite first, then we wire one-tap server-side posting.
- LinkedIn OAuth + Marketing API.
- X paid API ($100/mo Basic decision pending).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-04 23:06:14 +00:00
parent a8dc457742
commit 45cf96a203
4 changed files with 490 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ import React, { useState, useEffect, useCallback } from 'react';
import Link from 'next/link';
import { useAuth } from '@/contexts/AuthContext';
import { useRouter } from 'next/navigation';
import AdminShell from '@/components/admin/AdminShell';
// ─── Types ────────────────────────────────────────────────────────────────────
@@ -249,6 +250,7 @@ export default function AdminDashboardPage() {
if (!user) return null;
return (
<AdminShell title="Dashboard">
<div className="min-h-screen bg-[#0a0a0a]">
<div className="max-w-7xl mx-auto px-4 py-8">
@@ -615,5 +617,6 @@ export default function AdminDashboardPage() {
</div>
</div>
</div>
</AdminShell>
);
}