scalesite/components/dashboard/project-card.tsx
bast1qn 98552163a8 Initial ScaleSite Next.js implementation
Complete frontend implementation with:
- Next.js 16 with App Router and TypeScript
- Tailwind CSS v4 with custom violet theme
- shadcn/ui components with Lucide React icons
- Landing page with hero, services, pricing, testimonials, FAQ
- Service selection page with toggle
- Login/Register pages with social auth UI
- Multi-step checkout flow
- Client dashboard with stats, projects, support tickets
- Billing page with subscription, payment methods, invoices
- All mock data and TypeScript types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 21:42:48 +01:00

83 lines
3.0 KiB
TypeScript

'use client'
import { ArrowRight, Circle, CircleCheck } from 'lucide-react'
import Link from 'next/link'
import { Card, CardContent } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Progress } from '@/components/ui/progress'
import type { Project } from '@/lib/types'
interface ProjectCardProps {
project: Project
}
const statusColors: Record<Project['status'], string> = {
discovery: 'bg-blue-500/10 text-blue-400',
design: 'bg-purple-500/10 text-purple-400',
development: 'bg-yellow-500/10 text-yellow-400',
content: 'bg-orange-500/10 text-orange-400',
testing: 'bg-cyan-500/10 text-cyan-400',
completed: 'bg-emerald-500/10 text-emerald-400',
}
export function ProjectCard({ project }: ProjectCardProps) {
return (
<Link href={`/dashboard/projects/${project.id}`}>
<Card className="glow-card bg-card border-border hover:border-primary transition-all duration-300">
<CardContent className="p-6">
{/* Thumbnail */}
<div
className="w-full h-40 rounded-lg mb-4 bg-cover bg-center"
style={{ backgroundImage: `url(${project.thumbnail})` }}
/>
{/* Title and Status */}
<div className="flex items-start justify-between mb-3">
<div className="flex-1">
<h3 className="font-bold text-foreground text-lg mb-1">{project.title}</h3>
<p className="text-sm text-muted-foreground line-clamp-2">
{project.description}
</p>
</div>
<Badge className={`ml-2 ${statusColors[project.status]}`}>
{project.status}
</Badge>
</div>
{/* Progress */}
<div className="mb-4">
<div className="flex justify-between text-sm mb-2">
<span className="text-muted-foreground">Progress</span>
<span className="text-foreground font-medium">{project.progress}%</span>
</div>
<Progress value={project.progress} className="h-2" />
</div>
{/* Stages */}
<div className="flex items-center gap-2 text-xs text-muted-foreground">
{project.stages.map((stage, index) => (
<div key={index} className="flex items-center gap-1">
{stage.completed ? (
<CircleCheck className="w-4 h-4 text-primary" />
) : (
<Circle className="w-4 h-4" />
)}
<span className={stage.completed ? 'text-foreground' : ''}>
{stage.name}
</span>
{index < project.stages.length - 1 && <span></span>}
</div>
))}
</div>
{/* Updated */}
<div className="mt-4 pt-4 border-t border-border flex items-center justify-between text-xs text-muted-foreground">
<span>Updated {new Date(project.updatedAt).toLocaleDateString()}</span>
<ArrowRight className="w-4 h-4" />
</div>
</CardContent>
</Card>
</Link>
)
}