Job Apply AI - React Frontend
A modern, SaaS-like React frontend for the Job Application AI Agent with beautiful animations, dark theme, and professional UI.
π Features
- Modern React 18 with TypeScript
- State Management with Zustand for efficient state handling
- Tailwind CSS with custom emerald/black SaaS theme
- Framer Motion animations for smooth interactions
- Component Library with reusable, animated components
- Responsive Design that works on all devices
- REST API Integration with the Python backend
- Dark Mode with professional styling
π οΈ Tech Stack
- React 18 - UI framework
- TypeScript - Type safety
- Vite - Build tool and dev server
- Tailwind CSS - Utility-first CSS framework
- Framer Motion - Animation library
- Zustand - State management
- Axios - HTTP client
- Lucide React - Icon library
π¦ Installation
Prerequisites
- Node.js 18+ and npm/yarn
- Python backend running on port 5050
Setup
- Install Dependencies
cd frontend
npm install
- Configure Environment
# Copy environment template
cp .env.example .env
# Edit .env if needed
# VITE_API_URL=http://localhost:5050
- Start Development Server
npm run dev
The app will be available at http://localhost:3000
ποΈ Project Structure
frontend/
βββ src/
β βββ components/
β β βββ common/ # Reusable UI components
β β β βββ Button.tsx
β β β βββ Card.tsx
β β β βββ Input.tsx
β β β βββ Modal.tsx
β β β βββ ...
β β βββ pages/ # Full page components
β β β βββ HomePage.tsx
β β β βββ WorkflowPage.tsx
β β β βββ JobListPage.tsx
β β β βββ SettingsModal.tsx
β β βββ sections/ # Reusable page sections
β β βββ Header.tsx
β β βββ Footer.tsx
β β βββ CVUpload.tsx
β β βββ JobSearch.tsx
β βββ store/ # Zustand state management
β β βββ appStore.ts
β βββ types/ # TypeScript type definitions
β β βββ index.ts
β βββ utils/ # Utility functions
β β βββ api.ts
β β βββ helpers.ts
β βββ styles/ # Global styles
β β βββ globals.css
β βββ App.tsx # Root component
β βββ main.tsx # Entry point
βββ public/ # Static assets
βββ index.html # HTML template
βββ package.json
βββ tailwind.config.js # Tailwind CSS config
βββ tsconfig.json
βββ vite.config.ts # Vite config
π¨ Styling & Theming
The project uses Tailwind CSS with a custom color scheme:
Colors
- Background:
#0A0E27(black) - Primary:
#22c55e(emerald-500) - Secondary: Slate gray colors
- Accents: Emerald shades for highlights
Key Tailwind Config Features
- Custom gradient backgrounds
- Glow effects with custom shadows
- Animation utilities
- Responsive breakpoints
Using Layout Classes
// Dark SaaS background
<div className="bg-gradient-saas">
// Primary button with glow
<Button className="shadow-glow">Generate CVs</Button>
// Card with optional glow and inner glow
<Card glow innerGlow>Content</Card>
// Emerald gradient text
<h1 className="bg-gradient-emerald bg-clip-text text-transparent">
Title
</h1>
π§© Components
Common Components
All components are in src/components/common/:
Button
<Button
variant="primary" // primary, secondary, outline, ghost, danger
size="lg" // sm, md, lg
loading={false}
icon={<Icon />}
fullWidth
>
Click Me
</Button>
Card
<Card hover glow innerGlow>
Content with animations
</Card>
Input
<Input
label="Your Name"
placeholder="Enter name"
error={errors.name}
icon={<Icon />}
helperText="Optional"
/>
Badge
<Badge variant="primary" size="md" icon={<Icon />}>
Label
</Badge>
Modal
<Modal isOpen={isOpen} onClose={handleClose} title="Dialog">
Content
</Modal>
Toast Notification
<Toast
type="success" // success, error, warning, info
message="Success!"
title="Great"
onClose={() => {}}
autoClose={true}
/>
π State Management with Zustand
The app uses Zustand for state management. Store is located in src/store/appStore.ts:
import { useJobStore } from '@/store/appStore';
function MyComponent() {
const { jobs, setJobs, cvTemplate, setCVTemplate } = useJobStore();
// State is automatically persisted to localStorage
// Update state by calling setter functions
}
Available State
jobs- Array of found jobscvTemplate- Uploaded CV templatetailoringMode- 'local' or 'api'isSearching,isGenerating- Loading statesselectedJobIds- Jobs selected for batch generationbatchProgress- Progress of batch operationnotification- Toast notification data
π API Integration
The frontend communicates with the backend via REST API endpoints in src/utils/api.ts:
import { jobsAPI } from '@/utils/api';
// Search jobs
const result = await jobsAPI.searchJobs({
keyword: 'React Developer',
location: 'San Francisco',
maxJobs: 10
});
// Upload CV
await jobsAPI.uploadCV(file);
// Generate CV
await jobsAPI.generateCV(jobId);
// Batch generate
await jobsAPI.generateAllCVs(jobIds);
// Download file
const blob = await jobsAPI.downloadFile(filename);
π¬ Animations with Framer Motion
All components use Framer Motion for smooth animations:
import { motion } from 'framer-motion';
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
Animated content
</motion.div>
π§ Development
Commands
# Start dev server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Type check
npm run type-check
# Lint code
npm run lint
File Paths
Components use path aliases for clean imports:
// Instead of:
import Button from '../../../components/common/Button';
// Use:
import { Button } from '@/components/common';
import type { Job } from '@/types';
Available aliases:
@/components/*- Components@/store/*- State management@/types/*- Type definitions@/utils/*- Utilities@/hooks/*- Custom hooks
π Build & Deployment
Production Build
npm run build
This generates a production-optimized build in dist/ folder that gets served by the Flask backend.
Integration with Flask
The Vite config is set up to build directly into the Flask static folder:
frontend/dist/ β job_apply_ai/ui/static/dist/
The Flask app serves these files at /static/dist/ or /app/ routes.
π± Responsive Design
The app is fully responsive with Tailwind breakpoints:
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4">
// 1 column on mobile, 2 on tablet, 4 on desktop
</div>
βΏ Accessibility
- Semantic HTML
- ARIA labels where needed
- Keyboard navigation support
- Focus states for all interactive elements
- Color contrast compliance
π Troubleshooting
Dev server not connecting to backend
- Ensure Flask is running on port 5050
- Check
VITE_API_URLin.env - Clear browser cache
Tailwind styles not applying
- Restart dev server
- Verify file paths in
tailwind.config.jsinclude all source files
Type errors
- Run
npm run type-check - Ensure
tsconfig.jsonpaths are correct
π License
MIT
π€ Contributing
Contributions welcome! Please follow the existing code style and component patterns.