211 lines
5.6 KiB
TypeScript
211 lines
5.6 KiB
TypeScript
import type { FlowNode, FunnelNodeData, OutcomeNodeData, SourceNodeData } from './types'
|
|
|
|
// Colors for allocations
|
|
export const SPENDING_COLORS = ['#3b82f6', '#8b5cf6', '#ec4899', '#06b6d4', '#10b981', '#6366f1']
|
|
export const OVERFLOW_COLORS = ['#f59e0b', '#ef4444', '#f97316', '#eab308', '#dc2626', '#ea580c']
|
|
export const SOURCE_COLORS = ['#10b981', '#14b8a6', '#06b6d4', '#0ea5e9']
|
|
|
|
// Demo preset: Source → Treasury → 3 sub-funnels → 7 outcomes
|
|
export const demoNodes: FlowNode[] = [
|
|
// Revenue source (top)
|
|
{
|
|
id: 'revenue',
|
|
type: 'source',
|
|
position: { x: 660, y: -200 },
|
|
data: {
|
|
label: 'Revenue Stream',
|
|
flowRate: 5000,
|
|
sourceType: 'recurring',
|
|
targetAllocations: [
|
|
{ targetId: 'treasury', percentage: 100, color: '#10b981' },
|
|
],
|
|
} as SourceNodeData,
|
|
},
|
|
// Main Treasury Funnel
|
|
{
|
|
id: 'treasury',
|
|
type: 'funnel',
|
|
position: { x: 630, y: 0 },
|
|
data: {
|
|
label: 'Treasury',
|
|
currentValue: 85000,
|
|
minThreshold: 20000,
|
|
maxThreshold: 70000,
|
|
maxCapacity: 100000,
|
|
inflowRate: 1000,
|
|
sufficientThreshold: 60000,
|
|
dynamicOverflow: true,
|
|
overflowAllocations: [
|
|
{ targetId: 'public-goods', percentage: 40, color: OVERFLOW_COLORS[0] },
|
|
{ targetId: 'research', percentage: 35, color: OVERFLOW_COLORS[1] },
|
|
{ targetId: 'emergency', percentage: 25, color: OVERFLOW_COLORS[2] },
|
|
],
|
|
spendingAllocations: [
|
|
{ targetId: 'treasury-ops', percentage: 100, color: SPENDING_COLORS[0] },
|
|
],
|
|
} as FunnelNodeData,
|
|
},
|
|
// Sub-funnels (middle row)
|
|
{
|
|
id: 'public-goods',
|
|
type: 'funnel',
|
|
position: { x: 170, y: 450 },
|
|
data: {
|
|
label: 'Public Goods',
|
|
currentValue: 45000,
|
|
minThreshold: 15000,
|
|
maxThreshold: 50000,
|
|
maxCapacity: 70000,
|
|
inflowRate: 400,
|
|
sufficientThreshold: 42000,
|
|
overflowAllocations: [],
|
|
spendingAllocations: [
|
|
{ targetId: 'pg-infra', percentage: 50, color: SPENDING_COLORS[0] },
|
|
{ targetId: 'pg-education', percentage: 30, color: SPENDING_COLORS[1] },
|
|
{ targetId: 'pg-tooling', percentage: 20, color: SPENDING_COLORS[2] },
|
|
],
|
|
} as FunnelNodeData,
|
|
},
|
|
{
|
|
id: 'research',
|
|
type: 'funnel',
|
|
position: { x: 975, y: 450 },
|
|
data: {
|
|
label: 'Research',
|
|
currentValue: 28000,
|
|
minThreshold: 20000,
|
|
maxThreshold: 45000,
|
|
maxCapacity: 60000,
|
|
inflowRate: 350,
|
|
sufficientThreshold: 38000,
|
|
overflowAllocations: [],
|
|
spendingAllocations: [
|
|
{ targetId: 'research-grants', percentage: 70, color: SPENDING_COLORS[0] },
|
|
{ targetId: 'research-papers', percentage: 30, color: SPENDING_COLORS[1] },
|
|
],
|
|
} as FunnelNodeData,
|
|
},
|
|
{
|
|
id: 'emergency',
|
|
type: 'funnel',
|
|
position: { x: 1320, y: 450 },
|
|
data: {
|
|
label: 'Emergency',
|
|
currentValue: 12000,
|
|
minThreshold: 25000,
|
|
maxThreshold: 60000,
|
|
maxCapacity: 80000,
|
|
inflowRate: 250,
|
|
sufficientThreshold: 50000,
|
|
overflowAllocations: [],
|
|
spendingAllocations: [
|
|
{ targetId: 'emergency-response', percentage: 100, color: SPENDING_COLORS[0] },
|
|
],
|
|
} as FunnelNodeData,
|
|
},
|
|
// Outcome nodes (bottom row)
|
|
{
|
|
id: 'pg-infra',
|
|
type: 'outcome',
|
|
position: { x: -50, y: 900 },
|
|
data: {
|
|
label: 'Infrastructure',
|
|
description: 'Core infrastructure development',
|
|
fundingReceived: 22000,
|
|
fundingTarget: 30000,
|
|
status: 'in-progress',
|
|
} as OutcomeNodeData,
|
|
},
|
|
{
|
|
id: 'pg-education',
|
|
type: 'outcome',
|
|
position: { x: 180, y: 900 },
|
|
data: {
|
|
label: 'Education',
|
|
description: 'Developer education programs',
|
|
fundingReceived: 12000,
|
|
fundingTarget: 20000,
|
|
status: 'in-progress',
|
|
} as OutcomeNodeData,
|
|
},
|
|
{
|
|
id: 'pg-tooling',
|
|
type: 'outcome',
|
|
position: { x: 410, y: 900 },
|
|
data: {
|
|
label: 'Dev Tooling',
|
|
description: 'Open-source developer tools',
|
|
fundingReceived: 5000,
|
|
fundingTarget: 15000,
|
|
status: 'not-started',
|
|
} as OutcomeNodeData,
|
|
},
|
|
{
|
|
id: 'treasury-ops',
|
|
type: 'outcome',
|
|
position: { x: 640, y: 900 },
|
|
data: {
|
|
label: 'Treasury Ops',
|
|
description: 'Day-to-day treasury management',
|
|
fundingReceived: 15000,
|
|
fundingTarget: 25000,
|
|
status: 'in-progress',
|
|
} as OutcomeNodeData,
|
|
},
|
|
{
|
|
id: 'research-grants',
|
|
type: 'outcome',
|
|
position: { x: 870, y: 900 },
|
|
data: {
|
|
label: 'Grants',
|
|
description: 'Academic research grants',
|
|
fundingReceived: 18000,
|
|
fundingTarget: 25000,
|
|
status: 'in-progress',
|
|
} as OutcomeNodeData,
|
|
},
|
|
{
|
|
id: 'research-papers',
|
|
type: 'outcome',
|
|
position: { x: 1100, y: 900 },
|
|
data: {
|
|
label: 'Papers',
|
|
description: 'Peer-reviewed publications',
|
|
fundingReceived: 8000,
|
|
fundingTarget: 10000,
|
|
status: 'in-progress',
|
|
} as OutcomeNodeData,
|
|
},
|
|
{
|
|
id: 'emergency-response',
|
|
type: 'outcome',
|
|
position: { x: 1330, y: 900 },
|
|
data: {
|
|
label: 'Response Fund',
|
|
description: 'Rapid response for critical issues',
|
|
fundingReceived: 5000,
|
|
fundingTarget: 50000,
|
|
status: 'not-started',
|
|
} as OutcomeNodeData,
|
|
},
|
|
]
|
|
|
|
// Empty starter for user-created spaces
|
|
export const starterNodes: FlowNode[] = [
|
|
{
|
|
id: 'treasury-1',
|
|
type: 'funnel',
|
|
position: { x: 400, y: 50 },
|
|
data: {
|
|
label: 'My Treasury',
|
|
currentValue: 50000,
|
|
minThreshold: 10000,
|
|
maxThreshold: 40000,
|
|
maxCapacity: 60000,
|
|
inflowRate: 500,
|
|
overflowAllocations: [],
|
|
spendingAllocations: [],
|
|
} as FunnelNodeData,
|
|
},
|
|
]
|