Auto-Sync and Manual Refresh: Ensured fresh data on reload and added Sync button

This commit is contained in:
Christian Vidal Wolf
2026-01-27 15:02:18 +01:00
parent 1438049c71
commit 19fbd12e77
3 changed files with 42 additions and 9 deletions
+27 -6
View File
@@ -240,6 +240,8 @@ const App: React.FC = () => {
initializeData(cachedData); initializeData(cachedData);
setLastUpdated(cachedDate); setLastUpdated(cachedDate);
setLoading(false); setLoading(false);
// Trigger background sync to ensure data is fresh
handleDataFetch().catch(e => console.warn("Background sales sync failed", e));
} else { } else {
console.log("Fetching fresh data from Permanent URL..."); console.log("Fetching fresh data from Permanent URL...");
handleDataFetch().catch(e => { handleDataFetch().catch(e => {
@@ -252,6 +254,8 @@ const App: React.FC = () => {
if (cachedAds && cachedAds.length > 0) { if (cachedAds && cachedAds.length > 0) {
console.log("Loaded ads from cache:", cachedAds.length, "records"); console.log("Loaded ads from cache:", cachedAds.length, "records");
setAdsData(cachedAds); setAdsData(cachedAds);
// Trigger background sync
handleAdsFetch();
} else { } else {
console.log("Fetching fresh Ads from URL..."); console.log("Fetching fresh Ads from URL...");
handleAdsFetch(); handleAdsFetch();
@@ -481,16 +485,33 @@ const App: React.FC = () => {
{/* Title & Status */} {/* Title & Status */}
<div className="hidden lg:block border-l border-slate-700 pl-6"> <div className="hidden lg:block border-l border-slate-700 pl-6">
<h1 className="text-xl font-bold tracking-tight text-white text-shadow-sm">Analytics Dashboard</h1> <h1 className="text-xl font-bold tracking-tight text-white text-shadow-sm">Analytics Dashboard</h1>
{activeUrl && lastUpdated && ( <div className="flex items-center gap-3 mt-1.5">
<p className="text-[10px] text-emerald-400 mt-1 flex items-center gap-1 uppercase font-bold tracking-wider"> <div className="flex items-center gap-1.5 px-2 py-0.5 bg-emerald-500/10 border border-emerald-500/20 rounded-full">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse"></span> <span className={`w-1.5 h-1.5 rounded-full bg-emerald-400 ${syncing ? 'animate-ping' : ''}`}></span>
Live Sync Active <span className="text-[9px] text-emerald-400 font-black uppercase tracking-wider">Live Sync</span>
</p> </div>
{lastUpdated && (
<span className="text-[9px] text-slate-500 font-bold uppercase tracking-wider">
Last: {new Date(lastUpdated).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
</span>
)} )}
</div> </div>
</div> </div>
</div>
<div className="flex items-center gap-4"> <div className="flex items-center gap-6">
{/* Force Sync Action */}
<button
onClick={() => { handleDataFetch(); handleAdsFetch(); handleTrafficFetch(); }}
disabled={syncing}
className={`flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-black uppercase tracking-widest transition-all
${syncing
? 'bg-indigo-500/20 text-indigo-400 border border-indigo-500/30'
: 'bg-slate-900 text-slate-300 border border-border hover:border-indigo-500/50 hover:text-white shadow-lg active:scale-95'}`}
>
<RefreshIcon className={`w-4 h-4 ${syncing ? 'animate-spin' : ''}`} />
<span>{syncing ? 'Syncing...' : 'Sync Now'}</span>
</button>
{/* View Switcher is the priority now */} {/* View Switcher is the priority now */}
{/* View Switcher */} {/* View Switcher */}
<div className="flex bg-slate-900 rounded-lg p-1 border border-border"> <div className="flex bg-slate-900 rounded-lg p-1 border border-border">
+7 -1
View File
@@ -14,7 +14,13 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
try { try {
console.log('[fetch-ads] Fetching Ads from Dropbox...'); console.log('[fetch-ads] Fetching Ads from Dropbox...');
const response = await fetch(ADS_DROPBOX_URL); const response = await fetch(ADS_DROPBOX_URL, {
cache: 'no-store',
headers: {
'Pragma': 'no-cache',
'Cache-Control': 'no-cache'
}
});
if (!response.ok) { if (!response.ok) {
throw new Error(`Dropbox responded with ${response.status}`); throw new Error(`Dropbox responded with ${response.status}`);
+7 -1
View File
@@ -14,7 +14,13 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
try { try {
console.log('[fetch-data] Fetching from Dropbox...'); console.log('[fetch-data] Fetching from Dropbox...');
const response = await fetch(DROPBOX_URL); const response = await fetch(DROPBOX_URL, {
cache: 'no-store',
headers: {
'Pragma': 'no-cache',
'Cache-Control': 'no-cache'
}
});
if (!response.ok) { if (!response.ok) {
throw new Error(`Dropbox responded with ${response.status}`); throw new Error(`Dropbox responded with ${response.status}`);