fix(ui): light mode color corrections for LeadProjectPage and OwnerProjectDetail

- Replace hardcoded dark-only NEO_PANEL_CLASS bg with dark: prefixed variants so SpotlightCard's bg-white shows through in light mode
- Add light mode fallbacks to all NEON color constants (sky/amber/orange/green/red solid colors replace neon glows)
- Fix progress bar and stepper tracks from bg-black/80 to bg-zinc-200 dark:bg-black/80
- Update stepper node colors to use theme-aware border/text/bg classes
- Fix all section header text-white → text-zinc-900 dark:text-white throughout NeoCard content
- Replace bg-black/30, bg-white/[0.03], border-white/5, divide-white/5 inner elements with light mode equivalents
- Fix table headers (bg-[#18181b]/80 → bg-zinc-100 dark:), row hover states, and body text colors
- Fix action buttons, doc rows, timeline items, and activity feed for proper light mode rendering
This commit is contained in:
Satyam-Rastogi
2026-04-13 14:01:07 +05:30
parent c584d918ac
commit e96dffb3ec
2 changed files with 222 additions and 222 deletions
+89 -89
View File
@@ -19,11 +19,11 @@ import {
} from 'lucide-react'; } from 'lucide-react';
// ── Neomorphic constants (mirrors OwnerProjectDetail) ───────────────────────── // ── Neomorphic constants (mirrors OwnerProjectDetail) ─────────────────────────
const NEO_PANEL_CLASS = "bg-zinc-900/60 backdrop-blur-3xl border border-white/5 shadow-[8px_8px_16px_rgba(0,0,0,0.6),-8px_-8px_16px_rgba(255,255,255,0.02)] rounded-3xl relative overflow-hidden transition-all duration-300"; const NEO_PANEL_CLASS = "dark:bg-zinc-900/60 dark:backdrop-blur-3xl border border-zinc-200 dark:border-white/5 dark:shadow-[8px_8px_16px_rgba(0,0,0,0.6),-8px_-8px_16px_rgba(255,255,255,0.02)] rounded-3xl relative overflow-hidden transition-all duration-300";
const NEON_GREEN = "text-[#39ff14] drop-shadow-[0_0_8px_rgba(57,255,20,0.4)]"; const NEON_GREEN = "text-green-600 dark:text-[#39ff14] dark:drop-shadow-[0_0_8px_rgba(57,255,20,0.4)]";
const NEON_GOLD = "text-[#fda913] drop-shadow-[0_0_8px_rgba(253,169,19,0.4)]"; const NEON_GOLD = "text-amber-600 dark:text-[#fda913] dark:drop-shadow-[0_0_8px_rgba(253,169,19,0.4)]";
const NEON_ORANGE = "text-[#ff4500] drop-shadow-[0_0_8px_rgba(255,69,0,0.4)]"; const NEON_ORANGE = "text-orange-600 dark:text-[#ff4500] dark:drop-shadow-[0_0_8px_rgba(255,69,0,0.4)]";
const NEON_BLUE = "text-[#00f0ff] drop-shadow-[0_0_8px_rgba(0,240,255,0.4)]"; const NEON_BLUE = "text-sky-600 dark:text-[#00f0ff] dark:drop-shadow-[0_0_8px_rgba(0,240,255,0.4)]";
function formatCurrency(n) { function formatCurrency(n) {
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 }).format(n || 0); return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 }).format(n || 0);
@@ -62,7 +62,7 @@ function NeoCard({ children, className = '', spotlightColor = 'rgba(255,255,255,
// ── Animated progress bar ───────────────────────────────────────────────────── // ── Animated progress bar ─────────────────────────────────────────────────────
function NeoProgress({ pct, color = '#3B82F6', height = 'h-1.5' }) { function NeoProgress({ pct, color = '#3B82F6', height = 'h-1.5' }) {
return ( return (
<div className={`${height} w-full bg-black/80 rounded-full border border-white/5 relative overflow-hidden`}> <div className={`${height} w-full bg-zinc-200 dark:bg-black/80 rounded-full border border-zinc-200 dark:border-white/5 relative overflow-hidden`}>
<motion.div <motion.div
initial={{ width: 0 }} initial={{ width: 0 }}
animate={{ width: `${Math.min(pct, 100)}%` }} animate={{ width: `${Math.min(pct, 100)}%` }}
@@ -83,7 +83,7 @@ function StageMoverDropdown({ lead, columns, onStageChange }) {
<div className="relative"> <div className="relative">
<button <button
onClick={() => setOpen(v => !v)} onClick={() => setOpen(v => !v)}
className="flex items-center gap-2 px-4 py-2 rounded-xl border border-white/10 bg-white/5 hover:bg-white/10 text-zinc-200 text-sm font-semibold transition-colors" className="flex items-center gap-2 px-4 py-2 rounded-xl border border-zinc-300 dark:border-white/10 bg-zinc-100 dark:bg-white/5 hover:bg-zinc-200 dark:hover:bg-white/10 text-zinc-700 dark:text-zinc-200 text-sm font-semibold transition-colors"
> >
Move Stage <ChevronDown size={13} /> Move Stage <ChevronDown size={13} />
</button> </button>
@@ -138,13 +138,13 @@ function StageActivityItem({ entry, isLast }) {
isRegress ? <ArrowDownLeft size={13} style={{ color: dotColor }} /> : isRegress ? <ArrowDownLeft size={13} style={{ color: dotColor }} /> :
<ArrowUpRight size={13} style={{ color: dotColor }} />} <ArrowUpRight size={13} style={{ color: dotColor }} />}
</div> </div>
{!isLast && <div className="w-px flex-1 bg-white/5 my-2 min-h-[20px]" />} {!isLast && <div className="w-px flex-1 bg-zinc-200 dark:bg-white/5 my-2 min-h-[20px]" />}
</div> </div>
<div className={`flex-1 min-w-0 ${!isLast ? 'pb-5' : ''}`}> <div className={`flex-1 min-w-0 ${!isLast ? 'pb-5' : ''}`}>
<div className="bg-white/[0.03] border border-white/[0.07] rounded-xl px-4 py-3 hover:bg-white/[0.06] transition-colors"> <div className="bg-zinc-50 dark:bg-white/[0.03] border border-zinc-200 dark:border-white/[0.07] rounded-xl px-4 py-3 hover:bg-zinc-100 dark:hover:bg-white/[0.06] transition-colors">
<div className="mb-0.5"> <div className="mb-0.5">
{entry.from ? ( {entry.from ? (
<p className="text-sm font-semibold text-zinc-200"> <p className="text-sm font-semibold text-zinc-700 dark:text-zinc-200">
<span className="text-zinc-500">{entry.from}</span> <span className="text-zinc-500">{entry.from}</span>
<ArrowRight size={12} className="inline mx-1.5 text-zinc-600" /> <ArrowRight size={12} className="inline mx-1.5 text-zinc-600" />
<span style={{ color: dotColor }}>{entry.to}</span> <span style={{ color: dotColor }}>{entry.to}</span>
@@ -154,7 +154,7 @@ function StageActivityItem({ entry, isLast }) {
)} )}
<p className="text-xs text-zinc-600 mt-0.5">by <span className="font-medium text-zinc-400">{entry.by}</span> · {formatDate(entry.date)}</p> <p className="text-xs text-zinc-600 mt-0.5">by <span className="font-medium text-zinc-400">{entry.by}</span> · {formatDate(entry.date)}</p>
</div> </div>
{entry.note && <p className="text-sm text-zinc-400 leading-relaxed mt-2 pt-2 border-t border-white/5">{entry.note}</p>} {entry.note && <p className="text-sm text-zinc-500 dark:text-zinc-400 leading-relaxed mt-2 pt-2 border-t border-zinc-200 dark:border-white/5">{entry.note}</p>}
</div> </div>
</div> </div>
</div> </div>
@@ -390,10 +390,10 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(0,240,255,0.1)" className="lg:col-span-2"> <NeoCard spotlightColor="rgba(0,240,255,0.1)" className="lg:col-span-2">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<Milestone className={NEON_BLUE} size={20} /> <Milestone className={NEON_BLUE} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Project Progression</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Project Progression</h3>
</div> </div>
<div className="relative pt-8 pb-4"> <div className="relative pt-8 pb-4">
<div className="absolute top-[38px] left-[5%] right-[5%] h-1 bg-zinc-800 rounded-full z-0" /> <div className="absolute top-[38px] left-[5%] right-[5%] h-1 bg-zinc-200 dark:bg-zinc-800 rounded-full z-0" />
<motion.div <motion.div
initial={{ width: 0 }} animate={{ width: `${completionPct}%` }} transition={{ duration: 1.5 }} initial={{ width: 0 }} animate={{ width: `${completionPct}%` }} transition={{ duration: 1.5 }}
className="absolute top-[38px] left-[5%] h-1 bg-gradient-to-r from-blue-600 to-[#00f0ff] rounded-full shadow-[0_0_10px_#00f0ff] z-0" className="absolute top-[38px] left-[5%] h-1 bg-gradient-to-r from-blue-600 to-[#00f0ff] rounded-full shadow-[0_0_10px_#00f0ff] z-0"
@@ -403,10 +403,10 @@ export default function LeadProjectPage() {
const isActive = (i * 25) <= completionPct; const isActive = (i * 25) <= completionPct;
return ( return (
<div key={i} className="flex flex-col items-center gap-3 w-20"> <div key={i} className="flex flex-col items-center gap-3 w-20">
<div className={`w-8 h-8 rounded-full flex items-center justify-center border-2 shadow-lg transition-colors ${isActive ? 'bg-zinc-900 border-[#00f0ff] text-[#00f0ff] shadow-[0_0_15px_rgba(0,240,255,0.4)]' : 'bg-black border-zinc-700 text-zinc-600'}`}> <div className={`w-8 h-8 rounded-full flex items-center justify-center border-2 shadow-lg transition-colors ${isActive ? 'bg-zinc-50 dark:bg-zinc-900 border-sky-500 dark:border-[#00f0ff] text-sky-500 dark:text-[#00f0ff] dark:shadow-[0_0_15px_rgba(0,240,255,0.4)]' : 'bg-white dark:bg-black border-zinc-300 dark:border-zinc-700 text-zinc-400 dark:text-zinc-600'}`}>
{isActive ? <CheckCircle size={14} /> : <span className="w-2 h-2 rounded-full bg-zinc-700" />} {isActive ? <CheckCircle size={14} /> : <span className="w-2 h-2 rounded-full bg-zinc-300 dark:bg-zinc-700" />}
</div> </div>
<span className={`text-[10px] text-center font-bold tracking-wide uppercase leading-tight ${isActive ? 'text-white' : 'text-zinc-600'}`}>{step}</span> <span className={`text-[10px] text-center font-bold tracking-wide uppercase leading-tight ${isActive ? 'text-zinc-900 dark:text-white' : 'text-zinc-500 dark:text-zinc-600'}`}>{step}</span>
</div> </div>
); );
})} })}
@@ -419,7 +419,7 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(253,169,19,0.08)"> <NeoCard spotlightColor="rgba(253,169,19,0.08)">
<div className="flex items-center gap-3 mb-5"> <div className="flex items-center gap-3 mb-5">
<User className={NEON_GOLD} size={20} /> <User className={NEON_GOLD} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Contact & Contractor</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Contact & Contractor</h3>
</div> </div>
<div className="space-y-3"> <div className="space-y-3">
{[ {[
@@ -431,11 +431,11 @@ export default function LeadProjectPage() {
{ icon: Phone, label: 'Crew Phone', value: proj.contractorPhone }, { icon: Phone, label: 'Crew Phone', value: proj.contractorPhone },
{ icon: Shield, label: 'Assigned Agent', value: lead.assignedAgentName }, { icon: Shield, label: 'Assigned Agent', value: lead.assignedAgentName },
].map(({ icon: Icon, label, value }) => value ? ( ].map(({ icon: Icon, label, value }) => value ? (
<div key={label} className="flex items-start gap-3 py-2 border-b border-white/[0.04] last:border-0"> <div key={label} className="flex items-start gap-3 py-2 border-b border-zinc-100 dark:border-white/[0.04] last:border-0">
<Icon size={13} className="text-zinc-600 shrink-0 mt-0.5" /> <Icon size={13} className="text-zinc-600 shrink-0 mt-0.5" />
<div> <div>
<p className="text-[10px] text-zinc-600">{label}</p> <p className="text-[10px] text-zinc-600">{label}</p>
<p className="text-sm text-zinc-200 font-medium">{value}</p> <p className="text-sm text-zinc-700 dark:text-zinc-200 font-medium">{value}</p>
</div> </div>
</div> </div>
) : null)} ) : null)}
@@ -445,7 +445,7 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(57,255,20,0.06)"> <NeoCard spotlightColor="rgba(57,255,20,0.06)">
<div className="flex items-center gap-3 mb-5"> <div className="flex items-center gap-3 mb-5">
<AlertCircle className={NEON_ORANGE} size={20} /> <AlertCircle className={NEON_ORANGE} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Open Items</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Open Items</h3>
</div> </div>
<div className="grid grid-cols-2 gap-3 mb-5"> <div className="grid grid-cols-2 gap-3 mb-5">
{[ {[
@@ -454,16 +454,16 @@ export default function LeadProjectPage() {
{ label: 'Pending Invoices', count: (proj.invoices || []).filter(i => i.status === 'pending').length, color: '#00f0ff' }, { label: 'Pending Invoices', count: (proj.invoices || []).filter(i => i.status === 'pending').length, color: '#00f0ff' },
{ label: 'Milestones Done', count: (proj.milestones || []).filter(m => m.status === 'completed').length + '/' + (proj.milestones?.length || 0), color: '#39ff14' }, { label: 'Milestones Done', count: (proj.milestones || []).filter(m => m.status === 'completed').length + '/' + (proj.milestones?.length || 0), color: '#39ff14' },
].map(item => ( ].map(item => (
<div key={item.label} className="bg-black/30 border border-white/5 rounded-2xl p-4 text-center"> <div key={item.label} className="bg-zinc-100 dark:bg-black/30 border border-zinc-200 dark:border-white/5 rounded-2xl p-4 text-center">
<p className="text-2xl font-black" style={{ color: item.color, fontFamily: 'Barlow Condensed, sans-serif' }}>{item.count}</p> <p className="text-2xl font-black" style={{ color: item.color, fontFamily: 'Barlow Condensed, sans-serif' }}>{item.count}</p>
<p className="text-[10px] text-zinc-600 mt-1">{item.label}</p> <p className="text-[10px] text-zinc-500 dark:text-zinc-600 mt-1">{item.label}</p>
</div> </div>
))} ))}
</div> </div>
{lead.notes && ( {lead.notes && (
<div className="p-4 bg-amber-500/5 border border-amber-500/10 rounded-2xl"> <div className="p-4 bg-amber-500/5 border border-amber-500/10 rounded-2xl">
<p className="text-[10px] font-bold text-amber-500/70 uppercase tracking-widest mb-1.5">Field Notes</p> <p className="text-[10px] font-bold text-amber-500/70 uppercase tracking-widest mb-1.5">Field Notes</p>
<p className="text-sm text-zinc-300 leading-relaxed">{lead.notes}</p> <p className="text-sm text-zinc-600 dark:text-zinc-300 leading-relaxed">{lead.notes}</p>
</div> </div>
)} )}
</NeoCard> </NeoCard>
@@ -477,7 +477,7 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(59,130,246,0.08)"> <NeoCard spotlightColor="rgba(59,130,246,0.08)">
<div className="flex items-center gap-3 mb-5"> <div className="flex items-center gap-3 mb-5">
<User className={NEON_BLUE} size={20} /> <User className={NEON_BLUE} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Contact</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Contact</h3>
</div> </div>
{[ {[
{ icon: User, label: 'Name', value: lead.name }, { icon: User, label: 'Name', value: lead.name },
@@ -488,11 +488,11 @@ export default function LeadProjectPage() {
{ icon: Shield, label: 'Category', value: lead.insuranceType }, { icon: Shield, label: 'Category', value: lead.insuranceType },
{ icon: User, label: 'Assigned Agent', value: lead.assignedAgentName }, { icon: User, label: 'Assigned Agent', value: lead.assignedAgentName },
].map(({ icon: Icon, label, value }) => value ? ( ].map(({ icon: Icon, label, value }) => value ? (
<div key={label} className="flex items-start gap-3 py-2.5 border-b border-white/[0.04] last:border-0"> <div key={label} className="flex items-start gap-3 py-2.5 border-b border-zinc-100 dark:border-white/[0.04] last:border-0">
<Icon size={13} className="text-zinc-600 shrink-0 mt-0.5" /> <Icon size={13} className="text-zinc-600 shrink-0 mt-0.5" />
<div> <div>
<p className="text-[10px] text-zinc-600">{label}</p> <p className="text-[10px] text-zinc-600">{label}</p>
<p className="text-sm text-zinc-200 font-medium">{value}</p> <p className="text-sm text-zinc-700 dark:text-zinc-200 font-medium">{value}</p>
</div> </div>
</div> </div>
) : null)} ) : null)}
@@ -501,24 +501,24 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(245,158,11,0.06)"> <NeoCard spotlightColor="rgba(245,158,11,0.06)">
<div className="flex items-center gap-3 mb-5"> <div className="flex items-center gap-3 mb-5">
<Activity className={NEON_GOLD} size={20} /> <Activity className={NEON_GOLD} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Pipeline Position</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Pipeline Position</h3>
</div> </div>
<NeoProgress pct={stagePct} color={currentStage?.color ?? '#3B82F6'} height="h-2" /> <NeoProgress pct={stagePct} color={currentStage?.color ?? '#3B82F6'} height="h-2" />
<div className="flex items-center gap-0.5 flex-wrap mt-4 mb-5"> <div className="flex items-center gap-0.5 flex-wrap mt-4 mb-5">
{stageColumns.map((col, i) => ( {stageColumns.map((col, i) => (
<React.Fragment key={col.id}> <React.Fragment key={col.id}>
<span className="text-[10px] font-bold px-1.5 py-0.5 rounded transition-colors" <span className="text-[10px] font-bold px-1.5 py-0.5 rounded transition-colors"
style={i === stageIdx ? { color: col.color } : { color: i < stageIdx ? '#52525b' : '#27272a' }}> style={i === stageIdx ? { color: col.color } : { color: i < stageIdx ? '#71717a' : '#a1a1aa' }}>
{col.name} {col.name}
</span> </span>
{i < stageColumns.length - 1 && <ChevronRight size={10} className="text-zinc-800 shrink-0" />} {i < stageColumns.length - 1 && <ChevronRight size={10} className="text-zinc-400 dark:text-zinc-800 shrink-0" />}
</React.Fragment> </React.Fragment>
))} ))}
</div> </div>
{lead.notes && ( {lead.notes && (
<div className="p-4 bg-amber-500/5 border border-amber-500/10 rounded-2xl mt-auto"> <div className="p-4 bg-amber-500/5 border border-amber-500/10 rounded-2xl mt-auto">
<p className="text-[10px] font-bold text-amber-500/70 uppercase tracking-widest mb-1.5">Notes</p> <p className="text-[10px] font-bold text-amber-500/70 uppercase tracking-widest mb-1.5">Notes</p>
<p className="text-sm text-zinc-300 leading-relaxed">{lead.notes}</p> <p className="text-sm text-zinc-600 dark:text-zinc-300 leading-relaxed">{lead.notes}</p>
</div> </div>
)} )}
<div className="mt-4 p-3 bg-blue-500/5 border border-blue-500/10 rounded-xl"> <div className="mt-4 p-3 bg-blue-500/5 border border-blue-500/10 rounded-xl">
@@ -541,28 +541,28 @@ export default function LeadProjectPage() {
{ icon: Mail, label: 'Email', value: lead.email }, { icon: Mail, label: 'Email', value: lead.email },
{ icon: MapPin, label: 'Address', value: lead.address }, { icon: MapPin, label: 'Address', value: lead.address },
].map(({ icon: Icon, label, value }) => value ? ( ].map(({ icon: Icon, label, value }) => value ? (
<div key={label} className="flex items-start gap-3 py-2.5 border-b border-white/[0.04] last:border-0"> <div key={label} className="flex items-start gap-3 py-2.5 border-b border-zinc-100 dark:border-white/[0.04] last:border-0">
<Icon size={13} className="text-zinc-600 shrink-0 mt-0.5" /> <Icon size={13} className="text-zinc-600 shrink-0 mt-0.5" />
<div><p className="text-[10px] text-zinc-600">{label}</p><p className="text-sm text-zinc-200 font-medium">{value}</p></div> <div><p className="text-[10px] text-zinc-600">{label}</p><p className="text-sm text-zinc-700 dark:text-zinc-200 font-medium">{value}</p></div>
</div> </div>
) : null)} ) : null)}
</NeoCard> </NeoCard>
<NeoCard spotlightColor="rgba(139,92,246,0.08)"> <NeoCard spotlightColor="rgba(139,92,246,0.08)">
<p className="text-[10px] font-bold text-zinc-600 uppercase tracking-widest mb-4">Quick Actions</p> <p className="text-[10px] font-bold text-zinc-600 uppercase tracking-widest mb-4">Quick Actions</p>
{lead.phone && ( {lead.phone && (
<a href={`tel:${lead.phone}`} className="flex items-center gap-3 px-4 py-3 rounded-xl bg-white/5 hover:bg-white/10 border border-white/5 transition-colors mb-2"> <a href={`tel:${lead.phone}`} className="flex items-center gap-3 px-4 py-3 rounded-xl bg-zinc-50 dark:bg-white/5 hover:bg-zinc-100 dark:hover:bg-white/10 border border-zinc-100 dark:border-white/5 transition-colors mb-2">
<Phone size={14} className="text-emerald-400" /><span className="text-sm text-zinc-300">Call {lead.phone}</span> <Phone size={14} className="text-emerald-400" /><span className="text-sm text-zinc-600 dark:text-zinc-300">Call {lead.phone}</span>
</a> </a>
)} )}
{lead.email && ( {lead.email && (
<a href={`mailto:${lead.email}`} className="flex items-center gap-3 px-4 py-3 rounded-xl bg-white/5 hover:bg-white/10 border border-white/5 transition-colors mb-2"> <a href={`mailto:${lead.email}`} className="flex items-center gap-3 px-4 py-3 rounded-xl bg-zinc-50 dark:bg-white/5 hover:bg-zinc-100 dark:hover:bg-white/10 border border-zinc-100 dark:border-white/5 transition-colors mb-2">
<Mail size={14} className="text-blue-400" /><span className="text-sm text-zinc-300">Email {lead.email}</span> <Mail size={14} className="text-blue-400" /><span className="text-sm text-zinc-600 dark:text-zinc-300">Email {lead.email}</span>
</a> </a>
)} )}
{lead.address && ( {lead.address && (
<a href={`https://maps.google.com/?q=${encodeURIComponent(lead.address)}`} target="_blank" rel="noopener noreferrer" <a href={`https://maps.google.com/?q=${encodeURIComponent(lead.address)}`} target="_blank" rel="noopener noreferrer"
className="flex items-center gap-3 px-4 py-3 rounded-xl bg-white/5 hover:bg-white/10 border border-white/5 transition-colors"> className="flex items-center gap-3 px-4 py-3 rounded-xl bg-zinc-50 dark:bg-white/5 hover:bg-zinc-100 dark:hover:bg-white/10 border border-zinc-100 dark:border-white/5 transition-colors">
<MapPin size={14} className="text-amber-400" /><span className="text-sm text-zinc-300">View on Maps</span> <MapPin size={14} className="text-amber-400" /><span className="text-sm text-zinc-600 dark:text-zinc-300">View on Maps</span>
</a> </a>
)} )}
</NeoCard> </NeoCard>
@@ -592,7 +592,7 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(0,240,255,0.08)"> <NeoCard spotlightColor="rgba(0,240,255,0.08)">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<DollarSign className={NEON_BLUE} size={20} /> <DollarSign className={NEON_BLUE} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Budget Breakdown</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Budget Breakdown</h3>
</div> </div>
<div className="h-56"> <div className="h-56">
<ResponsiveContainer width="100%" height="100%"> <ResponsiveContainer width="100%" height="100%">
@@ -618,11 +618,11 @@ export default function LeadProjectPage() {
{/* Table */} {/* Table */}
<NeoCard spotlightColor="rgba(253,169,19,0.06)"> <NeoCard spotlightColor="rgba(253,169,19,0.06)">
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase mb-5">Line Item Breakdown</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase mb-5">Line Item Breakdown</h3>
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead> <thead>
<tr className="border-b border-white/5 text-[10px] uppercase tracking-wider text-zinc-600"> <tr className="border-b border-zinc-200 dark:border-white/5 text-[10px] uppercase tracking-wider text-zinc-500 dark:text-zinc-600">
<th className="text-left pb-3 font-bold">Category</th> <th className="text-left pb-3 font-bold">Category</th>
<th className="text-right pb-3 font-bold">Allocated</th> <th className="text-right pb-3 font-bold">Allocated</th>
<th className="text-right pb-3 font-bold">Committed</th> <th className="text-right pb-3 font-bold">Committed</th>
@@ -630,12 +630,12 @@ export default function LeadProjectPage() {
<th className="text-right pb-3 font-bold">Remaining</th> <th className="text-right pb-3 font-bold">Remaining</th>
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-white/[0.04]"> <tbody className="divide-y divide-zinc-100 dark:divide-white/[0.04]">
{(proj.budgetBreakdown || []).map((b, i) => { {(proj.budgetBreakdown || []).map((b, i) => {
const rem = b.allocated - b.actual; const rem = b.allocated - b.actual;
return ( return (
<tr key={i} className="hover:bg-white/[0.03] transition-colors"> <tr key={i} className="hover:bg-zinc-50 dark:hover:bg-white/[0.03] transition-colors">
<td className="py-3 text-zinc-300 font-medium">{b.category}</td> <td className="py-3 text-zinc-600 dark:text-zinc-300 font-medium">{b.category}</td>
<td className="py-3 text-right font-mono text-zinc-400">{formatCurrency(b.allocated)}</td> <td className="py-3 text-right font-mono text-zinc-400">{formatCurrency(b.allocated)}</td>
<td className="py-3 text-right font-mono text-zinc-400">{formatCurrency(b.committed)}</td> <td className="py-3 text-right font-mono text-zinc-400">{formatCurrency(b.committed)}</td>
<td className="py-3 text-right font-mono text-zinc-300">{formatCurrency(b.actual)}</td> <td className="py-3 text-right font-mono text-zinc-300">{formatCurrency(b.actual)}</td>
@@ -645,11 +645,11 @@ export default function LeadProjectPage() {
})} })}
</tbody> </tbody>
<tfoot> <tfoot>
<tr className="border-t border-white/10"> <tr className="border-t border-zinc-200 dark:border-white/10">
<td className="py-3 font-bold text-white text-[11px] uppercase tracking-wider">Total</td> <td className="py-3 font-bold text-zinc-900 dark:text-white text-[11px] uppercase tracking-wider">Total</td>
<td className="py-3 text-right font-mono font-bold text-white">{formatCurrency(proj.estimatedAmount)}</td> <td className="py-3 text-right font-mono font-bold text-zinc-900 dark:text-white">{formatCurrency(proj.estimatedAmount)}</td>
<td className="py-3 text-right font-mono font-bold text-white">{formatCurrency(proj.budgetBreakdown?.reduce((s, b) => s + b.committed, 0))}</td> <td className="py-3 text-right font-mono font-bold text-zinc-900 dark:text-white">{formatCurrency(proj.budgetBreakdown?.reduce((s, b) => s + b.committed, 0))}</td>
<td className="py-3 text-right font-mono font-bold text-white">{formatCurrency(proj.actualCost)}</td> <td className="py-3 text-right font-mono font-bold text-zinc-900 dark:text-white">{formatCurrency(proj.actualCost)}</td>
<td className={`py-3 text-right font-mono font-bold ${(proj.estimatedAmount - proj.actualCost) >= 0 ? 'text-emerald-400' : 'text-red-400'}`}> <td className={`py-3 text-right font-mono font-bold ${(proj.estimatedAmount - proj.actualCost) >= 0 ? 'text-emerald-400' : 'text-red-400'}`}>
{formatCurrency(proj.estimatedAmount - proj.actualCost)} {formatCurrency(proj.estimatedAmount - proj.actualCost)}
</td> </td>
@@ -666,7 +666,7 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(57,255,20,0.08)"> <NeoCard spotlightColor="rgba(57,255,20,0.08)">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<Milestone className={NEON_GREEN} size={20} /> <Milestone className={NEON_GREEN} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Project Milestones</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Project Milestones</h3>
<span className="text-xs text-zinc-600 ml-auto"> <span className="text-xs text-zinc-600 ml-auto">
{(proj.milestones || []).filter(m => m.status === 'completed').length} / {proj.milestones?.length || 0} complete {(proj.milestones || []).filter(m => m.status === 'completed').length} / {proj.milestones?.length || 0} complete
</span> </span>
@@ -675,15 +675,15 @@ export default function LeadProjectPage() {
{(proj.milestones || []).map((m, i) => { {(proj.milestones || []).map((m, i) => {
const dotColor = m.status === 'completed' ? '#39ff14' : m.status === 'in_progress' ? '#00f0ff' : '#3f3f46'; const dotColor = m.status === 'completed' ? '#39ff14' : m.status === 'in_progress' ? '#00f0ff' : '#3f3f46';
return ( return (
<div key={m.id} className="flex items-start gap-4 p-4 rounded-2xl bg-white/[0.03] border border-white/[0.06] hover:bg-white/[0.06] transition-colors"> <div key={m.id} className="flex items-start gap-4 p-4 rounded-2xl bg-zinc-50 dark:bg-white/[0.03] border border-zinc-100 dark:border-white/[0.06] hover:bg-zinc-100 dark:hover:bg-white/[0.06] transition-colors">
<div className={`w-4 h-4 rounded-full mt-0.5 shrink-0 shadow-[0_0_8px_currentColor]`} style={{ backgroundColor: dotColor, color: dotColor }} /> <div className={`w-4 h-4 rounded-full mt-0.5 shrink-0`} style={{ backgroundColor: dotColor }} />
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<div className="flex items-center justify-between gap-2"> <div className="flex items-center justify-between gap-2">
<p className="font-semibold text-zinc-200 text-sm">{m.name}</p> <p className="font-semibold text-zinc-700 dark:text-zinc-200 text-sm">{m.name}</p>
<span className={`text-[10px] font-bold uppercase px-2 py-0.5 rounded-full ${ <span className={`text-[10px] font-bold uppercase px-2 py-0.5 rounded-full ${
m.status === 'completed' ? 'bg-emerald-500/15 text-emerald-400' : m.status === 'completed' ? 'bg-emerald-500/15 text-emerald-600 dark:text-emerald-400' :
m.status === 'in_progress' ? 'bg-blue-500/15 text-blue-400' : m.status === 'in_progress' ? 'bg-blue-500/15 text-blue-600 dark:text-blue-400' :
'bg-zinc-800 text-zinc-600' 'bg-zinc-200 dark:bg-zinc-800 text-zinc-500 dark:text-zinc-600'
}`}>{m.status.replace('_', ' ')}</span> }`}>{m.status.replace('_', ' ')}</span>
</div> </div>
{m.date && <p className="text-xs text-zinc-600 mt-0.5">{formatDate(m.date)}</p>} {m.date && <p className="text-xs text-zinc-600 mt-0.5">{formatDate(m.date)}</p>}
@@ -701,8 +701,8 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(253,169,19,0.08)"> <NeoCard spotlightColor="rgba(253,169,19,0.08)">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<GitPullRequest className={NEON_GOLD} size={20} /> <GitPullRequest className={NEON_GOLD} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Change Orders</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Change Orders</h3>
<span className="text-xs font-bold bg-white/5 border border-white/5 px-2 py-0.5 rounded-full text-zinc-400 ml-auto"> <span className="text-xs font-bold bg-zinc-100 dark:bg-white/5 border border-zinc-200 dark:border-white/5 px-2 py-0.5 rounded-full text-zinc-500 dark:text-zinc-400 ml-auto">
{proj.changeOrders?.length || 0} {proj.changeOrders?.length || 0}
</span> </span>
</div> </div>
@@ -714,9 +714,9 @@ export default function LeadProjectPage() {
) : ( ) : (
<div className="space-y-3"> <div className="space-y-3">
{proj.changeOrders.map(co => ( {proj.changeOrders.map(co => (
<div key={co.id} className="p-4 rounded-2xl bg-white/[0.03] border border-white/[0.06] hover:bg-white/[0.06] transition-colors"> <div key={co.id} className="p-4 rounded-2xl bg-zinc-50 dark:bg-white/[0.03] border border-zinc-100 dark:border-white/[0.06] hover:bg-zinc-100 dark:hover:bg-white/[0.06] transition-colors">
<div className="flex items-start justify-between gap-2 mb-2"> <div className="flex items-start justify-between gap-2 mb-2">
<p className="font-semibold text-zinc-200 text-sm">{co.title}</p> <p className="font-semibold text-zinc-700 dark:text-zinc-200 text-sm">{co.title}</p>
<div className="flex items-center gap-2 shrink-0"> <div className="flex items-center gap-2 shrink-0">
<span className={`text-[10px] font-bold px-2 py-0.5 rounded-full uppercase ${co.status === 'approved' ? 'bg-emerald-500/15 text-emerald-400' : co.status === 'rejected' ? 'bg-red-500/15 text-red-400' : 'bg-amber-500/15 text-amber-400'}`}> <span className={`text-[10px] font-bold px-2 py-0.5 rounded-full uppercase ${co.status === 'approved' ? 'bg-emerald-500/15 text-emerald-400' : co.status === 'rejected' ? 'bg-red-500/15 text-red-400' : 'bg-amber-500/15 text-amber-400'}`}>
{co.status} {co.status}
@@ -738,8 +738,8 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(255,69,0,0.08)"> <NeoCard spotlightColor="rgba(255,69,0,0.08)">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<FileText className={NEON_ORANGE} size={20} /> <FileText className={NEON_ORANGE} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Requests for Information</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Requests for Information</h3>
<span className="text-xs font-bold bg-white/5 border border-white/5 px-2 py-0.5 rounded-full text-zinc-400 ml-auto"> <span className="text-xs font-bold bg-zinc-100 dark:bg-white/5 border border-zinc-200 dark:border-white/5 px-2 py-0.5 rounded-full text-zinc-500 dark:text-zinc-400 ml-auto">
{proj.rfis?.length || 0} {proj.rfis?.length || 0}
</span> </span>
</div> </div>
@@ -751,7 +751,7 @@ export default function LeadProjectPage() {
) : ( ) : (
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead className="border-b border-white/5 text-[10px] uppercase tracking-wider text-zinc-600"> <thead className="border-b border-zinc-200 dark:border-white/5 text-[10px] uppercase tracking-wider text-zinc-500 dark:text-zinc-600">
<tr> <tr>
<th className="text-left pb-3 font-bold">ID</th> <th className="text-left pb-3 font-bold">ID</th>
<th className="text-left pb-3 font-bold">Subject</th> <th className="text-left pb-3 font-bold">Subject</th>
@@ -761,11 +761,11 @@ export default function LeadProjectPage() {
<th className="text-left pb-3 font-bold">Closed</th> <th className="text-left pb-3 font-bold">Closed</th>
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-white/[0.04]"> <tbody className="divide-y divide-zinc-100 dark:divide-white/[0.04]">
{proj.rfis.map((r, i) => ( {proj.rfis.map((r, i) => (
<tr key={r.id} className="hover:bg-white/[0.03] transition-colors"> <tr key={r.id} className="hover:bg-zinc-50 dark:hover:bg-white/[0.03] transition-colors">
<td className="py-3 font-mono text-zinc-500 text-xs">{r.id.toUpperCase()}</td> <td className="py-3 font-mono text-zinc-500 text-xs">{r.id.toUpperCase()}</td>
<td className="py-3 text-zinc-200 font-semibold">{r.subject}</td> <td className="py-3 text-zinc-700 dark:text-zinc-200 font-semibold">{r.subject}</td>
<td className="py-3 text-center"> <td className="py-3 text-center">
<span className={`text-[10px] font-bold px-2 py-1 rounded-full uppercase ${r.status === 'closed' ? 'bg-emerald-500/15 text-emerald-400' : 'bg-amber-500/15 text-amber-400'}`}> <span className={`text-[10px] font-bold px-2 py-1 rounded-full uppercase ${r.status === 'closed' ? 'bg-emerald-500/15 text-emerald-400' : 'bg-amber-500/15 text-amber-400'}`}>
{r.status} {r.status}
@@ -801,11 +801,11 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(0,240,255,0.06)"> <NeoCard spotlightColor="rgba(0,240,255,0.06)">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<DollarSign className={NEON_BLUE} size={20} /> <DollarSign className={NEON_BLUE} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Invoice Schedule</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Invoice Schedule</h3>
</div> </div>
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead className="border-b border-white/5 text-[10px] uppercase tracking-wider text-zinc-600"> <thead className="border-b border-zinc-200 dark:border-white/5 text-[10px] uppercase tracking-wider text-zinc-500 dark:text-zinc-600">
<tr> <tr>
<th className="text-left pb-3 font-bold">Description</th> <th className="text-left pb-3 font-bold">Description</th>
<th className="text-right pb-3 font-bold">Amount</th> <th className="text-right pb-3 font-bold">Amount</th>
@@ -814,11 +814,11 @@ export default function LeadProjectPage() {
<th className="text-left pb-3 font-bold">Paid</th> <th className="text-left pb-3 font-bold">Paid</th>
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-white/[0.04]"> <tbody className="divide-y divide-zinc-100 dark:divide-white/[0.04]">
{(proj.invoices || []).map(inv => ( {(proj.invoices || []).map(inv => (
<tr key={inv.id} className="hover:bg-white/[0.03] transition-colors"> <tr key={inv.id} className="hover:bg-zinc-50 dark:hover:bg-white/[0.03] transition-colors">
<td className="py-3 text-zinc-300 font-medium">{inv.description}</td> <td className="py-3 text-zinc-600 dark:text-zinc-300 font-medium">{inv.description}</td>
<td className="py-3 text-right font-mono text-zinc-200 font-semibold">{formatCurrency(inv.amount)}</td> <td className="py-3 text-right font-mono text-zinc-700 dark:text-zinc-200 font-semibold">{formatCurrency(inv.amount)}</td>
<td className="py-3 text-center"> <td className="py-3 text-center">
<span className={`text-[10px] font-bold px-2 py-1 rounded-full uppercase ${ <span className={`text-[10px] font-bold px-2 py-1 rounded-full uppercase ${
inv.status === 'paid' ? 'bg-emerald-500/15 text-emerald-400' : inv.status === 'paid' ? 'bg-emerald-500/15 text-emerald-400' :
@@ -843,8 +843,8 @@ export default function LeadProjectPage() {
<div className="flex items-center justify-between mb-6"> <div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<FolderOpen className={NEON_BLUE} size={20} /> <FolderOpen className={NEON_BLUE} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Project Documents</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Project Documents</h3>
<span className="text-xs font-bold bg-white/5 border border-white/5 px-2 py-0.5 rounded-full text-zinc-400">{docs.length}</span> <span className="text-xs font-bold bg-zinc-100 dark:bg-white/5 border border-zinc-200 dark:border-white/5 px-2 py-0.5 rounded-full text-zinc-500 dark:text-zinc-400">{docs.length}</span>
</div> </div>
<button onClick={() => setUploadOpen(true)} <button onClick={() => setUploadOpen(true)}
className="flex items-center gap-2 px-4 py-2 rounded-xl bg-blue-600 hover:bg-blue-700 text-white text-sm font-semibold transition-colors"> className="flex items-center gap-2 px-4 py-2 rounded-xl bg-blue-600 hover:bg-blue-700 text-white text-sm font-semibold transition-colors">
@@ -854,7 +854,7 @@ export default function LeadProjectPage() {
{docs.length === 0 ? ( {docs.length === 0 ? (
<div className="text-center py-16"> <div className="text-center py-16">
<FolderOpen size={48} className="mx-auto mb-4 text-zinc-700" /> <FolderOpen size={48} className="mx-auto mb-4 text-zinc-700" />
<p className="font-bold text-lg text-white">No documents yet</p> <p className="font-bold text-lg text-zinc-900 dark:text-white">No documents yet</p>
</div> </div>
) : ( ) : (
<div className="space-y-2"> <div className="space-y-2">
@@ -862,13 +862,13 @@ export default function LeadProjectPage() {
const cfg = getDocType(doc.name); const cfg = getDocType(doc.name);
const DocIcon = cfg.icon; const DocIcon = cfg.icon;
return ( return (
<div key={doc.id} className="flex items-start gap-4 px-4 py-4 rounded-2xl bg-white/[0.03] border border-white/[0.06] hover:bg-white/[0.07] transition-colors group"> <div key={doc.id} className="flex items-start gap-4 px-4 py-4 rounded-2xl bg-zinc-50 dark:bg-white/[0.03] border border-zinc-100 dark:border-white/[0.06] hover:bg-zinc-100 dark:hover:bg-white/[0.07] transition-colors group">
<div className="w-10 h-10 rounded-xl flex items-center justify-center shrink-0 mt-0.5" style={{ backgroundColor: cfg.bg }}> <div className="w-10 h-10 rounded-xl flex items-center justify-center shrink-0 mt-0.5" style={{ backgroundColor: cfg.bg }}>
<DocIcon size={18} style={{ color: cfg.color }} /> <DocIcon size={18} style={{ color: cfg.color }} />
</div> </div>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<div className="flex items-center gap-2 flex-wrap"> <div className="flex items-center gap-2 flex-wrap">
<p className="font-semibold text-white text-sm truncate">{doc.name}</p> <p className="font-semibold text-zinc-900 dark:text-white text-sm truncate">{doc.name}</p>
<span className="text-[10px] font-bold px-1.5 py-0.5 rounded-md uppercase" style={{ backgroundColor: cfg.bg, color: cfg.color }}>{cfg.label}</span> <span className="text-[10px] font-bold px-1.5 py-0.5 rounded-md uppercase" style={{ backgroundColor: cfg.bg, color: cfg.color }}>{cfg.label}</span>
</div> </div>
<p className="text-xs text-zinc-600 mt-0.5">{doc.size} · {doc.uploadedBy} · {doc.uploadedDate}</p> <p className="text-xs text-zinc-600 mt-0.5">{doc.size} · {doc.uploadedBy} · {doc.uploadedDate}</p>
@@ -882,9 +882,9 @@ export default function LeadProjectPage() {
)} )}
</div> </div>
<div className="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"> <div className="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity">
<button onClick={() => setViewDoc(doc)} className="p-1.5 rounded-lg bg-white/5 hover:bg-white/10 text-zinc-400 hover:text-[#00f0ff] transition-colors" title="View"><Eye size={14} /></button> <button onClick={() => setViewDoc(doc)} className="p-1.5 rounded-lg bg-zinc-100 dark:bg-white/5 hover:bg-zinc-200 dark:hover:bg-white/10 text-zinc-500 dark:text-zinc-400 hover:text-sky-500 dark:hover:text-[#00f0ff] transition-colors" title="View"><Eye size={14} /></button>
<button onClick={() => setEditNoteDoc({ doc, noteText: doc.notes || '' })} className="p-1.5 rounded-lg bg-white/5 hover:bg-white/10 text-zinc-400 hover:text-amber-400 transition-colors" title="Edit note"><Pencil size={14} /></button> <button onClick={() => setEditNoteDoc({ doc, noteText: doc.notes || '' })} className="p-1.5 rounded-lg bg-zinc-100 dark:bg-white/5 hover:bg-zinc-200 dark:hover:bg-white/10 text-zinc-500 dark:text-zinc-400 hover:text-amber-500 dark:hover:text-amber-400 transition-colors" title="Edit note"><Pencil size={14} /></button>
<button onClick={() => setDeleteDocId(doc.id)} className="p-1.5 rounded-lg bg-white/5 hover:bg-red-500/20 text-zinc-400 hover:text-red-400 transition-colors" title="Delete"><Trash2 size={14} /></button> <button onClick={() => setDeleteDocId(doc.id)} className="p-1.5 rounded-lg bg-zinc-100 dark:bg-white/5 hover:bg-red-50 dark:hover:bg-red-500/20 text-zinc-500 dark:text-zinc-400 hover:text-red-500 dark:hover:text-red-400 transition-colors" title="Delete"><Trash2 size={14} /></button>
</div> </div>
</div> </div>
); );
@@ -902,23 +902,23 @@ export default function LeadProjectPage() {
<NeoCard spotlightColor="rgba(0,240,255,0.06)"> <NeoCard spotlightColor="rgba(0,240,255,0.06)">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<Activity className={NEON_BLUE} size={20} /> <Activity className={NEON_BLUE} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Work Timeline</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Work Timeline</h3>
</div> </div>
<div className="relative"> <div className="relative">
<div className="absolute left-6 top-0 bottom-0 w-px bg-white/10" /> <div className="absolute left-6 top-0 bottom-0 w-px bg-zinc-200 dark:bg-white/10" />
<div className="space-y-5"> <div className="space-y-5">
{proj.workTimeline.map((a, i) => ( {proj.workTimeline.map((a, i) => (
<div key={i} className="relative flex items-start gap-4 pl-12"> <div key={i} className="relative flex items-start gap-4 pl-12">
<div className="absolute left-[21px] top-1.5 w-2.5 h-2.5 rounded-full bg-[#09090b] border-2 border-[#00f0ff] shadow-[0_0_8px_rgba(0,240,255,0.5)]" /> <div className="absolute left-[21px] top-1.5 w-2.5 h-2.5 rounded-full bg-white dark:bg-[#09090b] border-2 border-sky-400 dark:border-[#00f0ff]" />
<div className="flex-1 p-4 rounded-xl bg-white/5 border border-white/5 hover:bg-white/10 transition-colors"> <div className="flex-1 p-4 rounded-xl bg-zinc-50 dark:bg-white/5 border border-zinc-100 dark:border-white/5 hover:bg-zinc-100 dark:hover:bg-white/10 transition-colors">
<div className="flex justify-between items-start"> <div className="flex justify-between items-start">
<div> <div>
<div className="font-bold text-white text-sm">{a.action}</div> <div className="font-bold text-zinc-900 dark:text-white text-sm">{a.action}</div>
{a.details && <div className="text-xs text-zinc-400 mt-1">{a.details}</div>} {a.details && <div className="text-xs text-zinc-500 dark:text-zinc-400 mt-1">{a.details}</div>}
</div> </div>
<div className="text-right shrink-0 ml-4"> <div className="text-right shrink-0 ml-4">
<div className="text-xs font-mono text-zinc-500">{a.date}</div> <div className="text-xs font-mono text-zinc-500">{a.date}</div>
{a.user && <div className="text-[10px] uppercase tracking-wider text-[#00f0ff] mt-1">{a.user}</div>} {a.user && <div className="text-[10px] uppercase tracking-wider text-sky-500 dark:text-[#00f0ff] mt-1">{a.user}</div>}
</div> </div>
</div> </div>
</div> </div>
@@ -934,9 +934,9 @@ export default function LeadProjectPage() {
<div className="flex items-center justify-between mb-6"> <div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<TrendingUp className={NEON_GREEN} size={20} /> <TrendingUp className={NEON_GREEN} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Stage Movement Log</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Stage Movement Log</h3>
</div> </div>
<span className="text-xs font-bold text-zinc-600 bg-white/5 border border-white/5 px-2 py-0.5 rounded-full"> <span className="text-xs font-bold text-zinc-500 dark:text-zinc-600 bg-zinc-100 dark:bg-white/5 border border-zinc-200 dark:border-white/5 px-2 py-0.5 rounded-full">
{lead.activity?.length ?? 0} entries {lead.activity?.length ?? 0} entries
</span> </span>
</div> </div>
+133 -133
View File
@@ -19,12 +19,12 @@ import InvoiceDetailModal from '../../components/owner/InvoiceDetailModal';
import CreateItemModal from '../../components/owner/CreateItemModal'; import CreateItemModal from '../../components/owner/CreateItemModal';
// --- NEOMORPHIC STYLING CONSTANTS --- // --- NEOMORPHIC STYLING CONSTANTS ---
const NEO_PANEL_CLASS = "bg-zinc-900/60 backdrop-blur-3xl border border-white/5 shadow-[8px_8px_16px_rgba(0,0,0,0.6),-8px_-8px_16px_rgba(255,255,255,0.02)] rounded-3xl relative overflow-hidden transition-all duration-300"; const NEO_PANEL_CLASS = "dark:bg-zinc-900/60 dark:backdrop-blur-3xl border border-zinc-200 dark:border-white/5 dark:shadow-[8px_8px_16px_rgba(0,0,0,0.6),-8px_-8px_16px_rgba(255,255,255,0.02)] rounded-3xl relative overflow-hidden transition-all duration-300";
const NEON_GREEN = "text-[#39ff14] drop-shadow-[0_0_8px_rgba(57,255,20,0.4)]"; const NEON_GREEN = "text-green-600 dark:text-[#39ff14] dark:drop-shadow-[0_0_8px_rgba(57,255,20,0.4)]";
const NEON_GOLD = "text-[#fda913] drop-shadow-[0_0_8px_rgba(253,169,19,0.4)]"; const NEON_GOLD = "text-amber-600 dark:text-[#fda913] dark:drop-shadow-[0_0_8px_rgba(253,169,19,0.4)]";
const NEON_ORANGE = "text-[#ff4500] drop-shadow-[0_0_8px_rgba(255,69,0,0.4)]"; const NEON_ORANGE = "text-orange-600 dark:text-[#ff4500] dark:drop-shadow-[0_0_8px_rgba(255,69,0,0.4)]";
const NEON_RED = "text-[#ff003c] drop-shadow-[0_0_8px_rgba(255,0,60,0.4)]"; const NEON_RED = "text-red-600 dark:text-[#ff003c] dark:drop-shadow-[0_0_8px_rgba(255,0,60,0.4)]";
const NEON_BLUE = "text-[#00f0ff] drop-shadow-[0_0_8px_rgba(0,240,255,0.4)]"; const NEON_BLUE = "text-sky-600 dark:text-[#00f0ff] dark:drop-shadow-[0_0_8px_rgba(0,240,255,0.4)]";
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// SHARED UI COMPONENTS // SHARED UI COMPONENTS
@@ -41,7 +41,7 @@ const NeoCard = ({ children, className = "", innerClassName = "", spotlightColor
const ProgressBar = ({ progress, goal = 100, colorClass = "bg-[#39ff14]", shadowClass = "shadow-[0_0_10px_#39ff14]", height = "h-1.5" }) => { const ProgressBar = ({ progress, goal = 100, colorClass = "bg-[#39ff14]", shadowClass = "shadow-[0_0_10px_#39ff14]", height = "h-1.5" }) => {
const pct = Math.min((progress / goal) * 100, 100); const pct = Math.min((progress / goal) * 100, 100);
return ( return (
<div className={`${height} w-full bg-black/80 rounded-full shadow-[inset_0_2px_4px_rgba(0,0,0,0.6)] border border-white/5 relative overflow-hidden flex-1`}> <div className={`${height} w-full bg-zinc-200 dark:bg-black/80 rounded-full border border-zinc-200 dark:border-white/5 relative overflow-hidden flex-1`}>
<motion.div <motion.div
initial={{ width: 0 }} initial={{ width: 0 }}
animate={{ width: `${pct}%` }} animate={{ width: `${pct}%` }}
@@ -306,11 +306,11 @@ const OwnerProjectDetail = () => {
<NeoCard spotlightColor="rgba(0, 240, 255, 0.1)" className="lg:col-span-2"> <NeoCard spotlightColor="rgba(0, 240, 255, 0.1)" className="lg:col-span-2">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<Milestone className={NEON_BLUE} size={20} /> <Milestone className={NEON_BLUE} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Project Progression</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Project Progression</h3>
</div> </div>
<div className="relative pt-8 pb-4"> <div className="relative pt-8 pb-4">
{/* Stepper Line */} {/* Stepper Line */}
<div className="absolute top-[38px] left-[10%] right-[10%] h-1 bg-zinc-800 rounded-full shadow-[inset_0_1px_3px_rgba(0,0,0,0.8)] z-0" /> <div className="absolute top-[38px] left-[10%] right-[10%] h-1 bg-zinc-200 dark:bg-zinc-800 rounded-full z-0" />
<motion.div <motion.div
initial={{ width: 0 }} animate={{ width: `${project.completionPercentage || 0}%` }} transition={{ duration: 1.5 }} initial={{ width: 0 }} animate={{ width: `${project.completionPercentage || 0}%` }} transition={{ duration: 1.5 }}
className="absolute top-[38px] left-[10%] h-1 bg-gradient-to-r from-blue-600 to-[#00f0ff] rounded-full shadow-[0_0_10px_#00f0ff] z-0" className="absolute top-[38px] left-[10%] h-1 bg-gradient-to-r from-blue-600 to-[#00f0ff] rounded-full shadow-[0_0_10px_#00f0ff] z-0"
@@ -323,11 +323,11 @@ const OwnerProjectDetail = () => {
return ( return (
<div key={i} className="flex flex-col items-center gap-3 w-20 relative"> <div key={i} className="flex flex-col items-center gap-3 w-20 relative">
<div className={`w-8 h-8 rounded-full flex items-center justify-center border-2 shadow-lg transition-colors <div className={`w-8 h-8 rounded-full flex items-center justify-center border-2 shadow-lg transition-colors
${isActive ? 'bg-zinc-900 border-[#00f0ff] text-[#00f0ff] shadow-[0_0_15px_rgba(0,240,255,0.4)]' : 'bg-black border-zinc-700 text-zinc-600'} ${isActive ? 'bg-zinc-50 dark:bg-zinc-900 border-sky-500 dark:border-[#00f0ff] text-sky-500 dark:text-[#00f0ff] dark:shadow-[0_0_15px_rgba(0,240,255,0.4)]' : 'bg-white dark:bg-black border-zinc-300 dark:border-zinc-700 text-zinc-400 dark:text-zinc-600'}
`}> `}>
{isActive ? <CheckCircle size={14} className="drop-shadow-[0_0_5px_rgba(0,240,255,0.8)]" /> : <span className="w-2 h-2 rounded-full bg-zinc-700" />} {isActive ? <CheckCircle size={14} /> : <span className="w-2 h-2 rounded-full bg-zinc-300 dark:bg-zinc-700" />}
</div> </div>
<span className={`text-[10px] text-center font-bold tracking-wide uppercase leading-tight ${isActive ? 'text-white' : 'text-zinc-500'}`}> <span className={`text-[10px] text-center font-bold tracking-wide uppercase leading-tight ${isActive ? 'text-zinc-900 dark:text-white' : 'text-zinc-500'}`}>
{step} {step}
</span> </span>
</div> </div>
@@ -345,31 +345,31 @@ const OwnerProjectDetail = () => {
<NeoCard spotlightColor="rgba(253, 169, 19, 0.1)"> <NeoCard spotlightColor="rgba(253, 169, 19, 0.1)">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<User className={NEON_GOLD} size={20} /> <User className={NEON_GOLD} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Relationship Intel</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Relationship Intel</h3>
</div> </div>
<div className="flex items-center gap-4 mb-6"> <div className="flex items-center gap-4 mb-6">
<div className="w-16 h-16 rounded-full bg-zinc-800 border-2 border-amber-500/30 flex items-center justify-center shadow-[inset_0_2px_10px_rgba(0,0,0,0.5)] flex-shrink-0"> <div className="w-16 h-16 rounded-full bg-zinc-100 dark:bg-zinc-800 border-2 border-amber-500/30 flex items-center justify-center flex-shrink-0">
<span className="text-xl font-black text-amber-500">{project.customerName?.[0] || 'C'}</span> <span className="text-xl font-black text-amber-600 dark:text-amber-500">{project.customerName?.[0] || 'C'}</span>
</div> </div>
<div> <div>
<h4 className="text-lg font-black text-white leading-tight">{project.customerName || 'Customer Records'}</h4> <h4 className="text-lg font-black text-zinc-900 dark:text-white leading-tight">{project.customerName || 'Customer Records'}</h4>
<p className="text-xs text-zinc-400 mt-1 font-mono">{contractor?.vendorName || project.contractorId}</p> <p className="text-xs text-zinc-500 dark:text-zinc-400 mt-1 font-mono">{contractor?.vendorName || project.contractorId}</p>
</div> </div>
</div> </div>
<div className="flex gap-2 w-full mb-6"> <div className="flex gap-2 w-full mb-6">
<button className="flex-1 py-2 bg-zinc-800 hover:bg-zinc-700 text-zinc-300 rounded-lg flex justify-center items-center gap-2 transition border border-white/5 hover:border-white/10 shadow-sm text-xs font-bold"> <button className="flex-1 py-2 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 text-zinc-600 dark:text-zinc-300 rounded-lg flex justify-center items-center gap-2 transition border border-zinc-200 dark:border-white/5 shadow-sm text-xs font-bold">
<Phone size={14} /> Call <Phone size={14} /> Call
</button> </button>
<button className="flex-1 py-2 bg-[#39ff14]/10 hover:bg-[#39ff14]/20 text-[#39ff14] border border-[#39ff14]/30 rounded-lg flex justify-center items-center gap-2 transition shadow-sm text-xs font-bold"> <button className="flex-1 py-2 bg-[#39ff14]/10 hover:bg-[#39ff14]/20 text-[#39ff14] border border-[#39ff14]/30 rounded-lg flex justify-center items-center gap-2 transition shadow-sm text-xs font-bold">
<MessageSquare size={14} /> Text <MessageSquare size={14} /> Text
</button> </button>
<button className="w-10 py-2 bg-zinc-800 hover:bg-zinc-700 text-zinc-300 rounded-lg flex justify-center items-center transition border border-white/5 hover:border-white/10 shadow-sm flex-shrink-0"> <button className="w-10 py-2 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 text-zinc-600 dark:text-zinc-300 rounded-lg flex justify-center items-center transition border border-zinc-200 dark:border-white/5 shadow-sm flex-shrink-0">
<Mail size={14} /> <Mail size={14} />
</button> </button>
</div> </div>
<div className="bg-black/40 rounded-xl p-3 border border-white/5 shadow-[inset_0_2px_10px_rgba(0,0,0,0.5)]"> <div className="bg-zinc-100 dark:bg-black/40 rounded-xl p-3 border border-zinc-200 dark:border-white/5">
<p className="text-[10px] font-mono text-amber-500 mb-1.5 flex items-center gap-1"><AlertTriangle size={10} /> PREFERENTIAL ROUTING</p> <p className="text-[10px] font-mono text-amber-600 dark:text-amber-500 mb-1.5 flex items-center gap-1"><AlertTriangle size={10} /> PREFERENTIAL ROUTING</p>
<p className="text-xs text-zinc-300 leading-tight border-b border-white/5 pb-2 mb-2">Responds fastest to SMS in the evenings. Critical approvals required via email.</p> <p className="text-xs text-zinc-600 dark:text-zinc-300 leading-tight border-b border-zinc-200 dark:border-white/5 pb-2 mb-2">Responds fastest to SMS in the evenings. Critical approvals required via email.</p>
<p className="text-[10px] text-zinc-500">Last Contact: 2 hours ago</p> <p className="text-[10px] text-zinc-500">Last Contact: 2 hours ago</p>
</div> </div>
</NeoCard> </NeoCard>
@@ -382,19 +382,19 @@ const OwnerProjectDetail = () => {
<NeoCard spotlightColor="rgba(57, 255, 20, 0.1)" innerClassName="justify-between h-full"> <NeoCard spotlightColor="rgba(57, 255, 20, 0.1)" innerClassName="justify-between h-full">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<Crosshair className={NEON_GREEN} size={20} /> <Crosshair className={NEON_GREEN} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Performance Snapshot</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Performance Snapshot</h3>
</div> </div>
<div className="flex items-center justify-between mb-6"> <div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<div className="relative w-16 h-16 flex items-center justify-center shrink-0"> <div className="relative w-16 h-16 flex items-center justify-center shrink-0">
<svg className="absolute inset-0 w-full h-full -rotate-90"> <svg className="absolute inset-0 w-full h-full -rotate-90">
<circle cx="32" cy="32" r="28" fill="none" stroke="rgba(255,255,255,0.05)" strokeWidth="6" /> <circle cx="32" cy="32" r="28" fill="none" stroke="rgba(0,0,0,0.08)" strokeWidth="6" className="dark:stroke-white/5" />
<circle cx="32" cy="32" r="28" fill="none" stroke="#39ff14" strokeWidth="6" strokeDasharray="175" strokeDashoffset={175 - (175 * 0.96)} strokeLinecap="round" className="drop-shadow-[0_0_5px_#39ff14]" /> <circle cx="32" cy="32" r="28" fill="none" stroke="#39ff14" strokeWidth="6" strokeDasharray="175" strokeDashoffset={175 - (175 * 0.96)} strokeLinecap="round" />
</svg> </svg>
<span className="text-lg font-black text-white">96%</span> <span className="text-lg font-black text-zinc-900 dark:text-white">96%</span>
</div> </div>
<div> <div>
<h4 className="text-sm font-bold text-white">Inspection Coverage</h4> <h4 className="text-sm font-bold text-zinc-900 dark:text-white">Inspection Coverage</h4>
<p className="text-[10px] text-zinc-500 font-mono mt-0.5 uppercase tracking-wider">Damage Verification Complete</p> <p className="text-[10px] text-zinc-500 font-mono mt-0.5 uppercase tracking-wider">Damage Verification Complete</p>
</div> </div>
</div> </div>
@@ -402,7 +402,7 @@ const OwnerProjectDetail = () => {
{/* Embedded Map/Evidence Thumbnails */} {/* Embedded Map/Evidence Thumbnails */}
<div className="grid grid-cols-3 gap-2 mt-auto"> <div className="grid grid-cols-3 gap-2 mt-auto">
{['Hail_Damaged_Shingles.jpg', 'Cracked_Storm_Shingles.jpg', 'Broken_Roof_Surface.jpg', 'Curled_Aging_Shingles.jpg', 'Storm_Worn_Roof.jpg', 'Red_Shingle_Cottage.jpg'].map((img, i) => ( {['Hail_Damaged_Shingles.jpg', 'Cracked_Storm_Shingles.jpg', 'Broken_Roof_Surface.jpg', 'Curled_Aging_Shingles.jpg', 'Storm_Worn_Roof.jpg', 'Red_Shingle_Cottage.jpg'].map((img, i) => (
<div key={i} className="aspect-square bg-zinc-800 rounded-md overflow-hidden border border-white/5 relative group"> <div key={i} className="aspect-square bg-zinc-100 dark:bg-zinc-800 rounded-md overflow-hidden border border-zinc-200 dark:border-white/5 relative group">
<img src={`/assets/images/properties/${img}`} alt="Evidence" className="w-full h-full object-cover opacity-60 group-hover:opacity-100 transition duration-300 grayscale group-hover:grayscale-0" /> <img src={`/assets/images/properties/${img}`} alt="Evidence" className="w-full h-full object-cover opacity-60 group-hover:opacity-100 transition duration-300 grayscale group-hover:grayscale-0" />
<div className="absolute inset-0 shadow-[inset_0_0_15px_rgba(0,0,0,0.8)] pointer-events-none" /> <div className="absolute inset-0 shadow-[inset_0_0_15px_rgba(0,0,0,0.8)] pointer-events-none" />
</div> </div>
@@ -412,31 +412,31 @@ const OwnerProjectDetail = () => {
{/* Evidence Summary */} {/* Evidence Summary */}
<NeoCard spotlightColor="rgba(253, 169, 19, 0.1)"> <NeoCard spotlightColor="rgba(253, 169, 19, 0.1)">
<div className="flex items-center gap-3 mb-6 border-b border-white/5 pb-4"> <div className="flex items-center gap-3 mb-6 border-b border-zinc-200 dark:border-white/5 pb-4">
<Shield className={NEON_GOLD} size={20} /> <Shield className={NEON_GOLD} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Evidence Summary</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Evidence Summary</h3>
</div> </div>
<div className="space-y-4 mb-6 flex-1"> <div className="space-y-4 mb-6 flex-1">
<div className="flex justify-between items-center text-sm"> <div className="flex justify-between items-center text-sm">
<span className="flex items-center gap-2 text-white font-medium"><div className="w-1.5 h-1.5 rounded-full bg-amber-500" /> Hail Impacts Detected</span> <span className="flex items-center gap-2 text-zinc-800 dark:text-white font-medium"><div className="w-1.5 h-1.5 rounded-full bg-amber-500" /> Hail Impacts Detected</span>
<span className="font-bold text-xl text-white">178</span> <span className="font-bold text-xl text-zinc-900 dark:text-white">178</span>
</div> </div>
<div className="flex justify-between items-center text-sm"> <div className="flex justify-between items-center text-sm">
<span className="flex items-center gap-2 text-zinc-300"><div className="w-1.5 h-1.5 rounded-full bg-orange-500" /> Gutters Denting</span> <span className="flex items-center gap-2 text-zinc-600 dark:text-zinc-300"><div className="w-1.5 h-1.5 rounded-full bg-orange-500" /> Gutters Denting</span>
<span className="font-medium text-amber-500 uppercase text-xs tracking-wider">Moderate</span> <span className="font-medium text-amber-600 dark:text-amber-500 uppercase text-xs tracking-wider">Moderate</span>
</div> </div>
<div className="flex justify-between items-center text-sm"> <div className="flex justify-between items-center text-sm">
<span className="flex items-center gap-2 text-zinc-300"><div className="w-1.5 h-1.5 rounded-full bg-yellow-500" /> Window Screens</span> <span className="flex items-center gap-2 text-zinc-600 dark:text-zinc-300"><div className="w-1.5 h-1.5 rounded-full bg-yellow-500" /> Window Screens</span>
<span className="font-medium text-white">4 / 12</span> <span className="font-medium text-zinc-800 dark:text-white">4 / 12</span>
</div> </div>
</div> </div>
<div className="mt-auto pt-4 border-t border-white/5 flex items-center justify-between"> <div className="mt-auto pt-4 border-t border-zinc-200 dark:border-white/5 flex items-center justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Zap size={14} className="text-[#39ff14]" /> <Zap size={14} className="text-green-600 dark:text-[#39ff14]" />
<span className="text-[10px] font-mono text-zinc-400 uppercase tracking-widest">AI Confidence:</span> <span className="text-[10px] font-mono text-zinc-500 dark:text-zinc-400 uppercase tracking-widest">AI Confidence:</span>
<span className="text-sm font-bold text-[#39ff14]">92%</span> <span className="text-sm font-bold text-green-600 dark:text-[#39ff14]">92%</span>
</div> </div>
<button className="text-[10px] uppercase font-bold tracking-widest bg-zinc-800 hover:bg-zinc-700 text-zinc-300 px-3 py-1.5 rounded-md border border-white/10 transition flex items-center gap-1.5"> <button className="text-[10px] uppercase font-bold tracking-widest bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 text-zinc-600 dark:text-zinc-300 px-3 py-1.5 rounded-md border border-zinc-200 dark:border-white/10 transition flex items-center gap-1.5">
Evidence Map <ChevronRight size={12} /> Evidence Map <ChevronRight size={12} />
</button> </button>
</div> </div>
@@ -444,25 +444,25 @@ const OwnerProjectDetail = () => {
{/* Financial Overview */} {/* Financial Overview */}
<NeoCard spotlightColor="rgba(0, 240, 255, 0.1)"> <NeoCard spotlightColor="rgba(0, 240, 255, 0.1)">
<div className="flex items-center gap-3 mb-6 border-b border-white/5 pb-4"> <div className="flex items-center gap-3 mb-6 border-b border-zinc-200 dark:border-white/5 pb-4">
<DollarSign className={NEON_BLUE} size={20} /> <DollarSign className={NEON_BLUE} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Financial Overview</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Financial Overview</h3>
</div> </div>
<div className="space-y-5"> <div className="space-y-5">
<div className="flex justify-between items-end"> <div className="flex justify-between items-end">
<span className="text-xs text-zinc-400 font-medium">Estimated Scope</span> <span className="text-xs text-zinc-500 dark:text-zinc-400 font-medium">Estimated Scope</span>
<span className="text-xl font-bold text-white">{formatCurrency(project.approvedBudget || 34190)}</span> <span className="text-xl font-bold text-zinc-900 dark:text-white">{formatCurrency(project.approvedBudget || 34190)}</span>
</div> </div>
<div className="flex justify-between items-end"> <div className="flex justify-between items-end">
<span className="text-xs text-zinc-400 font-medium">Supplements Potential</span> <span className="text-xs text-zinc-500 dark:text-zinc-400 font-medium">Supplements Potential</span>
<span className="text-sm font-bold text-blue-400">+ {formatCurrency(4800)}</span> <span className="text-sm font-bold text-blue-600 dark:text-blue-400">+ {formatCurrency(4800)}</span>
</div> </div>
<div className="flex justify-between items-end pb-4 border-b border-white/5"> <div className="flex justify-between items-end pb-4 border-b border-zinc-200 dark:border-white/5">
<span className="text-xs text-zinc-400 font-medium">Insurance Probability</span> <span className="text-xs text-zinc-500 dark:text-zinc-400 font-medium">Insurance Probability</span>
<span className="text-sm font-bold text-[#39ff14]">82%</span> <span className="text-sm font-bold text-green-600 dark:text-[#39ff14]">82%</span>
</div> </div>
<div className="flex justify-between items-end pt-2"> <div className="flex justify-between items-end pt-2">
<span className="text-sm font-bold text-zinc-300">Net Profit Projection</span> <span className="text-sm font-bold text-zinc-600 dark:text-zinc-300">Net Profit Projection</span>
<span className={`text-2xl font-black ${NEON_GREEN}`}>{formatCurrency(project.budget - project.spent || 14200)}</span> <span className={`text-2xl font-black ${NEON_GREEN}`}>{formatCurrency(project.budget - project.spent || 14200)}</span>
</div> </div>
</div> </div>
@@ -475,7 +475,7 @@ const OwnerProjectDetail = () => {
<NeoCard spotlightColor="rgba(255, 69, 0, 0.1)" className="lg:col-span-2"> <NeoCard spotlightColor="rgba(255, 69, 0, 0.1)" className="lg:col-span-2">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<AlertOctagon className={NEON_ORANGE} size={20} /> <AlertOctagon className={NEON_ORANGE} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Action Needed</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Action Needed</h3>
</div> </div>
<div className="space-y-3 mb-8"> <div className="space-y-3 mb-8">
{/* Pulled from Project Risks / Mocks */} {/* Pulled from Project Risks / Mocks */}
@@ -489,20 +489,20 @@ const OwnerProjectDetail = () => {
</div> </div>
</div> </div>
<div className="border-t border-white/5 pt-6 mt-auto"> <div className="border-t border-zinc-200 dark:border-white/5 pt-6 mt-auto">
<h4 className="text-[10px] uppercase font-mono font-bold text-zinc-500 tracking-widest mb-4">Project Timeline Highlights</h4> <h4 className="text-[10px] uppercase font-mono font-bold text-zinc-500 tracking-widest mb-4">Project Timeline Highlights</h4>
<div className="space-y-4"> <div className="space-y-4">
<div className="flex items-center justify-between text-xs"> <div className="flex items-center justify-between text-xs">
<div className="flex items-center gap-3 text-zinc-300"><CheckCircle size={14} className="text-[#39ff14]" /> Inspection Completed</div> <div className="flex items-center gap-3 text-zinc-600 dark:text-zinc-300"><CheckCircle size={14} className="text-green-600 dark:text-[#39ff14]" /> Inspection Completed</div>
<div className="flex items-center gap-3 font-mono"> <div className="flex items-center gap-3 font-mono">
<span className="text-zinc-500">Feb 20</span> <span className="text-zinc-500">Feb 20</span>
<span className="bg-zinc-800 text-zinc-400 px-2 py-0.5 rounded border border-white/5">Pending QC</span> <span className="bg-zinc-100 dark:bg-zinc-800 text-zinc-500 dark:text-zinc-400 px-2 py-0.5 rounded border border-zinc-200 dark:border-white/5">Pending QC</span>
</div> </div>
</div> </div>
<div className="flex items-center justify-between text-xs"> <div className="flex items-center justify-between text-xs">
<div className="flex items-center gap-3 text-zinc-300"><Clock size={14} className="text-orange-500" /> Claim Filed</div> <div className="flex items-center gap-3 text-zinc-600 dark:text-zinc-300"><Clock size={14} className="text-orange-500" /> Claim Filed</div>
<div className="flex items-center gap-3 font-mono"> <div className="flex items-center gap-3 font-mono">
<span className="text-zinc-600">Not Scheduled</span> <span className="text-zinc-500">Not Scheduled</span>
</div> </div>
</div> </div>
</div> </div>
@@ -513,16 +513,16 @@ const OwnerProjectDetail = () => {
<NeoCard spotlightColor="rgba(0, 240, 255, 0.1)" innerClassName="justify-between h-full relative"> <NeoCard spotlightColor="rgba(0, 240, 255, 0.1)" innerClassName="justify-between h-full relative">
<div className="flex items-center gap-3 mb-6"> <div className="flex items-center gap-3 mb-6">
<Activity className={NEON_BLUE} size={20} /> <Activity className={NEON_BLUE} size={20} />
<h3 className="text-sm font-mono font-bold text-white tracking-widest uppercase">Quick Actions</h3> <h3 className="text-sm font-mono font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Quick Actions</h3>
</div> </div>
<div className="space-y-2.5 flex-1 z-10"> <div className="space-y-2.5 flex-1 z-10">
<button className="w-full flex items-center gap-3 px-4 py-3 bg-zinc-800 hover:bg-zinc-700 hover:border-blue-500/50 text-white rounded-xl border border-white/5 transition-all group text-sm font-medium"> <button className="w-full flex items-center gap-3 px-4 py-3 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 hover:border-blue-500/50 text-zinc-800 dark:text-white rounded-xl border border-zinc-200 dark:border-white/5 transition-all group text-sm font-medium">
<Camera size={16} className="text-zinc-500 group-hover:text-blue-400 transition-colors" /> Capture Missing Photos <Camera size={16} className="text-zinc-500 group-hover:text-blue-400 transition-colors" /> Capture Missing Photos
</button> </button>
<button className="w-full flex items-center gap-3 px-4 py-3 bg-zinc-800 hover:bg-zinc-700 hover:border-amber-500/50 text-white rounded-xl border border-white/5 transition-all group text-sm font-medium"> <button className="w-full flex items-center gap-3 px-4 py-3 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 hover:border-amber-500/50 text-zinc-800 dark:text-white rounded-xl border border-zinc-200 dark:border-white/5 transition-all group text-sm font-medium">
<Map size={16} className="text-zinc-500 group-hover:text-amber-400 transition-colors" /> Generate Estimate Link <Map size={16} className="text-zinc-500 group-hover:text-amber-400 transition-colors" /> Generate Estimate Link
</button> </button>
<button className="w-full flex items-center gap-3 px-4 py-3 bg-zinc-800 hover:bg-zinc-700 hover:border-purple-500/50 text-white rounded-xl border border-white/5 transition-all group text-sm font-medium"> <button className="w-full flex items-center gap-3 px-4 py-3 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 hover:border-purple-500/50 text-zinc-800 dark:text-white rounded-xl border border-zinc-200 dark:border-white/5 transition-all group text-sm font-medium">
<FileText size={16} className="text-zinc-500 group-hover:text-purple-400 transition-colors" /> Send Homeowner Report <FileText size={16} className="text-zinc-500 group-hover:text-purple-400 transition-colors" /> Send Homeowner Report
</button> </button>
</div> </div>
@@ -543,7 +543,7 @@ const OwnerProjectDetail = () => {
<div className="flex items-center justify-between mb-1"> <div className="flex items-center justify-between mb-1">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<DollarSign className={NEON_BLUE} size={20} /> <DollarSign className={NEON_BLUE} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Budget Breakdown</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Budget Breakdown</h3>
</div> </div>
<button <button
onClick={() => setCreateModalConfig({ onClick={() => setCreateModalConfig({
@@ -562,7 +562,7 @@ const OwnerProjectDetail = () => {
</button> </button>
</div> </div>
<p className="text-xs text-zinc-400 mb-6 font-mono">Allocated vs Committed vs Actual ($k)</p> <p className="text-xs text-zinc-400 mb-6 font-mono">Allocated vs Committed vs Actual ($k)</p>
<div className="h-64 bg-black/20 rounded-xl p-4 border border-white/5 shadow-inner"> <div className="h-64 bg-zinc-50 dark:bg-black/20 rounded-xl p-4 border border-zinc-200 dark:border-white/5">
<ResponsiveContainer width="99%" height={256} minWidth={1} minHeight={1}> <ResponsiveContainer width="99%" height={256} minWidth={1} minHeight={1}>
<BarChart data={budgetChartData} barGap={2}> <BarChart data={budgetChartData} barGap={2}>
<XAxis dataKey="name" tick={{ fontSize: 11, fill: '#a1a1aa' }} axisLine={false} tickLine={false} /> <XAxis dataKey="name" tick={{ fontSize: 11, fill: '#a1a1aa' }} axisLine={false} tickLine={false} />
@@ -578,20 +578,20 @@ const OwnerProjectDetail = () => {
<NeoCard spotlightColor="rgba(253, 169, 19, 0.1)" innerClassName="p-0 lg:p-0"> <NeoCard spotlightColor="rgba(253, 169, 19, 0.1)" innerClassName="p-0 lg:p-0">
<div className="overflow-x-auto w-full rounded-2xl"> <div className="overflow-x-auto w-full rounded-2xl">
<table className="w-full text-left border-collapse min-w-[600px]"> <table className="w-full text-left border-collapse min-w-[600px]">
<thead className="bg-[#18181b]/80 border-b border-white/10"> <thead className="bg-zinc-100 dark:bg-[#18181b]/80 border-b border-zinc-200 dark:border-white/10">
<tr> <tr>
{['Category', 'Allocated', 'Committed', 'Actual', 'Variance'].map(h => ( {['Category', 'Allocated', 'Committed', 'Actual', 'Variance'].map(h => (
<th key={h} className={`px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-400 ${h !== 'Category' ? 'text-right' : ''}`}>{h}</th> <th key={h} className={`px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-400 ${h !== 'Category' ? 'text-right' : ''}`}>{h}</th>
))} ))}
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-white/5"> <tbody className="divide-y divide-zinc-100 dark:divide-white/5">
{(project.budgetBreakdown || []).map((b, i) => { {(project.budgetBreakdown || []).map((b, i) => {
const variance = b.actual - b.allocated; const variance = b.actual - b.allocated;
return ( return (
<tr key={i} className="hover:bg-white/5 transition-colors"> <tr key={i} className="hover:bg-zinc-50 dark:hover:bg-white/5 transition-colors">
<td className="px-5 py-4 font-bold text-sm text-white">{b.category}</td> <td className="px-5 py-4 font-bold text-sm text-zinc-900 dark:text-white">{b.category}</td>
<td className="px-5 py-4 text-right font-mono text-sm text-zinc-300">{formatCurrency(b.allocated)}</td> <td className="px-5 py-4 text-right font-mono text-sm text-zinc-600 dark:text-zinc-300">{formatCurrency(b.allocated)}</td>
<td className="px-5 py-4 text-right font-mono text-sm text-amber-500">{formatCurrency(b.committed)}</td> <td className="px-5 py-4 text-right font-mono text-sm text-amber-500">{formatCurrency(b.committed)}</td>
<td className="px-5 py-4 text-right font-mono text-sm text-[#00f0ff]">{formatCurrency(b.actual)}</td> <td className="px-5 py-4 text-right font-mono text-sm text-[#00f0ff]">{formatCurrency(b.actual)}</td>
<td className={`px-5 py-4 text-right font-mono text-sm font-bold ${variance > 0 ? 'text-[#ff4500]' : 'text-[#39ff14]'}`}> <td className={`px-5 py-4 text-right font-mono text-sm font-bold ${variance > 0 ? 'text-[#ff4500]' : 'text-[#39ff14]'}`}>
@@ -608,7 +608,7 @@ const OwnerProjectDetail = () => {
) : ( ) : (
<NeoCard className="p-12 text-center text-zinc-500"> <NeoCard className="p-12 text-center text-zinc-500">
<DollarSign size={48} className="mx-auto mb-4 text-zinc-600" /> <DollarSign size={48} className="mx-auto mb-4 text-zinc-600" />
<p className="font-bold text-lg text-white">No detailed budget breakdown available.</p> <p className="font-bold text-lg text-zinc-900 dark:text-white">No detailed budget breakdown available.</p>
<p className="text-sm mt-2 text-zinc-400 font-mono">Budget: {formatCurrency(project.approvedBudget || project.budget)} &nbsp;&middot;&nbsp; Spent: {formatCurrency(project.actualCost || project.spent)}</p> <p className="text-sm mt-2 text-zinc-400 font-mono">Budget: {formatCurrency(project.approvedBudget || project.budget)} &nbsp;&middot;&nbsp; Spent: {formatCurrency(project.actualCost || project.spent)}</p>
</NeoCard> </NeoCard>
)} )}
@@ -618,10 +618,10 @@ const OwnerProjectDetail = () => {
{/* CHANGE ORDERS TAB */} {/* CHANGE ORDERS TAB */}
{activeTab === 'changeOrders' && ( {activeTab === 'changeOrders' && (
<NeoCard spotlightColor="rgba(253, 169, 19, 0.1)" innerClassName="p-0 lg:p-0"> <NeoCard spotlightColor="rgba(253, 169, 19, 0.1)" innerClassName="p-0 lg:p-0">
<div className="p-5 border-b border-white/5 flex items-center justify-between"> <div className="p-5 border-b border-zinc-200 dark:border-white/5 flex items-center justify-between">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<GitPullRequest className={NEON_GOLD} size={20} /> <GitPullRequest className={NEON_GOLD} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Change Orders</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Change Orders</h3>
</div> </div>
<button <button
onClick={() => setCreateModalConfig({ onClick={() => setCreateModalConfig({
@@ -642,19 +642,19 @@ const OwnerProjectDetail = () => {
<div className="overflow-x-auto w-full"> <div className="overflow-x-auto w-full">
{(project.changeOrders || []).length > 0 ? ( {(project.changeOrders || []).length > 0 ? (
<table className="w-full text-left border-collapse min-w-[700px]"> <table className="w-full text-left border-collapse min-w-[700px]">
<thead className="bg-[#18181b]/80 border-b border-white/10"> <thead className="bg-zinc-100 dark:bg-[#18181b]/80 border-b border-zinc-200 dark:border-white/10">
<tr> <tr>
{['ID', 'Title', 'Amount', 'Status', 'Date'].map(h => ( {['ID', 'Title', 'Amount', 'Status', 'Date'].map(h => (
<th key={h} className="px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-400">{h}</th> <th key={h} className="px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-500 dark:text-zinc-400">{h}</th>
))} ))}
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-white/5"> <tbody className="divide-y divide-zinc-100 dark:divide-white/5">
{project.changeOrders.map((co, i) => ( {project.changeOrders.map((co, i) => (
<tr key={i} className="hover:bg-white/5 transition-colors cursor-pointer" tabIndex="0" onClick={() => setSelectedCO(co)} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setSelectedCO(co); } }}> <tr key={i} className="hover:bg-zinc-50 dark:hover:bg-white/5 transition-colors cursor-pointer" tabIndex="0" onClick={() => setSelectedCO(co)} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setSelectedCO(co); } }}>
<td className="px-5 py-4 font-mono text-xs text-zinc-500">{co.id}</td> <td className="px-5 py-4 font-mono text-xs text-zinc-500">{co.id}</td>
<td className="px-5 py-4"> <td className="px-5 py-4">
<div className="font-bold text-sm text-white">{co.title}</div> <div className="font-bold text-sm text-zinc-900 dark:text-white">{co.title}</div>
{co.description && <div className="text-xs text-zinc-400 mt-1">{co.description}</div>} {co.description && <div className="text-xs text-zinc-400 mt-1">{co.description}</div>}
</td> </td>
<td className="px-5 py-4 font-mono text-sm text-[#00f0ff]">{formatCurrency(co.amount)}</td> <td className="px-5 py-4 font-mono text-sm text-[#00f0ff]">{formatCurrency(co.amount)}</td>
@@ -674,7 +674,7 @@ const OwnerProjectDetail = () => {
) : ( ) : (
<div className="p-16 text-center text-zinc-500"> <div className="p-16 text-center text-zinc-500">
<GitPullRequest size={48} className="mx-auto mb-4 text-zinc-600" /> <GitPullRequest size={48} className="mx-auto mb-4 text-zinc-600" />
<p className="font-bold text-lg text-white">No change orders found.</p> <p className="font-bold text-lg text-zinc-900 dark:text-white">No change orders found.</p>
</div> </div>
)} )}
</div> </div>
@@ -684,10 +684,10 @@ const OwnerProjectDetail = () => {
{/* RFIs TAB */} {/* RFIs TAB */}
{activeTab === 'rfis' && ( {activeTab === 'rfis' && (
<NeoCard spotlightColor="rgba(0, 240, 255, 0.1)" innerClassName="p-0 lg:p-0"> <NeoCard spotlightColor="rgba(0, 240, 255, 0.1)" innerClassName="p-0 lg:p-0">
<div className="p-5 border-b border-white/5 flex items-center justify-between"> <div className="p-5 border-b border-zinc-200 dark:border-white/5 flex items-center justify-between">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<FileText className={NEON_BLUE} size={20} /> <FileText className={NEON_BLUE} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Requests for Information (RFI)</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Requests for Information (RFI)</h3>
</div> </div>
<button <button
onClick={() => setCreateModalConfig({ onClick={() => setCreateModalConfig({
@@ -709,18 +709,18 @@ const OwnerProjectDetail = () => {
<div className="overflow-x-auto w-full"> <div className="overflow-x-auto w-full">
{(project.rfis || []).length > 0 ? ( {(project.rfis || []).length > 0 ? (
<table className="w-full text-left border-collapse min-w-[800px]"> <table className="w-full text-left border-collapse min-w-[800px]">
<thead className="bg-[#18181b]/80 border-b border-white/10"> <thead className="bg-zinc-100 dark:bg-[#18181b]/80 border-b border-zinc-200 dark:border-white/10">
<tr> <tr>
{['ID', 'Subject', 'Status', 'Submitted By', 'Opened', 'Closed'].map(h => ( {['ID', 'Subject', 'Status', 'Submitted By', 'Opened', 'Closed'].map(h => (
<th key={h} className="px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-400">{h}</th> <th key={h} className="px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-500 dark:text-zinc-400">{h}</th>
))} ))}
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-white/5"> <tbody className="divide-y divide-zinc-100 dark:divide-white/5">
{project.rfis.map((rfi, i) => ( {project.rfis.map((rfi, i) => (
<tr key={i} className="hover:bg-white/5 transition-colors"> <tr key={i} className="hover:bg-zinc-50 dark:hover:bg-white/5 transition-colors">
<td className="px-5 py-4 font-mono text-xs text-zinc-500">{rfi.id}</td> <td className="px-5 py-4 font-mono text-xs text-zinc-500">{rfi.id}</td>
<td className="px-5 py-4 font-bold text-sm text-white">{rfi.subject}</td> <td className="px-5 py-4 font-bold text-sm text-zinc-900 dark:text-white">{rfi.subject}</td>
<td className="px-5 py-4"> <td className="px-5 py-4">
<span className={`px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-widest ${rfi.status === 'closed' ? 'text-[#39ff14] bg-[#39ff14]/10 border border-[#39ff14]/20' : <span className={`px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-widest ${rfi.status === 'closed' ? 'text-[#39ff14] bg-[#39ff14]/10 border border-[#39ff14]/20' :
'text-amber-400 bg-amber-500/10 border border-amber-500/20' 'text-amber-400 bg-amber-500/10 border border-amber-500/20'
@@ -738,7 +738,7 @@ const OwnerProjectDetail = () => {
) : ( ) : (
<div className="p-16 text-center text-zinc-500"> <div className="p-16 text-center text-zinc-500">
<FileText size={48} className="mx-auto mb-4 text-zinc-600" /> <FileText size={48} className="mx-auto mb-4 text-zinc-600" />
<p className="font-bold text-lg text-white">No RFIs for this project.</p> <p className="font-bold text-lg text-zinc-900 dark:text-white">No RFIs for this project.</p>
</div> </div>
)} )}
</div> </div>
@@ -749,25 +749,25 @@ const OwnerProjectDetail = () => {
{activeTab === 'milestones' && ( {activeTab === 'milestones' && (
<NeoCard spotlightColor="rgba(255, 255, 255, 0.1)"> <NeoCard spotlightColor="rgba(255, 255, 255, 0.1)">
<div className="flex items-center gap-3 mb-8"> <div className="flex items-center gap-3 mb-8">
<MapPin className="text-white" size={20} /> <MapPin className="text-zinc-700 dark:text-white" size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Milestone Timeline</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Milestone Timeline</h3>
</div> </div>
<div className="relative"> <div className="relative">
{/* Timeline line */} {/* Timeline line */}
<div className="absolute left-6 top-0 bottom-0 w-px bg-white/10" /> <div className="absolute left-6 top-0 bottom-0 w-px bg-zinc-200 dark:bg-white/10" />
<div className="space-y-6"> <div className="space-y-6">
{(project.milestones || []).map((ms, i) => ( {(project.milestones || []).map((ms, i) => (
<div key={i} className="relative flex items-start gap-4 pl-12"> <div key={i} className="relative flex items-start gap-4 pl-12">
<div className={`absolute left-[21px] top-1.5 w-2.5 h-2.5 rounded-full bg-[#09090b] border-2 shadow-[0_0_8px_rgba(255,255,255,0.4)] ${ms.status === 'completed' ? 'border-[#39ff14]' : ms.status === 'in_progress' ? 'border-[#00f0ff]' : 'border-zinc-500'}`} /> <div className={`absolute left-[21px] top-1.5 w-2.5 h-2.5 rounded-full bg-white dark:bg-[#09090b] border-2 ${ms.status === 'completed' ? 'border-green-500 dark:border-[#39ff14]' : ms.status === 'in_progress' ? 'border-sky-500 dark:border-[#00f0ff]' : 'border-zinc-400 dark:border-zinc-500'}`} />
<div className="flex-1 p-4 rounded-xl bg-white/5 border border-white/5 hover:bg-white/10 transition-colors"> <div className="flex-1 p-4 rounded-xl bg-zinc-50 dark:bg-white/5 border border-zinc-100 dark:border-white/5 hover:bg-zinc-100 dark:hover:bg-white/10 transition-colors">
<div className="flex justify-between items-start"> <div className="flex justify-between items-start">
<div> <div>
<div className="font-bold text-white">{ms.name}</div> <div className="font-bold text-zinc-900 dark:text-white">{ms.name}</div>
<div className="text-xs text-zinc-400 mt-1">Due: <span className="text-zinc-300 font-mono">{ms.dueDate}</span> &middot; Assigned to: <span className="text-[#00f0ff] uppercase tracking-wider">{ms.assignedTo}</span></div> <div className="text-xs text-zinc-500 dark:text-zinc-400 mt-1">Due: <span className="text-zinc-600 dark:text-zinc-300 font-mono">{ms.dueDate}</span> &middot; Assigned to: <span className="text-sky-600 dark:text-[#00f0ff] uppercase tracking-wider">{ms.assignedTo}</span></div>
</div> </div>
<span className={`text-[10px] font-bold uppercase tracking-wider px-3 py-1 rounded-full ${ms.status === 'completed' ? 'text-[#39ff14] bg-[#39ff14]/10 border border-[#39ff14]/20' : <span className={`text-[10px] font-bold uppercase tracking-wider px-3 py-1 rounded-full ${ms.status === 'completed' ? 'text-green-600 dark:text-[#39ff14] bg-green-50 dark:bg-[#39ff14]/10 border border-green-200 dark:border-[#39ff14]/20' :
ms.status === 'in_progress' ? 'text-[#00f0ff] bg-blue-500/10 border border-blue-500/20' : ms.status === 'in_progress' ? 'text-sky-600 dark:text-[#00f0ff] bg-sky-50 dark:bg-blue-500/10 border border-sky-200 dark:border-blue-500/20' :
'text-zinc-500 bg-white/5 border border-white/10' 'text-zinc-500 bg-zinc-100 dark:bg-white/5 border border-zinc-200 dark:border-white/10'
}`}> }`}>
{ms.status.replace('_', ' ')} {ms.status.replace('_', ' ')}
</span> </span>
@@ -783,10 +783,10 @@ const OwnerProjectDetail = () => {
{/* INVOICES TAB */} {/* INVOICES TAB */}
{activeTab === 'invoices' && ( {activeTab === 'invoices' && (
<NeoCard spotlightColor="rgba(0, 240, 255, 0.1)" innerClassName="p-0 lg:p-0"> <NeoCard spotlightColor="rgba(0, 240, 255, 0.1)" innerClassName="p-0 lg:p-0">
<div className="p-5 border-b border-white/5 flex items-center justify-between"> <div className="p-5 border-b border-zinc-200 dark:border-white/5 flex items-center justify-between">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<DollarSign className={NEON_BLUE} size={20} /> <DollarSign className={NEON_BLUE} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Invoices</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Invoices</h3>
</div> </div>
<button <button
onClick={() => setCreateModalConfig({ onClick={() => setCreateModalConfig({
@@ -807,16 +807,16 @@ const OwnerProjectDetail = () => {
<div className="overflow-x-auto w-full"> <div className="overflow-x-auto w-full">
{(project.invoices || []).length > 0 ? ( {(project.invoices || []).length > 0 ? (
<table className="w-full text-left border-collapse min-w-[700px]"> <table className="w-full text-left border-collapse min-w-[700px]">
<thead className="bg-[#18181b]/80 border-b border-white/10"> <thead className="bg-zinc-100 dark:bg-[#18181b]/80 border-b border-zinc-200 dark:border-white/10">
<tr> <tr>
{['Invoice ID', 'Amount', 'Submitted By', 'Status', 'Due Date', 'Paid Date'].map(h => ( {['Invoice ID', 'Amount', 'Submitted By', 'Status', 'Due Date', 'Paid Date'].map(h => (
<th key={h} className={`px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-400 ${h === 'Amount' ? 'text-right' : ''}`}>{h}</th> <th key={h} className={`px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-400 ${h === 'Amount' ? 'text-right' : ''}`}>{h}</th>
))} ))}
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-white/5"> <tbody className="divide-y divide-zinc-100 dark:divide-white/5">
{project.invoices.map((inv, i) => ( {project.invoices.map((inv, i) => (
<tr key={i} className="hover:bg-white/5 transition-colors cursor-pointer" tabIndex="0" onClick={() => setSelectedInvoice(inv)} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setSelectedInvoice(inv); } }}> <tr key={i} className="hover:bg-zinc-50 dark:hover:bg-white/5 transition-colors cursor-pointer" tabIndex="0" onClick={() => setSelectedInvoice(inv)} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setSelectedInvoice(inv); } }}>
<td className="px-5 py-4 font-mono text-xs text-zinc-500">{inv.id}</td> <td className="px-5 py-4 font-mono text-xs text-zinc-500">{inv.id}</td>
<td className="px-5 py-4 text-right font-mono text-sm font-bold text-[#00f0ff]"> <td className="px-5 py-4 text-right font-mono text-sm font-bold text-[#00f0ff]">
{formatCurrency(inv.amount)} {formatCurrency(inv.amount)}
@@ -840,7 +840,7 @@ const OwnerProjectDetail = () => {
) : ( ) : (
<div className="p-16 text-center text-zinc-500"> <div className="p-16 text-center text-zinc-500">
<DollarSign size={48} className="mx-auto mb-4 text-zinc-600" /> <DollarSign size={48} className="mx-auto mb-4 text-zinc-600" />
<p className="font-bold text-lg text-white">No invoices for this project.</p> <p className="font-bold text-lg text-zinc-900 dark:text-white">No invoices for this project.</p>
</div> </div>
)} )}
</div> </div>
@@ -852,10 +852,10 @@ const OwnerProjectDetail = () => {
<div className="space-y-6"> <div className="space-y-6">
{/* Risk Log */} {/* Risk Log */}
<NeoCard spotlightColor="rgba(253, 169, 19, 0.1)" innerClassName="p-0 lg:p-0"> <NeoCard spotlightColor="rgba(253, 169, 19, 0.1)" innerClassName="p-0 lg:p-0">
<div className="p-5 border-b border-white/5 flex items-center justify-between"> <div className="p-5 border-b border-zinc-200 dark:border-white/5 flex items-center justify-between">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Shield className={NEON_GOLD} size={20} /> <Shield className={NEON_GOLD} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Risk Log</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Risk Log</h3>
</div> </div>
<button <button
onClick={() => setCreateModalConfig({ onClick={() => setCreateModalConfig({
@@ -877,18 +877,18 @@ const OwnerProjectDetail = () => {
<div className="overflow-x-auto w-full"> <div className="overflow-x-auto w-full">
{(project.riskLog || []).length > 0 ? ( {(project.riskLog || []).length > 0 ? (
<table className="w-full text-left border-collapse min-w-[800px]"> <table className="w-full text-left border-collapse min-w-[800px]">
<thead className="bg-[#18181b]/80 border-b border-white/10"> <thead className="bg-zinc-100 dark:bg-[#18181b]/80 border-b border-zinc-200 dark:border-white/10">
<tr> <tr>
{['ID', 'Description', 'Severity', 'Likelihood', 'Status', 'Mitigation'].map(h => ( {['ID', 'Description', 'Severity', 'Likelihood', 'Status', 'Mitigation'].map(h => (
<th key={h} className="px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-400">{h}</th> <th key={h} className="px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-500 dark:text-zinc-400">{h}</th>
))} ))}
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-white/5"> <tbody className="divide-y divide-zinc-100 dark:divide-white/5">
{project.riskLog.map((r, i) => ( {project.riskLog.map((r, i) => (
<tr key={i} className="hover:bg-white/5 transition-colors"> <tr key={i} className="hover:bg-zinc-50 dark:hover:bg-white/5 transition-colors">
<td className="px-5 py-4 font-mono text-xs text-zinc-500">{r.id}</td> <td className="px-5 py-4 font-mono text-xs text-zinc-500">{r.id}</td>
<td className="px-5 py-4 text-sm font-medium text-white max-w-xs">{r.description}</td> <td className="px-5 py-4 text-sm font-medium text-zinc-700 dark:text-white max-w-xs">{r.description}</td>
<td className="px-5 py-4"> <td className="px-5 py-4">
<span className={`text-[10px] font-bold uppercase px-3 py-1 rounded-full ${r.severity === 'High' ? 'text-[#ff4500] bg-[#ff4500]/10 border border-[#ff4500]/20' : <span className={`text-[10px] font-bold uppercase px-3 py-1 rounded-full ${r.severity === 'High' ? 'text-[#ff4500] bg-[#ff4500]/10 border border-[#ff4500]/20' :
r.severity === 'Medium' ? 'text-amber-400 bg-amber-500/10 border border-amber-500/20' : r.severity === 'Medium' ? 'text-amber-400 bg-amber-500/10 border border-amber-500/20' :
@@ -907,7 +907,7 @@ const OwnerProjectDetail = () => {
) : ( ) : (
<div className="p-16 text-center text-zinc-500"> <div className="p-16 text-center text-zinc-500">
<Shield size={48} className="mx-auto mb-4 text-zinc-600" /> <Shield size={48} className="mx-auto mb-4 text-zinc-600" />
<p className="font-bold text-lg text-white">No risk entries for this project.</p> <p className="font-bold text-lg text-zinc-900 dark:text-white">No risk entries for this project.</p>
</div> </div>
)} )}
</div> </div>
@@ -915,10 +915,10 @@ const OwnerProjectDetail = () => {
{/* Issue Log */} {/* Issue Log */}
<NeoCard spotlightColor="rgba(255, 69, 0, 0.1)" innerClassName="p-0 lg:p-0"> <NeoCard spotlightColor="rgba(255, 69, 0, 0.1)" innerClassName="p-0 lg:p-0">
<div className="p-5 border-b border-white/5 flex items-center justify-between"> <div className="p-5 border-b border-zinc-200 dark:border-white/5 flex items-center justify-between">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<AlertCircle className={NEON_RED} size={20} /> <AlertCircle className={NEON_RED} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Issue Log</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Issue Log</h3>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<button <button
@@ -957,18 +957,18 @@ const OwnerProjectDetail = () => {
<div className="overflow-x-auto w-full"> <div className="overflow-x-auto w-full">
{(project.issueLog || []).length > 0 ? ( {(project.issueLog || []).length > 0 ? (
<table className="w-full text-left border-collapse min-w-[800px]"> <table className="w-full text-left border-collapse min-w-[800px]">
<thead className="bg-[#18181b]/80 border-b border-white/10"> <thead className="bg-zinc-100 dark:bg-[#18181b]/80 border-b border-zinc-200 dark:border-white/10">
<tr> <tr>
{['ID', 'Title', 'Priority', 'Status', 'Assigned To', 'Reported'].map(h => ( {['ID', 'Title', 'Priority', 'Status', 'Assigned To', 'Reported'].map(h => (
<th key={h} className="px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-400">{h}</th> <th key={h} className="px-5 py-4 text-xs font-bold uppercase tracking-wider text-zinc-500 dark:text-zinc-400">{h}</th>
))} ))}
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-white/5"> <tbody className="divide-y divide-zinc-100 dark:divide-white/5">
{project.issueLog.map((issue, i) => ( {project.issueLog.map((issue, i) => (
<tr key={i} className="hover:bg-white/5 transition-colors"> <tr key={i} className="hover:bg-zinc-50 dark:hover:bg-white/5 transition-colors">
<td className="px-5 py-4 font-mono text-xs text-zinc-500">{issue.id}</td> <td className="px-5 py-4 font-mono text-xs text-zinc-500">{issue.id}</td>
<td className="px-5 py-4 font-bold text-sm text-white">{issue.title}</td> <td className="px-5 py-4 font-bold text-sm text-zinc-900 dark:text-white">{issue.title}</td>
<td className="px-5 py-4"> <td className="px-5 py-4">
<span className={`text-[10px] font-bold uppercase px-3 py-1 rounded-full ${issue.priority === 'High' || issue.priority === 'critical' ? 'text-[#ff4500] bg-[#ff4500]/10 border border-[#ff4500]/20' : <span className={`text-[10px] font-bold uppercase px-3 py-1 rounded-full ${issue.priority === 'High' || issue.priority === 'critical' ? 'text-[#ff4500] bg-[#ff4500]/10 border border-[#ff4500]/20' :
issue.priority === 'Medium' || issue.priority === 'high' ? 'text-amber-400 bg-amber-500/10 border border-amber-500/20' : issue.priority === 'Medium' || issue.priority === 'high' ? 'text-amber-400 bg-amber-500/10 border border-amber-500/20' :
@@ -987,7 +987,7 @@ const OwnerProjectDetail = () => {
) : ( ) : (
<div className="p-16 text-center text-zinc-500"> <div className="p-16 text-center text-zinc-500">
<AlertCircle size={48} className="mx-auto mb-4 text-zinc-600" /> <AlertCircle size={48} className="mx-auto mb-4 text-zinc-600" />
<p className="font-bold text-lg text-white">No issues logged for this project.</p> <p className="font-bold text-lg text-zinc-900 dark:text-white">No issues logged for this project.</p>
</div> </div>
)} )}
</div> </div>
@@ -1002,8 +1002,8 @@ const OwnerProjectDetail = () => {
<div className="flex items-center justify-between mb-6"> <div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<FolderOpen className={NEON_BLUE} size={20} /> <FolderOpen className={NEON_BLUE} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Project Documents</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Project Documents</h3>
<span className="text-xs font-bold bg-white/5 border border-white/5 px-2 py-0.5 rounded-full text-zinc-400"> <span className="text-xs font-bold bg-zinc-100 dark:bg-white/5 border border-zinc-200 dark:border-white/5 px-2 py-0.5 rounded-full text-zinc-500 dark:text-zinc-400">
{docs.length} {docs.length}
</span> </span>
</div> </div>
@@ -1018,7 +1018,7 @@ const OwnerProjectDetail = () => {
{docs.length === 0 ? ( {docs.length === 0 ? (
<div className="text-center py-16"> <div className="text-center py-16">
<FolderOpen size={48} className="mx-auto mb-4 text-zinc-700" /> <FolderOpen size={48} className="mx-auto mb-4 text-zinc-700" />
<p className="font-bold text-lg text-white">No documents yet</p> <p className="font-bold text-lg text-zinc-900 dark:text-white">No documents yet</p>
<p className="text-sm text-zinc-500 mt-1">Upload contracts, photos, inspection reports, and more.</p> <p className="text-sm text-zinc-500 mt-1">Upload contracts, photos, inspection reports, and more.</p>
</div> </div>
) : ( ) : (
@@ -1029,7 +1029,7 @@ const OwnerProjectDetail = () => {
return ( return (
<div <div
key={doc.id} key={doc.id}
className="flex items-start gap-4 px-4 py-4 rounded-2xl bg-white/[0.03] border border-white/[0.06] hover:bg-white/[0.07] transition-colors group" className="flex items-start gap-4 px-4 py-4 rounded-2xl bg-zinc-50 dark:bg-white/[0.03] border border-zinc-100 dark:border-white/[0.06] hover:bg-zinc-100 dark:hover:bg-white/[0.07] transition-colors group"
> >
{/* Type icon */} {/* Type icon */}
<div <div
@@ -1042,7 +1042,7 @@ const OwnerProjectDetail = () => {
{/* Info */} {/* Info */}
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<div className="flex items-center gap-2 flex-wrap"> <div className="flex items-center gap-2 flex-wrap">
<p className="font-semibold text-white text-sm truncate">{doc.name}</p> <p className="font-semibold text-zinc-900 dark:text-white text-sm truncate">{doc.name}</p>
<span <span
className="text-[10px] font-bold px-1.5 py-0.5 rounded-md uppercase" className="text-[10px] font-bold px-1.5 py-0.5 rounded-md uppercase"
style={{ backgroundColor: cfg.bg, color: cfg.color }} style={{ backgroundColor: cfg.bg, color: cfg.color }}
@@ -1072,21 +1072,21 @@ const OwnerProjectDetail = () => {
<div className="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"> <div className="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity">
<button <button
onClick={() => setViewDoc(doc)} onClick={() => setViewDoc(doc)}
className="p-1.5 rounded-lg bg-white/5 hover:bg-white/10 text-zinc-400 hover:text-[#00f0ff] transition-colors" className="p-1.5 rounded-lg bg-zinc-100 dark:bg-white/5 hover:bg-zinc-200 dark:hover:bg-white/10 text-zinc-500 dark:text-zinc-400 hover:text-sky-500 dark:hover:text-[#00f0ff] transition-colors"
title="View" title="View"
> >
<Eye size={14} /> <Eye size={14} />
</button> </button>
<button <button
onClick={() => setEditNoteDoc({ doc, noteText: doc.notes || '' })} onClick={() => setEditNoteDoc({ doc, noteText: doc.notes || '' })}
className="p-1.5 rounded-lg bg-white/5 hover:bg-white/10 text-zinc-400 hover:text-amber-400 transition-colors" className="p-1.5 rounded-lg bg-zinc-100 dark:bg-white/5 hover:bg-zinc-200 dark:hover:bg-white/10 text-zinc-500 dark:text-zinc-400 hover:text-amber-500 dark:hover:text-amber-400 transition-colors"
title="Edit note" title="Edit note"
> >
<Pencil size={14} /> <Pencil size={14} />
</button> </button>
<button <button
onClick={() => setDeleteDocId(doc.id)} onClick={() => setDeleteDocId(doc.id)}
className="p-1.5 rounded-lg bg-white/5 hover:bg-red-500/20 text-zinc-400 hover:text-red-400 transition-colors" className="p-1.5 rounded-lg bg-zinc-100 dark:bg-white/5 hover:bg-red-50 dark:hover:bg-red-500/20 text-zinc-500 dark:text-zinc-400 hover:text-red-500 dark:hover:text-red-400 transition-colors"
title="Delete" title="Delete"
> >
<Trash2 size={14} /> <Trash2 size={14} />
@@ -1104,24 +1104,24 @@ const OwnerProjectDetail = () => {
<NeoCard spotlightColor="rgba(57, 255, 20, 0.1)"> <NeoCard spotlightColor="rgba(57, 255, 20, 0.1)">
<div className="flex items-center gap-3 mb-8"> <div className="flex items-center gap-3 mb-8">
<Clock className={NEON_GREEN} size={20} /> <Clock className={NEON_GREEN} size={20} />
<h3 className="text-lg font-bold text-white tracking-widest uppercase">Activity Timeline</h3> <h3 className="text-lg font-bold text-zinc-900 dark:text-white tracking-widest uppercase">Activity Timeline</h3>
</div> </div>
{(project.activityTimeline || []).length > 0 ? ( {(project.activityTimeline || []).length > 0 ? (
<div className="relative"> <div className="relative">
<div className="absolute left-6 top-0 bottom-0 w-px bg-white/10" /> <div className="absolute left-6 top-0 bottom-0 w-px bg-zinc-200 dark:bg-white/10" />
<div className="space-y-6"> <div className="space-y-6">
{project.activityTimeline.map((a, i) => ( {project.activityTimeline.map((a, i) => (
<div key={i} className="relative flex items-start gap-4 pl-12"> <div key={i} className="relative flex items-start gap-4 pl-12">
<div className={`absolute left-[21px] top-1.5 w-2.5 h-2.5 rounded-full bg-[#09090b] border-2 shadow-[0_0_8px_rgba(57,255,20,0.4)] ${a.action.includes('Payment') ? 'border-amber-400' : a.action.includes('Issue') ? 'border-[#ff4500]' : 'border-[#39ff14]'}`} /> <div className={`absolute left-[21px] top-1.5 w-2.5 h-2.5 rounded-full bg-white dark:bg-[#09090b] border-2 ${a.action.includes('Payment') ? 'border-amber-500' : a.action.includes('Issue') ? 'border-orange-500' : 'border-green-500 dark:border-[#39ff14]'}`} />
<div className="flex-1 p-4 rounded-xl bg-white/5 border border-white/5 hover:bg-white/10 transition-colors"> <div className="flex-1 p-4 rounded-xl bg-zinc-50 dark:bg-white/5 border border-zinc-100 dark:border-white/5 hover:bg-zinc-100 dark:hover:bg-white/10 transition-colors">
<div className="flex justify-between items-start"> <div className="flex justify-between items-start">
<div> <div>
<div className="font-bold text-white text-sm">{a.action}</div> <div className="font-bold text-zinc-900 dark:text-white text-sm">{a.action}</div>
{a.details && <div className="text-xs text-zinc-400 mt-1">{a.details}</div>} {a.details && <div className="text-xs text-zinc-500 dark:text-zinc-400 mt-1">{a.details}</div>}
</div> </div>
<div className="text-right shrink-0 ml-4"> <div className="text-right shrink-0 ml-4">
<div className="text-xs font-mono text-zinc-500">{a.date}</div> <div className="text-xs font-mono text-zinc-500">{a.date}</div>
{a.user && <div className="text-[10px] uppercase tracking-wider text-[#00f0ff] mt-1">{a.user}</div>} {a.user && <div className="text-[10px] uppercase tracking-wider text-sky-600 dark:text-[#00f0ff] mt-1">{a.user}</div>}
</div> </div>
</div> </div>
</div> </div>
@@ -1132,7 +1132,7 @@ const OwnerProjectDetail = () => {
) : ( ) : (
<div className="text-center text-zinc-500 py-16"> <div className="text-center text-zinc-500 py-16">
<Clock size={48} className="mx-auto mb-4 text-zinc-600" /> <Clock size={48} className="mx-auto mb-4 text-zinc-600" />
<p className="font-bold text-lg text-white">No activity logged yet.</p> <p className="font-bold text-lg text-zinc-900 dark:text-white">No activity logged yet.</p>
</div> </div>
)} )}
</NeoCard> </NeoCard>