AI suggested Milestone functionality, clean up add/edit milestone database interaction

This commit is contained in:
Josh 2025-03-31 13:51:21 +00:00
parent b13a7f1299
commit 13b102bfe2
8 changed files with 417 additions and 117 deletions

View File

@ -0,0 +1,24 @@
import React, { useState } from 'react';
const MilestoneTimeline = () => {
const [showInputFields, setShowInputFields] = useState(false);
const toggleInputFields = () => {
setShowInputFields((prev) => !prev);
};
return (
<div>
<button onClick={toggleInputFields}>+ New Milestone</button>
{showInputFields && (
<div>
<input type="text" placeholder="Milestone Name" />
<input type="date" placeholder="Due Date" />
<button>Save</button>
</div>
)}
</div>
);
};
export default MilestoneTimeline;

View File

@ -127,10 +127,14 @@ app.post('/api/premium/planned-path', authenticatePremiumUser, async (req, res)
} }
}); });
// Save a new milestone // Save a new milestone
app.post('/api/premium/milestones', authenticatePremiumUser, async (req, res) => { app.post('/api/premium/milestone', authenticatePremiumUser, async (req, res) => {
const rawMilestones = Array.isArray(req.body.milestones) ? req.body.milestones : [req.body];
const errors = [];
const validMilestones = [];
for (const [index, m] of rawMilestones.entries()) {
const { const {
milestone_type, milestone_type,
title, title,
@ -140,28 +144,74 @@ app.post('/api/premium/milestones', authenticatePremiumUser, async (req, res) =>
salary_increase, salary_increase,
status = 'planned', status = 'planned',
date_completed = null, date_completed = null,
context_snapshot = null context_snapshot = null,
} = req.body; progress = 0,
} = m;
if (!milestone_type || !title || !description || !date) { // Validate required fields
return res.status(400).json({ error: 'Missing required fields' }); if (!milestone_type || !title || !description || !date || !career_path_id) {
errors.push({
index,
error: 'Missing required fields',
title, // <-- Add the title for identification
date,
details: {
milestone_type: !milestone_type ? 'Required' : undefined,
title: !title ? 'Required' : undefined,
description: !description ? 'Required' : undefined,
date: !date ? 'Required' : undefined,
career_path_id: !career_path_id ? 'Required' : undefined,
}
});
continue;
}
validMilestones.push({
id: uuidv4(), // ✅ assign UUID for unique milestone ID
user_id: req.userId,
milestone_type,
title,
description,
date,
career_path_id,
salary_increase: salary_increase || null,
status,
date_completed,
context_snapshot,
progress
});
}
if (errors.length) {
console.warn('❗ Some milestones failed validation. Logging malformed records...');
console.warn(JSON.stringify(errors, null, 2));
return res.status(400).json({
error: 'Some milestones are invalid',
errors
});
} }
try { try {
await db.run( const insertPromises = validMilestones.map(m =>
db.run(
`INSERT INTO milestones ( `INSERT INTO milestones (
user_id, milestone_type, title, description, date, career_path_id, id, user_id, milestone_type, title, description, date, career_path_id,
salary_increase, status, date_completed, context_snapshot, progress, updated_at salary_increase, status, date_completed, context_snapshot, progress, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)`, ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)`,
[ [
req.userId, milestone_type, title, description, date, career_path_id, m.id, m.user_id, m.milestone_type, m.title, m.description, m.date, m.career_path_id,
salary_increase || null, status, date_completed, context_snapshot m.salary_increase, m.status, m.date_completed, m.context_snapshot, m.progress
] ]
)
); );
res.status(201).json({ message: 'Milestone saved successfully' });
await Promise.all(insertPromises);
res.status(201).json({ message: 'Milestones saved successfully', count: validMilestones.length });
} catch (error) { } catch (error) {
console.error('Error saving milestone:', error); console.error('Error saving milestones:', error);
res.status(500).json({ error: 'Failed to save milestone' }); res.status(500).json({ error: 'Failed to save milestones' });
} }
}); });
@ -170,19 +220,16 @@ app.post('/api/premium/milestones', authenticatePremiumUser, async (req, res) =>
// Get all milestones // Get all milestones
app.get('/api/premium/milestones', authenticatePremiumUser, async (req, res) => { app.get('/api/premium/milestones', authenticatePremiumUser, async (req, res) => {
try { try {
const milestones = await db.all( const { careerPathId } = req.query;
`SELECT * FROM milestones WHERE user_id = ? ORDER BY date ASC`,
[req.userId]
);
const mapped = milestones.map(m => ({ if (!careerPathId) {
title: m.title, return res.status(400).json({ error: 'careerPathId is required' });
description: m.description, }
date: m.date,
type: m.milestone_type, const milestones = await db.all(
progress: m.progress || 0, `SELECT * FROM milestones WHERE user_id = ? AND career_path_id = ? ORDER BY date ASC`,
career_path_id: m.career_path_id [req.userId, careerPathId]
})); );
res.json({ milestones }); res.json({ milestones });
} catch (error) { } catch (error) {
@ -191,6 +238,7 @@ app.get('/api/premium/milestones', authenticatePremiumUser, async (req, res) =>
} }
}); });
/// Update an existing milestone /// Update an existing milestone
app.put('/api/premium/milestones/:id', authenticatePremiumUser, async (req, res) => { app.put('/api/premium/milestones/:id', authenticatePremiumUser, async (req, res) => {
try { try {
@ -213,6 +261,21 @@ app.put('/api/premium/milestones/:id', authenticatePremiumUser, async (req, res)
context_snapshot, context_snapshot,
} = req.body; } = req.body;
// Explicit required field validation
if (!milestone_type || !title || !description || !date || progress === undefined) {
return res.status(400).json({
error: 'Missing required fields',
details: {
milestone_type: !milestone_type ? 'Required' : undefined,
title: !title ? 'Required' : undefined,
description: !description ? 'Required' : undefined,
date: !date ? 'Required' : undefined,
progress: progress === undefined ? 'Required' : undefined,
}
});
}
console.log('Updating milestone with:', { console.log('Updating milestone with:', {
milestone_type, milestone_type,
title, title,

View File

@ -1,8 +1,11 @@
// src/components/AISuggestedMilestones.js // src/components/AISuggestedMilestones.js
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
const AISuggestedMilestones = ({ career, careerPathId, authFetch }) => {
const AISuggestedMilestones = ({ userId, career, careerPathId, authFetch, activeView }) => {
const [suggestedMilestones, setSuggestedMilestones] = useState([]); const [suggestedMilestones, setSuggestedMilestones] = useState([]);
const [selected, setSelected] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => { useEffect(() => {
if (!career) return; if (!career) return;
@ -11,33 +14,69 @@ const AISuggestedMilestones = ({ career, careerPathId, authFetch }) => {
{ title: `Mid-Level ${career}`, date: '2027-01-01', progress: 0 }, { title: `Mid-Level ${career}`, date: '2027-01-01', progress: 0 },
{ title: `Senior-Level ${career}`, date: '2030-01-01', progress: 0 }, { title: `Senior-Level ${career}`, date: '2030-01-01', progress: 0 },
]); ]);
setSelected([]);
}, [career]); }, [career]);
const confirmMilestones = async () => { const toggleSelect = (index) => {
for (const milestone of suggestedMilestones) { setSelected(prev =>
await authFetch(`/api/premium/milestones`, { prev.includes(index) ? prev.filter(i => i !== index) : [...prev, index]
method: 'POST', );
body: JSON.stringify({
milestone_type: 'Career',
title: milestone.title,
description: milestone.title,
date: milestone.date,
career_path_id: careerPathId,
progress: milestone.progress,
status: 'planned',
}),
});
}
setSuggestedMilestones([]);
}; };
const confirmSelectedMilestones = async () => {
const milestonesToSend = selected.map(index => {
const m = suggestedMilestones[index];
return {
title: m.title,
description: m.title,
date: m.date,
progress: m.progress,
milestone_type: activeView || 'Career',
career_path_id: careerPathId,
};
});
try {
setLoading(true);
const res = await authFetch(`/api/premium/milestone`, {
method: 'POST',
body: JSON.stringify({ milestones: milestonesToSend }),
headers: { 'Content-Type': 'application/json' },
});
if (!res.ok) throw new Error('Failed to save selected milestones');
const data = await res.json();
console.log('Confirmed milestones:', data);
setSelected([]); // Clear selection
window.location.reload();
} catch (error) {
console.error('Error saving selected milestones:', error);
} finally {
setLoading(false);
}
};
if (!suggestedMilestones.length) return null; if (!suggestedMilestones.length) return null;
return ( return (
<div className="suggested-milestones"> <div className="suggested-milestones">
<h4>AI-Suggested Milestones</h4> <h4>AI-Suggested Milestones</h4>
<ul>{suggestedMilestones.map((m, i) => <li key={i}>{m.title} - {m.date}</li>)}</ul> <ul>
<button onClick={confirmMilestones}>Confirm Milestones</button> {suggestedMilestones.map((m, i) => (
<li key={i}>
<input
type="checkbox"
checked={selected.includes(i)}
onChange={() => toggleSelect(i)}
/>
{m.title} {m.date}
</li>
))}
</ul>
<button onClick={confirmSelectedMilestones} disabled={loading || selected.length === 0}>
{loading ? 'Saving...' : 'Confirm Selected'}
</button>
</div> </div>
); );
}; };

View File

@ -1,7 +1,29 @@
// src/components/CareerSelectDropdown.js // src/components/CareerSelectDropdown.js
import React from 'react'; import React, { useEffect } from 'react';
const CareerSelectDropdown = ({ existingCareerPaths, selectedCareer, onChange, loading, authFetch }) => {
const fetchMilestones = (careerPathId) => {
authFetch(`/api/premium/milestones?careerPathId=${careerPathId}`)
.then((response) => response.json())
.then((data) => {
console.log('Milestones:', data);
// Handle milestones data as needed
})
.catch((error) => {
console.error('Error fetching milestones:', error);
});
};
const handleChange = (selected) => {
onChange(selected); // selected is the full career object
if (selected?.id) {
fetchMilestones(selected.id); // 🔥 Correct: use the id from the object
} else {
console.warn('No career ID found for selected object:', selected);
}
};
const CareerSelectDropdown = ({ existingCareerPaths, selectedCareer, onChange, loading }) => {
return ( return (
<div className="career-select-dropdown"> <div className="career-select-dropdown">
<label>Select Career Path:</label> <label>Select Career Path:</label>
@ -9,20 +31,28 @@ const CareerSelectDropdown = ({ existingCareerPaths, selectedCareer, onChange, l
<p>Loading career paths...</p> <p>Loading career paths...</p>
) : ( ) : (
<select <select
value={selectedCareer || ''} value={selectedCareer?.id || ''}
onChange={(e) => onChange(e.target.value)} onChange={(e) => {
const selectedId = e.target.value;
const selected = existingCareerPaths.find(path => path.id === selectedId);
handleChange(selected); // ✅ Pass the full object
}}
> >
<option value="" disabled>Select career path...</option> <option value="" disabled>Select career path...</option>
{existingCareerPaths.map((path) => ( {existingCareerPaths.map((path) => (
<option key={path.career_path_id} value={path.career_name}> <option key={path.id} value={path.id}>
{path.career_name} {path.career_name}
</option> </option>
))} ))}
</select> </select>
)} )}
</div> </div>
); );
}; };
export default CareerSelectDropdown; export default CareerSelectDropdown;

View File

@ -0,0 +1,54 @@
.milestone-timeline-container {
position: relative;
margin-top: 40px;
height: 120px;
}
.milestone-timeline-line {
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 4px;
background-color: #ccc;
transform: translateY(-50%);
}
.milestone-timeline-post {
position: absolute;
transform: translateX(-50%);
cursor: pointer;
}
.milestone-timeline-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #007bff;
margin: 0 auto;
}
.milestone-content {
margin-top: 10px;
text-align: center;
width: 160px;
background: white;
border: 1px solid #ddd;
padding: 6px;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.progress-bar {
height: 6px;
background-color: #e0e0e0;
border-radius: 3px;
margin-top: 5px;
overflow: hidden;
}
.progress {
height: 100%;
background-color: #28a745;
}

View File

@ -3,29 +3,54 @@ import React, { useEffect, useState, useCallback } from 'react';
const today = new Date(); const today = new Date();
const MilestoneTimeline = ({ careerPathId, authFetch }) => { const MilestoneTimeline = ({ careerPathId, authFetch, activeView, setActiveView }) => {
const [milestones, setMilestones] = useState({ Career: [], Financial: [], Retirement: [] }); const [milestones, setMilestones] = useState({ Career: [], Financial: [], Retirement: [] });
const [activeView, setActiveView] = useState('Career'); const [newMilestone, setNewMilestone] = useState({ title: '', date: '', description: '', progress: 0 });
const [newMilestone, setNewMilestone] = useState({ title: '', date: '', progress: 0 });
const [showForm, setShowForm] = useState(false); const [showForm, setShowForm] = useState(false);
const [editingMilestone, setEditingMilestone] = useState(null); const [editingMilestone, setEditingMilestone] = useState(null);
const fetchMilestones = useCallback(async () => { const fetchMilestones = useCallback(async () => {
if (!careerPathId) return; if (!careerPathId) {
console.warn('No careerPathId provided.');
return;
}
const res = await authFetch(`api/premium/milestones`); const res = await authFetch(`/api/premium/milestones?careerPathId=${careerPathId}`);
if (!res) return; if (!res) {
console.error('Failed to fetch milestones.');
return;
}
const data = await res.json(); const data = await res.json();
const raw = Array.isArray(data.milestones[0])
? data.milestones.flat()
: data.milestones.milestones || data.milestones;
const flatMilestones = Array.isArray(data.milestones[0])
? data.milestones.flat()
: data.milestones;
const filteredMilestones = raw.filter(
(m) => m.career_path_id === careerPathId
);
const categorized = { Career: [], Financial: [], Retirement: [] }; const categorized = { Career: [], Financial: [], Retirement: [] };
data.milestones.forEach((m) => { filteredMilestones.forEach((m) => {
if (m.career_path_id === careerPathId && categorized[m.milestone_type]) { const type = m.milestone_type;
categorized[m.milestone_type].push(m); if (categorized[type]) {
categorized[type].push(m);
} else {
console.warn(`Unknown milestone type: ${type}`);
} }
}); });
setMilestones(categorized); setMilestones(categorized);
console.log('Milestones set for view:', categorized);
}, [careerPathId, authFetch]); }, [careerPathId, authFetch]);
// ✅ useEffect simply calls the function // ✅ useEffect simply calls the function
@ -34,24 +59,67 @@ const MilestoneTimeline = ({ careerPathId, authFetch }) => {
}, [fetchMilestones]); }, [fetchMilestones]);
const saveMilestone = async () => { const saveMilestone = async () => {
const url = editingMilestone ? `/api/premium/milestones/${editingMilestone.id}` : `/api/premium/milestones`; const url = editingMilestone
? `/api/premium/milestones/${editingMilestone.id}`
: `/api/premium/milestone`;
const method = editingMilestone ? 'PUT' : 'POST'; const method = editingMilestone ? 'PUT' : 'POST';
const payload = { const payload = {
milestone_type: activeView, milestone_type: activeView,
title: newMilestone.title, title: newMilestone.title,
description: newMilestone.title, description: newMilestone.description,
date: newMilestone.date, date: newMilestone.date,
career_path_id: careerPathId, career_path_id: careerPathId,
progress: newMilestone.progress, progress: newMilestone.progress,
status: newMilestone.progress === 100 ? 'completed' : 'planned', status: newMilestone.progress === 100 ? 'completed' : 'planned',
}; };
const res = await authFetch(url, { method, body: JSON.stringify(payload) }); try {
if (res && res.ok) { console.log('Sending request to:', url);
fetchMilestones(); console.log('HTTP Method:', method);
console.log('Payload:', payload);
const res = await authFetch(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!res.ok) {
const errorData = await res.json();
console.error('Failed to save milestone:', errorData);
let message = 'An error occurred while saving the milestone.';
if (errorData?.error === 'Missing required fields') {
message = 'Please complete all required fields before saving.';
console.warn('Missing fields:', errorData.details);
}
alert(message); // Replace with your preferred UI messaging
return;
}
const savedMilestone = await res.json();
// Update state locally instead of fetching all milestones
setMilestones((prevMilestones) => {
const updatedMilestones = { ...prevMilestones };
if (editingMilestone) {
// Update the existing milestone
updatedMilestones[activeView] = updatedMilestones[activeView].map((m) =>
m.id === editingMilestone.id ? savedMilestone : m
);
} else {
// Add the new milestone
updatedMilestones[activeView].push(savedMilestone);
}
return updatedMilestones;
});
setShowForm(false); setShowForm(false);
setEditingMilestone(null); setEditingMilestone(null);
setNewMilestone({ title: '', date: '', progress: 0 }); setNewMilestone({ title: '', description: '', date: '', progress: 0 });
} catch (error) {
console.error('Error saving milestone:', error);
} }
}; };
@ -69,47 +137,61 @@ const MilestoneTimeline = ({ careerPathId, authFetch }) => {
return Math.min(Math.max(position, 0), 100); return Math.min(Math.max(position, 0), 100);
}; };
console.log('Rendering view:', activeView, milestones?.[activeView]);
if (!activeView || !milestones?.[activeView]) {
return (
<div className="milestone-timeline">
<p>Loading milestones...</p>
</div>
);
}
return ( return (
<div className="milestone-timeline"> <div className="milestone-timeline">
<div className="view-selector"> <div className="view-selector">
{['Career', 'Financial', 'Retirement'].map((view) => ( {['Career', 'Financial', 'Retirement'].map((view) => (
<button key={view} className={activeView === view ? 'active' : ''} onClick={() => setActiveView(view)}> <button
key={view}
className={activeView === view ? 'active' : ''}
onClick={() => setActiveView(view)}
>
{view} {view}
</button> </button>
))} ))}
</div> </div>
<div className="timeline"> <button onClick={() => {
{milestones[activeView]?.map((m) => ( if (showForm) {
<div key={m.id} className="milestone-entry"> setShowForm(false);
<h4>{m.title}</h4> setEditingMilestone(null);
<p>{m.description}</p> setNewMilestone({ title: '', date: '', progress: 0 });
<p>Date: {m.date}</p> } else {
<p>Progress: {m.progress}%</p> setShowForm(true);
</div> }
))} }}>
</div> {showForm ? 'Cancel' : '+ New Milestone'}
</button>
<button onClick={() => setShowForm(true)}>+ New Milestone</button>
{showForm && ( {showForm && (
<div className="form"> <div className="form">
<input type="text" placeholder="Title" value={newMilestone.title} onChange={(e) => setNewMilestone({ ...newMilestone, title: e.target.value })} /> <input type="text" placeholder="Title" value={newMilestone.title} onChange={(e) => setNewMilestone({ ...newMilestone, title: e.target.value })} />
<input type="text" placeholder="Description" value={newMilestone.description} onChange={(e) => setNewMilestone({ ...newMilestone, description: e.target.value })} />
<input type="date" value={newMilestone.date} onChange={(e) => setNewMilestone({ ...newMilestone, date: e.target.value })} /> <input type="date" value={newMilestone.date} onChange={(e) => setNewMilestone({ ...newMilestone, date: e.target.value })} />
<input type="number" placeholder="Progress (%)" value={newMilestone.progress} onChange={(e) => setNewMilestone({ ...newMilestone, progress: parseInt(e.target.value, 10) })} /> <input type="number" placeholder="Progress (%)" value={newMilestone.progress} onChange={(e) => setNewMilestone({ ...newMilestone, progress: parseInt(e.target.value, 10) })} />
<button onClick={saveMilestone}>{editingMilestone ? 'Update' : 'Add'} Milestone</button> <button onClick={saveMilestone}>{editingMilestone ? 'Update' : 'Add'} Milestone</button>
</div> </div>
)} )}
<div className="timeline-container"> <div className="milestone-timeline-container">
<div className="timeline-line" /> <div className="milestone-timeline-line" />
{milestones[activeView]?.map((m) => ( {milestones[activeView]?.map((m) => (
<div key={m.id} className="milestone-post" style={{ left: `${calcPosition(m.date)}%` }} onClick={() => { <div key={m.id} className="milestone-timeline-post" style={{ left: `${calcPosition(m.date)}%` }} onClick={() => {
setEditingMilestone(m); setEditingMilestone(m);
setNewMilestone({ title: m.title, date: m.date, progress: m.progress }); setNewMilestone({ title: m.title, date: m.date, progress: m.progress });
setShowForm(true); setShowForm(true);
}}> }}>
<div className="milestone-dot" /> <div className="milestone-timeline-dot" />
<div className="milestone-content"> <div className="milestone-content">
<div className="title">{m.title}</div> <div className="title">{m.title}</div>
<div className="progress-bar"> <div className="progress-bar">

View File

@ -7,6 +7,7 @@ import CareerSearch from './CareerSearch.js';
import MilestoneTimeline from './MilestoneTimeline.js'; import MilestoneTimeline from './MilestoneTimeline.js';
import AISuggestedMilestones from './AISuggestedMilestones.js'; import AISuggestedMilestones from './AISuggestedMilestones.js';
import './MilestoneTracker.css'; import './MilestoneTracker.css';
import './MilestoneTimeline.css'; // Ensure this file contains styles for timeline-line and milestone-dot
const MilestoneTracker = ({ selectedCareer: initialCareer }) => { const MilestoneTracker = ({ selectedCareer: initialCareer }) => {
const location = useLocation(); const location = useLocation();
@ -17,6 +18,8 @@ const MilestoneTracker = ({ selectedCareer: initialCareer }) => {
const [existingCareerPaths, setExistingCareerPaths] = useState([]); const [existingCareerPaths, setExistingCareerPaths] = useState([]);
const [showSessionExpiredModal, setShowSessionExpiredModal] = useState(false); const [showSessionExpiredModal, setShowSessionExpiredModal] = useState(false);
const [pendingCareerForModal, setPendingCareerForModal] = useState(null); const [pendingCareerForModal, setPendingCareerForModal] = useState(null);
const [activeView, setActiveView] = useState("Career");
const apiURL = process.env.REACT_APP_API_URL; const apiURL = process.env.REACT_APP_API_URL;
@ -72,11 +75,12 @@ const MilestoneTracker = ({ selectedCareer: initialCareer }) => {
fetchCareerPaths(); fetchCareerPaths();
}, []); }, []);
const handleCareerChange = (careerName) => { const handleCareerChange = (selected) => {
const match = existingCareerPaths.find(p => p.career_name === careerName); if (selected && selected.id && selected.career_name) {
if (match) { setSelectedCareer(selected);
setSelectedCareer(match); setCareerPathId(selected.id);
setCareerPathId(match.career_path_id); } else {
console.warn('Invalid career object received in handleCareerChange:', selected);
} }
}; };
@ -103,17 +107,21 @@ const MilestoneTracker = ({ selectedCareer: initialCareer }) => {
<CareerSelectDropdown <CareerSelectDropdown
existingCareerPaths={existingCareerPaths} existingCareerPaths={existingCareerPaths}
selectedCareer={selectedCareer?.career_name} selectedCareer={selectedCareer}
onChange={handleCareerChange} onChange={handleCareerChange}
loading={!existingCareerPaths.length} loading={!existingCareerPaths.length}
authFetch={authFetch}
/> />
<MilestoneTimeline careerPathId={careerPathId} authFetch={authFetch} /> <MilestoneTimeline careerPathId={careerPathId} authFetch={authFetch} activeView={activeView} setActiveView={setActiveView} />
{console.log('Passing careerPathId to MilestoneTimeline:', careerPathId)}
<AISuggestedMilestones career={selectedCareer?.career_name} careerPathId={careerPathId} authFetch={authFetch} /> <AISuggestedMilestones career={selectedCareer?.career_name} careerPathId={careerPathId} authFetch={authFetch} activeView={activeView}/>
<CareerSearch <CareerSearch
onSelectCareer={(careerName) => setPendingCareerForModal(careerName)} onSelectCareer={(careerName) => setPendingCareerForModal(careerName)}
setPendingCareerForModal={setPendingCareerForModal}
authFetch={authFetch}
/> />
{pendingCareerForModal && ( {pendingCareerForModal && (

Binary file not shown.