Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds

Job Board & Applications

System ogłoszeń i aplikacji o pracę.

Job Listings 💼

1interface Job {
2  id: number;
3  title: string;
4  company: string;
5  location: string;
6  salary: string;
7  type: 'full-time' | 'part-time' | 'contract';
8  posted: string;
9}
10
11function JobBoard() {
12  const [jobs, setJobs] = useState<Job[]>([]);
13  const [filters, setFilters] = useState({
14    location: '',
15    type: '',
16    salary: ''
17  });
18
19  const filteredJobs = jobs.filter(job => {
20    if (filters.location && !job.location.includes(filters.location)) return false;
21    if (filters.type && job.type !== filters.type) return false;
22    return true;
23  });
24
25  return (
26    <div>
27      <div className="mb-4 flex gap-4">
28        <input
29          onChange={(e) => setFilters({...filters, location: e.target.value})}
30          className="border rounded px-3 py-2"
31        />
32        <select
33          onChange={(e) => setFilters({...filters, type: e.target.value as any})}
34          className="border rounded px-3 py-2"
35        >
36          <option value="">All Types</option>
37          <option value="full-time">Full Time</option>
38          <option value="part-time">Part Time</option>
39          <option value="contract">Contract</option>
40        </select>
41      </div>
42
43      <div className="space-y-4">
44        {filteredJobs.map(job => (
45          <div key={job.id} className="border rounded p-4">
46            <h3 className="font-bold text-lg">{job.title}</h3>
47            <p className="text-gray-600">{job.company}{job.location}</p>
48            <p className="text-green-600 font-medium">{job.salary}</p>
49            <button className="mt-2 bg-blue-600 text-white px-4 py-2 rounded">
50              Apply Now
51            </button>
52          </div>
53        ))}
54      </div>
55    </div>
56  );
57}

Application Form 📝

1function ApplicationForm({ jobId }: { jobId: number }) {
2  const [formData, setFormData] = useState({
3    name: '',
4    email: '',
5    phone: '',
6    resume: null as File | null,
7    coverLetter: ''
8  });
9
10  const handleSubmit = async (e: React.FormEvent) => {
11    e.preventDefault();
12    const data = new FormData();
13    Object.entries(formData).forEach(([key, value]) => {
14      if (value) data.append(key, value);
15    });
16
17    await fetch(`/api/jobs/${jobId}/apply`, {
18      method: 'POST',
19      body: data
20    });
21  };
22
23  return (
24    <form onSubmit={handleSubmit} className="space-y-4">
25      <input
26        onChange={(e) => setFormData({...formData, name: e.target.value})}
27        required
28        className="w-full border rounded px-3 py-2"
29      />
30      <input
31        type="email"
32        onChange={(e) => setFormData({...formData, email: e.target.value})}
33        required
34        className="w-full border rounded px-3 py-2"
35      />
36      <input
37        type="file"
38        accept=".pdf,.doc,.docx"
39        onChange={(e) => setFormData({...formData, resume: e.target.files?.[0] || null})}
40        required
41      />
42      <textarea
43        onChange={(e) => setFormData({...formData, coverLetter: e.target.value})}
44        rows={6}
45        className="w-full border rounded px-3 py-2"
46      />
47      <button type="submit" className="bg-blue-600 text-white px-6 py-2 rounded">
48        Submit Application
49      </button>
50    </form>
51  );
52}

Do zobaczenia! 🚀

Przejdź do CodeWorlds