Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Deploy to GitHub Pages

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Prepare Pages artifact
run: |
mkdir _site
cp index.html styles.css worktime.js app.js .nojekyll _site/
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: _site
- id: deployment
uses: actions/deploy-pages@v4
15 changes: 15 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Test

on:
push:
pull_request:

jobs:
worktime:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: node --test worktime.test.js
39 changes: 9 additions & 30 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,39 +1,18 @@
# Visual Studio
# Visual Studio / editors
.vs/
.vscode/

# Archivos de compilación
bin/
obj/

# Configuración de usuario
*.userprefs
*.user
*.suo
*.user
*.userprefs

# Dependencias restaurables
packages/
.nuget/

# Archivos de caché y logs
# Logs and swap
*.log
*.swp
*.swo

# MAUI-specific ignores
Platforms/**/bin/
Platforms/**/obj/
Resources/Raw/**/*.db
Resources/Raw/**/*.sqlite

# Archivos específicos de macOS/iOS
xcuserdata/
Pods/
DerivedData/
*.xcworkspace
*.xcuserstate
# OS
.DS_Store
Thumbs.db

# Archivos específicos de Android
*.apk
*.aab
*.keystore
# Local Pages artifact
_site/
Empty file added .nojekyll
Empty file.
97 changes: 34 additions & 63 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,89 +1,60 @@
# Agent Guide — Worktime Calculator
# Agent Guide — Horas laborales

This document helps AI coding agents work effectively in this repository.

## Repository Overview

**Worktime Calculator** is a small .NET MAUI application (.NET 9) for analyzing working hours over a date range. It is not a backend service or multi-module monorepo—the entire app lives under `WorktimeCalculator/`.
This repository is a **static GitHub Pages site**. There is no .NET / MAUI app, no backend, and no bundler.

| Path | Purpose |
|------|---------|
| `WorktimeCalculator/Utilities/WorktimeCalculator.cs` | Working-day count, expected hours, daily average |
| `WorktimeCalculator/ViewModels/WorktimeCalculatorVM.cs` | Main view model; parse input and bind results |
| `WorktimeCalculator/Views/WorktimeCalculatorPage.xaml` | Primary (and only) user screen |
| `WorktimeCalculator/Converters/BoolToColorConverter.cs` | Red text when hours difference is negative |
| `WorktimeCalculator/MauiProgram.cs` | App bootstrap; minimal configuration |
| `index.html` | Single page UI (Spanish) |
| `styles.css` | Page styles |
| `worktime.js` | Working-day count, expected hours, parse/format `h:mm` |
| `app.js` | Form defaults and live recalculation |
| `worktime.test.js` | Node tests for `worktime.js` |
| `.github/workflows/pages.yml` | Deploy to GitHub Pages from `main` |
| `.github/workflows/test.yml` | Run `node --test worktime.test.js` |

## Conventions

- **Language**: C# with `ImplicitUsings` and `Nullable` enabled.
- **MVVM**: View models use `CommunityToolkit.Mvvm` (`ObservableObject`, `SetProperty`, `ICommand` via `Command`).
- **Namespaces**: Match folder structure (e.g. `WorktimeCalculator.ViewModels`).
- **Time format**: User input and display use `h:mm` strings (hours and minutes separated by `:`).
- **Working day rules**: Monday–Friday minus dates in the static `holydays` list in `WorktimeCalculator.cs` (note: the field name is `holydays`, not `holidays`).
- **Expected hours**: Fixed at **8 hours per working day**; change `CalculateExpectedWorkinghours` if this should be configurable.

## Build Commands

From the repo root:

```bash
dotnet restore WorktimeCalculator.sln
dotnet build WorktimeCalculator.sln
```
- Vanilla HTML/CSS/JS. Classic `<script>` tags (not ES modules) so `file://` and Pages both work.
- Time format: `h:mm` (minutes always two digits).
- Working days: Monday–Friday minus ISO dates in `HOLIDAYS` (`worktime.js`). Compare `YYYY-MM-DD` strings; iterate in UTC.
- Expected hours: **8 per working day** (`HOURS_PER_DAY`).
- UI language: Spanish. README and this file: English.
- Commit messages: English.

Target a single platform when validating:
## Commands

