This commit is contained in:
2025-09-09 07:31:48 +00:00
parent 94b34d5946
commit 2171d5e744
3 changed files with 129 additions and 50 deletions

View File

@@ -341,21 +341,20 @@ export default function Page({user}: {user: any}) {
expectedRevenue: { border: '#16A34A', bg: 'rgba(22, 163, 74, 0.25)' },
}
const selectedRows = useMemo(() => sortedVisibleRows.filter(r => checkedIds.has(r.id)), [sortedVisibleRows, checkedIds])
const [seriesMode, setSeriesMode] = useState<'items'|'series'>('items')
const [seriesInterval, setSeriesInterval] = useState<'day'|'week'|'month'>('day')
const [seriesItems, setSeriesItems] = useState<Array<{ period: string, views: number, validViews: number, premiumViews: number, expectedRevenue: number }>>([])
const chartData = useMemo(() => {
const col = metricColor[selectedMetric]
if (seriesMode === 'series') {
const labels = seriesItems.map(it => it.period)
const dataVals = seriesItems.map(it => (it as any)[selectedMetric] as number)
return { labels, datasets: [{ label: `${metricLabel[selectedMetric]} (${seriesInterval})`, data: dataVals, borderColor: col.border, backgroundColor: col.bg, tension: 0.35 }] }
}
const labels = selectedRows.map(r => r.subject)
const dataVals = selectedRows.map(r => (r as any)[selectedMetric] as number)
const col = metricColor[selectedMetric]
return {
labels,
datasets: [{
label: metricLabel[selectedMetric],
data: dataVals,
borderColor: col.border,
backgroundColor: col.bg,
tension: 0.35,
}]
}
}, [selectedRows, selectedMetric])
return { labels, datasets: [{ label: metricLabel[selectedMetric], data: dataVals, borderColor: col.border, backgroundColor: col.bg, tension: 0.35 }] }
}, [selectedRows, selectedMetric, seriesMode, seriesItems, seriesInterval])
const chartOptions = useMemo(() => ({
responsive: true,
plugins: { legend: { display: false }, title: { display: false } },
@@ -616,7 +615,28 @@ export default function Page({user}: {user: any}) {
</div>
<div className="border-1 hidden xl:col-[3/5] xl:row-[3/5] bg-white rounded-lg p-4 xl:flex xl:flex-col" style={{ borderColor: metricColor[selectedMetric].border }}>
<div className="text-xl font-bold"> {metricLabel[selectedMetric]} </div>
<div className="text-normal text-gray-500"> .</div>
<div className="text-normal text-gray-500 flex flex-row gap-2 items-center">
<select className="border-1 border-[#e6e9ef] rounded px-2 py-1" value={seriesMode} onChange={e => setSeriesMode(e.target.value as any)}>
<option value="items"></option>
<option value="series"></option>
</select>
{seriesMode === 'series' && (
<>
<select className="border-1 border-[#e6e9ef] rounded px-2 py-1" value={seriesInterval} onChange={e => setSeriesInterval(e.target.value as any)}>
<option value="day"></option>
<option value="week"></option>
<option value="month"></option>
</select>
<button className="border-1 border-[#e6e9ef] rounded px-2 py-1" onClick={async () => {
const s = startDate; const e = endDate;
const qs = new URLSearchParams({ start: s.toISOString(), end: e.toISOString(), mode: 'series', interval: seriesInterval })
const res = await fetch(`/api/contents/mycontent?${qs.toString()}`, { cache: 'no-store' })
const data = await res.json()
if (res.ok) setSeriesItems(data.items || [])
}}></button>
</>
)}
</div>
<div className="flex flex-row justify-start items-center">
<div className="font-bold text-3xl my-4"> {formatNumberWithCommas(
selectedMetric === 'views' ? totals.views :