gohorsejobs/frontend/src/app/dashboard/candidato/page.tsx
Tiago Yamamoto 1c7ef95c1a first commit
2025-12-09 19:04:48 -03:00

221 lines
6.9 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { DashboardHeader } from "@/components/dashboard-header";
import { StatsCard } from "@/components/stats-card";
import { JobCard } from "@/components/job-card";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { Badge } from "@/components/ui/badge";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { getCurrentUser } from "@/lib/auth";
import { mockJobs, mockApplications, mockNotifications } from "@/lib/mock-data";
import {
Bell,
FileText,
Clock,
CheckCircle,
XCircle,
AlertCircle,
Edit,
} from "lucide-react";
import { motion } from "framer-motion";
export default function CandidateDashboard() {
const router = useRouter();
const [user, setUser] = useState(getCurrentUser());
useEffect(() => {
const currentUser = getCurrentUser();
if (!currentUser || currentUser.role !== "candidate") {
router.push("/login");
} else {
setUser(currentUser);
}
}, [router]);
if (!user) {
return null;
}
const recommendedJobs = mockJobs.slice(0, 3);
const unreadNotifications = mockNotifications.filter((n) => !n.read);
const getStatusBadge = (status: string) => {
switch (status) {
case "pending":
return (
<Badge variant="secondary">
<Clock className="h-3 w-3 mr-1" />
Em análise
</Badge>
);
case "reviewing":
return (
<Badge variant="secondary">
<AlertCircle className="h-3 w-3 mr-1" />
Em análise
</Badge>
);
case "interview":
return (
<Badge className="bg-blue-500 hover:bg-blue-600">
<CheckCircle className="h-3 w-3 mr-1" />
Entrevista
</Badge>
);
case "accepted":
return (
<Badge className="bg-green-500 hover:bg-green-600">
<CheckCircle className="h-3 w-3 mr-1" />
Aprovado
</Badge>
);
case "rejected":
return (
<Badge variant="destructive">
<XCircle className="h-3 w-3 mr-1" />
Rejeitado
</Badge>
);
default:
return <Badge variant="outline">{status}</Badge>;
}
};
return (
<div className="min-h-screen bg-background">
<DashboardHeader />
<main className="container mx-auto px-4 sm:px-6 lg:px-8 py-8">
{/* Profile Summary */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<Card className="mb-8">
<CardContent className="pt-6">
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
<div className="flex-1">
<h1 className="text-2xl font-bold mb-2">Olá, {user.name}!</h1>
<p className="text-muted-foreground">{user.area}</p>
</div>
<Button className="cursor-pointer">
<Edit className="mr-2 h-4 w-4" />
Editar Perfil
</Button>
</div>
</CardContent>
</Card>
</motion.div>
{/* Stats */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.1 }}
className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8"
>
<StatsCard
title="Candidaturas"
value={mockApplications.length}
icon={FileText}
description="Total de vagas aplicadas"
/>
<StatsCard
title="Em processo"
value={
mockApplications.filter(
(a) => a.status === "reviewing" || a.status === "interview"
).length
}
icon={Clock}
description="Aguardando resposta"
/>
<StatsCard
title="Notificações"
value={unreadNotifications.length}
icon={Bell}
description="Novas atualizações"
/>
</motion.div>
<div className="grid grid-cols-1 lg:grid-cols-1 gap-8">
{/* Main Content */}
<div className="space-y-8">
{/* Recommended Jobs */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.2 }}
>
<Card>
<CardHeader>
<CardTitle>Vagas recomendadas</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
{recommendedJobs.map((job) => (
<JobCard key={job.id} job={job} />
))}
</CardContent>
</Card>
</motion.div>
{/* Applications */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.3 }}
>
<Card>
<CardHeader>
<CardTitle>Minhas candidaturas</CardTitle>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead>Vaga</TableHead>
<TableHead>Empresa</TableHead>
<TableHead>Status</TableHead>
<TableHead>Data</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{mockApplications.map((application) => (
<TableRow key={application.id}>
<TableCell className="font-medium">
{application.jobTitle}
</TableCell>
<TableCell>{application.company}</TableCell>
<TableCell>
{getStatusBadge(application.status)}
</TableCell>
<TableCell className="text-muted-foreground">
{new Date(application.appliedAt).toLocaleDateString(
"pt-BR"
)}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
</motion.div>
</div>
</div>
</main>
</div>
);
}