Merge pull request 'fix/job-application-modal' (#3) from mohakj/nextplacement:fix/job-application-modal into main

Reviewed-on: Arnab-Afk/nextplacement#3
This commit is contained in:
2026-01-08 01:04:59 +05:30
2 changed files with 42 additions and 13 deletions

View File

@@ -40,6 +40,9 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
const [isPending, startTransition] = useTransition();
const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);
const deadline = new Date(job.applicationDeadline);
const isDeadlinePassed = new Date() > deadline;
const handleApply = async () => {
if (!selectedResume) {
setMessage({ type: 'error', text: 'Please select a resume' });
@@ -63,12 +66,14 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
setMessage({ type: 'error', text: result.error || 'Failed to submit application' });
}
} catch (error) {
setMessage({ type: 'error', text: 'An error occurred while submitting your application' });
setMessage({
type: 'error',
text: error instanceof Error ? error.message : 'An error occurred while submitting your application'
});
}
});
};
const isDeadlinePassed = new Date() > new Date(job.applicationDeadline as any);
const cannotApplyReason = isApplied
? 'You have already applied to this job'
: resumes.length === 0
@@ -78,21 +83,33 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
: null;
return (
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogTrigger asChild>
<Dialog open={isOpen} onOpenChange={(open) => !isPending && setIsOpen(open)}>
{!cannotApplyReason && (
<DialogTrigger asChild>
<div className="flex flex-col items-start">
<Button
size="sm"
className="bg-blue-600 hover:bg-blue-700"
>
Apply Now
</Button>
</div>
</DialogTrigger>
)}
{cannotApplyReason && (
<div className="flex flex-col items-start">
<Button
size="sm"
className="bg-blue-600 hover:bg-blue-700"
disabled={Boolean(cannotApplyReason)}
disabled
>
{isApplied ? 'Applied' : 'Apply Now'}
</Button>
{cannotApplyReason && (
<span className="mt-1 text-xs text-red-600">{cannotApplyReason}</span>
)}
<span className="mt-1 text-xs text-red-600">{cannotApplyReason}</span>
</div>
</DialogTrigger>
)}
<DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
@@ -127,7 +144,7 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
</div>
<div className="flex items-center gap-1">
<Calendar className="w-4 h-4" />
<span>Deadline: {job.applicationDeadline.toLocaleDateString()}</span>
<span>Deadline: {deadline.toLocaleDateString()}</span>
</div>
<div className="flex items-center gap-1">
<Star className="w-4 h-4" />
@@ -162,6 +179,18 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
))}
</SelectContent>
</Select>
{selectedResume && (
<a
href={resumes.find(r => r.id.toString() === selectedResume)?.fileUrl}
target="_blank"
rel="noopener noreferrer"
className="text-sm text-blue-600 underline mt-2 inline-block"
>
Preview selected resume
</a>
)}
{resumes.length === 0 && (
<p className="text-sm text-red-600 mt-1">
No resumes found. Please upload a resume first.
@@ -171,11 +200,10 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
{/* Message Display */}
{message && (
<div className={`p-3 rounded-lg ${
message.type === 'success'
<div className={`p-3 rounded-lg ${message.type === 'success'
? 'bg-green-100 text-green-700 border border-green-200'
: 'bg-red-100 text-red-700 border border-red-200'
}`}>
}`}>
<div className="flex items-center gap-2">
{message.type === 'success' ? (
<CheckCircle className="w-4 h-4" />