import React, { useState, useEffect } from 'react'; import { ChevronLeft, ChevronRight, Calculator, TrendingUp, Home, DollarSign, FileText, BarChart3, PieChart } from 'lucide-react'; const FloridaRealEstateAnalyzer = () => { const [currentStep, setCurrentStep] = useState(1); const [propertyData, setPropertyData] = useState({ // General Information address: '', city: '', state: 'Florida', zipCode: '', propertyType: 'Residential', constructionYear: 2000, lastRenovation: 2020, // Surface Area buildingArea: 0, landArea: 0, // Physical Attributes bedrooms: 1, bathrooms: 1, parkingType: 'None', // Amenities amenities: { pool: false, gym: false, elevator: false, security: false, ac: false, heating: false, dishwasher: false, laundry: false, balcony: false, garden: false }, // Initial Investment purchasePrice: 0, closingCosts: 0, makeReadyCosts: 0, // Income monthlyRent: 0, vacancyRate: 5.0, // Operating Expenses propertyTaxes: 0, landlordInsurance: 0, maintenance: 0, propertyManagement: 0.0, utilities: 0, hoaFees: 0, specialAssessments: 0, // Risk Provision capexFund: 0, // Qualitative Checklist checklist: { reserveStudy: false, delinquencyRate: false, rentalCaps: false, lawsRestrictions: false }, // Analysis Parameters desiredCapRate: 5.0, projectionYears: 10, annualAppreciation: 2.0, propertyAppreciationRate: 2.0, annualRentIncrease: 2.0, sp500Return: 8.0, bondsReturn: 4.0 }); // Calculated metrics const [metrics, setMetrics] = useState({ totalCashOutlay: 0, totalOpex: 0, grossIncome: 0, noi: 0, annualCashFlow: 0, capRate: 0, cashOnCashReturn: 0, grm: 0, paybackPeriod: 0, maxPurchasePrice: 0 }); // Calculate metrics whenever propertyData changes useEffect(() => { calculateMetrics(); }, [propertyData]); const calculateMetrics = () => { const totalCashOutlay = propertyData.purchasePrice + propertyData.closingCosts + propertyData.makeReadyCosts; const grossIncome = propertyData.monthlyRent * 12 * (1 - propertyData.vacancyRate / 100); const totalOpex = propertyData.propertyTaxes + propertyData.landlordInsurance + propertyData.maintenance + (propertyData.propertyManagement / 100 * grossIncome) + propertyData.utilities + propertyData.hoaFees + propertyData.specialAssessments + propertyData.capexFund; const noi = grossIncome - totalOpex; const annualCashFlow = noi; const capRate = propertyData.purchasePrice > 0 ? (noi / propertyData.purchasePrice) * 100 : 0; const cashOnCashReturn = totalCashOutlay > 0 ? (annualCashFlow / totalCashOutlay) * 100 : 0; const grm = propertyData.monthlyRent > 0 ? propertyData.purchasePrice / (propertyData.monthlyRent * 12) : 0; const paybackPeriod = annualCashFlow > 0 ? totalCashOutlay / annualCashFlow : 0; const maxPurchasePrice = propertyData.desiredCapRate > 0 ? noi / (propertyData.desiredCapRate / 100) : 0; setMetrics({ totalCashOutlay, totalOpex, grossIncome, noi, annualCashFlow, capRate, cashOnCashReturn, grm, paybackPeriod, maxPurchasePrice }); }; const updatePropertyData = (field, value) => { if (field.includes('.')) { const [parent, child] = field.split('.'); setPropertyData(prev => ({ ...prev, [parent]: { ...prev[parent], [child]: value } })); } else { setPropertyData(prev => ({ ...prev, [field]: value })); } }; const formatCurrency = (amount) => { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0 }).format(amount); }; const formatPercentage = (value) => { return `${value.toFixed(2)}%`; }; const steps = [ { id: 1, title: 'Pillar 1', subtitle: 'General Info' }, { id: 2, title: 'Pillar 2', subtitle: 'Property Details' }, { id: 3, title: 'Pillar 3', subtitle: 'Financial Analysis' }, { id: 4, title: 'Pillar 4', subtitle: 'Projections' } ]; const renderGeneralInfo = () => (

General Information

updatePropertyData('address', e.target.value)} placeholder="Please enter or select a valid address." className="w-full bg-gray-700 text-white rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" /> {!propertyData.address && (

Please enter or select a valid address.

)}
updatePropertyData('city', e.target.value)} className="w-full bg-gray-700 text-white rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />
updatePropertyData('state', e.target.value)} className="w-full bg-gray-700 text-white rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />
updatePropertyData('zipCode', e.target.value)} className="w-full bg-gray-700 text-white rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />

