maj du frontend
This commit is contained in:
parent
0585ff56fd
commit
1c8d960b52
8 changed files with 281 additions and 26 deletions
122
frontend/src/components/JobDetail.tsx
Normal file
122
frontend/src/components/JobDetail.tsx
Normal file
|
@ -0,0 +1,122 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { useParams, Link } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import type { JobOffer } from '../types'; // Use type-only import
|
||||
|
||||
const API_BASE_URL = 'http://localhost:3000/api/jobs';
|
||||
|
||||
const JobDetail: React.FC = () => {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const [job, setJob] = useState<JobOffer | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchJobDetail = async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const response = await axios.get<JobOffer>(`${API_BASE_URL}/${id}`);
|
||||
setJob(response.data);
|
||||
} catch (err) {
|
||||
console.error('Error fetching job detail:', err);
|
||||
if (axios.isAxiosError(err) && err.response?.status === 404) {
|
||||
setError('Job offer not found.');
|
||||
} else {
|
||||
setError('Failed to load job offer details. Please try again.');
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (id) {
|
||||
fetchJobDetail();
|
||||
}
|
||||
}, [id]);
|
||||
|
||||
const handleApplyClick = () => {
|
||||
// Logique pour trouver la meilleure URL de candidature
|
||||
const applyUrl = job?.urlOffre || job?.contact?.urlPostulation || job?.origineOffre?.urlOrigine;
|
||||
|
||||
if (applyUrl) {
|
||||
window.open(applyUrl, '_blank'); // Ouvre l'URL dans un nouvel onglet
|
||||
} else {
|
||||
alert("No application URL available for this job offer.");
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return <p className="info-message">Loading job details...</p>;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="job-detail-container">
|
||||
<p className="info-message" style={{ color: 'red' }}>Error: {error}</p>
|
||||
<Link to="/" style={{ display: 'block', textAlign: 'center', marginTop: '20px' }}>Back to Search</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!job) {
|
||||
return (
|
||||
<div className="job-detail-container">
|
||||
<p className="info-message">No job details available.</p>
|
||||
<Link to="/" style={{ display: 'block', textAlign: 'center', marginTop: '20px' }}>Back to Search</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="job-detail-container" style={{ padding: '20px', maxWidth: '800px', margin: '20px auto', backgroundColor: '#fff', borderRadius: '8px', boxShadow: '0 4px 8px rgba(0,0,0,0.1)' }}>
|
||||
<Link to="/" style={{ textDecoration: 'none', color: '#3498db', fontWeight: 'bold', marginBottom: '20px', display: 'inline-block' }}>
|
||||
← Back to Job Search
|
||||
</Link>
|
||||
<h1 style={{ color: '#2c3e50', marginBottom: '10px' }}>{job.title}</h1>
|
||||
<p style={{ fontSize: '1.1em', color: '#555', marginBottom: '15px' }}>
|
||||
<strong>Company:</strong> {job.companyName || 'N/A'}
|
||||
</p>
|
||||
<p style={{ fontSize: '1.1em', color: '#555', marginBottom: '15px' }}>
|
||||
<strong>Location:</strong> {job.locationLabel || job.cityName || 'N/A'}
|
||||
</p>
|
||||
<p style={{ fontSize: '1.1em', color: '#555', marginBottom: '15px' }}>
|
||||
<strong>Contract:</strong> {job.contractLabel || job.contractType || 'N/A'}
|
||||
</p>
|
||||
<p style={{ fontSize: '1.1em', color: '#555', marginBottom: '15px' }}>
|
||||
<strong>Published:</strong> {new Date(job.publicationDate).toLocaleDateString()}
|
||||
</p>
|
||||
{job.romeLabel && <p style={{ fontSize: '1.1em', color: '#555', marginBottom: '15px' }}><strong>ROME:</strong> {job.romeLabel}</p>}
|
||||
{job.postalCode && <p style={{ fontSize: '1.1em', color: '#555', marginBottom: '15px' }}><strong>Postal Code:</strong> {job.postalCode}</p>}
|
||||
{job.departmentCode && <p style={{ fontSize: '1.1em', color: '#555', marginBottom: '15px' }}><strong>Department Code:</strong> {job.departmentCode}</p>}
|
||||
|
||||
<h2 style={{ color: '#2c3e50', marginTop: '30px', marginBottom: '10px' }}>Description</h2>
|
||||
<p style={{ lineHeight: '1.6', whiteSpace: 'pre-wrap' }}>{job.description}</p>
|
||||
|
||||
{/* Bouton Postuler */}
|
||||
{(job.urlOffre || job.contact?.urlPostulation || job.origineOffre?.urlOrigine) && (
|
||||
<button
|
||||
onClick={handleApplyClick}
|
||||
style={{
|
||||
backgroundColor: '#28a745', // Vert pour le bouton "Postuler"
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
borderRadius: '5px',
|
||||
padding: '12px 25px',
|
||||
fontSize: '1.1em',
|
||||
cursor: 'pointer',
|
||||
marginTop: '30px',
|
||||
display: 'block',
|
||||
width: 'fit-content',
|
||||
margin: '30px auto 0 auto',
|
||||
transition: 'background-color 0.3s ease',
|
||||
}}
|
||||
>
|
||||
Apply Now
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default JobDetail;
|
Loading…
Add table
Add a link
Reference in a new issue