Newer
Older
job-tracker / frontend / src / components / CompanyList.js
import React, {useEffect, useState} from 'react';
import {Link} from 'react-router-dom';
import {apiDelete, apiGet} from "../api";

function CompanyList() {
    const [companies, setCompanies] = useState([]);
    const [error,setError]=useState(null);
    const [selectedCompany, setSelectedCompany] = useState(null);

    useEffect(() => {
        apiGet('/api/companies')
            .then(setCompanies)
                .catch(error => setError(error));
    }, []);
            
        const handleDelete = async (id) => {
        if(window.confirm("Are you sure you want to delete this company?")) {
            try {
                await apiDelete(`/api/companies/${id}`);
                setCompanies(prev => prev.filter(c => c.id !== id)); // update local state
            } catch (err) {
                setError(err.message || "Failed to delete company");
            }
        }
    };
    const handleExportClick = async () => {
      try {
        const response = await fetch('/api/companies/export');
        if (!response.ok) throw new Error('Export failed');

        // Extract filename with timestamp from header
        const disposition = response.headers.get('Content-Disposition');
        const filenameMatch = disposition?.match(/filename="(.+)"/);
        const filename = filenameMatch ? filenameMatch[1] : 'jobs.csv';

        const blob = await response.blob();
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = filename;
        a.click();
        window.URL.revokeObjectURL(url);
      } catch (err) {
        setError(err.message);
      }
    };


    return (
        <div className="container mt-4">
            <div className="d-flex justify-content-between align-items-center mb-3">
            <h2>Companies</h2>
            <p><Link to="/companies/new" className="btn btn-primary">+ Add company</Link>
            <button onClick={handleExportClick} className="btn btn-secondary ms-2">Export CSV</button></p>
            </div>
            {error && <div className="alter alter-danger">{error}</div>}            
            <table className='table table-striped table-hover'>
                <thead className='table-dark'>
                    <tr>
                        <th>Company Name</th>
                        <th>Company URL</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    {companies.map(company => (
                        <tr key={company.id}>
                            <td>{company.name}</td>
                            <td><a href={company.website} target="_blank" rel="noopener noreferrer">WebSite</a></td>
                            <td>
                                <Link to={`/companies/${company.id}/edit`} className="btn btn-sm btn-warning me-2">Edit</Link>
                                <button onClick={() => handleDelete(company.id)} className="btn btn-sm btn-danger">Delete</button>
                                <Link to={`/companies/${company.id}/jobs`} className="btn btn-sm btn-info ms-2">Jobs</Link>
                                <button onClick={() => setSelectedCompany(company)} className="btn btn-sm btn-secondary ms-2">...</button>
                            </td>
                        </tr>
                    ))}
                </tbody>
            </table>
            {selectedCompany && (
                <div className="mt-4 p-3 border rounded">
                    <div className="d-flex justify-content-between align-items-center mb-3">
                        <h4>Details for {selectedCompany.name}</h4>
                        <button onClick={() => setSelectedCompany(null)} className="btn btn-sm btn-secondary">Hide Details</button>
                    </div>
                    {selectedCompany.website && <p><strong>Website:</strong> <a href={selectedCompany.website} target="_blank" rel="noopener noreferrer">{selectedCompany.website}</a></p>}
                    {selectedCompany.notes && <p><strong>Notes:</strong> {selectedCompany.notes}</p>}
                </div>
            )}

        </div>
        );
}

export default CompanyList;