Property Type

{['Residential', 'Multifamily', 'Commercial', 'Industrial', 'Mixed Use'].map((type) => ( ))}
updatePropertyData('constructionYear', parseInt(e.target.value))} className="w-full bg-gray-700 text-white rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />
updatePropertyData('lastRenovation', parseInt(e.target.value))} className="w-full bg-gray-700 text-white rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />
); const renderPropertyDetails = () => (

Surface Area

updatePropertyData('buildingArea', parseFloat(e.target.value) || 0)} className="w-full bg-gray-700 text-white rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />
updatePropertyData('landArea', parseFloat(e.target.value) || 0)} className="w-full bg-gray-700 text-white rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />

Physical Attributes

{propertyData.bedrooms}
{propertyData.bathrooms}
{['None', 'Street', 'Driveway', 'Garage', 'Carport', 'Assigned'].map((type) => ( ))}

Amenities

{Object.entries(propertyData.amenities).map(([key, value]) => ( ))}
); const renderFinancialAnalysis = () => (

Initial Investment

$ updatePropertyData('purchasePrice', parseFloat(e.target.value) || 0)} className="w-full bg-gray-700 text-white rounded-lg pl-8 pr-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />
{propertyData.purchasePrice === 0 && (

Purchase price cannot be zero.

)}
$ updatePropertyData('closingCosts', parseFloat(e.target.value) || 0)} className="w-full bg-gray-700 text-white rounded-lg pl-8 pr-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />
$ updatePropertyData('makeReadyCosts', parseFloat(e.target.value) || 0)} className="w-full bg-gray-700 text-white rounded-lg pl-8 pr-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />
Total Cash Outlay {formatCurrency(metrics.totalCashOutlay)}

Income

$ updatePropertyData('monthlyRent', parseFloat(e.target.value) || 0)} className="w-full bg-gray-700 text-white rounded-lg pl-8 pr-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />
{propertyData.monthlyRent === 0 && (

Projected monthly rent cannot be zero.

)}
updatePropertyData('vacancyRate', parseFloat(e.target.value))} className="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" /> {formatPercentage(propertyData.vacancyRate)}
Gross Income (Annual) {formatCurrency(metrics.grossIncome)}

Operating Expenses (OPEX - Annual)

{[ { key: 'propertyTaxes', label: 'Property Taxes' }, { key: 'landlordInsurance', label: 'Landlord Insurance' }, { key: 'maintenance', label: 'Maintenance & Repairs' }, { key: 'utilities', label: 'Utilities' }, { key: 'hoaFees', label: 'Monthly HOA Fees' }, { key: 'specialAssessments', label: 'Known Special Assessments (Annual)' }, { key: 'capexFund', label: 'CapEx & Assessment Fund' } ].map((expense) => (
$ updatePropertyData(expense.key, parseFloat(e.target.value) || 0)} className="w-full bg-gray-700 text-white rounded-lg pl-8 pr-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />
))}
% updatePropertyData('propertyManagement', parseFloat(e.target.value) || 0)} className="w-full bg-gray-700 text-white rounded-lg pl-8 pr-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" />

Interactive Qualitative Checklist

{[ { key: 'reserveStudy', label: 'Did you review the Reserve Study?' }, { key: 'delinquencyRate', label: 'Do you know the Delinquency Rate?' }, { key: 'rentalCaps', label: 'Are there Rental Caps?' }, { key: 'lawsRestrictions', label: 'Laws/Restrictions?' } ].map((item) => ( ))}

Key Metrics

{[ { label: 'Total Cash Outlay', value: formatCurrency(metrics.totalCashOutlay) }, { label: 'Total OPEX Annual', value: formatCurrency(metrics.totalOpex) }, { label: 'Net Operating Income (NOI)', value: formatCurrency(metrics.noi) }, { label: 'Annual Cash Flow', value: formatCurrency(metrics.annualCashFlow) }, { label: 'Cap Rate', value: formatPercentage(metrics.capRate) }, { label: 'Cash-on-Cash Return', value: formatPercentage(metrics.cashOnCashReturn) } ].map((metric, index) => (
{metric.label} {metric.value}
))}

