Files
GNX-WEB/gnx-react/components/pages/career/JobApplicationForm.tsx
Iliyan Angelov d48c54e2c5 update
2025-10-07 22:10:27 +03:00

974 lines
35 KiB
TypeScript

"use client";
import { useState, FormEvent, ChangeEvent } from "react";
import { JobPosition, JobApplication, careerService } from "@/lib/api/careerService";
interface JobApplicationFormProps {
job: JobPosition;
onClose?: () => void;
}
const inputStyle = {
padding: '10px 12px',
borderRadius: '6px',
border: '1px solid #e0e0e0',
fontSize: '14px',
transition: 'all 0.2s',
width: '100%'
};
const labelStyle = {
fontWeight: '500',
color: '#555',
marginBottom: '6px',
display: 'block',
fontSize: '14px'
};
const sectionStyle = {
backgroundColor: '#ffffff',
padding: 'clamp(16px, 3vw, 20px)',
borderRadius: '8px',
border: '1px solid #e8e8e8',
marginBottom: '16px',
boxShadow: '0 2px 8px rgba(0,0,0,0.04)'
};
const sectionHeaderStyle = {
display: 'flex',
alignItems: 'center',
marginBottom: '14px',
paddingBottom: '10px',
borderBottom: '1px solid #f0f0f0'
};
const JobApplicationForm = ({ job, onClose }: JobApplicationFormProps) => {
const [formData, setFormData] = useState({
first_name: "",
last_name: "",
email: "",
phone: "",
current_position: "",
current_company: "",
years_of_experience: "",
cover_letter: "",
portfolio_url: "",
linkedin_url: "",
github_url: "",
website_url: "",
available_from: "",
notice_period: "",
expected_salary: "",
salary_currency: "USD",
consent: false,
});
const [resume, setResume] = useState<File | null>(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const [submitStatus, setSubmitStatus] = useState<{
type: "success" | "error" | null;
message: string;
}>({ type: null, message: "" });
const handleInputChange = (
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>
) => {
const { name, value, type } = e.target;
if (type === "checkbox") {
const checked = (e.target as HTMLInputElement).checked;
setFormData((prev) => ({ ...prev, [name]: checked }));
} else {
setFormData((prev) => ({ ...prev, [name]: value }));
}
};
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
// Validate file type
const allowedTypes = [
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
];
if (!allowedTypes.includes(file.type)) {
setSubmitStatus({
type: "error",
message: "Please upload a PDF, DOC, or DOCX file",
});
return;
}
// Validate file size (5MB)
if (file.size > 5 * 1024 * 1024) {
setSubmitStatus({
type: "error",
message: "Resume file size must be less than 5MB",
});
return;
}
setResume(file);
setSubmitStatus({ type: null, message: "" });
}
};
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
setIsSubmitting(true);
setSubmitStatus({ type: null, message: "" });
// Validation
if (!resume) {
setSubmitStatus({
type: "error",
message: "Please upload your resume",
});
setIsSubmitting(false);
return;
}
if (!formData.consent) {
setSubmitStatus({
type: "error",
message: "You must consent to data processing to apply",
});
setIsSubmitting(false);
return;
}
try {
const applicationData: JobApplication = {
job: job.id,
first_name: formData.first_name,
last_name: formData.last_name,
email: formData.email,
phone: formData.phone || undefined,
current_position: formData.current_position || undefined,
current_company: formData.current_company || undefined,
years_of_experience: formData.years_of_experience || undefined,
cover_letter: formData.cover_letter || undefined,
resume: resume,
portfolio_url: formData.portfolio_url || undefined,
linkedin_url: formData.linkedin_url || undefined,
github_url: formData.github_url || undefined,
website_url: formData.website_url || undefined,
available_from: formData.available_from || undefined,
notice_period: formData.notice_period || undefined,
expected_salary: formData.expected_salary ? parseFloat(formData.expected_salary) : undefined,
salary_currency: formData.salary_currency || undefined,
consent: formData.consent,
};
await careerService.submitApplication(applicationData);
setSubmitStatus({
type: "success",
message: "Application submitted successfully! We'll be in touch soon.",
});
// Reset form
setFormData({
first_name: "",
last_name: "",
email: "",
phone: "",
current_position: "",
current_company: "",
years_of_experience: "",
cover_letter: "",
portfolio_url: "",
linkedin_url: "",
github_url: "",
website_url: "",
available_from: "",
notice_period: "",
expected_salary: "",
salary_currency: "USD",
consent: false,
});
setResume(null);
// Reset file input
const fileInput = document.getElementById('resume') as HTMLInputElement;
if (fileInput) fileInput.value = '';
} catch (error) {
setSubmitStatus({
type: "error",
message: error instanceof Error ? error.message : "Failed to submit application. Please try again.",
});
} finally {
setIsSubmitting(false);
}
};
return (
<div className="job-application-form" style={{
position: 'relative',
display: 'flex',
flexDirection: 'column',
height: '100%',
maxHeight: '90vh'
}}>
{/* Header Section with Gradient */}
<div style={{
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
padding: 'clamp(24px, 4vw, 32px)',
borderRadius: '16px 16px 0 0',
position: 'relative',
flexShrink: 0
}}>
{/* Close Button */}
{onClose && (
<button
onClick={onClose}
style={{
position: 'absolute',
top: '16px',
right: '16px',
background: 'rgba(255,255,255,0.2)',
border: 'none',
color: 'white',
cursor: 'pointer',
fontSize: '24px',
padding: '8px',
lineHeight: '1',
borderRadius: '50%',
width: '40px',
height: '40px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
transition: 'all 0.2s',
zIndex: 10
}}
onMouseEnter={(e) => {
e.currentTarget.style.backgroundColor = 'rgba(220, 53, 69, 0.9)';
e.currentTarget.style.transform = 'scale(1.1)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.2)';
e.currentTarget.style.transform = 'scale(1)';
}}
title="Close"
>
<span className="material-symbols-outlined" style={{ fontSize: 'inherit' }}>close</span>
</button>
)}
<div className="intro" style={{ textAlign: 'center', color: 'white' }}>
<div style={{
width: '60px',
height: '60px',
borderRadius: '50%',
backgroundColor: 'rgba(255,255,255,0.2)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto 16px',
backdropFilter: 'blur(10px)'
}}>
<span className="material-symbols-outlined" style={{
fontSize: '32px',
color: 'white'
}}>work_outline</span>
</div>
<h3 id="application-form-title" className="fw-7" style={{
color: 'white',
fontSize: 'clamp(20px, 3vw, 24px)',
marginBottom: '8px'
}}>
Apply for {job.title}
</h3>
<p style={{
color: 'rgba(255,255,255,0.9)',
fontSize: 'clamp(13px, 2vw, 14px)',
margin: '0'
}}>
Join our team and make an impact
</p>
</div>
</div>
{/* Form Content - Scrollable Area */}
<form onSubmit={handleSubmit} style={{
display: 'flex',
flexDirection: 'column',
flex: '1 1 auto',
minHeight: 0,
overflow: 'hidden'
}}>
<div
className="form-scrollable-content"
style={{
padding: 'clamp(20px, 4vw, 32px)',
overflowY: 'scroll',
overflowX: 'hidden',
flex: '1 1 auto',
WebkitOverflowScrolling: 'touch',
touchAction: 'pan-y',
scrollbarWidth: 'thin',
scrollbarColor: '#667eea #f0f0f0'
}}
>
{submitStatus.type && (
<div
className={`alert mb-24`}
style={{
padding: "16px 20px",
borderRadius: "8px",
backgroundColor: submitStatus.type === "success" ? "#d4edda" : "#f8d7da",
color: submitStatus.type === "success" ? "#155724" : "#721c24",
border: `2px solid ${submitStatus.type === "success" ? "#28a745" : "#dc3545"}`,
display: 'flex',
alignItems: 'center',
gap: '10px',
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
}}
>
<span className="material-symbols-outlined" style={{ fontSize: '20px' }}>
{submitStatus.type === "success" ? "check_circle" : "error"}
</span>
<span style={{ fontSize: '14px', fontWeight: '500' }}>{submitStatus.message}</span>
</div>
)}
{/* Personal Information */}
<div className="section" style={sectionStyle}>
<div style={sectionHeaderStyle}>
<span className="material-symbols-outlined me-2" style={{ color: '#667eea', fontSize: 'clamp(20px, 3vw, 22px)' }}>person</span>
<h4 className="fw-6 mb-0" style={{ color: '#333', fontSize: 'clamp(15px, 2.5vw, 16px)' }}>Personal Information</h4>
</div>
<div className="row">
<div className="col-12 col-md-6 mb-3">
<label htmlFor="first_name" className="form-label" style={labelStyle}>
First Name <span style={{ color: '#dc3545' }}>*</span>
</label>
<input
type="text"
id="first_name"
name="first_name"
className="form-control"
style={inputStyle}
value={formData.first_name}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
required
/>
</div>
<div className="col-12 col-md-6 mb-3">
<label htmlFor="last_name" className="form-label" style={labelStyle}>
Last Name <span style={{ color: '#dc3545' }}>*</span>
</label>
<input
type="text"
id="last_name"
name="last_name"
className="form-control"
style={inputStyle}
value={formData.last_name}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
required
/>
</div>
<div className="col-12 col-md-6 mb-3">
<label htmlFor="email" className="form-label" style={labelStyle}>
Email Address <span style={{ color: '#dc3545' }}>*</span>
</label>
<input
type="email"
id="email"
name="email"
className="form-control"
style={inputStyle}
value={formData.email}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
required
/>
</div>
<div className="col-12 col-md-6 mb-3">
<label htmlFor="phone" className="form-label" style={labelStyle}>
Phone Number
</label>
<input
type="tel"
id="phone"
name="phone"
className="form-control"
style={inputStyle}
value={formData.phone}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
</div>
</div>
{/* Professional Information */}
<div className="section" style={sectionStyle}>
<div style={sectionHeaderStyle}>
<span className="material-symbols-outlined me-2" style={{ color: '#667eea', fontSize: '22px' }}>work</span>
<h4 className="fw-6 mb-0" style={{ color: '#333', fontSize: '16px' }}>Professional Info</h4>
</div>
<div className="row">
<div className="col-12 col-md-6 mb-24">
<label htmlFor="current_position" className="form-label" style={labelStyle}>
Current Position
</label>
<input
type="text"
id="current_position"
name="current_position"
className="form-control"
style={inputStyle}
value={formData.current_position}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
<div className="col-12 col-md-6 mb-24">
<label htmlFor="current_company" className="form-label" style={labelStyle}>
Current Company
</label>
<input
type="text"
id="current_company"
name="current_company"
className="form-control"
style={inputStyle}
value={formData.current_company}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
<div className="col-12 mb-24">
<label htmlFor="years_of_experience" className="form-label" style={labelStyle}>
Years of Experience
</label>
<input
type="text"
id="years_of_experience"
name="years_of_experience"
className="form-control"
style={inputStyle}
placeholder="e.g., 3-5 years"
value={formData.years_of_experience}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
</div>
</div>
{/* Resume and Cover Letter */}
<div className="section" style={sectionStyle}>
<div style={sectionHeaderStyle}>
<span className="material-symbols-outlined me-2" style={{ color: '#667eea', fontSize: '22px' }}>upload_file</span>
<h4 className="fw-6 mb-0" style={{ color: '#333', fontSize: '16px' }}>Documents</h4>
</div>
<div className="row">
<div className="col-12 mb-24">
<label htmlFor="resume" className="form-label" style={labelStyle}>
Resume (PDF, DOC, DOCX - Max 5MB) <span style={{ color: '#dc3545' }}>*</span>
</label>
<input
type="file"
id="resume"
name="resume"
className="form-control"
style={{...inputStyle, padding: '10px 16px'}}
accept=".pdf,.doc,.docx"
onChange={handleFileChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
required
/>
{resume && <small style={{ color: '#28a745', fontWeight: '500', display: 'block', marginTop: '8px' }}> Selected: {resume.name}</small>}
</div>
<div className="col-12 mb-3">
<label htmlFor="cover_letter" className="form-label" style={labelStyle}>
Cover Letter / Message
</label>
<textarea
id="cover_letter"
name="cover_letter"
className="form-control"
style={{...inputStyle, minHeight: '120px', resize: 'vertical'}}
rows={5}
placeholder="Tell us why you're interested in this position..."
value={formData.cover_letter}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
</div>
</div>
{/* Links */}
<div className="section" style={sectionStyle}>
<div style={sectionHeaderStyle}>
<span className="material-symbols-outlined me-2" style={{ color: '#667eea', fontSize: '22px' }}>link</span>
<h4 className="fw-6 mb-0" style={{ color: '#333', fontSize: '16px' }}>Links (Optional)</h4>
</div>
<div className="row">
<div className="col-12 col-md-6 mb-24">
<label htmlFor="portfolio_url" className="form-label" style={labelStyle}>
Portfolio / Website
</label>
<input
type="url"
id="portfolio_url"
name="portfolio_url"
className="form-control"
style={inputStyle}
placeholder="https://"
value={formData.portfolio_url}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
<div className="col-12 col-md-6 mb-24">
<label htmlFor="linkedin_url" className="form-label" style={labelStyle}>
LinkedIn Profile
</label>
<input
type="url"
id="linkedin_url"
name="linkedin_url"
className="form-control"
style={inputStyle}
placeholder="https://linkedin.com/in/..."
value={formData.linkedin_url}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
<div className="col-12 col-md-6 mb-24">
<label htmlFor="github_url" className="form-label" style={labelStyle}>
GitHub Profile
</label>
<input
type="url"
id="github_url"
name="github_url"
className="form-control"
style={inputStyle}
placeholder="https://github.com/..."
value={formData.github_url}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
<div className="col-12 col-md-6 mb-24">
<label htmlFor="website_url" className="form-label" style={labelStyle}>
Personal Website
</label>
<input
type="url"
id="website_url"
name="website_url"
className="form-control"
style={inputStyle}
placeholder="https://"
value={formData.website_url}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
</div>
</div>
{/* Availability & Salary */}
<div className="section" style={sectionStyle}>
<div style={sectionHeaderStyle}>
<span className="material-symbols-outlined me-2" style={{ color: '#667eea', fontSize: '22px' }}>event_available</span>
<h4 className="fw-6 mb-0" style={{ color: '#333', fontSize: '16px' }}>Availability</h4>
</div>
<div className="row">
<div className="col-12 col-md-6 mb-24">
<label htmlFor="available_from" className="form-label" style={labelStyle}>
Available From
</label>
<input
type="date"
id="available_from"
name="available_from"
className="form-control"
style={inputStyle}
value={formData.available_from}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
<div className="col-12 col-md-6 mb-24">
<label htmlFor="notice_period" className="form-label" style={labelStyle}>
Notice Period
</label>
<input
type="text"
id="notice_period"
name="notice_period"
className="form-control"
style={inputStyle}
placeholder="e.g., 2 weeks, 1 month"
value={formData.notice_period}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
<div className="col-12 col-md-6 mb-24">
<label htmlFor="expected_salary" className="form-label" style={labelStyle}>
Expected Salary
</label>
<input
type="number"
id="expected_salary"
name="expected_salary"
className="form-control"
style={inputStyle}
placeholder="Amount"
value={formData.expected_salary}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
/>
</div>
<div className="col-12 col-md-6 mb-24">
<label htmlFor="salary_currency" className="form-label" style={labelStyle}>
Currency
</label>
<select
id="salary_currency"
name="salary_currency"
className="form-control"
style={inputStyle}
value={formData.salary_currency}
onChange={handleInputChange}
onFocus={(e) => {
e.target.style.borderColor = '#667eea';
e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#e0e0e0';
e.target.style.boxShadow = 'none';
}}
>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
<option value="GBP">GBP</option>
<option value="INR">INR</option>
<option value="AUD">AUD</option>
<option value="CAD">CAD</option>
</select>
</div>
</div>
</div>
{/* Consent */}
<div className="section" style={{
background: 'linear-gradient(135deg, #fff9e6 0%, #fffbf0 100%)',
padding: 'clamp(14px, 3vw, 16px)',
borderRadius: '8px',
border: '1px solid #ffd700',
marginBottom: '16px'
}}>
<div className="form-check d-flex align-items-start">
<input
type="checkbox"
id="consent"
name="consent"
className="form-check-input"
style={{
width: '18px',
height: '18px',
marginTop: '2px',
marginRight: '10px',
cursor: 'pointer',
flexShrink: 0,
accentColor: '#667eea'
}}
checked={formData.consent}
onChange={handleInputChange}
required
/>
<label htmlFor="consent" className="form-check-label" style={{
fontSize: 'clamp(12px, 2vw, 13px)',
color: '#555',
lineHeight: '1.5',
cursor: 'pointer'
}}>
I consent to data processing for recruitment purposes. <span style={{ color: '#dc3545', fontWeight: '600' }}>*</span>
</label>
</div>
</div>
</div>
{/* Submit and Cancel Buttons - Fixed Footer */}
<div className="text-center" style={{
paddingTop: '16px',
paddingBottom: '16px',
borderTop: '2px solid #e8e8e8',
backgroundColor: 'white',
padding: '16px clamp(20px, 4vw, 32px)',
borderRadius: '0 0 16px 16px',
boxShadow: '0 -4px 12px rgba(0,0,0,0.05)',
flexShrink: 0
}}>
<div style={{ display: 'flex', gap: '12px', justifyContent: 'center', flexWrap: 'wrap' }}>
<button
type="submit"
className="btn"
disabled={isSubmitting}
style={{
minWidth: "160px",
backgroundColor: isSubmitting ? '#ccc' : 'white',
color: '#333',
border: '2px solid #667eea',
padding: '12px 32px',
fontSize: '15px',
fontWeight: '600',
borderRadius: '6px',
transition: 'all 0.3s ease',
cursor: isSubmitting ? 'not-allowed' : 'pointer',
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
gap: '8px'
}}
onMouseEnter={(e) => {
if (!isSubmitting) {
e.currentTarget.style.backgroundColor = '#FFD700';
e.currentTarget.style.borderColor = '#FFD700';
e.currentTarget.style.transform = 'translateY(-2px)';
e.currentTarget.style.boxShadow = '0 8px 16px rgba(0,0,0,0.15)';
}
}}
onMouseLeave={(e) => {
if (!isSubmitting) {
e.currentTarget.style.backgroundColor = 'white';
e.currentTarget.style.borderColor = '#667eea';
e.currentTarget.style.transform = 'translateY(0)';
e.currentTarget.style.boxShadow = 'none';
}
}}
>
{isSubmitting ? (
<>
<span className="material-symbols-outlined" style={{ fontSize: '20px', animation: 'spin 1s linear infinite' }}>progress_activity</span>
Submitting...
</>
) : (
<>
<span className="material-symbols-outlined" style={{ fontSize: '20px' }}>send</span>
Submit Application
</>
)}
</button>
{onClose && !isSubmitting && (
<button
type="button"
onClick={onClose}
className="btn"
style={{
minWidth: "120px",
backgroundColor: 'transparent',
color: '#666',
border: '2px solid #e0e0e0',
padding: '12px 24px',
fontSize: '15px',
fontWeight: '600',
borderRadius: '6px',
transition: 'all 0.3s ease',
cursor: 'pointer',
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
gap: '8px'
}}
onMouseEnter={(e) => {
e.currentTarget.style.backgroundColor = '#f5f5f5';
e.currentTarget.style.borderColor = '#999';
e.currentTarget.style.color = '#333';
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = 'transparent';
e.currentTarget.style.borderColor = '#e0e0e0';
e.currentTarget.style.color = '#666';
}}
>
<span className="material-symbols-outlined" style={{ fontSize: '18px' }}>close</span>
Cancel
</button>
)}
</div>
<p style={{
marginTop: '10px',
color: '#999',
fontSize: 'clamp(11px, 2vw, 12px)'
}}>
By submitting, you agree to our terms
</p>
</div>
</form>
<style>{`
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* Custom scrollbar styling */
.form-scrollable-content::-webkit-scrollbar {
width: 8px;
}
.form-scrollable-content::-webkit-scrollbar-track {
background: #f0f0f0;
border-radius: 4px;
}
.form-scrollable-content::-webkit-scrollbar-thumb {
background: #667eea;
border-radius: 4px;
}
.form-scrollable-content::-webkit-scrollbar-thumb:hover {
background: #5568d3;
}
/* Ensure smooth scrolling on touch devices */
.form-scrollable-content {
-webkit-overflow-scrolling: touch;
overscroll-behavior: contain;
}
/* Better mobile input styling */
@media (max-width: 768px) {
.form-control {
font-size: 16px !important; /* Prevents zoom on iOS */
}
}
`}</style>
</div>
);
};
export default JobApplicationForm;