import React, { useState, useEffect, useRef } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { supabase } from '../../supabaseClient'; import FullProfileOverlay from '../FullProfileOverlay'; import ScheduleInterviewModal from '../ScheduleInterviewModal'; // --- ICONS --- const SmallCalendarIcon = () => (); const ChevronRightIcon = () => (); const CloseIcon = () => ; const SendIcon = () => ; // --- NEW FULL CHAT UI MODAL --- const AdminChatModal = ({ isOpen, onClose, applicant }) => { const [messages, setMessages] = useState([]); const [text, setText] = useState(''); const [loading, setLoading] = useState(true); const [adminId, setAdminId] = useState(null); const messagesEndRef = useRef(null); // Fetch chat history useEffect(() => { if (!isOpen || !applicant?.userId) return; const fetchMessages = async () => { setLoading(true); try { const { data: { user } } = await supabase.auth.getUser(); if (!user) return; setAdminId(user.id); // Fetch conversation strictly between this Admin and this Applicant const { data, error } = await supabase .from('messages') .select('*') .or(`and(sender_id.eq.${user.id},receiver_id.eq.${applicant.userId}),and(sender_id.eq.${applicant.userId},receiver_id.eq.${user.id})`) .order('created_at', { ascending: true }); if (!error && data) { setMessages(data); } } catch (err) { console.error("Error fetching chat:", err); } finally { setLoading(false); } }; fetchMessages(); }, [isOpen, applicant]); // Auto-scroll to bottom of chat useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages]); const sendMsg = async () => { if (!text.trim() || !adminId || !applicant?.userId) return; const newMsg = { id: Date.now(), // Temporary ID for optimistic UI update sender_id: adminId, receiver_id: applicant.userId, content: text.trim(), created_at: new Date().toISOString() }; // Update UI instantly setMessages(prev => [...prev, newMsg]); setText(''); // Send to database const { error } = await supabase.from('messages').insert([{ sender_id: adminId, receiver_id: applicant.userId, content: newMsg.content }]); if (error) console.error("Error sending message:", error); }; const unsendMsg = async (msgId) => { if (!window.confirm("Unsend this message?")) return; // 1. Try to delete the message const { data, error } = await supabase.from('messages').delete().eq('id', msgId).select(); if (error) { console.error("Unsend Error:", error); alert("Failed to unsend message."); return; } // 2. If RLS silently blocks deletion, fallback to update if (!data || data.length === 0) { const { error: updateError } = await supabase .from('messages') .update({ content: "🚫 This message was unsent" }) .eq('id', msgId); if (updateError) { alert("Database policies prevent unsending this message."); return; } setMessages(prev => prev.map(m => m.id === msgId ? { ...m, content: "🚫 This message was unsent" } : m)); } else { setMessages(prev => prev.filter(m => m.id !== msgId)); } }; const canUnsend = (rawTime) => { if (!rawTime) return false; const msgTime = new Date(rawTime).getTime(); return (Date.now() - msgTime) < 5 * 60 * 1000; // 5 minutes }; if (!isOpen || !applicant) return null; return (
{/* Chat Header */}
{applicant.name}

{applicant.name}

{applicant.role}

{/* Chat History */}
{loading ? (
Loading conversation...
) : messages.length === 0 ? (
No previous messages. Start the conversation!
) : ( messages.map(m => { const isMe = m.sender_id === adminId; return (
{m.content}
{new Date(m.created_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
{isMe && canUnsend(m.created_at) && ( )}
); }) )}
{/* Input Area */}