import React from 'react' import { router, usePage } from '@inertiajs/react' import StudioLayout from '../../Layouts/StudioLayout' import { studioSurface, trackStudioEvent } from '../../utils/studioEvents' const rangeOptions = [7, 14, 30, 60, 90] const summaryCards = [ ['followers', 'Followers', 'fa-user-group'], ['published_in_range', 'Published', 'fa-calendar-check'], ['engagement_actions', 'Engagement actions', 'fa-bolt'], ['profile_completion', 'Profile completion', 'fa-id-card'], ['challenge_entries', 'Challenge entries', 'fa-trophy'], ['featured_modules', 'Featured modules', 'fa-star'], ] function formatShortDate(value) { const date = new Date(value) if (Number.isNaN(date.getTime())) return value return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }) } function TrendBars({ title, subtitle, points, colorClass }) { const values = (points || []).map((point) => Number(point.value || point.count || 0)) const maxValue = Math.max(...values, 1) return ( {title} {subtitle} {(points || []).map((point) => { const value = Number(point.value || point.count || 0) const height = `${Math.max(8, Math.round((value / maxValue) * 100))}%` return ( {value.toLocaleString()} {formatShortDate(point.date)} ) })} ) } export default function StudioGrowth() { const { props } = usePage() const { summary, moduleFocus, checkpoints, opportunities, milestones, momentum, topContent, rangeDays } = props const updateRange = (days) => { trackStudioEvent('studio_filter_used', { surface: studioSurface(), module: 'growth', meta: { range_days: days, }, }) router.get(window.location.pathname, { range_days: days }, { preserveScroll: true, preserveState: true, replace: true, }) } return ( Growth window Creator growth over the last {rangeDays || 30} days This view blends audience momentum, profile readiness, featured curation, and challenge participation into one operating surface. {rangeOptions.map((days) => ( updateRange(days)} className={`rounded-full px-4 py-2 text-sm font-semibold transition ${Number(rangeDays || 30) === days ? 'bg-white text-slate-950' : 'text-slate-300 hover:text-white'}`}> {days}d ))} {summaryCards.map(([key, label, icon]) => ( {label} {Number(summary?.[key] || 0).toLocaleString()} ))} Growth checkpoints {(checkpoints || []).map((item) => ( {item.label} {item.detail} {item.score} {item.status.replace('_', ' ')} = 80 ? 'bg-emerald-400/70' : item.score >= 55 ? 'bg-amber-400/70' : 'bg-rose-400/70'}`} style={{ width: `${Math.max(6, item.score)}%` }} /> trackStudioEvent('studio_insight_clicked', { surface: studioSurface(), module: 'growth', meta: { insight_key: item.key, href: item.href, }, })} className="mt-4 inline-flex items-center gap-2 text-sm font-medium text-sky-100" > {item.cta} ))} Growth opportunities {(opportunities || []).map((item) => ( trackStudioEvent('studio_insight_clicked', { surface: studioSurface(), module: 'growth', meta: { insight_key: item.title, href: item.href, }, })} className="block rounded-[22px] border border-white/10 bg-black/20 p-4 transition hover:border-white/20" > {item.title} {item.body} {item.cta} ))} Module focus Share of workspace output {(moduleFocus || []).map((item) => ( {item.label} {item.published_count} published • {item.draft_count} drafts Open Views{item.views.toLocaleString()} Engagement{item.engagement.toLocaleString()} ))} Milestones {(milestones || []).map((item) => ( {item.label} {item.current.toLocaleString()} of {item.target.toLocaleString()} {item.progress}% ))} Publishing rhythm {(momentum?.publishing_timeline || []).map((point) => ( {formatShortDate(point.date)} {point.count} ))} Top content this window {(topContent || []).map((item) => ( trackStudioEvent('studio_insight_clicked', { surface: studioSurface(), module: 'growth', item_module: item.module_key, item_id: item.numeric_id, meta: { insight_key: 'top_content', href: item.analytics_url || item.view_url, }, })} className="block rounded-[22px] border border-white/10 bg-black/20 p-4 transition hover:border-white/20" > {item.module_label} {item.title} Views{Number(item.metrics?.views || 0).toLocaleString()} Reactions{Number(item.metrics?.appreciation || 0).toLocaleString()} Comments{Number(item.metrics?.comments || 0).toLocaleString()} ))} ) }
{subtitle}
Growth window
This view blends audience momentum, profile readiness, featured curation, and challenge participation into one operating surface.
{item.detail}
{item.body}