skillsync-cli / frontend /README.md
Mr-Haseeb786
Sanitized Production Build
56c7b6d
|
Raw
History Blame Contribute Delete
8.1 kB

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

  1. Install Dependencies
cd frontend
npm install
  1. Configure Environment
# Copy environment template
cp .env.example .env

# Edit .env if needed
# VITE_API_URL=http://localhost:5050
  1. 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 jobs
  • cvTemplate - Uploaded CV template
  • tailoringMode - 'local' or 'api'
  • isSearching, isGenerating - Loading states
  • selectedJobIds - Jobs selected for batch generation
  • batchProgress - Progress of batch operation
  • notification - 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_URL in .env
  • Clear browser cache

Tailwind styles not applying

  • Restart dev server
  • Verify file paths in tailwind.config.js include all source files

Type errors

  • Run npm run type-check
  • Ensure tsconfig.json paths are correct

πŸ“„ License

MIT

🀝 Contributing

Contributions welcome! Please follow the existing code style and component patterns.