Implement academy analytics, billing, and web stories updates
This commit is contained in:
73
resources/js/Pages/Admin/Academy/AnalyticsOverview.jsx
Normal file
73
resources/js/Pages/Admin/Academy/AnalyticsOverview.jsx
Normal file
@@ -0,0 +1,73 @@
|
||||
import React from 'react'
|
||||
import { Head } from '@inertiajs/react'
|
||||
import AdminLayout from '../../../Layouts/AdminLayout'
|
||||
import AnalyticsNav from './AnalyticsNav'
|
||||
|
||||
function StatCard({ label, value }) {
|
||||
return (
|
||||
<div className="rounded-2xl border border-white/[0.08] bg-white/[0.04] p-5">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500">{label}</p>
|
||||
<p className="mt-3 text-3xl font-bold text-white">{Number(value || 0).toLocaleString()}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function ContentList({ title, items = [] }) {
|
||||
return (
|
||||
<div className="rounded-[28px] border border-white/[0.08] bg-white/[0.03] p-6">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500">{title}</p>
|
||||
<div className="mt-4 space-y-3">
|
||||
{items.length ? items.map((item) => (
|
||||
<div key={`${item.content_type}-${item.content_id || 'none'}`} className="rounded-2xl border border-white/[0.08] bg-black/20 px-4 py-4">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<div>
|
||||
<p className="text-sm font-semibold text-white">{item.title}</p>
|
||||
<p className="mt-1 text-xs uppercase tracking-[0.18em] text-slate-500">{item.content_type_label}</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<p className="text-sm font-semibold text-sky-100">{item.popularity_score}</p>
|
||||
<p className="text-xs uppercase tracking-[0.18em] text-slate-500">popularity</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)) : <p className="rounded-2xl border border-dashed border-white/[0.08] bg-black/20 px-4 py-6 text-sm text-slate-400">No rollup data yet for this range.</p>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function AcademyAnalyticsOverview({ nav = [], range, stats, topContent = [], topWeek = [] }) {
|
||||
return (
|
||||
<AdminLayout title="Academy Analytics" subtitle="Daily rollup overview for Academy traffic, engagement, and subscription intent.">
|
||||
<Head title="Admin · Academy Analytics" />
|
||||
|
||||
<div className="space-y-6">
|
||||
<AnalyticsNav items={nav} />
|
||||
|
||||
<div className="rounded-[28px] border border-white/[0.08] bg-white/[0.03] p-6">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500">Range</p>
|
||||
<p className="mt-3 text-sm text-slate-300">{range?.from} to {range?.to}</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
|
||||
<StatCard label="Views" value={stats.views} />
|
||||
<StatCard label="Unique Visitors" value={stats.uniqueVisitors} />
|
||||
<StatCard label="Logged-in Views" value={stats.userViews} />
|
||||
<StatCard label="Guest Views" value={stats.guestViews} />
|
||||
<StatCard label="Subscriber Views" value={stats.subscriberViews} />
|
||||
<StatCard label="Prompt Copies" value={stats.promptCopies} />
|
||||
<StatCard label="Likes" value={stats.likes} />
|
||||
<StatCard label="Saves" value={stats.saves} />
|
||||
<StatCard label="Lesson Completions" value={stats.lessonCompletions} />
|
||||
<StatCard label="Course Starts" value={stats.courseStarts} />
|
||||
<StatCard label="Upgrade Clicks" value={stats.upgradeClicks} />
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 xl:grid-cols-2">
|
||||
<ContentList title="Top Content In Range" items={topContent} />
|
||||
<ContentList title="Top Content This Week" items={topWeek} />
|
||||
</div>
|
||||
</div>
|
||||
</AdminLayout>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user