forked from Arnab-Afk/nextplacement
Compare commits
3 Commits
1648a56680
...
3a1deddb8c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a1deddb8c | ||
|
|
441ae8169b | ||
|
|
3bcb5b851d |
@@ -40,6 +40,9 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
|
|||||||
const [isPending, startTransition] = useTransition();
|
const [isPending, startTransition] = useTransition();
|
||||||
const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);
|
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 () => {
|
const handleApply = async () => {
|
||||||
if (!selectedResume) {
|
if (!selectedResume) {
|
||||||
setMessage({ type: 'error', text: 'Please select a resume' });
|
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' });
|
setMessage({ type: 'error', text: result.error || 'Failed to submit application' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} 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
|
const cannotApplyReason = isApplied
|
||||||
? 'You have already applied to this job'
|
? 'You have already applied to this job'
|
||||||
: resumes.length === 0
|
: resumes.length === 0
|
||||||
@@ -78,21 +83,33 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
|
|||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
<Dialog open={isOpen} onOpenChange={(open) => !isPending && setIsOpen(open)}>
|
||||||
|
{!cannotApplyReason && (
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<div className="flex flex-col items-start">
|
<div className="flex flex-col items-start">
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
className="bg-blue-600 hover:bg-blue-700"
|
className="bg-blue-600 hover:bg-blue-700"
|
||||||
disabled={Boolean(cannotApplyReason)}
|
>
|
||||||
|
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
|
||||||
>
|
>
|
||||||
{isApplied ? 'Applied' : 'Apply Now'}
|
{isApplied ? 'Applied' : 'Apply Now'}
|
||||||
</Button>
|
</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>
|
</div>
|
||||||
</DialogTrigger>
|
)}
|
||||||
|
|
||||||
<DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
|
<DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex items-center gap-2">
|
<DialogTitle className="flex items-center gap-2">
|
||||||
@@ -127,7 +144,7 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<Calendar className="w-4 h-4" />
|
<Calendar className="w-4 h-4" />
|
||||||
<span>Deadline: {job.applicationDeadline.toLocaleDateString()}</span>
|
<span>Deadline: {deadline.toLocaleDateString()}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<Star className="w-4 h-4" />
|
<Star className="w-4 h-4" />
|
||||||
@@ -162,6 +179,18 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
|
|||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</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 && (
|
{resumes.length === 0 && (
|
||||||
<p className="text-sm text-red-600 mt-1">
|
<p className="text-sm text-red-600 mt-1">
|
||||||
No resumes found. Please upload a resume first.
|
No resumes found. Please upload a resume first.
|
||||||
@@ -171,8 +200,7 @@ export default function JobApplicationModal({ job, studentId, resumes, isApplied
|
|||||||
|
|
||||||
{/* Message Display */}
|
{/* Message Display */}
|
||||||
{message && (
|
{message && (
|
||||||
<div className={`p-3 rounded-lg ${
|
<div className={`p-3 rounded-lg ${message.type === 'success'
|
||||||
message.type === 'success'
|
|
||||||
? 'bg-green-100 text-green-700 border border-green-200'
|
? 'bg-green-100 text-green-700 border border-green-200'
|
||||||
: 'bg-red-100 text-red-700 border border-red-200'
|
: 'bg-red-100 text-red-700 border border-red-200'
|
||||||
}`}>
|
}`}>
|
||||||
|
|||||||
1
nextplacement
Submodule
1
nextplacement
Submodule
Submodule nextplacement added at 1648a56680
Reference in New Issue
Block a user