/** * Composable for loading and managing fixture data * Provides centralized access to demo data for all screens */ export const useFixtures = () => { // Load fixture data (in real app, this would come from API or stores) const loadMembers = async () => { // In production, this would fetch from content/fixtures/members.json // For now, return inline data that matches the fixture structure return { members: [ { id: 'member-1', displayName: 'Alex Chen', roleFocus: 'Technical Lead', payRelationship: 'Hybrid', capacity: { minHours: 20, targetHours: 120, maxHours: 160 }, riskBand: 'Medium', externalCoveragePct: 60, privacyNeeds: 'aggregate_ok', deferredHours: 85, quarterlyDeferredCap: 240 }, { id: 'member-2', displayName: 'Jordan Silva', roleFocus: 'Design & UX', payRelationship: 'FullyPaid', capacity: { minHours: 30, targetHours: 140, maxHours: 180 }, riskBand: 'Low', externalCoveragePct: 20, privacyNeeds: 'aggregate_ok', deferredHours: 0, quarterlyDeferredCap: 240 }, { id: 'member-3', displayName: 'Sam Rodriguez', roleFocus: 'Operations & Growth', payRelationship: 'Supplemental', capacity: { minHours: 10, targetHours: 60, maxHours: 100 }, riskBand: 'High', externalCoveragePct: 85, privacyNeeds: 'steward_only', deferredHours: 32, quarterlyDeferredCap: 120 } ] } } const loadStreams = async () => { return { revenueStreams: [ { id: 'stream-1', name: 'Client Services', category: 'Services', subcategory: 'Development', targetPct: 65, targetMonthlyAmount: 0, certainty: 'Committed', payoutDelayDays: 30, terms: 'Net 30', revenueSharePct: 0, platformFeePct: 0, restrictions: 'General', effortHoursPerMonth: 180 }, { id: 'stream-2', name: 'Platform Sales', category: 'Product', subcategory: 'Digital Tools', targetPct: 20, targetMonthlyAmount: 0, certainty: 'Probable', payoutDelayDays: 14, terms: 'Platform payout', revenueSharePct: 0, platformFeePct: 5, restrictions: 'General', effortHoursPerMonth: 40 }, { id: 'stream-3', name: 'Innovation Grant', category: 'Grant', subcategory: 'Government', targetPct: 10, targetMonthlyAmount: 0, certainty: 'Committed', payoutDelayDays: 45, terms: 'Quarterly disbursement', revenueSharePct: 0, platformFeePct: 0, restrictions: 'Restricted', effortHoursPerMonth: 8 }, { id: 'stream-4', name: 'Community Donations', category: 'Donation', subcategory: 'Individual', targetPct: 3, targetMonthlyAmount: 0, certainty: 'Aspirational', payoutDelayDays: 3, terms: 'Immediate', revenueSharePct: 0, platformFeePct: 2.9, restrictions: 'General', effortHoursPerMonth: 5 }, { id: 'stream-5', name: 'Consulting & Training', category: 'Other', subcategory: 'Professional Services', targetPct: 2, targetMonthlyAmount: 0, certainty: 'Probable', payoutDelayDays: 21, terms: 'Net 21', revenueSharePct: 0, platformFeePct: 0, restrictions: 'General', effortHoursPerMonth: 12 } ] } } const loadFinances = async () => { return { currentBalances: { cash: 5000, savings: 8000, totalLiquid: 13000 }, policies: { equalHourlyWage: 20, payrollOncostPct: 25, savingsTargetMonths: 3, minCashCushionAmount: 3000, deferredCapHoursPerQtr: 240, deferredSunsetMonths: 12 }, deferredLiabilities: { totalDeferred: 2340, byMember: { 'member-1': 1700, 'member-2': 0, 'member-3': 640 } } } } const loadCosts = async () => { return { overheadCosts: [ { id: 'overhead-1', name: 'Coworking Space', amount: 0, category: 'Workspace', recurring: true }, { id: 'overhead-2', name: 'Tools & Software', amount: 0, category: 'Technology', recurring: true }, { id: 'overhead-3', name: 'Business Insurance', amount: 0, category: 'Legal & Compliance', recurring: true } ], productionCosts: [ { id: 'production-1', name: 'Development Kits', amount: 0, category: 'Hardware', period: '2024-01' } ] } } // Calculate derived metrics from fixture data const calculateMetrics = async () => { const [members, streams, finances, costs] = await Promise.all([ loadMembers(), loadStreams(), loadFinances(), loadCosts() ]) const totalTargetHours = members.members.reduce((sum, member) => sum + member.capacity.targetHours, 0 ) const totalTargetRevenue = streams.revenueStreams.reduce((sum, stream) => sum + stream.targetMonthlyAmount, 0 ) const totalOverheadCosts = costs.overheadCosts.reduce((sum, cost) => sum + cost.amount, 0 ) const monthlyPayroll = totalTargetHours * finances.policies.equalHourlyWage * (1 + finances.policies.payrollOncostPct / 100) const monthlyBurn = monthlyPayroll + totalOverheadCosts + costs.productionCosts.reduce((sum, cost) => sum + cost.amount, 0) const runway = finances.currentBalances.totalLiquid / monthlyBurn return { totalTargetHours, totalTargetRevenue, monthlyPayroll, monthlyBurn, runway, members: members.members, streams: streams.revenueStreams, finances: finances, costs: costs } } return { loadMembers, loadStreams, loadFinances, loadCosts, calculateMetrics } }