+
+
+
+ Top Performers
+
+
+ {/* Simple Timeframe Toggle for now */}
+
+
+
+
+
+
+ {/* Metric Selector Tabs */}
+
+ {[
+ { id: 'revenue', icon: DollarSign, label: 'Rev' },
+ { id: 'volume', icon: Target, label: 'Vol' },
+ { id: 'winRate', icon: TrendingUp, label: 'Win%' }
+ ].map(m => (
+
+ ))}
+
+
+ {/* List */}
+
+ {leaderboardData.map((agent, index) => (
+
+
+
+ {index + 1}
+
+
+
{agent.name}
+
{agent.role.replace('_', ' ')}
+
+
+
+
+ {formatValue(agent[metric], metric)}
+
+
+
+ ))}
+
+
+ );
+};
+
+export default LeaderboardWidget;
diff --git a/src/data/mockStore.jsx b/src/data/mockStore.jsx
index 2f0a049..84bb9e8 100644
--- a/src/data/mockStore.jsx
+++ b/src/data/mockStore.jsx
@@ -642,6 +642,38 @@ const MOCK_USERS = [
{ id: 'a3', type: 'employee', empId: 'ADM03', email: 'admin3@plano.com', password: 'password', role: 'ADMIN', name: 'Arthur Director' }
];
+// --- NEW MOCK SALES HISTORY FOR LEADERBOARD ---
+const MOCK_SALES_HISTORY = [
+ // Frank Agent (High Revenue, Low Volume - "The Sniper")
+ { id: 'tx_1', agentId: 'e1', date: '2026-02-10', amount: 450000, status: 'closed_won' },
+ { id: 'tx_2', agentId: 'e1', date: '2026-02-05', amount: 520000, status: 'closed_won' },
+ { id: 'tx_3', agentId: 'e1', date: '2026-01-28', amount: 380000, status: 'closed_won' },
+ { id: 'tx_4', agentId: 'e1', date: '2026-02-01', amount: 0, status: 'closed_lost' }, // Lost deal
+
+ // Fiona Field (High Volume, Mid Revenue - "The Grinder")
+ { id: 'tx_5', agentId: 'e2', date: '2026-02-09', amount: 250000, status: 'closed_won' },
+ { id: 'tx_6', agentId: 'e2', date: '2026-02-08', amount: 240000, status: 'closed_won' },
+ { id: 'tx_7', agentId: 'e2', date: '2026-02-06', amount: 260000, status: 'closed_won' },
+ { id: 'tx_8', agentId: 'e2', date: '2026-01-30', amount: 230000, status: 'closed_won' },
+ { id: 'tx_9', agentId: 'e2', date: '2026-02-02', amount: 255000, status: 'closed_won' },
+ { id: 'tx_10', agentId: 'e2', date: '2026-01-25', amount: 0, status: 'closed_lost' },
+ { id: 'tx_11', agentId: 'e2', date: '2026-01-20', amount: 0, status: 'closed_lost' },
+
+ // Fred Flyer (New/Low Performance)
+ { id: 'tx_12', agentId: 'e3', date: '2026-02-07', amount: 180000, status: 'closed_won' },
+ { id: 'tx_13', agentId: 'e3', date: '2026-02-03', amount: 0, status: 'closed_lost' },
+ { id: 'tx_14', agentId: 'e3', date: '2026-01-29', amount: 0, status: 'closed_lost' },
+
+ // Felicity Fast (Consistent)
+ { id: 'tx_15', agentId: 'e4', date: '2026-02-10', amount: 310000, status: 'closed_won' },
+ { id: 'tx_16', agentId: 'e4', date: '2026-02-04', amount: 305000, status: 'closed_won' },
+ { id: 'tx_17', agentId: 'e4', date: '2026-01-27', amount: 295000, status: 'closed_won' },
+
+ // Felix Fixer (Closer - High Win Rate)
+ { id: 'tx_18', agentId: 'e5', date: '2026-02-08', amount: 410000, status: 'closed_won' },
+ { id: 'tx_19', agentId: 'e5', date: '2026-02-01', amount: 390000, status: 'closed_won' },
+];
+
// Helper to generate meetings
function generateMockMeetings() {
const agents = ['e1', 'e2', 'e3', 'e4', 'e5'];
@@ -774,6 +806,7 @@ export const MockStoreProvider = ({ children }) => {
const [properties, setProperties] = useState([]);
const [users, setUsers] = useState(MOCK_USERS);
const [meetings, setMeetings] = useState(MOCK_MEETINGS);
+ const [salesHistory, setSalesHistory] = useState(MOCK_SALES_HISTORY);
// Initialize properties once
useEffect(() => {
@@ -849,9 +882,9 @@ export const MockStoreProvider = ({ children }) => {
return (