← back to Goodquestion

src/components/market/MarketSizeChart.tsx

221 lines

'use client'

import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'
import {
  BarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
  PieChart,
  Pie,
  Cell,
} from 'recharts'
import { TrendingUp } from 'lucide-react'
import type { MarketSize } from '@/types/swot'

interface MarketSizeChartProps {
  marketSize: MarketSize
  demographics: {
    population: number
    medianIncome: number
    averageHouseholdSize: number
    targetDemographicPercentage: number
  }
}

export function MarketSizeChart({ marketSize, demographics }: MarketSizeChartProps) {
  const marketData = [
    {
      name: 'Total Addressable Market',
      value: marketSize.totalAddressableMarket,
      color: '#3b82f6',
    },
    {
      name: 'Serviceable Market',
      value: marketSize.serviceableMarket,
      color: '#8b5cf6',
    },
    {
      name: 'Target Market',
      value: marketSize.targetMarket,
      color: '#22c55e',
    },
  ]

  const barChartData = [
    {
      name: 'TAM',
      value: marketSize.totalAddressableMarket,
    },
    {
      name: 'SAM',
      value: marketSize.serviceableMarket,
    },
    {
      name: 'SOM',
      value: marketSize.targetMarket,
    },
  ]

  const COLORS = ['#3b82f6', '#8b5cf6', '#22c55e']

  const formatCurrency = (value: number) => {
    if (value >= 1000000) {
      return `$${(value / 1000000).toFixed(1)}M`
    }
    if (value >= 1000) {
      return `$${(value / 1000).toFixed(0)}K`
    }
    return `$${value.toLocaleString()}`
  }

  return (
    <div className="space-y-6">
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <TrendingUp className="h-5 w-5" />
            Market Size Analysis
          </CardTitle>
          <CardDescription>
            Potential market share: {marketSize.marketSharePotential}%
          </CardDescription>
        </CardHeader>
        <CardContent>
          <div className="grid md:grid-cols-2 gap-6">
            {/* Bar Chart */}
            <div>
              <h4 className="text-sm font-semibold mb-4">Market Breakdown</h4>
              <ResponsiveContainer width="100%" height={250}>
                <BarChart data={barChartData}>
                  <CartesianGrid strokeDasharray="3 3" />
                  <XAxis dataKey="name" />
                  <YAxis tickFormatter={formatCurrency} />
                  <Tooltip formatter={(value: any) => formatCurrency(value)} />
                  <Bar dataKey="value" fill="#3b82f6">
                    {barChartData.map((entry, index) => (
                      <Cell key={`cell-${index}`} fill={COLORS[index]} />
                    ))}
                  </Bar>
                </BarChart>
              </ResponsiveContainer>
            </div>

            {/* Pie Chart */}
            <div>
              <h4 className="text-sm font-semibold mb-4">Market Distribution</h4>
              <ResponsiveContainer width="100%" height={250}>
                <PieChart>
                  <Pie
                    data={marketData}
                    cx="50%"
                    cy="50%"
                    labelLine={false}
                    label={({ name, percent }) => `${name.split(' ')[0]}: ${(percent * 100).toFixed(0)}%`}
                    outerRadius={80}
                    fill="#8884d8"
                    dataKey="value"
                  >
                    {marketData.map((entry, index) => (
                      <Cell key={`cell-${index}`} fill={entry.color} />
                    ))}
                  </Pie>
                  <Tooltip formatter={(value: any) => formatCurrency(value)} />
                </PieChart>
              </ResponsiveContainer>
            </div>
          </div>

          {/* Market Details */}
          <div className="grid md:grid-cols-3 gap-4 mt-6">
            <div className="bg-blue-50 p-4 rounded-lg">
              <div className="text-xs text-blue-600 font-medium mb-1">
                Total Addressable Market
              </div>
              <div className="text-2xl font-bold text-blue-900">
                {formatCurrency(marketSize.totalAddressableMarket)}
              </div>
              <div className="text-xs text-blue-600 mt-1">
                Total market potential
              </div>
            </div>
            <div className="bg-purple-50 p-4 rounded-lg">
              <div className="text-xs text-purple-600 font-medium mb-1">
                Serviceable Market
              </div>
              <div className="text-2xl font-bold text-purple-900">
                {formatCurrency(marketSize.serviceableMarket)}
              </div>
              <div className="text-xs text-purple-600 mt-1">
                Realistically serviceable
              </div>
            </div>
            <div className="bg-green-50 p-4 rounded-lg">
              <div className="text-xs text-green-600 font-medium mb-1">
                Target Market
              </div>
              <div className="text-2xl font-bold text-green-900">
                {formatCurrency(marketSize.targetMarket)}
              </div>
              <div className="text-xs text-green-600 mt-1">
                Initial target segment
              </div>
            </div>
          </div>

          {/* Assumptions */}
          {marketSize.assumptions.length > 0 && (
            <div className="mt-6 p-4 bg-muted/50 rounded-lg">
              <h4 className="text-sm font-semibold mb-2">Key Assumptions</h4>
              <ul className="text-sm space-y-1 list-disc list-inside text-muted-foreground">
                {marketSize.assumptions.map((assumption, index) => (
                  <li key={index}>{assumption}</li>
                ))}
              </ul>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Demographics */}
      <Card>
        <CardHeader>
          <CardTitle>Local Demographics</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="grid md:grid-cols-4 gap-4">
            <div className="text-center p-4 bg-muted/50 rounded-lg">
              <div className="text-3xl font-bold text-primary">
                {demographics.population.toLocaleString()}
              </div>
              <div className="text-sm text-muted-foreground mt-1">Population</div>
            </div>
            <div className="text-center p-4 bg-muted/50 rounded-lg">
              <div className="text-3xl font-bold text-primary">
                ${demographics.medianIncome.toLocaleString()}
              </div>
              <div className="text-sm text-muted-foreground mt-1">Median Income</div>
            </div>
            <div className="text-center p-4 bg-muted/50 rounded-lg">
              <div className="text-3xl font-bold text-primary">
                {demographics.averageHouseholdSize.toFixed(1)}
              </div>
              <div className="text-sm text-muted-foreground mt-1">Avg Household Size</div>
            </div>
            <div className="text-center p-4 bg-muted/50 rounded-lg">
              <div className="text-3xl font-bold text-primary">
                {demographics.targetDemographicPercentage}%
              </div>
              <div className="text-sm text-muted-foreground mt-1">Target Demographic</div>
            </div>
          </div>
        </CardContent>
      </Card>
    </div>
  )
}