Refactor JobCardMetrics display
Consistently style the revenue progress and performance indicator, either with or without a backdrop/icon.
This commit is contained in:
@@ -84,7 +84,7 @@ const JobCardMetrics: React.FC<JobCardMetricsProps> = ({ job }) => {
|
|||||||
</div>
|
</div>
|
||||||
</JobTransactionPopover>
|
</JobTransactionPopover>
|
||||||
{job.projectedCost > 0 && (
|
{job.projectedCost > 0 && (
|
||||||
<div className="text-xs text-gray-400">
|
<div className="text-xs text-gray-400 space-y-1">
|
||||||
vs {editingField === 'projectedCost' ? (
|
vs {editingField === 'projectedCost' ? (
|
||||||
<Input
|
<Input
|
||||||
value={tempValues.projectedCost || ''}
|
value={tempValues.projectedCost || ''}
|
||||||
@@ -105,8 +105,15 @@ const JobCardMetrics: React.FC<JobCardMetricsProps> = ({ job }) => {
|
|||||||
{formatISK(job.projectedCost)}
|
{formatISK(job.projectedCost)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<div className={`text-xs font-medium ${totalExpenditure <= job.projectedCost ? 'text-green-400' : 'text-red-400'}`}>
|
<div
|
||||||
{((totalExpenditure / job.projectedCost) * 100).toFixed(0)}%
|
className={`text-xs font-medium px-2 py-0.5 rounded-full inline-block ${
|
||||||
|
totalExpenditure <= job.projectedCost
|
||||||
|
? 'bg-green-900/50 text-green-400'
|
||||||
|
: 'bg-red-900/50 text-red-400'
|
||||||
|
}`}
|
||||||
|
title={`Cost efficiency: ${((totalExpenditure / job.projectedCost) * 100).toFixed(1)}% of projected cost`}
|
||||||
|
>
|
||||||
|
{totalExpenditure <= job.projectedCost ? '✅' : '⚠️'} {((totalExpenditure / job.projectedCost) * 100).toFixed(0)}%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -119,7 +126,7 @@ const JobCardMetrics: React.FC<JobCardMetricsProps> = ({ job }) => {
|
|||||||
</div>
|
</div>
|
||||||
</JobTransactionPopover>
|
</JobTransactionPopover>
|
||||||
{job.projectedRevenue > 0 && (
|
{job.projectedRevenue > 0 && (
|
||||||
<div className="text-xs text-gray-400">
|
<div className="text-xs text-gray-400 space-y-1">
|
||||||
vs {editingField === 'projectedRevenue' ? (
|
vs {editingField === 'projectedRevenue' ? (
|
||||||
<Input
|
<Input
|
||||||
value={tempValues.projectedRevenue || ''}
|
value={tempValues.projectedRevenue || ''}
|
||||||
@@ -140,25 +147,34 @@ const JobCardMetrics: React.FC<JobCardMetricsProps> = ({ job }) => {
|
|||||||
{formatISK(job.projectedRevenue)}
|
{formatISK(job.projectedRevenue)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<div className={`text-xs font-medium ${totalIncome >= job.projectedRevenue ? 'text-green-400' : 'text-red-400'}`}>
|
<div className="flex justify-center gap-2">
|
||||||
{((totalIncome / job.projectedRevenue) * 100).toFixed(0)}%
|
<div
|
||||||
|
className={`text-xs font-medium px-2 py-0.5 rounded-full inline-block ${
|
||||||
|
totalIncome >= job.projectedRevenue
|
||||||
|
? 'bg-green-900/50 text-green-400'
|
||||||
|
: 'bg-yellow-900/50 text-yellow-400'
|
||||||
|
}`}
|
||||||
|
title={`Revenue progress: ${((totalIncome / job.projectedRevenue) * 100).toFixed(1)}% of projected revenue`}
|
||||||
|
>
|
||||||
|
{totalIncome >= job.projectedRevenue ? '🎯' : '📊'} {((totalIncome / job.projectedRevenue) * 100).toFixed(0)}%
|
||||||
|
</div>
|
||||||
|
{showPerformanceIndicator && (
|
||||||
|
<div
|
||||||
|
className={`text-xs font-medium px-2 py-0.5 rounded-full inline-block ${
|
||||||
|
performancePercentage >= 100
|
||||||
|
? 'bg-green-900/50 text-green-400'
|
||||||
|
: performancePercentage >= 90
|
||||||
|
? 'bg-yellow-900/50 text-yellow-400'
|
||||||
|
: 'bg-red-900/50 text-red-400'
|
||||||
|
}`}
|
||||||
|
title={`Performance: ${formatISK(actualRevenuePerItem)}/item vs ${formatISK(expectedRevenuePerItem)}/item expected (${performancePercentage.toFixed(1)}%)`}
|
||||||
|
>
|
||||||
|
{performancePercentage >= 100 ? '📈' : performancePercentage >= 90 ? '⚠️' : '📉'} {performancePercentage.toFixed(0)}%
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{showPerformanceIndicator && (
|
|
||||||
<div
|
|
||||||
className={`text-xs font-medium px-2 py-0.5 rounded-full inline-block ${
|
|
||||||
performancePercentage >= 100
|
|
||||||
? 'bg-green-900/50 text-green-400'
|
|
||||||
: performancePercentage >= 90
|
|
||||||
? 'bg-yellow-900/50 text-yellow-400'
|
|
||||||
: 'bg-red-900/50 text-red-400'
|
|
||||||
}`}
|
|
||||||
title={`Performance: ${formatISK(actualRevenuePerItem)}/item vs ${formatISK(expectedRevenuePerItem)}/item expected (${performancePercentage.toFixed(1)}%)`}
|
|
||||||
>
|
|
||||||
{performancePercentage >= 100 ? '📈' : performancePercentage >= 90 ? '⚠️' : '📉'} {performancePercentage.toFixed(0)}%
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="text-center space-y-1">
|
<div className="text-center space-y-1">
|
||||||
<div className="text-xs font-medium text-gray-300 uppercase tracking-wide">Profit</div>
|
<div className="text-xs font-medium text-gray-300 uppercase tracking-wide">Profit</div>
|
||||||
|
Reference in New Issue
Block a user