A real-time employee & manager productivity platform built with React and Firebase.
ManageMe is a full-stack web app for managing employees, tasks, time tracking, and team productivity. It supports two roles — Manager and Employee — each with a dedicated dashboard and feature set.
All data syncs live across sessions using Firestore's onSnapshot listeners. No page refresh required — ever.
| Dark Mode | Light Mode | Purple Mode |
|---|---|---|
#0c0c0f deep black |
#f2f2f8 off-white |
#100820 deep violet |
Accent #8b5cf6 |
Accent #6d28d9 |
Accent #c084fc |
| Layer | Technology |
|---|---|
| Frontend | React 18 + Vite |
| Styling | CSS custom properties — no UI library |
| Database | Firebase Firestore (real-time) |
| Auth | Firebase Authentication (email/password) |
| Fonts | Syne + DM Mono (Google Fonts) |
mailto: via system mail client |
src/
├── components/
│ ├── UI.jsx # Sidebar, Avatar, Toast, SearchBar, Empty
│ ├── PunchCard.jsx # Clock-in / clock-out with live elapsed timer
│ ├── AssignTaskModal.jsx # Create & edit tasks (individual or team)
│ ├── Taskdetail.jsx # Task detail modal (checklist, notes, deliverables)
│ ├── SettingsScreen.jsx # Profile, password, theme picker
│ ├── WorkHistory.jsx # Session log with hours + earnings
│ └── OnboardFlow.jsx # First-run setup for new users
│
├── pages/
│ ├── BossDashboard.jsx # Manager view — full team & task management
│ └── EmployeeDashboard.jsx # Employee view — personal & team tasks
│
├── lib/
│ ├── firebase.js # Firebase app init (db, auth exports)
│ ├── inject.js # Global CSS injection + theme system
│ └── utils.js # sendEmail, avatarColor, initials helpers
│
└── hooks/
└── index.js # useToast, useClock, useElapsed
- Dashboard — stat cards (open tasks, urgent, completed, hourly rate) + overall progress bar
- Punch In / Out — live elapsed timer, session note on punch-out
- My Tasks — personal + team tasks unified, with:
- Filter by source:
All/👤 Personal/👥 Team - Filter by status:
To Do/In Progress/Done - Quick-complete circle button — mark done without opening the task
- Real-time updates — new tasks appear instantly, no refresh
- Filter by source:
- Task Detail — checklist, notes, deliverables, claim/unclaim team tasks, send email
- Work History — session log with duration and earnings breakdown
- Teams — view your mini-teams, click any member for a profile popup
- Settings — profile editing, password change, theme picker
- Dashboard — team stats, clocked-in employees, urgent tasks, currently active list
- All Tasks — full task list with filters: status, priority, assignee, type; edit any task
- Completed Tasks — filter by month, search completed work
- Team tab:
- Employee list with live clock-in status
- Click any employee → view their full work history
- Set hourly rate per employee
- Mini-Teams — create/delete teams, add/remove members, assign tasks to a whole team
- Assign Task Modal — title, description, priority, due date, reminder emails, checklist builder, auto-sends notification email on assignment
- Settings — profile editing, password change, theme picker
Three fully-scoped themes, saved to localStorage and applied via data-theme on <html>:
| Theme | Background | Accent | Best For |
|---|---|---|---|
| 🌑 Dark | #0c0c0f |
#8b5cf6 |
Low-light environments |
| ☀️ Light | #f2f2f8 |
#6d28d9 |
Bright, high-contrast work |
| 🔮 Purple | #100820 |
#c084fc |
Rich immersive experience |
All components use CSS variables (--text, --surface, --accent, etc.) so they adapt automatically to any theme. Users switch themes in Settings → Appearance and their choice persists across sessions.
Click to expand schema
users/{uid}
name, email, role ("boss" | "employee"), phone, jobTitle
companies: [{ code, name, role }]
sessions: { [companyCode]: { active, startedAt } }
clockedIn: boolean
tasks/{id}
title, description, priority ("low" | "medium" | "urgent")
status ("todo" | "inprogress" | "done")
assignerId, assignerName, companyCode
assigneeId, assigneeName, assigneeEmail ← individual tasks
teamId, teamName, teamMemberIds ← team tasks
claimedBy, claimedByName ← team task claiming
dueDate, reminder, checklist[], notes
deliverable, deliverables[], deliverableAt
createdAt, updatedAt
sessions/{id}
userId, userName, companyCode
startTime, startedAt, endTime
status ("active" | "complete"), note
teams/{id}
name, companyCode, managerUid
memberUids[], createdAt
memberRates/{companyCode_uid}
rate ← hourly rate
git clone https://github.com/your-username/manageme.git
cd manageme
npm installCreate a project at console.firebase.google.com, enable Email/Password Auth and Firestore, then create src/lib/firebase.js:
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID"
};
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
export const auth = getAuth(app);Call these once at the very top of your app entry point (main.jsx or App.jsx):
import { injectStyles, loadSavedTheme } from "./lib/inject";
injectStyles(); // injects all global CSS
loadSavedTheme(); // reads localStorage and sets data-theme on <html>npm run dev # development server with HMR
npm run build # production build → /dist
npm run preview # preview production build locallyAll Firestore reads use onSnapshot() instead of getDocs(). This means:
- ✅ Tasks appear instantly when a manager assigns them
- ✅ Clock-in status updates live across all open tabs
- ✅ Team task claims reflect immediately for all team members
- ✅ Status changes sync to the manager view in real time
Listeners are registered in useEffect() and cleaned up on unmount via the returned unsubscribe function.
Team task queries chunk myTeamIds into groups of 10 (Firestore in operator limit) and run parallel onSnapshot listeners per chunk.
inject.jsmust load before any component renders. CallinjectStyles()andloadSavedTheme()at the very top of your entry point.
SettingsScreen.jsxis self-contained.THEMESandapplyThemeare inlined directly — do not import them frominject.jsin this file or Vite will throw an import resolution error.
Profile popups use
position: fixed. They calculate position fromgetBoundingClientRect()to escape anyoverflow: hiddenparent. Do not addoverflow: hiddento team card wrappers or the popup will be clipped.
Private / proprietary. All rights reserved. Do not distribute without permission.