const { useState, useEffect } = React; function OverallReportView() { const [loading, setLoading] = useState(false); const [errorMsg, setErrorMsg] = useState(''); const [reportData, setReportData] = useState(null); // Date Presets const getPreset = (days) => { const end = new Date(); const start = new Date(); start.setDate(end.getDate() - days); return { start: start.toISOString().split('T')[0], end: end.toISOString().split('T')[0] }; }; const presets = { today: getPreset(0), yesterday: { start: new Date(Date.now() - 86400000).toISOString().split('T')[0], end: new Date(Date.now() - 86400000).toISOString().split('T')[0] }, last7: getPreset(6), last30: getPreset(29), thisMonth: { start: new Date(new Date().getFullYear(), new Date().getMonth(), 1).toISOString().split('T')[0], end: new Date().toISOString().split('T')[0] } }; const [startDate, setStartDate] = useState(presets.last7.start); const [endDate, setEndDate] = useState(presets.last7.end); const [statusFilter, setStatusFilter] = useState('ALL'); // ALL, ACTIVE, INACTIVE const [activeTab, setActiveTab] = useState('campaigns'); const handleFetch = async () => { setLoading(true); setErrorMsg(''); setReportData(null); try { if (typeof fetchOverallReport !== 'function') throw new Error('Data fetcher not ready'); let data = await fetchOverallReport(startDate, endDate, statusFilter); // If data is array (raw items), or has rawData, or has data.data, we should transform it if (Array.isArray(data) || data.rawData || data.data || data.status === 'success') { if (typeof transformMetaRawData === 'function') { data = transformMetaRawData(data, startDate, endDate); } } setReportData(data); } catch (err) { setErrorMsg(err.message); } setLoading(false); }; const formatCurrency = (val) => '฿' + Number(val).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); const formatNumber = (val) => Number(val).toLocaleString(); const formatPercent = (val) => Number(val).toFixed(2) + '%'; const renderTable = (headers, rows, style = {}) => (
{headers.map((h, i) => )} {rows.length === 0 ? ( ) : rows.map((row, i) => ( {row.map((cell, j) => )} ))}
{h}
ไม่พบข้อมูลในช่วงเวลานี้
{cell !== undefined && cell !== null ? cell : '-'}
); const getCampaignRows = () => { return (reportData?.campaigns || []).map(c => [ c.name, formatCurrency(c.spend), formatNumber(c.impressions), formatNumber(c.clicks), formatPercent(c.ctr), formatNumber(c.purchases), formatCurrency(c.sales), formatCurrency(c.cpa), Number(c.roas).toFixed(2) ]); }; const getAdSetRows = () => { return (reportData?.adSets || []).map(a => [ a.name, a.campaign_name, formatCurrency(a.spend), formatNumber(a.impressions), formatNumber(a.clicks), formatPercent(a.ctr), formatNumber(a.purchases), formatCurrency(a.sales), formatCurrency(a.cpa), Number(a.roas).toFixed(2) ]); }; const getAdRows = () => { return (reportData?.ads || []).map(a => [ a.name, a.adset_name, a.campaign_name, formatCurrency(a.spend), formatNumber(a.impressions), formatNumber(a.clicks), formatPercent(a.ctr), formatNumber(a.purchases), formatCurrency(a.sales), formatCurrency(a.cpa), Number(a.roas).toFixed(2) ]); }; return (
setStartDate(e.target.value)} />
setEndDate(e.target.value)} />
{errorMsg && (
{errorMsg}
)}
{!reportData && !loading && !errorMsg && (

เลือกช่วงวันที่ และตั้งค่า Status Filter จากนั้นกดปุ่ม "ดึงข้อมูล"

)} {loading && (

กำลังโหลดและประมวลผลข้อมูลจาก Meta API...

)} {reportData && !loading && (
{activeTab === 'campaigns' && (

Performance by Campaign

{renderTable( ['Campaign Name', 'Spend', 'Impressions', 'Clicks', 'CTR', 'Purchases', 'Sales Value', 'CPA', 'ROAS'], getCampaignRows() )}
)} {activeTab === 'adsets' && (

Performance by Ad Set

{renderTable( ['Ad Set Name', 'Campaign Name', 'Spend', 'Impressions', 'Clicks', 'CTR', 'Purchases', 'Sales Value', 'CPA', 'ROAS'], getAdSetRows() )}
)} {activeTab === 'ads' && (

Performance by Ad

{renderTable( ['Ad Name', 'Ad Set Name', 'Campaign Name', 'Spend', 'Impressions', 'Clicks', 'CTR', 'Purchases', 'Sales Value', 'CPA', 'ROAS'], getAdRows() )}
)}
)}
); } Object.assign(window, { OverallReportView });