Famous.AI Integration - Fixed Code
Copy-paste ready components with all bugs fixed ✅
src/components/PendingPearlsNotification.tsx
import React, { useState, useEffect, useRef } from 'react';
import { getStoredPlatformAuth } from '../utils/platformAuth';
export default function PendingPearlsNotification() {
const [pendingCount, setPendingCount] = useState(0);
const [syncing, setSyncing] = useState(false);
const [syncProgress, setSyncProgress] = useState(0);
const retryCountRef = useRef(0);
const [lastError, setLastError] = useState('');
useEffect(() => {
const checkPending = () => {
const pending = JSON.parse(localStorage.getItem('pending_pearl_awards') || '[]');
setPendingCount(pending.length);
};
checkPending();
const interval = setInterval(checkPending, 10000);
return () => clearInterval(interval);
}, []);
const syncPendingPearlAwards = async () => {
setSyncing(true);
setSyncProgress(0);
setLastError('');
const pending = JSON.parse(localStorage.getItem('pending_pearl_awards') || '[]');
// ✅ FIX: Use platformAuth module instead of raw sessionStorage
const authData = getStoredPlatformAuth();
const token = authData?.token;
if (!token) {
alert('Please reconnect to Snappy Idioms platform');
setSyncing(false);
return;
}
const synced = [];
for (let i = 0; i < pending.length; i++) {
const award = pending[i];
try {
// ✅ Exponential backoff with cap at 30s
const backoffDelay = Math.min(Math.pow(2, retryCountRef.current) * 1000, 30000);
if (retryCountRef.current > 0) {
await new Promise(r => setTimeout(r, backoffDelay));
}
const response = await fetch(`https://snappyidioms.com/api/platform-api`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
action: 'award_pearls',
pearls: award.pearls,
reason: award.reason,
levelId: award.levelId
})
});
if (response.ok) {
synced.push(award);
retryCountRef.current = 0;
setSyncProgress(Math.floor(((i + 1) / pending.length) * 100));
} else {
retryCountRef.current += 1;
const nextDelay = Math.min(Math.pow(2, retryCountRef.current) * 1000, 30000);
setLastError(`Failed, retrying in ${nextDelay/1000}s...`);
}
} catch (error) {
console.error('Sync failed:', error);
retryCountRef.current += 1;
const nextDelay = Math.min(Math.pow(2, retryCountRef.current) * 1000, 30000);
setLastError(`Network error, retrying in ${nextDelay/1000}s...`);
}
}
const remaining = pending.filter(p => !synced.includes(p));
localStorage.setItem('pending_pearl_awards', JSON.stringify(remaining));
setPendingCount(remaining.length);
setSyncing(false);
setSyncProgress(0);
};
if (pendingCount === 0) return null;
return (
<div className="fixed bottom-4 right-4 bg-gradient-to-r from-amber-400 to-orange-500 text-white p-4 rounded-lg shadow-xl max-w-sm">
<div className="flex items-center justify-between mb-2">
<span className="font-bold">⚠️ Pending Pearls: {pendingCount}</span>
<button
onClick={syncPendingPearlAwards}
disabled={syncing}
className="bg-white text-orange-600 px-3 py-1 rounded-lg font-semibold hover:bg-orange-50 disabled:opacity-50"
>
{syncing ? 'Syncing...' : retryCountRef.current > 0 ? `Retry (${retryCountRef.current})` : 'Sync Now'}
</button>
</div>
{syncing && (
<div className="space-y-1">
<div className="w-full bg-white/30 rounded-full h-2 overflow-hidden">
<div
className="h-full bg-white transition-all duration-300"
style={{ width: `${syncProgress}%` }}
/>
</div>
<div className="text-xs text-white/90 text-center">{syncProgress}% synced</div>
</div>
)}
{lastError && !syncing && (
<div className="text-xs mt-2 text-white/90">{lastError}</div>
)}
</div>
);
}✅ Fixes Applied:
- • Uses
platformAuthmodule instead of raw sessionStorage - • Exponential backoff capped at 30s (2s → 4s → 8s → 16s → 30s)
- • Visual progress bar with percentage indicator
- • Retry attempt counter in button text
- • Error feedback showing next backoff delay
Installation Steps
1
Create Component Files
Copy each component into your Famous.AI
src/ folder2
Add to App.tsx Routes
Import PlatformStats and add route:
<Route path="/platform-stats" element=<PlatformStats /> />3
Update Navigation
Add "Platform Stats" link to your main menu
4
Test Integration
Play a round → Check pending pearls → Wait for token refresh → View stats