diff --git a/.spark-initial-sha b/.spark-initial-sha new file mode 100644 index 0000000..ffea877 --- /dev/null +++ b/.spark-initial-sha @@ -0,0 +1 @@ +HEAD diff --git a/PRD.md b/PRD.md new file mode 100644 index 0000000..89768c2 --- /dev/null +++ b/PRD.md @@ -0,0 +1,145 @@ +# Planning Guide + +An integrated strategy management platform that enables organizations to create, align, execute, and track strategic initiatives from conception to delivery, replacing fragmented spreadsheets with a unified source of truth. + +**Experience Qualities**: +1. **Authoritative** - Every view, metric, and decision point radiates confidence and clarity, positioning this as the definitive system of record for strategic execution. +2. **Structured yet Flexible** - Guided frameworks accelerate strategy creation while adapting to diverse methodologies (Hoshin Kanri, OKRs, Portfolio Management) without rigid constraints. +3. **Traceable** - Crystal-clear visibility from enterprise goals down to individual initiatives, with instant drill-down and relationship mapping that eliminates ambiguity. + +**Complexity Level**: Complex Application (advanced functionality, likely with multiple views) +This is an enterprise-grade platform requiring multiple interconnected views (Strategy Cards creation, Workbench execution tracking, Portfolio management, KPI dashboards), role-based workflows, real-time data relationships, and sophisticated visualization of strategic hierarchies and dependencies. + +## Essential Features + +### Strategy Card Creation +- **Functionality**: Structured strategy formulation using proven frameworks (SWOT, Value Disciplines, Strategic Pillars) +- **Purpose**: Eliminate blank-page paralysis and ensure comprehensive strategic thinking +- **Trigger**: User clicks "Create Strategy Card" or "New Strategic Initiative" +- **Progression**: Select framework → Fill guided sections (Vision, Goals, Assumptions) → Add metrics → Review & Publish → Link to Workbench initiatives +- **Success criteria**: User can create a complete strategy card in under 10 minutes; all critical strategic elements are captured with clear rationale + +### Initiative Execution Tracking +- **Functionality**: Translate strategic objectives into trackable initiatives with owners, timelines, and KPIs +- **Purpose**: Bridge the gap between strategy and execution with clear accountability +- **Trigger**: User creates initiative from Strategy Card or Workbench portfolio view +- **Progression**: Define initiative → Assign owner → Set timeline & budget → Link strategic goals → Define KPIs → Track status updates +- **Success criteria**: Every initiative clearly traces to strategic goals; real-time status is always current; owners receive clear accountability signals + +### Portfolio Management & Governance +- **Functionality**: Group initiatives into portfolios (M&A, OpEx, ESG) with capacity planning and impact analysis +- **Purpose**: Enable enterprise-level prioritization and resource allocation decisions +- **Trigger**: User navigates to "Portfolios" and creates/manages portfolio groups +- **Progression**: Create portfolio → Add initiatives → Analyze capacity vs demand → Assess alignment score → Prioritize → Review governance dashboard +- **Success criteria**: Leadership can assess entire strategic portfolio at a glance; capacity conflicts are immediately visible; prioritization decisions are data-informed + +### Real-Time KPI Dashboard +- **Functionality**: Multi-level scorecards from enterprise to initiative with drill-down capability +- **Purpose**: Provide unified visibility into strategic progress and financial outcomes +- **Trigger**: User accesses Dashboard or clicks metric in any view +- **Progression**: View enterprise scorecard → Select portfolio or initiative → Drill into specific KPI → View trend & targets → Navigate to related initiatives +- **Success criteria**: No ambiguity about performance; financial and operational metrics connected; accessible to all stakeholders + +### Strategy-to-Execution Traceability +- **Functionality**: Visual relationship mapping showing how initiatives link to strategic goals and outcomes +- **Purpose**: Ensure every activity directly supports strategic intent; identify gaps +- **Trigger**: User clicks "View Connections" or "Trace to Strategy" on any initiative +- **Progression**: Select initiative or goal → View relationship map → Identify gaps or misalignments → Create new links or initiatives +- **Success criteria**: Complete line of sight from daily work to enterprise strategy; no orphaned initiatives + +## Edge Case Handling + +- **Orphaned Initiatives** - Display warnings when initiatives lack strategic linkage; suggest potential connections +- **Capacity Overload** - Flag portfolios exceeding resource capacity with visual indicators; recommend rebalancing +- **Stale Data** - Highlight KPIs and initiatives not updated within defined thresholds; send gentle reminders to owners +- **Conflicting Priorities** - Surface initiatives competing for same resources with conflict resolution workflow +- **Incomplete Strategy Cards** - Auto-save drafts; provide completion checklist; allow progressive elaboration +- **Access Control** - Role-based visibility ensuring executives see enterprise view while contributors focus on their initiatives + +## Design Direction + +The design should evoke **executive confidence, operational precision, and strategic clarity**. This is a tool for serious decisions—it must feel authoritative without being bureaucratic, data-rich without overwhelming, and sophisticated yet accessible. Visual language should suggest enterprise-grade reliability (think Bloomberg Terminal meets modern SaaS), with clear hierarchies, purposeful data density, and confident use of space to signal importance. + +## Color Selection + +**Deep Navy & Gold Executive Palette** - Conveys authority, strategic thinking, and high-stakes decision-making appropriate for C-suite and strategy offices. + +- **Primary Color**: Deep Navy `oklch(0.28 0.05 250)` - Strategic authority and executive presence; used for primary navigation, key actions, and strategic elements +- **Secondary Colors**: + - Slate `oklch(0.42 0.02 250)` - Supporting structure for secondary actions and containers + - Cool Gray `oklch(0.92 0.01 250)` - Subtle backgrounds and dividers maintaining visual hierarchy +- **Accent Color**: Rich Gold `oklch(0.72 0.14 85)` - Strategic focus and achievement; highlights critical metrics, success states, and high-priority initiatives +- **Foreground/Background Pairings**: + - Primary Navy (oklch(0.28 0.05 250)): White text (oklch(0.99 0 0)) - Ratio 11.2:1 ✓ + - Slate (oklch(0.42 0.02 250)): White text (oklch(0.99 0 0)) - Ratio 6.8:1 ✓ + - Gold Accent (oklch(0.72 0.14 85)): Deep Navy text (oklch(0.28 0.05 250)) - Ratio 4.9:1 ✓ + - Background (oklch(0.98 0.005 250)): Foreground text (oklch(0.25 0.02 250)) - Ratio 13.4:1 ✓ + +## Font Selection + +Typography should communicate **executive gravitas, analytical precision, and structured thinking**—appropriate for strategy documents and financial reporting while remaining highly scannable for dashboard views. + +- **Typographic Hierarchy**: + - H1 (Strategic Section Headers): Outfit Bold / 32px / tight (-0.02em) - Commands attention for major sections + - H2 (Portfolio/Card Titles): Outfit SemiBold / 24px / tight (-0.01em) - Clear hierarchical signaling + - H3 (Initiative Titles): Outfit Medium / 18px / normal - Balanced weight for scannability + - Body (Descriptions/Content): Inter Regular / 15px / relaxed (1.6) - Exceptional readability for detailed content + - Data/Metrics: JetBrains Mono Medium / 14px / normal - Precision and clarity for numbers, KPIs, dates + - Captions/Labels: Inter Medium / 13px / wide (0.01em) / uppercase - Clear visual separation for metadata + +## Animations + +Animations should reinforce the sense of **authoritative transitions and data relationships**, never frivolous. Use purposeful motion to guide attention during navigation between strategy levels (enterprise → portfolio → initiative), smooth drill-downs that maintain spatial context, and subtle highlights when metrics update or thresholds are crossed. Strategic elements should feel weighty—cards and modals transition with slight deceleration suggesting substance and importance. + +## Component Selection + +- **Components**: + - `Card` - Primary container for Strategy Cards, initiative summaries, and portfolio groups; add subtle shadow and border treatment for depth + - `Tabs` - Navigation between Strategy Cards and Workbench; styled with underline indicator and bold active state + - `Dialog` - Full-screen modals for creating/editing Strategy Cards and initiatives with structured forms + - `Table` - Initiative lists, KPI scorecards, and portfolio views with sortable columns and row hover states + - `Badge` - Status indicators (On Track, At Risk, Blocked), priority levels, and portfolio tags with semantic colors + - `Progress` - Visual representation of initiative completion, capacity utilization, and KPI achievement + - `Select` - Framework selection, owner assignment, portfolio categorization with clear dropdown styling + - `Button` - Primary actions use solid navy with gold hover accent; secondary actions use outline style + - `Separator` - Clear visual breaks between strategy sections and dashboard panels + - `Avatar` - Owner identification with fallback initials + - `ScrollArea` - Smooth scrolling for long strategy content and initiative lists + +- **Customizations**: + - Strategy Card component with collapsible framework sections (Vision, Goals, Metrics, Assumptions) + - Traceability visualization using connected cards or tree view showing goal → initiative relationships + - Portfolio capacity gauge combining Progress with numeric indicators + - KPI scorecard component with trend indicators (up/down arrows) and target comparison + - Initiative timeline component showing milestones and current progress + +- **States**: + - Buttons: Navy default → Gold hover → Pressed with slight scale → Disabled with reduced opacity + - Cards: Subtle hover elevation; active state with gold left border; selected state with gold outline + - Table rows: Hover with light slate background; selected with stronger slate background + - Status badges: Green (On Track), Amber (At Risk), Red (Blocked), Gray (Not Started) + +- **Icon Selection**: + - `Strategy` - Use structured grid or layers icon for Strategy Cards + - `ChartBar` - Workbench and execution tracking + - `FolderOpen` - Portfolio management + - `Target` - Goals and KPIs + - `Link` - Traceability and connections + - `Plus` - Create new cards/initiatives + - `ArrowRight` - Drill-down and navigation + - `Warning` - Risk flags and capacity alerts + - `TrendUp/TrendDown` - KPI performance indicators + +- **Spacing**: + - Page margins: `p-8` for generous breathing room around main content + - Card padding: `p-6` for substantial internal space + - Section gaps: `gap-6` between major sections; `gap-4` between related elements + - List items: `py-3` for comfortable touch targets and scannability + +- **Mobile**: + - Tab navigation converts to bottom sheet selector + - Strategy Cards stack vertically with collapsible sections expanded one at a time + - Tables transform to card-based lists with key data prioritized + - Portfolio dashboard shows one metric card at a time with horizontal swipe + - Create/Edit dialogs use full viewport with simplified forms + - Reduce typographic scale by 10-15% for mobile readability diff --git a/index.html b/index.html index f62002d..a84cfb5 100644 --- a/index.html +++ b/index.html @@ -4,9 +4,10 @@ - + StrategyOS - Strategy Management Platform + diff --git a/src/App.tsx b/src/App.tsx index 98ef973..8af281d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,85 @@ +import { useKV } from '@github/spark/hooks' +import { useState } from 'react' +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' +import { Strategy, ChartBar, FolderOpen, Target } from '@phosphor-icons/react' +import StrategyCards from './components/StrategyCards' +import Workbench from './components/Workbench' +import Portfolios from './components/Portfolios' +import Dashboard from './components/Dashboard' +import type { StrategyCard, Initiative } from './types' + function App() { - return
+ const [strategyCards] = useKV('strategy-cards', []) + const [initiatives] = useKV('initiatives', []) + const [activeTab, setActiveTab] = useState('strategy') + + return ( +
+
+
+
+
+

+ StrategyOS +

+

+ Strategy Management Platform +

+
+
+
+ Cards + {strategyCards?.length || 0} +
+
+ Initiatives + {initiatives?.length || 0} +
+
+
+
+
+ +
+ + + + + Strategy Cards + + + + Workbench + + + + Portfolios + + + + Dashboard + + + + + + + + + + + + + + + + + + + +
+
+ ) } -export default App \ No newline at end of file +export default App diff --git a/src/components/Dashboard.tsx b/src/components/Dashboard.tsx new file mode 100644 index 0000000..908482c --- /dev/null +++ b/src/components/Dashboard.tsx @@ -0,0 +1,279 @@ +import { useKV } from '@github/spark/hooks' +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' +import { Badge } from '@/components/ui/badge' +import { Progress } from '@/components/ui/progress' +import { Separator } from '@/components/ui/separator' +import { Target, TrendUp, TrendDown, Minus, CheckCircle, Warning, Link as LinkIcon } from '@phosphor-icons/react' +import type { Initiative, StrategyCard } from '@/types' + +export default function Dashboard() { + const [initiatives] = useKV('initiatives', []) + const [strategyCards] = useKV('strategy-cards', []) + + const totalInitiatives = initiatives?.length || 0 + const totalBudget = initiatives?.reduce((sum, i) => sum + i.budget, 0) || 0 + const avgProgress = totalInitiatives > 0 + ? Math.round((initiatives?.reduce((sum, i) => sum + i.progress, 0) || 0) / totalInitiatives) + : 0 + + const statusBreakdown = { + onTrack: initiatives?.filter(i => i.status === 'on-track').length || 0, + atRisk: initiatives?.filter(i => i.status === 'at-risk').length || 0, + blocked: initiatives?.filter(i => i.status === 'blocked').length || 0, + notStarted: initiatives?.filter(i => i.status === 'not-started').length || 0, + completed: initiatives?.filter(i => i.status === 'completed').length || 0, + } + + const strategicAlignment = strategyCards?.map(card => { + const linkedInitiatives = initiatives?.filter(i => i.strategyCardId === card.id) || [] + const totalLinkedBudget = linkedInitiatives.reduce((sum, i) => sum + i.budget, 0) + const avgLinkedProgress = linkedInitiatives.length > 0 + ? Math.round(linkedInitiatives.reduce((sum, i) => sum + i.progress, 0) / linkedInitiatives.length) + : 0 + + return { + card, + initiativeCount: linkedInitiatives.length, + totalBudget: totalLinkedBudget, + avgProgress: avgLinkedProgress, + } + }) || [] + + const kpiMockData = [ + { name: 'Cost Reduction', current: 8.2, target: 10, unit: 'M USD', trend: 'up' as const }, + { name: 'Cycle Time Improvement', current: 18, target: 25, unit: '%', trend: 'up' as const }, + { name: 'Customer Satisfaction', current: 87, target: 90, unit: 'NPS', trend: 'up' as const }, + { name: 'Revenue Growth', current: 12.5, target: 15, unit: '%', trend: 'up' as const }, + ] + + const getTrendIcon = (trend: string) => { + switch (trend) { + case 'up': return TrendUp + case 'down': return TrendDown + default: return Minus + } + } + + const getKPIProgress = (current: number, target: number) => { + return Math.min((current / target) * 100, 100) + } + + return ( +
+
+

