page under construction

import React, { useState } from ‘react’;
import { AlertTriangle, TrendingUp, TrendingDown, DollarSign, Users, ShoppingCart, AlertCircle } from ‘lucide-react’;

const PrimeCostDashboard = () => {
const [data, setData] = useState({
revenue: 250000,
cogs: 72500,
laborCost: 87500,
// Labor breakdown
managementLabor: 22500,
hourlyLabor: 52500,
benefits: 12500,
// COGS breakdown
food: 55000,
beverage: 12500,
supplies: 5000,
// Additional metrics
coverCount: 5000,
avgCheck: 50,
employeeCount: 35,
turnoverRate: 45,
});

const calculateMetrics = () => {
const cogsPercent = (data.cogs / data.revenue) * 100;
const laborPercent = (data.laborCost / data.revenue) * 100;
const primeCost = data.cogs + data.laborCost;
const primeCostPercent = (primeCost / data.revenue) * 100;
const laborPerCover = data.laborCost / data.coverCount;
const revenuePerEmployee = data.revenue / data.employeeCount;

```
return {
cogsPercent: cogsPercent.toFixed(1),
laborPercent: laborPercent.toFixed(1),
primeCost,
primeCostPercent: primeCostPercent.toFixed(1),
laborPerCover: laborPerCover.toFixed(2),
revenuePerEmployee: revenuePerEmployee.toFixed(0),
};
```

};

const metrics = calculateMetrics();

const getStatusColor = (value, benchmarkLow, benchmarkHigh) => {
if (value <= benchmarkLow) return ‘text-green-600 bg-green-50 border-green-200’;
if (value <= benchmarkHigh) return ‘text-yellow-600 bg-yellow-50 border-yellow-200’;
return ‘text-red-600 bg-red-50 border-red-200’;
};

const getStatusIcon = (value, benchmarkLow, benchmarkHigh) => {
if (value <= benchmarkLow) return <TrendingDown className="w-5 h-5" />;
if (value <= benchmarkHigh) return <AlertCircle className="w-5 h-5" />;
return <TrendingUp className="w-5 h-5" />;
};

const calculateMonthlyCostOfDysfunction = () => {
const issues = [];
let totalMonthlyCost = 0;

```
// Prime Cost above 65%
if (parseFloat(metrics.primeCostPercent) > 65) {
const excessPoints = parseFloat(metrics.primeCostPercent) - 65;
const monthlyCost = (data.revenue * excessPoints) / 100;
totalMonthlyCost += monthlyCost;
issues.push({
issue: 'Prime Cost Above Target (65%)',
current: `${metrics.primeCostPercent}%`,
target: '65%',
monthlyCost: monthlyCost.toFixed(0),
culturalCause: 'Leadership misalignment, poor accountability systems, lack of financial training'
});
}

// COGS above 30%
if (parseFloat(metrics.cogsPercent) > 30) {
const excessPoints = parseFloat(metrics.cogsPercent) - 30;
const monthlyCost = (data.revenue * excessPoints) / 100;
totalMonthlyCost += monthlyCost;
issues.push({
issue: 'Food Cost Above Target (30%)',
current: `${metrics.cogsPercent}%`,
target: '30%',
monthlyCost: monthlyCost.toFixed(0),
culturalCause: 'Poor portion control, inadequate training, lack of inventory systems, theft/waste not addressed'
});
}

// Labor above 35%
if (parseFloat(metrics.laborPercent) > 35) {
const excessPoints = parseFloat(metrics.laborPercent) - 35;
const monthlyCost = (data.revenue * excessPoints) / 100;
totalMonthlyCost += monthlyCost;
issues.push({
issue: 'Labor Cost Above Target (35%)',
current: `${metrics.laborPercent}%`,
target: '35%',
monthlyCost: monthlyCost.toFixed(0),
culturalCause: 'Inefficient scheduling, high turnover, overstaffing, favoritism in shift assignments'
});
}

// High turnover cost (above 30%)
if (data.turnoverRate > 30) {
const avgHourlyWage = 18;
const hoursToTrain = 40;
const turnoverEmployees = (data.employeeCount * data.turnoverRate) / 100;
const costPerTurnover = avgHourlyWage * hoursToTrain * 2; // 2x for training cost + lost productivity
const annualTurnoverCost = turnoverEmployees * costPerTurnover;
const monthlyCost = annualTurnoverCost / 12;
totalMonthlyCost += monthlyCost;
issues.push({
issue: 'High Turnover Rate',
current: `${data.turnoverRate}%`,
target: '30% or less',
monthlyCost: monthlyCost.toFixed(0),
culturalCause: 'Poor leadership, toxic culture, lack of training/support, no recognition systems'
});
}

return { issues, totalMonthlyCost: totalMonthlyCost.toFixed(0) };
```

};

const dysfunctionAnalysis = calculateMonthlyCostOfDysfunction();

const handleInputChange = (field, value) => {
setData({ …data, [field]: parseFloat(value) || 0 });
};

return (
<div className="max-w-7xl mx-auto p-6 bg-gray-50 min-h-screen">
<div className="mb-6">
<h1 className="text-3xl font-bold text-gray-900 mb-2">Prime Cost Analysis Dashboard</h1>
<p className="text-gray-600">Connect operational culture to financial performance</p>
</div>

```
{/* Input Section */}
<div className="bg-white rounded-lg shadow-lg p-6 mb-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">Monthly Data Input</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Total Revenue</label>
<input
type="number"
value={data.revenue}
onChange={(e) => handleInputChange('revenue', e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Total COGS</label>
<input
type="number"
value={data.cogs}
onChange={(e) => handleInputChange('cogs', e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Total Labor Cost</label>
<input
type="number"
value={data.laborCost}
onChange={(e) => handleInputChange('laborCost', e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Cover Count</label>
<input
type="number"
value={data.coverCount}
onChange={(e) => handleInputChange('coverCount', e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Employee Count</label>
<input
type="number"
value={data.employeeCount}
onChange={(e) => handleInputChange('employeeCount', e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Turnover Rate (%)</label>
<input
type="number"
value={data.turnoverRate}
onChange={(e) => handleInputChange('turnoverRate', e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
</div>

{/* Key Metrics Dashboard */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
<div className={`rounded-lg shadow-lg p-6 border-2 ${getStatusColor(parseFloat(metrics.primeCostPercent), 60, 65)}`}>
<div className="flex items-center justify-between mb-2">
<h3 className="text-lg font-semibold">Prime Cost</h3>
{getStatusIcon(parseFloat(metrics.primeCostPercent), 60, 65)}
</div>
<div className="text-4xl font-bold mb-2">{metrics.primeCostPercent}%</div>
<div className="text-sm opacity-80 mb-2">${metrics.primeCost.toLocaleString()}</div>
<div className="text-xs font-medium">Target: 60-65% | Acceptable: up to 68%</div>
</div>

<div className={`rounded-lg shadow-lg p-6 border-2 ${getStatusColor(parseFloat(metrics.cogsPercent), 28, 30)}`}>
<div className="flex items-center justify-between mb-2">
<h3 className="text-lg font-semibold">COGS %</h3>
<ShoppingCart className="w-5 h-5" />
</div>
<div className="text-4xl font-bold mb-2">{metrics.cogsPercent}%</div>
<div className="text-sm opacity-80 mb-2">${data.cogs.toLocaleString()}</div>
<div className="text-xs font-medium">Target: 28-30% | Acceptable: up to 32%</div>
</div>

<div className={`rounded-lg shadow-lg p-6 border-2 ${getStatusColor(parseFloat(metrics.laborPercent), 30, 35)}`}>
<div className="flex items-center justify-between mb-2">
<h3 className="text-lg font-semibold">Labor %</h3>
<Users className="w-5 h-5" />
</div>
<div className="text-4xl font-bold mb-2">{metrics.laborPercent}%</div>
<div className="text-sm opacity-80 mb-2">${data.laborCost.toLocaleString()}</div>
<div className="text-xs font-medium">Target: 30-35% | Acceptable: up to 38%</div>
</div>
</div>

{/* Additional Metrics */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
<div className="bg-white rounded-lg shadow p-4">
<div className="text-sm text-gray-600 mb-1">Labor Per Cover</div>
<div className="text-2xl font-bold text-gray-900">${metrics.laborPerCover}</div>
</div>
<div className="bg-white rounded-lg shadow p-4">
<div className="text-sm text-gray-600 mb-1">Revenue Per Employee</div>
<div className="text-2xl font-bold text-gray-900">${metrics.revenuePerEmployee}</div>
</div>
<div className="bg-white rounded-lg shadow p-4">
<div className="text-sm text-gray-600 mb-1">Average Check</div>
<div className="text-2xl font-bold text-gray-900">${data.avgCheck}</div>
</div>
<div className={`rounded-lg shadow p-4 ${data.turnoverRate > 30 ? 'bg-red-50' : 'bg-green-50'}`}>
<div className="text-sm text-gray-600 mb-1">Turnover Rate</div>
<div className={`text-2xl font-bold ${data.turnoverRate > 30 ? 'text-red-600' : 'text-green-600'}`}>
{data.turnoverRate}%
</div>
</div>
</div>

{/* Cost of Dysfunction Analysis */}
{dysfunctionAnalysis.issues.length > 0 && (
<div className="bg-red-50 border-2 border-red-200 rounded-lg shadow-lg p-6 mb-6">
<div className="flex items-start gap-3 mb-4">
<AlertTriangle className="w-6 h-6 text-red-600 flex-shrink-0 mt-1" />
<div>
<h2 className="text-2xl font-bold text-red-900 mb-2">
Monthly Cost of Cultural Dysfunction
</h2>
<p className="text-red-700 mb-4">
Your operational culture issues are costing you approximately{' '}
<span className="text-3xl font-bold">${parseInt(dysfunctionAnalysis.totalMonthlyCost).toLocaleString()}</span>
{' '}per month
</p>
<p className="text-red-700 font-semibold">
Annual impact: ${(parseInt(dysfunctionAnalysis.totalMonthlyCost) * 12).toLocaleString()}
</p>
</div>
</div>

<div className="space-y-4">
{dysfunctionAnalysis.issues.map((issue, idx) => (
<div key={idx} className="bg-white rounded-lg p-4 border border-red-200">
<div className="flex justify-between items-start mb-2">
<h3 className="font-semibold text-gray-900">{issue.issue}</h3>
<span className="text-red-600 font-bold">${parseInt(issue.monthlyCost).toLocaleString()}/mo</span>
</div>
<div className="grid grid-cols-2 gap-2 mb-2 text-sm">
<div>
<span className="text-gray-600">Current: </span>
<span className="font-semibold text-red-600">{issue.current}</span>
</div>
<div>
<span className="text-gray-600">Target: </span>
<span className="font-semibold text-green-600">{issue.target}</span>
</div>
</div>
<div className="text-sm text-gray-700 bg-gray-50 p-3 rounded">
<span className="font-semibold">Root Cultural Cause: </span>
{issue.culturalCause}
</div>
</div>
))}
</div>
</div>
)}

{/* Breakdown Analysis */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<div className="bg-white rounded-lg shadow-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">COGS Breakdown</h3>
<div className="space-y-3">
<div className="flex justify-between items-center">
<span className="text-gray-700">Food Cost</span>
<div className="text-right">
<div className="font-bold text-gray-900">${data.food.toLocaleString()}</div>
<div className="text-sm text-gray-600">{((data.food / data.revenue) * 100).toFixed(1)}%</div>
</div>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-700">Beverage Cost</span>
<div className="text-right">
<div className="font-bold text-gray-900">${data.beverage.toLocaleString()}</div>
<div className="text-sm text-gray-600">{((data.beverage / data.revenue) * 100).toFixed(1)}%</div>
</div>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-700">Supplies</span>
<div className="text-right">
<div className="font-bold text-gray-900">${data.supplies.toLocaleString()}</div>
<div className="text-sm text-gray-600">{((data.supplies / data.revenue) * 100).toFixed(1)}%</div>
</div>
</div>
</div>
</div>

<div className="bg-white rounded-lg shadow-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">Labor Breakdown</h3>
<div className="space-y-3">
<div className="flex justify-between items-center">
<span className="text-gray-700">Management</span>
<div className="text-right">
<div className="font-bold text-gray-900">${data.managementLabor.toLocaleString()}</div>
<div className="text-sm text-gray-600">{((data.managementLabor / data.revenue) * 100).toFixed(1)}%</div>
</div>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-700">Hourly Labor</span>
<div className="text-right">
<div className="font-bold text-gray-900">${data.hourlyLabor.toLocaleString()}</div>
<div className="text-sm text-gray-600">{((data.hourlyLabor / data.revenue) * 100).toFixed(1)}%</div>
</div>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-700">Benefits/Taxes</span>
<div className="text-right">
<div className="font-bold text-gray-900">${data.benefits.toLocaleString()}</div>
<div className="text-sm text-gray-600">{((data.benefits / data.revenue) * 100).toFixed(1)}%</div>
</div>
</div>
</div>
</div>
</div>

{/* Action Items */}
<div className="bg-blue-50 border-2 border-blue-200 rounded-lg shadow-lg p-6">
<h2 className="text-xl font-semibold text-gray-900 mb-3">Diagnostic Next Steps</h2>
<div className="space-y-2 text-sm text-gray-700">
<p>✓ Compare these financial results with your Culture Assessment scores</p>
<p>✓ Low culture scores in "Operational Standards" typically correlate with high COGS</p>
<p>✓ Low scores in "Leadership & Accountability" drive high labor costs and turnover</p>
<p>✓ Poor "Financial Accountability" scores mean staff don't understand how their actions impact these numbers</p>
<p className="font-semibold text-blue-900 mt-3">
The gap between where you are and industry benchmarks represents the monthly cost of cultural dysfunction.
</p>
</div>
</div>
</div>
```

);
};

export default PrimeCostDashboard;
Previous
Previous

Scope & Vision