A full-stack timesheet application for tracking work hours across projects with validation and persistence.
- Frontend: React 19 + TypeScript + Vite
- Backend: Express.js + Node.js
- Database: SQLite3 with Prisma ORM
- Styling: CSS with responsive design
viso-task/
├── src/ # Frontend (React)
│ ├── App.tsx # Main React component
│ └── main.tsx # React entry point
├── backend/ # Backend (Express)
│ ├── server.js # Express server
│ ├── package.json # Backend dependencies
│ └── prisma/
│ ├── schema.prisma # Database schema
│ └── migrations/ # Database migrations
├── index.html # HTML entry point
├── index.css # Global styles
├── package.json # Frontend dependencies
├── vite.config.ts # Vite configuration
└── .gitignore # Git ignore rules
✅ Time Entry Management
- Add time entries with date, project, hours, and description
- Delete existing entries
- View all entries organized by date
✅ Validation
- Maximum 24 hours per calendar day
- All fields required (date, project, hours, description)
- Hours must be positive numbers
- Real-time error feedback
✅ Entry History
- Entries grouped by date (newest first)
- Daily total hours per date
- Grand total hours across all entries
✅ Data Persistence
- SQLite database for reliable data storage
- Prisma ORM for type-safe queries
- Automatic schema management with migrations
- Node.js v20.11.0 or higher
- npm (comes with Node.js)
# Navigate to project root
cd viso-task
# Install frontend dependencies
npm install
# Install backend dependencies
cd backend
npm install
cd ..# Navigate to backend directory
cd backend
# Run Prisma migrations (creates SQLite database)
npx prisma migrate dev --name init
cd ..This will:
- Create
backend/timesheet.db(SQLite database file) - Set up the
entriestable with the correct schema - Generate Prisma Client
Terminal 1 - Start Frontend:
npm run dev
# Frontend runs on http://localhost:5175Terminal 2 - Start Backend:
cd backend
node server.js
# Backend runs on http://localhost:3001The app will be available at http://localhost:5175
- Select a date
- Choose a project from the dropdown
- Enter hours worked (0-24, must be positive)
- Add description of work
- Click "Add"
- Entries are automatically grouped by date
- Each date shows:
- Date header
- Daily total hours
- Individual entries with project, hours, and description
- Grand total shown at the top
- Click the "Delete" button next to any entry
- 24-hour limit: Backend prevents adding hours that exceed 24h per day
- Required fields: All fields (date, project, hours, description) are mandatory
- Positive hours: Hours must be greater than 0
- Error messages display if validation fails
All endpoints are prefixed with /api
Returns all time entries sorted by date (newest first)
Response:
[
{
"id": 1,
"date": "2024-01-15",
"project": "Viso Internal",
"hours": 8,
"description": "Feature development",
"createdAt": "2024-01-15T10:30:00Z"
}
]Creates a new time entry
Request body:
{
"date": "2024-01-15",
"project": "Viso Internal",
"hours": 8,
"description": "Feature development"
}Validation errors:
- Missing fields: "All fields are required"
- Invalid hours: "Hours must be a positive number"
- Exceeds 24h: "Cannot add Xh. Maximum 24 hours per day..."
Deletes a time entry by ID
Response:
{
"deleted": 1
}Entry Model
model Entry {
id Int @id @default(autoincrement())
date String // Format: YYYY-MM-DD
project String
hours Float // 0.5 to 24
description String
createdAt DateTime @default(now())
}npm run dev # Start development server
npm run build # Build for production
npm run preview # Preview production buildcd backend
node server.js # Start server
npx prisma studio # Open Prisma Studio (GUI)
npx prisma db push # Sync schema with database
npx prisma generate # Regenerate Prisma ClientNo environment variables required! The app uses:
- Frontend:
http://localhost:5175(Vite default) - Backend:
http://localhost:3001(configured in server.js) - Database:
backend/timesheet.db(local SQLite file)
For production, you may want to add .env files for configuration.
# Reset database (WARNING: deletes all data)
cd backend
rm timesheet.db
npx prisma migrate dev --name init- Frontend: Change port in
vite.config.ts - Backend: Change PORT variable in
backend/server.js
cd backend
npx prisma generate- Verify backend is running on
http://localhost:3001 - Check CORS is enabled in
backend/server.js - Verify API_URL in
src/App.tsxmatches backend port
- SQLite is suitable for small to medium projects (< 100k entries)
- For larger datasets, consider migrating to PostgreSQL:
- Change
datasourceinprisma/schema.prisma - Update backend database connection
- Run
npx prisma migrate deploy
- Change
MIT
Created: January 15, 2026