Executive Dashboard

+

Real-time view of strategic execution

+
+ +
+ + + Total Initiatives + {totalInitiatives} + + +
+ {statusBreakdown.onTrack} On Track + {statusBreakdown.atRisk > 0 && ( + {statusBreakdown.atRisk} At Risk + )} +
+
+
+ + + + Total Investment + + ${(totalBudget / 1000000).toFixed(1)}M + + + +

+ Across {strategyCards?.length || 0} strategic themes +

+
+
+ + + + Average Progress + {avgProgress}% + + + + + + + + + Completion Rate + + {totalInitiatives > 0 ? Math.round((statusBreakdown.completed / totalInitiatives) * 100) : 0}% + + + +

+ {statusBreakdown.completed} of {totalInitiatives} completed +

+
+
+
+ +
+ + + + + Initiative Status Breakdown + + + +
+
+ On Track +
+ 0 ? (statusBreakdown.onTrack / totalInitiatives) * 100 : 0} className="w-32 h-2" /> + {statusBreakdown.onTrack} +
+
+
+ At Risk +
+ 0 ? (statusBreakdown.atRisk / totalInitiatives) * 100 : 0} className="w-32 h-2" /> + {statusBreakdown.atRisk} +
+
+
+ Blocked +
+ 0 ? (statusBreakdown.blocked / totalInitiatives) * 100 : 0} className="w-32 h-2" /> + {statusBreakdown.blocked} +
+
+
+ Not Started +
+ 0 ? (statusBreakdown.notStarted / totalInitiatives) * 100 : 0} className="w-32 h-2" /> + {statusBreakdown.notStarted} +
+
+
+ Completed +
+ 0 ? (statusBreakdown.completed / totalInitiatives) * 100 : 0} className="w-32 h-2" /> + {statusBreakdown.completed} +
+
+
+ + {statusBreakdown.atRisk + statusBreakdown.blocked > 0 && ( + <> + +
+ + + {statusBreakdown.atRisk + statusBreakdown.blocked} {statusBreakdown.atRisk + statusBreakdown.blocked === 1 ? 'initiative requires' : 'initiatives require'} attention + +
+ + )} +
+
+ + + + + + Key Performance Indicators + + + + {kpiMockData.map((kpi) => { + const TrendIcon = getTrendIcon(kpi.trend) + const progress = getKPIProgress(kpi.current, kpi.target) + const isOnTarget = progress >= 80 + + return ( +
+
+ {kpi.name} +
+ + + {kpi.current} / {kpi.target} {kpi.unit} + +
+
+ +
+ ) + })} +
+
+
+ + + + + + Strategic Alignment & Traceability + + + View how initiatives map to strategic goals + + + + {strategicAlignment.length === 0 ? ( +
+

Create strategy cards to view strategic alignment

+
+ ) : ( +
+ {strategicAlignment.map(({ card, initiativeCount, totalBudget, avgProgress }) => ( +
+
+
+

{card.title}

+

+ {card.framework.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')} +

+
+ + {initiativeCount} {initiativeCount === 1 ? 'Initiative' : 'Initiatives'} + +
+ + {initiativeCount > 0 ? ( +
+
+

Investment

+

+ ${(totalBudget / 1000000).toFixed(2)}M +

+
+
+

Avg Progress

+

{avgProgress}%

+
+
+

Goals Defined

+

{card.goals.length}

+
+
+ ) : ( +
+

+ No initiatives linked yet - create initiatives in the Workbench +

+
+ )} +
+ ))} +
+ )} +
+
+
+ ) +} diff --git a/src/components/Portfolios.tsx b/src/components/Portfolios.tsx new file mode 100644 index 0000000..7b5bb28 --- /dev/null +++ b/src/components/Portfolios.tsx @@ -0,0 +1,211 @@ +import { useKV } from '@github/spark/hooks' +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' +import { Progress } from '@/components/ui/progress' +import { Badge } from '@/components/ui/badge' +import { FolderOpen, ChartBar, Warning, TrendUp } from '@phosphor-icons/react' +import type { Initiative, Portfolio as PortfolioType } from '@/types' + +const portfolioDefinitions: PortfolioType[] = [ + { + type: 'operational-excellence', + name: 'Operational Excellence', + description: 'Lean, Hoshin Kanri, and continuous improvement initiatives', + capacity: 100, + utilized: 0, + }, + { + type: 'ma', + name: 'M&A', + description: 'Merger and acquisition integration programs', + capacity: 100, + utilized: 0, + }, + { + type: 'financial-transformation', + name: 'Financial Transformation', + description: 'Finance operations and systems modernization', + capacity: 100, + utilized: 0, + }, + { + type: 'esg', + name: 'ESG', + description: 'Environmental, Social, and Governance programs', + capacity: 100, + utilized: 0, + }, + { + type: 'innovation', + name: 'Innovation', + description: 'New products, services, and business models', + capacity: 100, + utilized: 0, + }, +] + +export default function Portfolios() { + const [initiatives] = useKV('initiatives', []) + + const getPortfolioMetrics = (portfolioType: string) => { + const portfolioInitiatives = initiatives?.filter(i => i.portfolio === portfolioType) || [] + const totalBudget = portfolioInitiatives.reduce((sum, i) => sum + i.budget, 0) + const avgProgress = portfolioInitiatives.length > 0 + ? portfolioInitiatives.reduce((sum, i) => sum + i.progress, 0) / portfolioInitiatives.length + : 0 + + const statusCounts = { + onTrack: portfolioInitiatives.filter(i => i.status === 'on-track').length, + atRisk: portfolioInitiatives.filter(i => i.status === 'at-risk').length, + blocked: portfolioInitiatives.filter(i => i.status === 'blocked').length, + } + + const capacityUsed = portfolioInitiatives.length * 20 + + return { + count: portfolioInitiatives.length, + totalBudget, + avgProgress: Math.round(avgProgress), + statusCounts, + capacityUsed: Math.min(capacityUsed, 100), + } + } + + return ( +
+
+
+

