import React, { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { supabase } from '../supabaseClient';
// --- Icons ---
const PlusIcon = () => ;
const EditIcon = () => ;
const TrashIcon = () => ;
const SpinnerIcon = () => ;
export default function JobPosting({ onNavigate }) {
const [jobs, setJobs] = useState([]);
const [loading, setLoading] = useState(true);
const [isSaving, setIsSaving] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
const [editingJob, setEditingJob] = useState(null);
const [formData, setFormData] = useState({
title: '',
department: '',
location: '',
job_type: 'Full-time',
experience_level: '',
salary_range: '',
skills_required: '',
deadline: '',
description: ''
});
useEffect(() => {
fetchJobs();
}, []);
const fetchJobs = async () => {
setLoading(true);
try {
const { data: { user } } = await supabase.auth.getUser();
if(!user) return;
// ✅ FIXED: Fetch company_id from 'user_roles' instead of 'profiles'
const { data: roleData } = await supabase
.from('user_roles')
.select('company_id')
.eq('user_id', user.id)
.single();
if (roleData?.company_id) {
const { data, error } = await supabase
.from('jobs')
.select('*')
.eq('company_id', roleData.company_id)
.order('created_at', { ascending: false });
if (data) setJobs(data);
if (error) console.error("Error fetching jobs:", error.message);
}
} catch (error) {
console.error("System error:", error.message);
} finally {
setLoading(false);
}
};
const handleSubmit = async (e) => {
e.preventDefault();
setIsSaving(true);
try {
const { data: { user } } = await supabase.auth.getUser();
if (!user) throw new Error("User not found");
const skillsArray = formData.skills_required.split(',').map(s => s.trim()).filter(s => s);
// ✅ FIXED: Fetch company_id from 'user_roles' instead of 'profiles'
const { data: roleData } = await supabase
.from('user_roles')
.select('company_id')
.eq('user_id', user.id)
.single();
if (!roleData?.company_id) throw new Error("You are not linked to a company.");
const payload = {
title: formData.title,
department: formData.department,
location: formData.location,
job_type: formData.job_type,
experience_level: formData.experience_level,
salary_range: formData.salary_range,
skills_required: skillsArray,
deadline: formData.deadline || null,
description: formData.description,
company_id: roleData.company_id, // ✅ Using correct ID
status: 'Active'
};
let error;
if (editingJob) {
const { error: updateError } = await supabase.from('jobs').update(payload).eq('id', editingJob.id);
error = updateError;
} else {
const { error: insertError } = await supabase.from('jobs').insert(payload);
error = insertError;
}
if (error) throw error;
alert(editingJob ? "Job updated successfully!" : "Job posted successfully!");
fetchJobs();
closeModal();
} catch (error) {
alert("Error saving job: " + error.message);
} finally {
setIsSaving(false);
}
};
const handleDelete = async (id) => {
if (!window.confirm("Are you sure? This will delete the job posting.")) return;
try {
const { error } = await supabase.from('jobs').delete().eq('id', id);
if (error) throw error;
setJobs(jobs.filter(job => job.id !== id));
} catch (error) {
alert("Error deleting job: " + error.message);
}
};
const openModal = (job = null) => {
if (job) {
setEditingJob(job);
setFormData({
title: job.title,
department: job.department || '',
location: job.location || '',
job_type: job.job_type || 'Full-time',
experience_level: job.experience_level || '',
salary_range: job.salary_range || '',
skills_required: job.skills_required ? job.skills_required.join(', ') : '',
deadline: job.deadline || '',
description: job.description || ''
});
} else {
setEditingJob(null);
setFormData({
title: '', department: '', location: '',
job_type: 'Full-time', experience_level: '', salary_range: '',
skills_required: '', deadline: '', description: ''
});
}
setIsModalOpen(true);
};
const closeModal = () => setIsModalOpen(false);
const inputStyle = { width: '100%', padding: '0.75rem', borderRadius: '0.5rem', border: '1px solid rgba(239, 68, 68, 0.3)', backgroundColor: 'rgba(255,255,255,0.05)', color: 'white', marginBottom: '1rem', boxSizing: 'border-box' };
const labelStyle = { display: 'block', color: '#d1d5db', marginBottom: '0.5rem', fontSize: '0.875rem' };
return (
Job Postings
openModal()}
style={{
backgroundColor: '#EF4444',
color: 'white',
padding: '0.75rem 1.5rem',
borderRadius: '0.5rem',
border: 'none',
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
fontWeight: 'bold',
marginRight: '11rem'
}}
>
Post New Job
{loading ?
Loading jobs...
: (
{jobs.length === 0 &&
No jobs posted yet.
}
{jobs.map(job => (
{job.title}
{job.status || 'Active'}
{job.department}•{job.job_type}•{job.location}
openModal(job)} style={{ background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '0.5rem', color: 'white', cursor: 'pointer', padding: '0.5rem' }}>
handleDelete(job.id)} style={{ background: 'rgba(239, 68, 68, 0.1)', border: '1px solid rgba(239, 68, 68, 0.3)', borderRadius: '0.5rem', color: '#EF4444', cursor: 'pointer', padding: '0.5rem' }}>
))}
)}
{isModalOpen && (
{editingJob ? 'Edit Job' : 'Post New Job'}
)}
);
}