mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 12:45:23 +02:00
refactor: simplified data loading with direct fetch endpoint
This commit is contained in:
@@ -49,49 +49,35 @@ const App: React.FC = () => {
|
||||
title: [],
|
||||
});
|
||||
|
||||
// Handle URL Fetch (Auto/Manual)
|
||||
const handleUrlFetch = useCallback(async (url: string) => {
|
||||
// Handle Data Fetch (Simplified)
|
||||
const handleDataFetch = useCallback(async () => {
|
||||
setSyncing(true);
|
||||
try {
|
||||
let directUrl = url;
|
||||
// Create a direct download link for Dropbox if it's a share link.
|
||||
if (url.includes('dropbox.com/') && !url.includes('dl.dropboxusercontent.com')) {
|
||||
const urlObject = new URL(url);
|
||||
urlObject.searchParams.set('dl', '1');
|
||||
directUrl = urlObject.toString();
|
||||
console.log('[App] Fetching data from /api/fetch-data...');
|
||||
const response = await fetch('/api/fetch-data');
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch CSV: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
|
||||
// Unified Fetch Logic for Local (Vite) and Production (Vercel Function)
|
||||
// Both environments now support the /api/dropbox/... path.
|
||||
// - Local: Vite proxies /api/dropbox -> https://www.dropbox.com
|
||||
// - Vercel: api/dropbox.js handles the request -> https://www.dropbox.com
|
||||
|
||||
const urlObj = new URL(directUrl);
|
||||
const searchParams = urlObj.search;
|
||||
// Construct path relative to root: /api/dropbox/scl/fi/...
|
||||
const fetchUrl = `/api/dropbox${urlObj.pathname}${searchParams}`;
|
||||
|
||||
const response = await fetch(fetchUrl);
|
||||
if (!response.ok) throw new Error(`Failed to fetch CSV from URL: ${response.status} ${response.statusText}`);
|
||||
|
||||
const csvText = await response.text();
|
||||
const data = await processCSV(csvText);
|
||||
|
||||
await saveSalesData(data);
|
||||
|
||||
initializeData(data);
|
||||
setActiveUrl(url); // Store the original user-facing URL
|
||||
setActiveUrl(PERMANENT_DROPBOX_URL);
|
||||
const now = new Date().toISOString();
|
||||
setLastUpdated(now);
|
||||
localStorage.setItem('craze_last_updated', now);
|
||||
localStorage.setItem('craze_csv_url', url);
|
||||
setIsDataModalOpen(false); // Close modal on success
|
||||
localStorage.setItem('craze_csv_url', PERMANENT_DROPBOX_URL);
|
||||
setIsDataModalOpen(false);
|
||||
|
||||
console.log('[App] Successfully loaded', data.length, 'rows');
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch/parse CSV from URL", error);
|
||||
// Don't alert on auto-fetch to avoid spamming the user on startup if offline
|
||||
// alert("Error syncing data. Please check the URL.");
|
||||
throw error; // re-throw to be caught by caller
|
||||
console.error("Failed to fetch/parse CSV", error);
|
||||
alert("Error loading data. Please refresh the page.");
|
||||
throw error;
|
||||
} finally {
|
||||
setSyncing(false);
|
||||
setLoading(false);
|
||||
@@ -144,13 +130,13 @@ const App: React.FC = () => {
|
||||
setLoading(false);
|
||||
} else {
|
||||
console.log("Fetching fresh data from Permanent URL...");
|
||||
handleUrlFetch(PERMANENT_DROPBOX_URL).catch(e => {
|
||||
handleDataFetch().catch(e => {
|
||||
console.error("Initial fetch failed.");
|
||||
});
|
||||
}
|
||||
};
|
||||
initApp();
|
||||
}, [handleUrlFetch]);
|
||||
}, [handleDataFetch]);
|
||||
|
||||
// Handle uploaded Sales file (Manual)
|
||||
const handleSalesUpload = async (file: File) => {
|
||||
@@ -196,7 +182,7 @@ const App: React.FC = () => {
|
||||
// Refresh if it's after 7 AM and we haven't refreshed today
|
||||
if (now.getHours() >= 7 && lastRefreshDate !== today) {
|
||||
console.log("Triggering daily data refresh...");
|
||||
handleUrlFetch(PERMANENT_DROPBOX_URL).then(() => {
|
||||
handleDataFetch().then(() => {
|
||||
localStorage.setItem('craze_last_refresh_date', today);
|
||||
console.log("Daily refresh successful.");
|
||||
}).catch(err => {
|
||||
@@ -212,7 +198,7 @@ const App: React.FC = () => {
|
||||
const interval = setInterval(checkAndRefresh, 15 * 60 * 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [handleUrlFetch]);
|
||||
}, [handleDataFetch]);
|
||||
|
||||
|
||||
// Derive Data
|
||||
@@ -322,7 +308,7 @@ const App: React.FC = () => {
|
||||
|
||||
{/* NEW REFRESH BUTTON */}
|
||||
<button
|
||||
onClick={() => activeUrl && handleUrlFetch(activeUrl)}
|
||||
onClick={handleDataFetch}
|
||||
disabled={syncing}
|
||||
title="Refresh Data"
|
||||
className="p-3 rounded-lg bg-slate-800 border border-border text-slate-400 hover:text-white hover:bg-slate-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
||||
@@ -400,9 +386,9 @@ const App: React.FC = () => {
|
||||
|
||||
<div className="p-6">
|
||||
<FileUpload
|
||||
onSalesUpload={handleSalesUpload} // CORRECTED: Was handleFileUpload
|
||||
onAdsUpload={handleAdsUpload} // ADDED: Missing prop causing error
|
||||
onUrlSubmit={handleUrlFetch}
|
||||
onSalesUpload={handleSalesUpload}
|
||||
onAdsUpload={handleAdsUpload}
|
||||
onUrlSubmit={handleDataFetch}
|
||||
isLoading={syncing}
|
||||
activeUrl={activeUrl}
|
||||
onDisconnect={disconnectUrl}
|
||||
|
||||
Reference in New Issue
Block a user