Maximum Purchase Price

Cap Rate measures annual return before financing. Adjust your target rate to know the maximum price you should pay based on the calculated NOI.

Annual NOI (USD) {formatCurrency(metrics.noi)}
updatePropertyData('desiredCapRate', parseFloat(e.target.value))} className="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" /> {formatPercentage(propertyData.desiredCapRate)}
{metrics.noi <= 0 && (

Make sure the NOI is greater than zero to calculate the maximum price

)} {metrics.noi > 0 && (
Maximum Purchase Price {formatCurrency(metrics.maxPurchasePrice)}
)}
); const renderProjections = () => { const projectedValue = propertyData.purchasePrice * Math.pow(1 + propertyData.propertyAppreciationRate / 100, propertyData.projectionYears); const appreciationGain = projectedValue - propertyData.purchasePrice; return (

Reference Metrics

Cap Rate {formatPercentage(metrics.capRate)}
GRM {metrics.grm.toFixed(2)} BIEN
Payback Period (Years) {metrics.paybackPeriod.toFixed(1)}

Sensitivity Analysis

updatePropertyData('annualAppreciation', parseFloat(e.target.value))} className="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" /> {formatPercentage(propertyData.annualAppreciation)}
1% 3% 5% 7% 9% 10%
Payback Period Years to Break Even
Without Appreciation {metrics.paybackPeriod.toFixed(1)}
With Appreciation {(metrics.paybackPeriod * 0.8).toFixed(1)}

Future Value Projection

Projection Years
{propertyData.projectionYears} years
updatePropertyData('propertyAppreciationRate', parseFloat(e.target.value))} className="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" /> {formatPercentage(propertyData.propertyAppreciationRate)}
Projected Value in {propertyData.projectionYears} Years {formatCurrency(projectedValue)}
Appreciation Gain {formatCurrency(appreciationGain)}

Opportunity Cost Analysis

updatePropertyData('sp500Return', parseFloat(e.target.value))} className="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" /> {formatPercentage(propertyData.sp500Return)}
updatePropertyData('bondsReturn', parseFloat(e.target.value))} className="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" /> {formatPercentage(propertyData.bondsReturn)}
Kawamma
S&P 500
Bonds

Projected Cap Rate Analysis

updatePropertyData('propertyAppreciationRate', parseFloat(e.target.value))} className="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" /> {formatPercentage(propertyData.propertyAppreciationRate)}
updatePropertyData('annualRentIncrease', parseFloat(e.target.value))} className="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" /> {formatPercentage(propertyData.annualRentIncrease)}
Projection Year
Year {Math.min(propertyData.projectionYears, 5)}
{[...Array(10)].map((_, i) => (
))}
1 5 10

Year {Math.min(propertyData.projectionYears, 5)} Projection

Property Value {formatCurrency(projectedValue)}
Annual Rent {formatCurrency(propertyData.monthlyRent * 12 * Math.pow(1 + propertyData.annualRentIncrease / 100, Math.min(propertyData.projectionYears, 5)))}
Net Operating Income {formatCurrency(metrics.noi * Math.pow(1 + propertyData.annualRentIncrease / 100, Math.min(propertyData.projectionYears, 5)))}
Projected Cap Rate {formatPercentage(metrics.capRate)}
vs Current Cap Rate {formatPercentage(metrics.capRate)} → {formatPercentage(metrics.capRate)}
i
Note:

The projected Cap Rate may decrease over time if the property's value appreciates faster than the rental income increases. This is a normal market behavior and indicates that the asset is gaining value at a higher rate than its income potential. It's common in strong real estate markets where property appreciation outpaces rent growth.

); }; const exportToPDF = () => { // Simulate PDF export alert('PDF Export functionality would be implemented here with a library like jsPDF or Puppeteer'); }; return (
{/* Header */}

Florida Real Estate
Investment Analyzer

{/* Step Navigation */}
{steps.map((step) => ( ))}
{/* Content */}
{currentStep === 1 && renderGeneralInfo()} {currentStep === 2 && renderPropertyDetails()} {currentStep === 3 && renderFinancialAnalysis()} {currentStep === 4 && renderProjections()}
{/* Navigation Buttons */}
); }; export default FloridaRealEstateAnalyzer;