import React, { useState, useEffect } from 'react'; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, BarChart, Bar, PieChart, Pie, Cell, Area, AreaChart } from 'recharts'; import { TrendingUp, TrendingDown, Home, DollarSign, Calendar, MapPin, Activity, AlertCircle, Star, RefreshCw, Wifi, WifiOff } from 'lucide-react'; const ApartmentDashboard = () => { const [selectedUnit, setSelectedUnit] = useState(null); const [viewMode, setViewMode] = useState('overview'); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [lastUpdated, setLastUpdated] = useState(null); // Real data state const [dailySummary, setDailySummary] = useState(null); const [priceHistory, setPriceHistory] = useState([]); const [availableUnits, setAvailableUnits] = useState([]); const [recentActivity, setRecentActivity] = useState([]); const [planStats, setPlanStats] = useState([]); // API base URL const API_BASE = '/api'; // Fetch data from API const fetchData = async () => { setLoading(true); setError(null); try { console.log('🔄 Fetching apartment data...'); // Fetch all endpoints in parallel const [ dailySummaryRes, priceHistoryRes, availableUnitsRes, recentActivityRes, planStatsRes ] = await Promise.all([ fetch(`${API_BASE}/daily-summary`), fetch(`${API_BASE}/price-history`), fetch(`${API_BASE}/available-units`), fetch(`${API_BASE}/recent-activity`), fetch(`${API_BASE}/plan-stats`) ]); // Check if all requests were successful if (!dailySummaryRes.ok || !priceHistoryRes.ok || !availableUnitsRes.ok || !recentActivityRes.ok || !planStatsRes.ok) { throw new Error('One or more API requests failed'); } // Parse JSON responses const [ dailySummaryData, priceHistoryData, availableUnitsData, recentActivityData, planStatsData ] = await Promise.all([ dailySummaryRes.json(), priceHistoryRes.json(), availableUnitsRes.json(), recentActivityRes.json(), planStatsRes.json() ]); console.log('✅ Data fetched successfully:', { dailySummary: dailySummaryData, priceHistory: priceHistoryData.length, availableUnits: availableUnitsData.length, recentActivity: recentActivityData.length, planStats: planStatsData.length }); // Update state with real data setDailySummary(dailySummaryData); setPriceHistory(priceHistoryData); setAvailableUnits(availableUnitsData); setRecentActivity(recentActivityData); setPlanStats(planStatsData); setLastUpdated(new Date()); setLoading(false); } catch (err) { console.error('❌ Error fetching data:', err); setError(err.message); setLoading(false); } }; // Initial data fetch useEffect(() => { fetchData(); }, []); // Auto-refresh every 5 minutes useEffect(() => { const interval = setInterval(fetchData, 5 * 60 * 1000); return () => clearInterval(interval); }, []); const MetricCard = ({ title, value, subtitle, icon: Icon, trend, color = "blue" }) => (

{title}

{value}

{subtitle &&

{subtitle}

}
{trend && ( 0 ? 'text-green-600' : 'text-red-600'} flex items-center`}> {trend > 0 ? : } {Math.abs(trend)}% )}
); const formatPrice = (price) => `$${price?.toLocaleString()}`; const formatDate = (dateStr) => new Date(dateStr).toLocaleDateString(); const COLORS = ['#8B0000', '#DC143C', '#B22222', '#CD5C5C', '#F08080']; // Loading state if (loading && !dailySummary) { return (

Loading Apartment Data

Fetching real-time market information...

); } // Error state if (error && !dailySummary) { return (

Connection Error

Unable to fetch apartment data: {error}

); } return (
{/* Header */}

Country Club Towers & Gardens

Real-time apartment market dashboard

{lastUpdated && (
Last updated: {lastUpdated.toLocaleTimeString()}
)}
{/* Overview Tab */} {viewMode === 'overview' && dailySummary && ( <> {/* Daily Metrics */}
{/* Price Trends */}

Average Price Trend ({priceHistory.length} days)

d.avgPrice !== null)}> new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} /> `$${value}`} /> [formatPrice(value), 'Avg Price']} labelFormatter={(date) => formatDate(date)} />

Unit Availability

new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} /> [value, 'Available Units']} labelFormatter={(date) => formatDate(date)} />
{/* Plan Distribution */} {planStats.length > 0 && (

Units by Floor Plan

`${name}: ${count}`} outerRadius={80} fill="#8884d8" dataKey="count" > {planStats.map((entry, index) => ( ))}

Average Price by Plan

`$${value}`} /> [formatPrice(value), 'Avg Price']} />
)} {/* Recent Activity */} {recentActivity.length > 0 && (

Recent Activity

{recentActivity.map((activity, index) => (
{activity.type === 'new' &&
} {activity.type === 'rented' &&
} {activity.type === 'price_drop' &&
}

{activity.type === 'new' && `New unit available: ${activity.unitCode}`} {activity.type === 'rented' && `Unit rented: ${activity.unitCode}`} {activity.type === 'price_drop' && `Price drop: ${activity.unitCode}`}

{activity.planName} • {activity.bedCount}BR/{activity.bathCount}BA {activity.type === 'price_drop' ? ` • ${formatPrice(activity.oldPrice)} → ${formatPrice(activity.newPrice)}` : activity.price ? ` • ${formatPrice(activity.price)}` : '' }

{formatDate(activity.date)}
))}
)} )} {/* Units Tab */} {viewMode === 'units' && (

Available Units ({availableUnits.length})

{availableUnits.map((unit) => (

{unit.unitCode}

{unit.planName}

{unit.planName && unit.planName.toLowerCase().includes('maroon peak') && unit.currentPrice < 3800 && Priority }

{formatPrice(unit.currentPrice)}

Current Price

Bedrooms

{unit.bedCount}

Bathrooms

{unit.bathCount}

Area

{unit.area} sqft

Available

{unit.daysAvailable || 0} days

Price Range: {formatPrice(unit.minPrice)} - {formatPrice(unit.maxPrice)}
unit.minPrice ? `${((unit.currentPrice - unit.minPrice) / (unit.maxPrice - unit.minPrice)) * 100}%` : '50%' }} >
))}
{availableUnits.length === 0 && !loading && (

No Available Units

No apartment units are currently available.

)}
)} {/* Analytics Tab */} {viewMode === 'analytics' && (

Market Analytics

Price Distribution by Plan

{planStats.map((plan, index) => (
{plan.name}

{formatPrice(plan.avgPrice)}

{plan.count} units

))}

Market Insights

Maroon Peak Priority

Maroon Peak units under $3,800 are highlighted as priority opportunities based on your preferences.

{dailySummary && (

Market Activity

Daily turnover rate of {(dailySummary.turnoverRate || dailySummary.turnover_rate || 0).toFixed(1)}% indicates { (dailySummary.turnoverRate || dailySummary.turnover_rate || 0) > 10 ? 'high' : (dailySummary.turnoverRate || dailySummary.turnover_rate || 0) > 5 ? 'moderate' : 'low' } market activity.

)} {priceHistory.length > 0 && (

Price Trends

{priceHistory.length > 1 ? ( `Average prices ${priceHistory[priceHistory.length - 1].avgPrice > priceHistory[priceHistory.length - 2].avgPrice ? 'increased' : 'decreased'} in recent days.` ) : ( 'Price trend data is being collected.' )}

)}
)} {/* Unit Detail Modal */} {selectedUnit && (

{selectedUnit.unitCode}

{selectedUnit.planName} • {selectedUnit.community}

Current Price

{formatPrice(selectedUnit.currentPrice)}

Price Range

{formatPrice(selectedUnit.minPrice)} - {formatPrice(selectedUnit.maxPrice)}

Bedrooms

{selectedUnit.bedCount}

Bathrooms

{selectedUnit.bathCount}

Area

{selectedUnit.area}

Days Available

{selectedUnit.daysAvailable || 0}

{selectedUnit.priceHistory && selectedUnit.priceHistory.length > 0 && (

Price History

new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} /> `$${value}`} /> [formatPrice(value), 'Price']} labelFormatter={(date) => formatDate(date)} />
)}
)}
); }; export default ApartmentDashboard;