Timmo is a minimalist, premium productivity and focus application designed to help users track their focus times, observe their work consistency, and compete on a global leaderboard. It features custom countdowns, stopwatches, a GitHub-style activity heatmap, and a fully customizable dark-mode aesthetic.
- Dual-Timer Mode: Support for both manual Stopwatch tracking and structured Countdown sessions.
- Achievements & Badges: Gamified achievements tracking user progress (e.g., Touched the Timer, Locked In, Touch Grass Pls, Has No Life, Seek Professional Help, etc.) featuring a modern aesthetic list of gamer-inspired solid-color badges (Zap, Target, Leaf, Crown, Trophy, ShieldAlert, HeartCrack, LifeBuoy, Ghost).
- Global Leaderboards: A real-time leaderboard showing the top 100 focus builders of the day. Features personalized ranking cards and hover tooltips showing earned user badges. Optimized for responsive layouts with text truncation to prevent column overlapping.
- Visual Performance Analytics: Custom dashboard charting your daily focus trends over the last 30 days.
- Activity Heatmaps: A GitHub-style 365-day calendar visualizing your focus history.
- Premium Custom Settings:
- Customizable theme accent colors (White, Gold, Coral, Blue, Mint, Purple, Peach, Lime) plus a Custom Color Picker allowing users to select any custom hex color for all three clock interfaces.
- Multiple sidebar opening options (Manual toggle, Hover, Mix).
- Time layout formats (12-hour AM/PM vs. 24-hour) and option to toggle seconds.
- Responsive Design: Optimized layouts with flexible flex/grid wrapping for smooth mobile and desktop experiences.
- Detailed Profile Statistics: Displays today's focus, current streak, best streak, total sessions, and all-time milestone records formatted dynamically with seconds precision.
- Core: React 19 & Vite
- Styling: Tailwind CSS (with
@tailwindcss/viteplugin) - Animations: Framer Motion
- Charts: Shad cn components (for analytics and heatmap calendar)
- API Client: Axios
- Runtime: Node.js & Express.js
- Validation: Zod (for request validation schemas)
- Authentication: JSON Web Tokens (stored in HTTP-only cookies) & BCrypt (password hashing)
- Rate Limiting: Express Rate Limiter (to prevent brute force attacks)
- Database: MongoDB (managed via Mongoose ODM with database indexing for optimal performance)
├── backend/ # Express REST API
│ ├── db/ # Database connection helper
│ ├── middlewares/ # Auth guards and rate limiters
│ ├── model/ # Mongoose Database schemas
│ ├── routes/ # API route controllers
│ ├── utils/ # Helper utilities (dates, validation)
│ └── app.js # Server entry point
│
├── frontend/ # React client
│ ├── public/ # Static assets (favicons, og-image)
│ ├── src/
│ │ ├── components/ # Custom React views and components
│ │ ├── App.jsx # Main App shell and global event listeners
│ │ └── main.jsx # App root entry point
│ ├── vercel.json # Vercel SPA routing & API rewrites configuration
│ └── vite.config.js # Vite build and development configuration
git clone https://github.com/Sam721166/timmo.git
cd timmo- Navigate to the
backendfolder:cd backend npm install - Create a
.envfile in thebackenddirectory:MONGO_URI="mongodb://localhost:27017/timmo" JWT_SECRET="yourSecret123" PORT=3000
- Start the backend server in development mode:
npm run dev
- Navigate to the
frontendfolder:cd ../frontend npm install - Create a
.envfile in thefrontenddirectory:BACKEND_URL="http://localhost:3000"
- Start the Vite development server:
npm run dev
Open http://localhost:5173 in your browser.
- Hosted on a persistent server (e.g., Render Web Service).
- Set up environment variables:
MONGO_URI(pointing to a MongoDB Atlas cluster) andJWT_SECRET. - Configure CORS in
backend/app.jsto allow requests originating from your frontend Vercel domain.
- Hosted on Vercel with the Root Directory set to
frontend. - Vercel automatically detects the Vite preset and builds the application output into the
distdirectory. - Uses a reverse proxy in
vercel.jsonto route/api/*requests directly to the backend Render app, bypassing CORS restrictions:
{
"outputDirectory": "dist",
"rewrites": [
{
"source": "/api/:path*",
"destination": "https://your-backend-app.onrender.com/api/:path*"
},
{
"source": "/((?!api/).*)",
"destination": "/index.html"
}
]
}