```bash
dotnet build WorktimeCalculator/WorktimeCalculator.csproj -f net9.0-windows10.0.19041.0
node --test worktime.test.js
python3 -m http.server 8080
```

There is no dedicated test project. If you add tests, prefer a `WorktimeCalculator.Tests` project targeting `Utilities/WorktimeCalculator.cs` logic.
GitHub Pages URL: `https://cesarordazv.github.io/WorktimeCalculator/`

## Common Tasks
## Common tasks

### Add or update public holidays
### Add or update holidays

Edit the `holydays` list in `WorktimeCalculator/Utilities/WorktimeCalculator.cs`. Use `DateTime` with year, month, day. Holidays are matched by full date (year included).
Edit the `HOLIDAYS` array in `worktime.js`. Use `YYYY-MM-DD`. Holidays are year-specific; add a new year explicitly.

### Change expected hours per day
### Change hours per day

Modify `CalculateExpectedWorkinghours` in `WorktimeCalculator.cs` (currently `8 * countWorkingDays`).
Edit `HOURS_PER_DAY` in `worktime.js`.

### New UI fields

1. Add properties to `WorktimeCalculatorVM`.
2. Update calculation in `CalculateDailyWorkingHours` (or a new command).
3. Bind controls in `WorktimeCalculatorPage.xaml`.

### Platform-specific changes

Use `WorktimeCalculator/Platforms/<platform>/` only when necessary. Most features should stay in shared MAUI code.
1. Add logic in `worktime.js` (`calculate` / helpers) with no DOM.
2. Cover it in `worktime.test.js`.
3. Bind in `index.html` + `app.js`.

## Pitfalls

- **Empty working-day range**: If every day in the range is a weekend or holiday, `CountWorkingDays` returns 0 and `CalculateDailyWorkingHours` will divide by zero.
- **Input parsing**: `Workinghours` is parsed manually in the view model; invalid `h:mm` input silently falls back to `0:00`.
- **Holiday scope**: Only dates in the hardcoded list are excluded; there is no locale or year auto-detection.
- **XAML**: `WorktimeCalculatorPage.xaml` uses `x:DataType` for compiled bindings; keep bindings aligned with `WorktimeCalculatorVM` properties.

## Dependencies

- `Microsoft.Maui.Controls` (via SDK MAUI version)
- `CommunityToolkit.Mvvm` 8.4.0
- `Microsoft.Extensions.Logging.Debug` 9.0.0

Do not add packages without a clear need; the app intentionally stays minimal.

## Pull Requests

- Keep changes focused; this is a small app.
- Update `README.md` if user-facing behavior or setup steps change.
- Update this file if project structure, conventions, or agent workflows change.
- English for user-facing docs and commit messages.
- Zero working days: do not divide; show `—` for the daily average.
- Invalid `h:mm` and start-after-end must show an error, not silent zeros.
- Relative asset paths only (`styles.css`, not `/styles.css`) so the project Pages URL works.
- Do not reintroduce a MAUI/XAML app unless explicitly requested.

## Out of Scope (unless explicitly requested)
## Out of scope (unless explicitly requested)

- Cloud sync, persistence, or user accounts
- Localization beyond the current English UI strings
- Dynamic holiday APIs (current design is a static list)
- Dynamic holiday APIs
- Build tools or npm dependencies
119 changes: 49 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,92 +1,71 @@
# Worktime Calculator
# Horas laborales

A cross-platform .NET MAUI app that helps you track and analyze working hours over a date range. Enter your total hours worked between two dates and the app calculates expected hours, the difference, and your daily average—excluding weekends and configured public holidays.
Static site that answers **how many hours you should have logged** between two dates: 8 hours per working day (Monday–Friday, minus the holiday list).

## Features
There is no backend, build, or package manager. GitHub Pages serves the files as-is.

- **Date range selection** — Pick a start and end date for the period you want to analyze.
- **Total working hours input** — Enter hours in `h:mm` format (e.g. `160:30`).
- **Expected working hours** — Computes 8 hours per working day in the range.
- **Hours difference** — Shows how many hours you are ahead or behind expectations; negative values are highlighted in red.
- **Daily average** — Divides total hours by the number of working days in the range.
- **Weekend and holiday exclusion** — Saturdays, Sundays, and a built-in list of public holidays are not counted as working days.
Live site (after Pages is enabled on `main`):

