Interactive Demo

Work Hours Tracker

A full-stack Python/Flask web application for logging work hours across multiple clients — with automatic earnings calculation, schedule validation, weekly summaries, and data management.

Python Flask Pandas Excel (openpyxl) Jinja2 Templates REST API
Total Hours Logged
0
All time
Total Earnings
$0
Gross pay
This Week
$0
0 hrs this week
Entries Logged
0
Work sessions

Recent Entries

DateDayClientHoursEarnings
Select a client, then pick a date. The app validates that you only log hours on the client's scheduled working days — matching the Flask backend logic exactly.
Amanda
$20.00 / hr
Working days:
MonTueWedFri
Heidi
$24.00 / hr
Working days:
MonTueWedThuFri

Log Work Hours

Estimated Earnings
$0.00

Schedule Reference

ClientRateMonTueWedThuFri
Amanda $20/hr
Heidi $24/hr
#DateDayClientHoursEarningsAction
Week of
Loading...

This Week's Entries

DateDayClientHoursEarnings

Tech Stack

LayerTechnologyRole
BackendPython 3 / FlaskWeb server, routing, logic
DataPandasDataFrame manipulation
StorageExcel (openpyxl)Persistent data store
TemplatesJinja2Server-side HTML rendering
FrontendHTML / CSSResponsive UI
DeployRender / HerokuCloud hosting via PORT env

API Routes

MethodRouteAction
GET/Load all entries
POST/logSubmit new hours
POST/delete/<id>Remove an entry
GET/weekly_summaryAggregated week view

Core Business Logic — app.py

# Hourly rates per client HOURLY_RATES = { 'Amanda': 20, 'Heidi': 24 } # Valid working days per client WORK_SCHEDULE = { 'Amanda': ['Monday', 'Tuesday', 'Wednesday', 'Friday'], 'Heidi': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] } def log_hours(file_path, date, hours, client): date_obj = datetime.strptime(date, '%Y-%m-%d') day_of_week = date_obj.strftime('%A') # Validate: reject non-working days if day_of_week not in WORK_SCHEDULE[client]: raise ValueError(f"{client} doesn't work on {day_of_week}") earnings = hours * HOURLY_RATES[client] new_entry = pd.DataFrame({ "Date": [date], "Day": [day_of_week], "Hours Worked": [hours], "Client": [client], "Earnings": [earnings] }) df = pd.concat([df, new_entry], ignore_index=True) df.to_excel(file_path, index=False)
# Weekly summary — groupby + agg using Pandas work_hours['Date'] = pd.to_datetime(work_hours['Date']) start_of_week = today - timedelta(days=today.weekday()) weekly_data = work_hours[work_hours['Date'] >= start_of_week] summary = weekly_data.groupby('Client').agg({ 'Hours Worked': 'sum', 'Earnings': 'sum' }).reset_index()

Skills Demonstrated

Backend Dev
  • • Flask routing & REST API design
  • • Form handling (POST/redirect)
  • • Business rule validation
  • • Environment-based config
Data Handling
  • • Pandas DataFrames
  • • Excel read/write (openpyxl)
  • • GroupBy aggregation
  • • Date parsing & filtering
Architecture
  • • MVC-style Flask structure
  • • Jinja2 templating
  • • Cloud deployment (PORT env)
  • • File-based persistence