A full-stack job board application built with the MERN stack. Users can browse and search job listings, view job details, and submit applications. Admins can post and delete jobs through a built-in admin panel.
| Layer | Technology |
|---|---|
| Frontend | React.js + Vite |
| Styling | Tailwind CSS |
| Routing | React Router v7 |
| Backend | Node.js + Express |
| Database | MongoDB Atlas |
| Auth | Firebase Authentication |
| HTTP Client | Axios |
- Job Listings Page — Browse all jobs with search by keyword/location and filter by category
- Job Detail Page — Full job info with an Apply Now form (name, email, resume URL, cover note)
- Admin Panel — Post new jobs and delete existing listings
- Responsive UI — Fully responsive across mobile, tablet, and desktop
- Form Validation — All forms validate required fields, email format, and URL format
quickhire/
├── client/ # React frontend (Vite)
│ ├── public/
│ ├── src/
│ │ ├── assets/ # Images, logos, icons
│ │ │ ├── Pic.png
│ │ │ ├── dashboard.png
│ │ │ └── logos/
│ │ │ ├── vodafone.png
│ │ │ ├── intel.png
│ │ │ ├── tesla.png
│ │ │ ├── amd.png
│ │ │ └── talkit.png
│ │ ├── components/ # Reusable UI components
│ │ │ ├── Navbar.jsx
│ │ │ ├── Hero.jsx
│ │ │ ├── Companies.jsx
│ │ │ ├── Category.jsx
│ │ │ ├── PostJobBanner.jsx
│ │ │ ├── FeaturedJobs.jsx
│ │ │ ├── LatestJobs.jsx
│ │ │ ├── JobCard.jsx
│ │ │ └── Footer.jsx
│ │ ├── pages/ # Page-level components
│ │ │ ├── Home.jsx
│ │ │ ├── AllJobs.jsx
│ │ │ ├── JobDetail.jsx
│ │ │ └── Admin.jsx
│ │ ├── App.jsx
│ │ └── main.jsx
│ ├── .env.local
│ └── package.json
│
└── server/ # Express backend
├── server.js
├── .env
└── package.json
- Node.js v18+
- A MongoDB Atlas account
- A Firebase project (for authentication)
git clone https://github.com/your-username/quickhire.git
cd quickhirecd server
npm installCreate a .env file in the server/ folder:
PORT=5000
DB_USER=your_mongodb_username
DB_PASS=your_mongodb_passwordStart the server:
node server.jsThe server will run at http://localhost:5000
cd client
npm installCreate a .env.local file in the client/ folder:
VITE_API_URL=http://localhost:5000
VITE_FIREBASE_API_KEY=your_firebase_api_key
VITE_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your_project_id
VITE_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
VITE_FIREBASE_APP_ID=your_app_idStart the frontend:
npm run devThe app will run at http://localhost:5173
Once your server is running, populate it with sample job data by making a single POST request:
# Using curl
curl -X POST http://localhost:5000/api/seed
# Or open this URL in Postman / Insomnia as a POST requestThis will insert 16 sample jobs (8 featured + 8 latest) matching the design.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/jobs |
Get all jobs (supports query filters) |
GET |
/api/jobs/:id |
Get a single job by ID |
POST |
/api/jobs |
Create a new job (Admin) |
DELETE |
/api/jobs/:id |
Delete a job (Admin) |
POST |
/api/seed |
Seed sample data (dev only) |
| Param | Type | Example | Description |
|---|---|---|---|
keyword |
string | ?keyword=designer |
Search title, company, description |
location |
string | ?location=Berlin |
Filter by location |
category |
string | ?category=Marketing |
Filter by category |
featured |
boolean | ?featured=true |
Only featured jobs |
limit |
number | ?limit=8 |
Limit number of results |
sort |
string | ?sort=newest |
Sort by newest first |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/applications |
Submit a job application |
GET |
/api/applications |
Get all applications (Admin) |
GET |
/api/applications/:jobId |
Get applications for a specific job |
{
"job_id": "64abc123...",
"name": "John Doe",
"email": "john@example.com",
"resume_link": "https://linkedin.com/in/johndoe",
"cover_note": "I am excited to apply for this position..."
}{
"_id": "ObjectId",
"title": "Brand Designer",
"company": "Dropbox",
"location": "San Francisco, USA",
"category": "Design",
"type": "Full Time",
"description": "Job description here...",
"featured": true,
"logo": null,
"created_at": "2024-01-01T00:00:00.000Z"
}{
"_id": "ObjectId",
"job_id": "ObjectId (ref: jobs)",
"name": "John Doe",
"email": "john@example.com",
"resume_link": "https://example.com/resume.pdf",
"cover_note": "Cover note text here...",
"created_at": "2024-01-01T00:00:00.000Z"
}Design · Sales · Marketing · Finance · Technology · Engineering · Business · Human Resource
| Variable | Description |
|---|---|
PORT |
Server port (default: 5000) |
DB_USER |
MongoDB Atlas username |
DB_PASS |
MongoDB Atlas password |
| Variable | Description |
|---|---|
VITE_API_URL |
Backend base URL (e.g. http://localhost:5000) |
VITE_FIREBASE_API_KEY |
Firebase API key |
VITE_FIREBASE_AUTH_DOMAIN |
Firebase auth domain |
VITE_FIREBASE_PROJECT_ID |
Firebase project ID |
VITE_FIREBASE_STORAGE_BUCKET |
Firebase storage bucket |
VITE_FIREBASE_MESSAGING_SENDER_ID |
Firebase messaging sender ID |
VITE_FIREBASE_APP_ID |
Firebase app ID |
- Push your
client/folder to GitHub - Import the repo on vercel.com
- Set the root directory to
client - Add all
VITE_*environment variables in the Vercel dashboard - Deploy
- Push your
server/folder to GitHub - Create a new Web Service on render.com
- Set the root directory to
server - Set the start command to
node server.js - Add
DB_USERandDB_PASSas environment variables - After deploying, update
VITE_API_URLin Vercel to your Render URL
A screen recording should cover:
- Home page — hero section, categories, featured jobs, latest jobs
- Searching and filtering jobs on the
/jobspage - Clicking a job to view full details
- Filling out and submitting the Apply Now form
- Visiting
/adminto post a new job and delete an existing one
This project was built as part of a technical assessment task. All rights reserved.