"use client"; import React, { useState, useEffect } from "react"; import { supabase } from "@/lib/supabase"; import { useApp } from "@/components/AppContext"; interface Interview { id: string; candidate_id: string; job_id: string; interview_date: string; stage: string; feedback: string | null; created_at: string; candidates: { name: string; } | null; jobs: { title: string; } | null; } const translations = { en: { interviewsTitle: "Interviews", interviewsSubtitle: "Manage scheduled candidate interview stages and write evaluation feedback.", loadingInterviews: "Loading interviews...", noInterviews: "No interviews scheduled. Upload candidate CVs under the Jobs tab to trigger evaluations.", unknownCandidate: "Unknown Candidate", unknownJob: "Unknown Job", role: "Role", dateScheduled: "Date Scheduled", stage: "Stage", interviewFeedback: "Interview Feedback", feedbackPlaceholder: "Write detailed assessment feedback, questions, or observations...", saving: "Saving...", updateInterview: "Update Interview", updateSuccess: "Interview updated successfully!", updateFailed: "Failed to update interview.", screening: "Screening", technical: "Technical", cultural: "Cultural", offer: "Offer", hired: "Hired", rejected: "Rejected" }, es: { interviewsTitle: "Entrevistas", interviewsSubtitle: "Gestione las etapas de entrevistas programadas de los candidatos y escriba comentarios de evaluación.", loadingInterviews: "Cargando entrevistas...", noInterviews: "No hay entrevistas programadas. Cargue los CV de los candidatos en la pestaña Vacantes para activar las evaluaciones.", unknownCandidate: "Candidato Desconocido", unknownJob: "Puesto Desconocido", role: "Puesto", dateScheduled: "Fecha Programada", stage: "Etapa", interviewFeedback: "Comentarios de la Entrevista", feedbackPlaceholder: "Escriba comentarios detallados de la evaluación, preguntas u observaciones...", saving: "Guardando...", updateInterview: "Actualizar Entrevista", updateSuccess: "¡Entrevista actualizada con éxito!", updateFailed: "Error al actualizar la entrevista.", screening: "Preselección", technical: "Técnica", cultural: "Cultural", offer: "Oferta", hired: "Contratado", rejected: "Rechazado" } }; export default function InterviewsPage() { const { lang } = useApp(); const t = translations[lang]; const [interviews, setInterviews] = useState([]); const [loading, setLoading] = useState(true); const [updatingId, setUpdatingId] = useState(null); const [editStates, setEditStates] = useState< Record >({}); const [actionMessage, setActionMessage] = useState(null); useEffect(() => { let active = true; async function fetchInterviews() { try { const { data, error } = await supabase .from("interviews") .select("*, candidates(name), jobs(title)") .order("interview_date", { ascending: false }); if (error) throw error; if (active) { const typedData = (data as unknown as Interview[]) || []; setInterviews(typedData); // Initialize edit states const initialEditStates: Record = {}; typedData.forEach((item) => { initialEditStates[item.id] = { stage: item.stage, feedback: item.feedback || "", }; }); setEditStates(initialEditStates); setLoading(false); } } catch (err) { console.error("Error fetching interviews:", err); if (active) { setLoading(false); } } } fetchInterviews(); return () => { active = false; }; }, []); const handleStateChange = (id: string, field: "stage" | "feedback", value: string) => { setEditStates((prev) => ({ ...prev, [id]: { ...prev[id], [field]: value, }, })); }; const handleUpdate = async (id: string) => { const editState = editStates[id]; if (!editState) return; try { setUpdatingId(id); setActionMessage(null); const { error } = await supabase .from("interviews") .update({ stage: editState.stage, feedback: editState.feedback, }) .eq("id", id); if (error) throw error; setActionMessage(t.updateSuccess); // Hide message after 3 seconds setTimeout(() => setActionMessage(null), 3000); // Refresh interview data locally setInterviews((prev) => prev.map((item) => item.id === id ? { ...item, stage: editState.stage, feedback: editState.feedback } : item ) ); } catch (err: unknown) { console.error("Error updating interview:", err); setActionMessage(t.updateFailed); } finally { setUpdatingId(null); } }; return (

{t.interviewsTitle}

{t.interviewsSubtitle}

{actionMessage && (
{actionMessage}
)}
{loading ? (

{t.loadingInterviews}

) : interviews.length === 0 ? (

{t.noInterviews}

) : (
{interviews.map((interview) => { const currentEdit = editStates[interview.id] || { stage: interview.stage, feedback: interview.feedback || "", }; return (
{/* Header */}

{interview.candidates?.name || t.unknownCandidate}

{t.role}: {interview.jobs?.title || t.unknownJob}

{t.dateScheduled}:{" "} {new Date(interview.interview_date).toLocaleString()}

{/* Feedback Area */}