Refactor UI for improved visuals

- Fixed tag alignment in JobCard.
- Styled category headers with their respective colors and removed the arrow icon.
- Improved the display of "expenditure", "income", and "profit" information.
This commit is contained in:
gpt-engineer-app[bot]
2025-07-07 11:23:14 +00:00
parent fa03bdb207
commit 2a1382bf2e
2 changed files with 48 additions and 65 deletions

View File

@@ -220,12 +220,14 @@ const JobCard: React.FC<JobCardProps> = ({
<CardHeader className="flex-shrink-0">
<div className="flex justify-between items-start">
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-2">
<div className="flex items-center gap-3 mb-2">
<CardTitle className="text-blue-400 truncate">{job.outputItem}</CardTitle>
<Badge className={`${getStatusColor(job.status)} text-white flex-shrink-0`}>
<div className="flex items-center gap-2 flex-shrink-0">
<Badge className={`${getStatusColor(job.status)} text-white`}>
{job.status}
</Badge>
</div>
</div>
<p className="text-gray-400 text-sm">
Quantity: {job.outputQuantity.toLocaleString()}
<span className="ml-4">
@@ -258,7 +260,7 @@ const JobCard: React.FC<JobCardProps> = ({
</span>
</p>
</div>
<div className="flex flex-col gap-2 flex-shrink-0">
<div className="flex flex-col gap-2 flex-shrink-0 items-end">
<div className="flex gap-2">
<Button
variant="outline"
@@ -276,7 +278,7 @@ const JobCard: React.FC<JobCardProps> = ({
Delete
</Button>
</div>
<div className="flex gap-1 justify-end">
<div className="flex gap-1">
<Button
variant="ghost"
size="sm"
@@ -360,62 +362,42 @@ const JobCard: React.FC<JobCardProps> = ({
<div className="flex-1" />
<div className="grid grid-cols-3 gap-4 pt-4 border-t border-gray-700 flex-shrink-0">
<div className="text-center">
<div className="flex items-center justify-center gap-1 text-red-400">
<TrendingDown className="w-4 h-4" />
<span className="text-sm">Expenditure</span>
</div>
<div className="font-semibold text-sm">{formatISK(totalExpenditure)}</div>
<div className="grid grid-cols-3 gap-3 pt-4 border-t border-gray-700 flex-shrink-0">
<div className="text-center space-y-1">
<div className="text-xs font-medium text-red-400 uppercase tracking-wide">Costs</div>
<div className="text-lg font-bold text-red-400">{formatISK(totalExpenditure)}</div>
{job.projectedCost > 0 && (
<div className="text-xs text-gray-400">
vs Projected: {formatISK(job.projectedCost)}
<Badge
variant={totalExpenditure <= job.projectedCost ? 'default' : 'destructive'}
className="ml-1 text-xs"
>
{((totalExpenditure / job.projectedCost) * 100).toFixed(1)}%
</Badge>
vs {formatISK(job.projectedCost)}
<div className={`text-xs font-medium ${totalExpenditure <= job.projectedCost ? 'text-green-400' : 'text-red-400'}`}>
{((totalExpenditure / job.projectedCost) * 100).toFixed(0)}%
</div>
</div>
)}
</div>
<div className="text-center">
<div className="flex items-center justify-center gap-1 text-green-400">
<TrendingUp className="w-4 h-4" />
<span className="text-sm">Income</span>
</div>
<div className="font-semibold text-sm">{formatISK(totalIncome)}</div>
<div className="text-center space-y-1">
<div className="text-xs font-medium text-green-400 uppercase tracking-wide">Revenue</div>
<div className="text-lg font-bold text-green-400">{formatISK(totalIncome)}</div>
{job.projectedRevenue > 0 && (
<div className="text-xs text-gray-400">
vs Projected: {formatISK(job.projectedRevenue)}
<Badge
variant={totalIncome >= job.projectedRevenue ? 'default' : 'destructive'}
className="ml-1 text-xs"
>
{((totalIncome / job.projectedRevenue) * 100).toFixed(1)}%
</Badge>
vs {formatISK(job.projectedRevenue)}
<div className={`text-xs font-medium ${totalIncome >= job.projectedRevenue ? 'text-green-400' : 'text-red-400'}`}>
{((totalIncome / job.projectedRevenue) * 100).toFixed(0)}%
</div>
</div>
)}
</div>
<div className="text-center">
<div className="flex items-center justify-center gap-1 text-gray-400">
<span className="text-sm">Profit</span>
</div>
<div className={`font-semibold text-sm ${profit >= 0 ? 'text-green-400' : 'text-red-400'}`}>
<div className="text-center space-y-1">
<div className="text-xs font-medium text-gray-300 uppercase tracking-wide">Profit</div>
<div className={`text-lg font-bold ${profit >= 0 ? 'text-green-400' : 'text-red-400'}`}>
{formatISK(profit)}
<Badge variant={profit >= 0 ? 'default' : 'destructive'} className="ml-1 text-xs">
{margin.toFixed(1)}%
</Badge>
</div>
<div className={`text-xs font-medium ${profit >= 0 ? 'text-green-400' : 'text-red-400'}`}>
{margin.toFixed(1)}% margin
</div>
{job.projectedRevenue > 0 && job.projectedCost > 0 && (
<div className="text-xs text-gray-400">
vs Projected: {formatISK(job.projectedRevenue - job.projectedCost)}
<Badge
variant={profit >= (job.projectedRevenue - job.projectedCost) ? 'default' : 'destructive'}
className="ml-1 text-xs"
>
{((profit / (job.projectedRevenue - job.projectedCost)) * 100).toFixed(1)}%
</Badge>
vs {formatISK(job.projectedRevenue - job.projectedCost)}
</div>
)}
</div>

View File

@@ -295,18 +295,18 @@ const Index = () => {
{Object.entries(jobGroups).map(([status, statusJobs]) => (
<div key={status} className="space-y-4">
<div
className="flex items-center gap-3 cursor-pointer select-none p-3 rounded-lg hover:bg-gray-800/50 transition-colors"
className={`${getStatusColor(status)} rounded-lg cursor-pointer select-none transition-colors hover:opacity-90`}
onClick={() => toggleGroup(status)}
>
<div className={`transform transition-transform text-xl text-gray-400 ${collapsedGroups[status] ? '' : 'rotate-90'}`}>
</div>
<div className="flex items-center justify-between p-4">
<h3 className="text-xl font-semibold text-white flex items-center gap-3">
<Badge className={`${getStatusColor(status)} text-white px-3 py-1 text-base`}>
{status}
</Badge>
<span className="text-gray-400 text-lg">({statusJobs.length} jobs)</span>
<span>{status}</span>
<span className="text-gray-200 text-lg">({statusJobs.length} jobs)</span>
</h3>
<div className={`text-white text-lg transition-transform ${collapsedGroups[status] ? '-rotate-90' : 'rotate-0'}`}>
</div>
</div>
</div>
{!collapsedGroups[status] && (
@@ -331,17 +331,18 @@ const Index = () => {
{trackedJobs.length > 0 && (
<div className="space-y-4 mt-8 pt-8 border-t border-gray-700">
<div
className="flex items-center gap-3 cursor-pointer select-none p-3 rounded-lg hover:bg-gray-800/50 transition-colors"
className="bg-cyan-600 rounded-lg cursor-pointer select-none transition-colors hover:opacity-90"
onClick={() => toggleGroup('Tracked')}
>
<div className={`transform transition-transform text-xl text-gray-400 ${collapsedGroups['Tracked'] ? '' : 'rotate-90'}`}>
</div>
<div className="flex items-center justify-between p-4">
<h2 className="text-xl font-bold text-white flex items-center gap-3">
<span className="w-2.5 h-2.5 rounded-full bg-cyan-600"></span>
Tracked Transactions
<span className="text-gray-400 text-lg">({trackedJobs.length} jobs)</span>
<span>Tracked Transactions</span>
<span className="text-gray-200 text-lg">({trackedJobs.length} jobs)</span>
</h2>
<div className={`text-white text-lg transition-transform ${collapsedGroups['Tracked'] ? '-rotate-90' : 'rotate-0'}`}>
</div>
</div>
</div>
{!collapsedGroups['Tracked'] && (