Portfolio Management

+

Strategic portfolio analysis and governance

+
+
+ +
+ {portfolioDefinitions.map((portfolio) => { + const metrics = getPortfolioMetrics(portfolio.type) + const hasRisks = metrics.statusCounts.atRisk > 0 || metrics.statusCounts.blocked > 0 + + return ( + + +
+
+
+
+ +
+
+ {portfolio.name} + {portfolio.description} +
+
+
+
+ + {metrics.count} {metrics.count === 1 ? 'Initiative' : 'Initiatives'} + + {hasRisks && ( + + + Attention Required + + )} +
+
+
+ +
+
+
+ + Total Budget +
+

+ ${(metrics.totalBudget / 1000000).toFixed(1)}M +

+
+ +
+
+ + Avg Progress +
+

+ {metrics.avgProgress}% +

+
+ +
+

Status Summary

+
+ {metrics.statusCounts.onTrack > 0 && ( + + {metrics.statusCounts.onTrack} On Track + + )} + {metrics.statusCounts.atRisk > 0 && ( + + {metrics.statusCounts.atRisk} At Risk + + )} + {metrics.statusCounts.blocked > 0 && ( + + {metrics.statusCounts.blocked} Blocked + + )} +
+
+ +
+

Capacity

+
+
+ + {metrics.capacityUsed}% + + 80 ? 'text-warning' : 'text-muted-foreground'}`}> + {metrics.capacityUsed > 80 ? 'High utilization' : 'Available'} + +
+ +
+
+
+ + {metrics.count === 0 && ( +
+

+ No initiatives in this portfolio yet +

+
+ )} +
+
+ ) + })} +
+ + + + Portfolio Governance Notes + + +
+ +

Capacity Planning: Each portfolio shows utilization based on active initiatives (estimated 20% capacity per initiative)

+
+
+ +

Risk Flags: Portfolios with at-risk or blocked initiatives receive attention markers

+
+
+ +

Resource Balancing: Monitor capacity utilization to avoid portfolio overload and ensure delivery success

+
+
+
+
+ ) +} diff --git a/src/components/StrategyCards.tsx b/src/components/StrategyCards.tsx new file mode 100644 index 0000000..1b12778 --- /dev/null +++ b/src/components/StrategyCards.tsx @@ -0,0 +1,358 @@ +import { useKV } from '@github/spark/hooks' +import { useState } from 'react' +import { Button } from '@/components/ui/button' +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' +import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { Textarea } from '@/components/ui/textarea' +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' +import { Badge } from '@/components/ui/badge' +import { Separator } from '@/components/ui/separator' +import { ScrollArea } from '@/components/ui/scroll-area' +import { Plus, Target, Lightbulb, ChartLineUp } from '@phosphor-icons/react' +import { toast } from 'sonner' +import type { StrategyCard } from '@/types' + +const frameworks = [ + { value: 'swot', label: 'SWOT Analysis', description: 'Strengths, Weaknesses, Opportunities, Threats' }, + { value: 'value-disciplines', label: 'Value Disciplines', description: 'Operational Excellence, Product Leadership, Customer Intimacy' }, + { value: 'strategic-pillars', label: 'Strategic Pillars', description: 'Core strategic themes and priorities' }, + { value: 'hoshin-kanri', label: 'Hoshin Kanri', description: 'Policy deployment and strategic alignment' }, + { value: 'okr', label: 'OKR Framework', description: 'Objectives and Key Results' }, +] + +export default function StrategyCards() { + const [strategyCards, setStrategyCards] = useKV('strategy-cards', []) + const [isDialogOpen, setIsDialogOpen] = useState(false) + const [selectedCard, setSelectedCard] = useState(null) + + const [formData, setFormData] = useState({ + title: '', + framework: '', + vision: '', + goals: '', + metrics: '', + assumptions: '', + }) + + const handleCreate = () => { + if (!formData.title || !formData.framework || !formData.vision) { + toast.error('Please fill in required fields') + return + } + + const newCard: StrategyCard = { + id: `card-${Date.now()}`, + title: formData.title, + framework: formData.framework, + vision: formData.vision, + goals: formData.goals.split('\n').filter(g => g.trim()), + metrics: formData.metrics.split('\n').filter(m => m.trim()), + assumptions: formData.assumptions.split('\n').filter(a => a.trim()), + createdAt: Date.now(), + updatedAt: Date.now(), + } + + setStrategyCards((current) => [...(current || []), newCard]) + toast.success('Strategy Card created successfully') + setIsDialogOpen(false) + resetForm() + } + + const resetForm = () => { + setFormData({ + title: '', + framework: '', + vision: '', + goals: '', + metrics: '', + assumptions: '', + }) + } + + const handleCardClick = (card: StrategyCard) => { + setSelectedCard(card) + } + + return ( +
+
+
+

Strategy Cards

+

Create and manage strategic frameworks

+
+ + + + + + + Create New Strategy Card + + Use a proven framework to structure your strategic thinking + + + +
+
+ + setFormData({ ...formData, title: e.target.value })} + /> +
+ +
+ + +
+ + + +
+ +