React + Vite HRM system development instructions with role-based access control, localStorage persistence, and Nepali date integration
Development instructions for a React + Vite Human Resource Management (HRM) system with role-based access control (Superadmin, HR, Employee). Uses localStorage for mock data persistence with no backend integration.
React + Vite HRM system featuring:
```
MockDataProvider (outer) → AuthProvider (inner) → App
```
**Critical**: This order is required - `AuthContext` depends on `MockDataProvider` for user data.
All application state lives in React Context + localStorage:
**Key principle**: Every data mutation must update both state AND localStorage to persist changes.
System uses external APIs to populate initial data:
Pattern for API initialization:
```jsx
const dummyData = await initializeDummyData();
localStorage.setItem("hrm_users", JSON.stringify(dummyData.users));
```
Three roles with distinct capabilities:
Route protection implemented via `src/components/ProtectedRoute.jsx` with `allowedRoles` prop.
Always follow this sequence when modifying data:
```jsx
const newData = [...existingData, newItem];
setState(newData);
localStorage.setItem("hrm_key", JSON.stringify(newData));
```
See `src/context/MockData.jsx` for reference implementations: `addUser`, `addAttendance`, `updateLeaveStatus` functions.
Pages follow this structure:
1. Form state in component
2. `handleChange` updates state via `e.target.name`/`e.target.value`
3. `handleSubmit` calls context function to persist
4. Modal toggles via boolean state (`showModal`)
5. Success message with 3-second auto-hide
Reference: `src/pages/Employees.jsx`, `src/pages/superadmin/CreateHR.jsx`
`nepali-date-converter` library used for BS/AD date conversion:
See `src/pages/Employees.jsx` for implementation example.
```bash
npm run dev # Start dev server (Vite HMR on http://localhost:5173)
npm run build # Production build
npm run preview # Preview production build
npm run lint # ESLint check
```
**Default superadmin**:
**All dummy API users**:
**Reset Data**: Clear browser localStorage or use DevTools to remove `hrm_*` keys to reload fresh data from API.
**New Page with Role Protection**:
1. Create component in `src/pages/`
2. Add route in `src/App.jsx` with `<ProtectedRoute allowedRoles={['role1', 'role2']}>`
3. Update `getMenuItems()` in `src/components/Sidebar.jsx` for navigation
**New Data Entity**:
1. Add state + localStorage key in `MockDataProvider`
2. Create helper functions (add/update/delete pattern)
3. Initialize with `useEffect` on mount
4. Export via context value
Uses `lucide-react` - import specific icons as components:
```jsx
import { Home, Users, Calendar } from "lucide-react";
```
Ternary for simple toggles, early returns for role checks:
```jsx
if (!user) return <Navigate to="/login" replace />;
```
```jsx
// 1. Create the page component
// src/pages/NewFeature.jsx
import { useAuth } from '../context/AuthContext';
export default function NewFeature() {
const { user } = useAuth();
return (
<div className="p-6">
<h1 className="text-2xl font-bold text-slate-800">New Feature</h1>
{/* Feature content */}
</div>
);
}
// 2. Add route in App.jsx
<Route path="/new-feature" element={
<ProtectedRoute allowedRoles={['hr', 'superadmin']}>
<MainLayout><NewFeature /></MainLayout>
</ProtectedRoute>
} />
// 3. Add to Sidebar.jsx navigation
{ name: 'New Feature', icon: Star, path: '/new-feature', roles: ['hr', 'superadmin'] }
```
```jsx
// In src/context/MockData.jsx
const [customData, setCustomData] = useState([]);
useEffect(() => {
const stored = localStorage.getItem('hrm_custom_data');
if (stored) setCustomData(JSON.parse(stored));
}, []);
const addCustomData = (newData) => {
const updated = [...customData, { ...newData, id: `CUST${Date.now()}` }];
setCustomData(updated);
localStorage.setItem('hrm_custom_data', JSON.stringify(updated));
};
// Export in context value
<MockDataContext.Provider value={{ customData, addCustomData, ... }}>
```
1. **Starting Development**: Run `npm run dev` and navigate to `http://localhost:5173`
2. **Login**: Use superadmin credentials (`[email protected]` / `admin`) or any dummy user (`password123`)
3. **Adding Features**: Follow the patterns in Critical Files section for consistency
4. **Data Persistence**: Always update both state and localStorage when mutating data
5. **Role Checks**: Use `allowedRoles` prop on `ProtectedRoute` for access control
6. **Styling**: Follow Tailwind conventions outlined in Styling Conventions section
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/github-copilot-hrm-development/raw