## Tech Stack
https://cesarordazv.github.io/WorktimeCalculator/

| Layer | Technology |
|-------|------------|
| Framework | .NET 9 |
| UI | .NET MAUI |
| MVVM | CommunityToolkit.Mvvm |
| Platforms | Android, iOS, macOS (Mac Catalyst), Windows |
## Local use

## Project Structure

```
WorktimeCalculator/
├── Converters/ # XAML value converters (e.g. color for positive/negative)
├── Platforms/ # Platform-specific entry points and manifests
├── Resources/ # Icons, fonts, splash screen, styles
├── Utilities/ # Core calculation logic and helpers
├── ViewModels/ # MVVM view models
└── Views/ # XAML pages
```

Core business logic lives in `Utilities/WorktimeCalculator.cs`. The main UI is `Views/WorktimeCalculatorPage.xaml` bound to `ViewModels/WorktimeCalculatorVM.cs`.

## Prerequisites

- [.NET 9 SDK](https://dotnet.microsoft.com/download)
- MAUI workload: `dotnet workload install maui`
- For mobile targets, the corresponding SDKs (Android SDK, Xcode for iOS/macOS, etc.)

## Build and Run

Restore and build from the repository root:
Open `index.html` in a browser, or:

```bash
dotnet restore WorktimeCalculator.sln
dotnet build WorktimeCalculator.sln
python3 -m http.server 8080
```

Run on a specific platform (examples):
Then visit `http://localhost:8080`.

```bash
# Windows
dotnet build -t:Run -f net9.0-windows10.0.19041.0 WorktimeCalculator/WorktimeCalculator.csproj

# Android (device or emulator required)
dotnet build -t:Run -f net9.0-android WorktimeCalculator/WorktimeCalculator.csproj

# macOS
dotnet build -t:Run -f net9.0-maccatalyst WorktimeCalculator/WorktimeCalculator.csproj
```
## GitHub Pages

You can also open `WorktimeCalculator.sln` in Visual Studio 2022 and run from the IDE.
1. Merge this to `main`.
2. Repo → **Settings** → **Pages**.
3. **Source**: GitHub Actions (see `.github/workflows/pages.yml`).
4. Wait for the **Deploy to GitHub Pages** workflow.

## Usage
Alternative: **Deploy from a branch** → `main` → `/` (root). Asset paths are relative, so the project site under `/WorktimeCalculator/` works.

1. Set **Start Date** and **End Date** for your reporting period.
2. Enter your **Working hours** total in `h:mm` format.
3. Tap **Calculate**.
## Rules

The app displays:
- Date range is **inclusive**.
- A working day is Monday–Friday and **not** in `HOLIDAYS` (`worktime.js`).
- Expected hours = `8 × working days` (the main result).
- Difference = hours worked − expected (minus sign and red when behind).
- Daily average = worked ÷ working days (`—` if there are no working days).
- Time format: `h:mm` with two-digit minutes.

| Field | Description |
|-------|-------------|
| Expected Workinghours | 8 hours × number of working days in the range |
| Workinghours difference | Your total minus expected; red when behind |
| Daily Workinghours | Average hours per working day |
Holidays (2025, carried over from the former MAUI app):

## Holidays
```
2025-01-01
2025-02-03
2025-03-17
2025-04-17
2025-04-18
2025-05-01
2025-09-16
2025-11-18
2025-12-25
```

Public holidays are defined in `Utilities/WorktimeCalculator.cs` as a static list. The current list covers **2025** (Mexican federal holidays). To support other years or regions, extend or replace that list.
Add more ISO dates (`YYYY-MM-DD`) to `HOLIDAYS` in `worktime.js`. Change hours per day with `HOURS_PER_DAY` in the same file.

Working days exclude:
## Files

- Saturday and Sunday
- Dates in the holidays list
| File | Role |
|------|------|
| `index.html` | Page |
| `styles.css` | Layout |
| `worktime.js` | Calculation (no DOM) |
| `app.js` | Form |
| `.nojekyll` | Skip Jekyll on Pages |
| `.github/workflows/pages.yml` | Publish |
| `.github/workflows/test.yml` | `node --test worktime.test.js` |

## License
## Tests

No license file is present in this repository. Contact the repository owner for usage terms.
```bash
node --test worktime.test.js
```
Loading
Loading