From c5ec964f78f09553654038ccc5c851aea56c054a Mon Sep 17 00:00:00 2001 From: NANDO9322 Date: Sat, 17 Jan 2026 18:41:21 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20corre=C3=A7ao=20de=20conflitos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/dashboard/candidato/perfil/page.tsx | 10 +- .../app/dashboard/my-applications/page.tsx | 327 +++++------------- frontend/src/app/dashboard/my-jobs/page.tsx | 3 - frontend/src/app/forgot-password/page.tsx | 102 ++---- frontend/src/app/jobs/[id]/apply/page.tsx | 91 ++--- frontend/src/app/jobs/page.tsx | 2 +- .../candidate-dashboard.tsx | 6 +- frontend/src/lib/api.ts | 116 +++---- 8 files changed, 183 insertions(+), 474 deletions(-) diff --git a/frontend/src/app/dashboard/candidato/perfil/page.tsx b/frontend/src/app/dashboard/candidato/perfil/page.tsx index 9c5698c..4f47945 100644 --- a/frontend/src/app/dashboard/candidato/perfil/page.tsx +++ b/frontend/src/app/dashboard/candidato/perfil/page.tsx @@ -143,11 +143,11 @@ export default function ProfilePage() { try { toast({ title: "Enviando foto..." }); - // 1. Get presigned URL - const { uploadUrl, publicUrl } = await storageApi.getUploadUrl(file.name, file.type); - // 2. Upload - await storageApi.uploadFile(uploadUrl, file); - // 3. Update state + toast({ title: "Enviando foto..." }); + // 1. Upload via Proxy (avoids CORS) + const { publicUrl } = await storageApi.uploadFile(file, "avatars"); + + // 2. Update state setProfilePic(publicUrl); toast({ title: "Foto enviada!", description: "Não esqueça de salvar o perfil." }); } catch (err) { diff --git a/frontend/src/app/dashboard/my-applications/page.tsx b/frontend/src/app/dashboard/my-applications/page.tsx index be1b5b2..558f459 100644 --- a/frontend/src/app/dashboard/my-applications/page.tsx +++ b/frontend/src/app/dashboard/my-applications/page.tsx @@ -3,7 +3,6 @@ import { useEffect, useState } from "react"; import Link from "next/link"; import { format } from "date-fns"; -<<<<<<< HEAD import { ptBR } from "date-fns/locale"; import { Building2, @@ -11,7 +10,12 @@ import { Search, ExternalLink, Loader2, - AlertCircle + AlertCircle, + Calendar, + CheckCircle2, + XCircle, + Clock, + FileText } from "lucide-react"; import { Button } from "@/components/ui/button"; @@ -27,15 +31,30 @@ import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { Navbar } from "@/components/navbar"; import { Footer } from "@/components/footer"; -import { applicationsApi, ApiApplication } from "@/lib/api"; +import { applicationsApi } from "@/lib/api"; -type ApplicationWithJob = ApiApplication & { +type Application = { + id: string; + jobId: string; jobTitle: string; companyName: string; + companyId: string; + status: string; + createdAt: string; + resumeUrl?: string; + message?: string; +}; + +const statusConfig: Record = { + pending: { label: "Em Análise", color: "bg-yellow-100 text-yellow-800 hover:bg-yellow-100/80", icon: Clock }, + reviewed: { label: "Visualizado", color: "bg-blue-100 text-blue-800 hover:bg-blue-100/80", icon: CheckCircle2 }, + shortlisted: { label: "Selecionado", color: "bg-purple-100 text-purple-800 hover:bg-purple-100/80", icon: CheckCircle2 }, + hired: { label: "Contratado", color: "bg-green-100 text-green-800 hover:bg-green-100/80", icon: CheckCircle2 }, + rejected: { label: "Não Selecionado", color: "bg-red-100 text-red-800 hover:bg-red-100/80", icon: XCircle }, }; export default function MyApplicationsPage() { - const [applications, setApplications] = useState([]); + const [applications, setApplications] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [searchTerm, setSearchTerm] = useState(""); @@ -48,9 +67,9 @@ export default function MyApplicationsPage() { try { setLoading(true); const data = await applicationsApi.listMyApplications(); - // The backend now returns ApplicationWithDetails which has jobTitle and companyName - // We cast it to our extended type - setApplications(data as unknown as ApplicationWithJob[]); + // Backend endpoint consistency check: listMyApplications usually returns ApplicationWithDetails + // Casting to ensure type safety if generic + setApplications(data as unknown as Application[]); } catch (err) { console.error("Failed to fetch applications", err); setError("Não foi possível carregar suas candidaturas. Tente novamente."); @@ -59,27 +78,6 @@ export default function MyApplicationsPage() { } }; - const getStatusColor = (status: string) => { - switch (status) { - case "pending": return "bg-yellow-100 text-yellow-800 hover:bg-yellow-100/80"; - case "reviewed": return "bg-blue-100 text-blue-800 hover:bg-blue-100/80"; - case "hired": return "bg-green-100 text-green-800 hover:bg-green-100/80"; - case "rejected": return "bg-red-100 text-red-800 hover:bg-red-100/80"; - default: return "bg-gray-100 text-gray-800 hover:bg-gray-100/80"; - } - }; - - const getStatusLabel = (status: string) => { - const labels: Record = { - pending: "Em Análise", - reviewed: "Visualizado", - shortlisted: "Selecionado", - hired: "Contratado", - rejected: "Não Selecionado" - }; - return labels[status] || status; - }; - const filteredApplications = applications.filter(app => app.jobTitle.toLowerCase().includes(searchTerm.toLowerCase()) || app.companyName.toLowerCase().includes(searchTerm.toLowerCase()) @@ -137,226 +135,71 @@ export default function MyApplicationsPage() { ) : (
- {filteredApplications.map((app) => ( - - -
- - - {app.jobTitle} - - - - - {app.companyName} - -
- - {getStatusLabel(app.status)} - -
- -
-
- - Aplicado em {format(new Date(app.createdAt), "dd 'de' MMMM, yyyy", { locale: ptBR })} + {filteredApplications.map((app) => { + const status = statusConfig[app.status] || { + label: app.status, + color: "bg-gray-100 text-gray-800 hover:bg-gray-100/80", + icon: AlertCircle + }; + const StatusIcon = status.icon; + + return ( + + +
+ + + {app.jobTitle} + + + + + {app.companyName} +
-
- - - - Ver Vaga - - {app.resumeUrl && ( - - Ver Currículo Enviado + +
+ + {status.label} +
+
+ + +
+
+ + Aplicado em {format(new Date(app.createdAt), "dd 'de' MMMM, yyyy", { locale: ptBR })} +
+
+ {app.message && ( +
+ "{app.message.length > 100 ? app.message.substring(0, 100) + "..." : app.message}" +
+ )} +
+ + + Ver Vaga - )} - - - ))} + {app.resumeUrl && ( + + + Ver Currículo + + )} +
+ + ); + })}
)}