import React, { useState, useEffect } from 'react'; import { Briefcase, Plus, Trash2, Edit2, Save, X, FileText, DollarSign, Building2, Calendar, MapPin, Search } from 'lucide-react'; const JobTracker = () => { const [jobs, setJobs] = useState([]); const [showAddForm, setShowAddForm] = useState(false); const [editingId, setEditingId] = useState(null); const [searchTerm, setSearchTerm] = useState(''); const [filterStatus, setFilterStatus] = useState('all'); const [sortBy, setSortBy] = useState('date'); const [formData, setFormData] = useState({ company: '', title: '', location: '', salary: '', status: 'applied', dateApplied: new Date().toISOString().split('T')[0], resume: '', coverLetter: '', contactName: '', contactEmail: '', jobUrl: '', notes: '' }); // Load data on component mount useEffect(() => { loadJobs(); }, []); const loadJobs = async () => { try { const result = await window.storage.get('job-applications'); if (result && result.value) { setJobs(JSON.parse(result.value)); } } catch (error) { console.log('No saved jobs found or error loading:', error); } }; const saveJobs = async (updatedJobs) => { try { await window.storage.set('job-applications', JSON.stringify(updatedJobs)); setJobs(updatedJobs); } catch (error) { console.error('Error saving jobs:', error); } }; const handleSubmit = () => { if (!formData.company || !formData.title) { alert('Please fill in required fields (Company and Job Title)'); return; } if (editingId) { const updatedJobs = jobs.map(job => job.id === editingId ? { ...formData, id: editingId } : job ); saveJobs(updatedJobs); setEditingId(null); } else { const newJob = { ...formData, id: Date.now().toString() }; saveJobs([...jobs, newJob]); } resetForm(); }; const resetForm = () => { setFormData({ company: '', title: '', location: '', salary: '', status: 'applied', dateApplied: new Date().toISOString().split('T')[0], resume: '', coverLetter: '', contactName: '', contactEmail: '', jobUrl: '', notes: '' }); setShowAddForm(false); }; const handleEdit = (job) => { setFormData(job); setEditingId(job.id); setShowAddForm(true); }; const handleDelete = (id) => { if (window.confirm('Are you sure you want to delete this application?')) { const updatedJobs = jobs.filter(job => job.id !== id); saveJobs(updatedJobs); } }; const getStatusColor = (status) => { const colors = { 'applied': 'bg-blue-100 text-blue-800', 'interview': 'bg-yellow-100 text-yellow-800', 'offered': 'bg-green-100 text-green-800', 'rejected': 'bg-red-100 text-red-800', 'withdrawn': 'bg-gray-100 text-gray-800' }; return colors[status] || 'bg-gray-100 text-gray-800'; }; // Filter and sort jobs const filteredJobs = jobs .filter(job => { const matchesSearch = job.company.toLowerCase().includes(searchTerm.toLowerCase()) || job.title.toLowerCase().includes(searchTerm.toLowerCase()) || job.location.toLowerCase().includes(searchTerm.toLowerCase()); const matchesStatus = filterStatus === 'all' || job.status === filterStatus; return matchesSearch && matchesStatus; }) .sort((a, b) => { if (sortBy === 'date') { return new Date(b.dateApplied) - new Date(a.dateApplied); } else if (sortBy === 'company') { return a.company.localeCompare(b.company); } else if (sortBy === 'status') { return a.status.localeCompare(b.status); } return 0; }); const stats = { total: jobs.length, applied: jobs.filter(j => j.status === 'applied').length, interview: jobs.filter(j => j.status === 'interview').length, offered: jobs.filter(j => j.status === 'offered').length, rejected: jobs.filter(j => j.status === 'rejected').length }; return (

Job Application Tracker

{/* Stats */}
{stats.total}
Total Applied
{stats.applied}
Pending
{stats.interview}
Interviews
{stats.offered}
Offers
{stats.rejected}
Rejected
{/* Search and Filters */}
setSearchTerm(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />
{/* Add/Edit Form */} {showAddForm && (

{editingId ? 'Edit Application' : 'Add New Application'}

setFormData({...formData, company: e.target.value})} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />
setFormData({...formData, title: e.target.value})} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />
setFormData({...formData, location: e.target.value})} placeholder="e.g., New York, NY or Remote" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />
setFormData({...formData, salary: e.target.value})} placeholder="e.g., $80,000 - $100,000" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />
setFormData({...formData, dateApplied: e.target.value})} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />
setFormData({...formData, resume: e.target.value})} placeholder="e.g., Tech_Resume_v3.pdf" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />
setFormData({...formData, coverLetter: e.target.value})} placeholder="e.g., Custom_CL_Company.pdf" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />
setFormData({...formData, contactName: e.target.value})} placeholder="Hiring manager or recruiter" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />
setFormData({...formData, contactEmail: e.target.value})} placeholder="contact@company.com" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />
setFormData({...formData, jobUrl: e.target.value})} placeholder="https://..." className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" />