Index: AGENTS.md
===================================================================
--- AGENTS.md	(revision 447c39f7111f1415e8f44660911d00bb61568780)
+++ AGENTS.md	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -0,0 +1,79 @@
+# AGENTS.md — Agent onboarding for Trekr
+
+Checklist for an AI coding agent when working in this repo
+- [ ] Understand architecture: `frontend` (Vite + React) talking to `backend` (Spring Boot REST API).
+- [ ] Know how to run & iterate locally (frontend dev server + backend JVM with env vars/.env).
+- [ ] Token & auth contract: JWT format, Authorization: Bearer header, token stored by frontend at `localStorage:authToken`.
+- [ ] Data & DB locations: `db-scripts/` (migrations, triggers, views) and JPA entities under `backend/src/main/java/com/trekr/backend/entity`.
+
+Quick summary (one-liner)
+Trekr is a split repo: a Vite React frontend (calls `/api/*`) and a Spring Boot backend (Java 17, Spring Data JPA, Spring Security with JWT). Backend loads a `.env`/`env` file before boot and expects DB and JWT secrets via environment properties.
+
+Essential files & places to read first
+- `backend/src/main/java/com/trekr/backend/BackendApplication.java` — .env loader behavior and how system properties are set.
+- `backend/src/main/resources/application.properties` — key runtime properties (datasource, `jwt.secret`, JPA settings).
+- `backend/src/main/java/com/trekr/backend/config/SecurityConfig.java` — top-level security rules and CORS dev origins (`http://localhost:5173`).
+- `backend/src/main/java/com/trekr/backend/service/JwtService.java` — exact JWT payload (subject = userId, claims: `username`, `email`) and token validity.
+- `backend/src/main/java/com/trekr/backend/security/JwtAuthenticationFilter.java` — how the backend extracts and validates the Bearer token.
+- `backend/src/main/java/com/trekr/backend/config/LegacyPasswordEncoder.java` — password rules: supports BCrypt (new) and plaintext (legacy seeds).
+- `backend/src/main/java/com/trekr/backend/controller/*` and `.../service/*` — canonical pattern: controllers are thin HTTP layers delegating to services; DTOs under `dto/`.
+- `frontend/src/api/axios.js` and `frontend/src/utils/authSession.js` — axios interceptors, where tokens are read/written, dev API base (`import.meta.env.VITE_API_BASE_URL`).
+- `db-scripts/` — migrations (`migrations/`), triggers and views—use these as source of truth for DB shape/constraints.
+
+Run / build / dev commands
+- Backend (preferred for local dev):
+  - Start with a .env or `env` file in repo root or `backend/` (see `BackendApplication` search order). Example env keys used: `SPRING_DATASOURCE_URL`, `SPRING_DATASOURCE_USERNAME`, `SPRING_DATASOURCE_PASSWORD`, `JWT_SECRET`.
+  - Dev run (from repo root):
+
+    cd backend && ./mvnw spring-boot:run
+
+  - Package and run jar:
+
+    cd backend && ./mvnw package
+    java -jar target/backend-0.0.1-SNAPSHOT.jar
+
+  - Run tests / compile:
+
+    cd backend && ./mvnw test
+
+- Frontend (Vite + npm):
+
+  cd frontend && npm install
+  npm run dev           # runs at :5173 by default (frontend dev)
+  npm run build         # production bundle
+
+Key runtime contracts & examples
+- API prefix: frontend uses `VITE_API_BASE_URL` default `http://localhost:8080/api` and axios attaches `Authorization: Bearer <token>` header (see `frontend/src/api/axios.js`).
+- Login flow: POST `/api/auth/login` returns `AuthResponse` (see `backend/src/main/java/com/trekr/backend/dto/auth/AuthResponse.java` and `AuthController`).
+- JWT payload (verify when issuing tokens): subject = userId, claims `username` and `email` (see `JwtService.generateToken`).
+- Token storage: frontend keys: `authToken` and `authUser` in localStorage (see `authSession.js`).
+
+Project-specific conventions & notable patterns
+- Layering: `controller` -> `service` -> `repository` (Spring Data JPA). DTOs are collected in `dto/<domain>` and entities are in `entity/<domain>`.
+- Legacy seed convenience: `LegacyPasswordEncoder` accepts plain-text seeded passwords (non-bcrypt). When changing auth/seed data be careful to preserve compatibility.
+- .env handling: Backend intentionally loads `.env` or `env` from several locations before Spring starts and sets values as system properties (so Spring `${...}` placeholders resolve). Put development env variables in repo root `.env` or `backend/.env`.
+- Database: the repo contains SQL migrations and helpers in `db-scripts/` (migrations, triggers, views). Treat these as authoritative when changing JPA mappings and ensure migrations remain in sync.
+- CORS: dev origins are explicitly whitelisted in `SecurityConfig` for the Vite dev server. If adding a different frontend origin add it there.
+
+Integration & dependency notes
+- JDBC: production target is PostgreSQL (dependency present in `pom.xml`), but tests use H2 (test scope). The default `application.properties` disables automatic DDL by default — change `SPRING_JPA_HIBERNATE_DDL_AUTO` if you need schema auto-update.
+- JWT implementation uses `io.jsonwebtoken` (jjwt); signing key comes from `jwt.secret` (env `JWT_SECRET` or `JWT_CONFIG_SECRET`). The code pads a dev fallback to 32+ chars if secret is missing.
+- Dotenv: the backend sets system properties using `io.github.cdimascio.dotenv.Dotenv` before Spring starts — do not rely on Spring's property loading only for dev overrides that the app expects early.
+
+Debugging tips for agents
+- If a token-authenticated endpoint returns 401 in dev, check:
+  1) the frontend `authToken` is present and not expired (`authSession.isTokenExpired`).
+  2) backend logs (Spring Security DEBUG is enabled in `application.properties`).
+  3) CORS origins if calling from the browser dev server.
+- To reproduce DB-related bugs locally, prefer running Postgres (set `SPRING_DATASOURCE_URL`) or temporarily set `SPRING_JPA_HIBERNATE_DDL_AUTO=update` for quick iteration (but be cautious with managed DBs).
+
+Where to look for more context
+- `backend/HELP.md` — general pointers and links to Spring docs.
+- `db-scripts/` — migration and trigger logic (useful for understanding computed columns and constraints).
+- `frontend/src/pages/*` and `frontend/src/api/*` — real call sites showing which backend endpoints are used.
+
+If you need to make changes
+- Prefer small edits in the pattern used: update DTOs + services + controllers; update SQL migrations when the schema changes; update `frontend/src/api/axios.js` and `VITE_API_BASE_URL` if changing API paths.
+
+Done: create this file at repo root as `AGENTS.md` to guide future agents.
+
Index: backend/src/main/java/com/trekr/backend/dto/discipline/UpdateTaskStatusRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/UpdateTaskStatusRequest.java	(revision 447c39f7111f1415e8f44660911d00bb61568780)
+++ backend/src/main/java/com/trekr/backend/dto/discipline/UpdateTaskStatusRequest.java	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -0,0 +1,19 @@
+package com.trekr.backend.dto.discipline;
+
+import com.trekr.backend.entity.discipline.TaskStatus;
+
+public class UpdateTaskStatusRequest {
+    private TaskStatus status;
+
+    public UpdateTaskStatusRequest() {
+    }
+
+    public TaskStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(TaskStatus status) {
+        this.status = status;
+    }
+}
+
Index: backend/src/main/java/com/trekr/backend/dto/training/CreateTrainingSessionRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/training/CreateTrainingSessionRequest.java	(revision 42da64dc0d28f9380336816f6fb82c7572d0021d)
+++ backend/src/main/java/com/trekr/backend/dto/training/CreateTrainingSessionRequest.java	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -4,6 +4,8 @@
 import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.PastOrPresent;
 
 import java.math.BigDecimal;
+import java.time.LocalDate;
 
 public class CreateTrainingSessionRequest {
@@ -21,4 +23,7 @@
     @DecimalMin(value = "0", inclusive = true)
     private BigDecimal calories;
+
+    @PastOrPresent
+    private LocalDate date;
 
     public CreateTrainingSessionRequest() {
@@ -56,3 +61,11 @@
         this.calories = calories;
     }
+
+    public LocalDate getDate() {
+        return date;
+    }
+
+    public void setDate(LocalDate date) {
+        this.date = date;
+    }
 }
Index: backend/src/main/java/com/trekr/backend/entity/discipline/TaskStatus.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/discipline/TaskStatus.java	(revision 447c39f7111f1415e8f44660911d00bb61568780)
+++ backend/src/main/java/com/trekr/backend/entity/discipline/TaskStatus.java	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -0,0 +1,8 @@
+package com.trekr.backend.entity.discipline;
+
+public enum TaskStatus {
+    NOT_STARTED,
+    IN_PROGRESS,
+    FINISHED
+}
+
Index: backend/src/main/java/com/trekr/backend/service/TrainingService.java
===================================================================
--- backend/src/main/java/com/trekr/backend/service/TrainingService.java	(revision 42da64dc0d28f9380336816f6fb82c7572d0021d)
+++ backend/src/main/java/com/trekr/backend/service/TrainingService.java	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -177,5 +177,13 @@
         session.setDuration(durationMinutes);
         session.setCalories(calories);
-        session.setDate(LocalDate.now());
+        // Allow client to supply a date (past or present). If not provided, use today.
+        java.time.LocalDate suppliedDate = request.getDate();
+        if (suppliedDate == null) {
+            suppliedDate = LocalDate.now();
+        }
+        if (suppliedDate.isAfter(LocalDate.now())) {
+            throw new RuntimeException("Date cannot be in the future");
+        }
+        session.setDate(suppliedDate);
 
         TrainingSession saved = trainingSessionRepository.save(session);
Index: db-scripts/migrations/V001__expand_tasks_table.sql
===================================================================
--- db-scripts/migrations/V001__expand_tasks_table.sql	(revision 447c39f7111f1415e8f44660911d00bb61568780)
+++ db-scripts/migrations/V001__expand_tasks_table.sql	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -0,0 +1,44 @@
+-- Flyway Migration: Expand TASKS table with description, due_date, priority, and status enum
+-- This migration adds new columns to support custom tracking tasks with enhanced details.
+-- Daily discipline tasks will use NULL for these optional fields.
+
+SET search_path TO trekr;
+
+-- Create ENUM type for task status
+CREATE TYPE task_status AS ENUM ('NOT_STARTED', 'IN_PROGRESS', 'FINISHED');
+
+-- Add new columns to TASKS table
+ALTER TABLE trekr.tasks
+ADD COLUMN description TEXT,
+ADD COLUMN due_date DATE,
+ADD COLUMN priority VARCHAR(10) DEFAULT 'MEDIUM' CHECK (priority IN ('LOW', 'MEDIUM', 'HIGH')),
+ADD COLUMN status task_status DEFAULT 'NOT_STARTED';
+
+-- For backwards compatibility, migrate is_finished to status
+-- is_finished = true → status = FINISHED
+-- is_finished = false → status = NOT_STARTED
+UPDATE trekr.tasks
+SET status = CASE
+    WHEN is_finished = true THEN 'FINISHED'::task_status
+    ELSE 'NOT_STARTED'::task_status
+END;
+
+-- Drop the is_finished column (after migration)
+ALTER TABLE trekr.tasks
+DROP COLUMN is_finished;
+
+-- Add index for filtering tasks by status and custom_tracking_id
+CREATE INDEX idx_tasks_custom_tracking_status
+ON trekr.tasks(custom_tracking_id, status)
+WHERE custom_tracking_id IS NOT NULL;
+
+-- Add index for filtering by discipline_user_id and status (for daily completion computation)
+CREATE INDEX idx_tasks_discipline_status
+ON trekr.tasks(discipline_user_id, status)
+WHERE discipline_user_id IS NOT NULL;
+
+-- Add index for due_date filtering (useful for reports)
+CREATE INDEX idx_tasks_due_date
+ON trekr.tasks(due_date)
+WHERE due_date IS NOT NULL;
+
Index: db-scripts/tunnel_scripta.sh
===================================================================
--- db-scripts/tunnel_scripta.sh	(revision 42da64dc0d28f9380336816f6fb82c7572d0021d)
+++ db-scripts/tunnel_scripta.sh	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -5,7 +5,7 @@
 echo "AKO SAKATE DA SLUSHA NA DRUGA PORTA, SMENETE JA SKRIPTATA SOODVETNO"
 echo "AKO SAKATE DA STOPIRATE (CTRL+C)"
-read -p "Press any key to continue ..."
 
-ssh -v -2 -C -N -L 9999:localhost:5432 t_trekr@194.149.135.130
+
+sshpass -p '459499b8' ssh -v -2 -C -N -L 9999:localhost:5432 t_trekr@194.149.135.130
 
 echo "VRSKATA TREBA DA STOI OTVORENA SE DODEKA IMATE PRISTAP DO SERVEROT"
@@ -13,3 +13,2 @@
 echo "AKO TOA SE SLUCHILO SAMO OD SEBE, IMATE PROBLEM SO VOSPOSTAVUVANJE"
 echo "NA VRSKATA DO SERVEROT (BLOKADA) ILI VI SE POGRESHNI PARAMETRITE"
-read -p "Press any key to continue ..."
Index: frontend/index.html
===================================================================
--- frontend/index.html	(revision 42da64dc0d28f9380336816f6fb82c7572d0021d)
+++ frontend/index.html	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -3,7 +3,7 @@
   <head>
     <meta charset="UTF-8" />
-    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.png" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>frontend</title>
+    <title>Trekr</title>
   </head>
   <body>
Index: frontend/src/pages/Dashboard/pages/CustomCategory/components/TaskFormModal.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/CustomCategory/components/TaskFormModal.jsx	(revision 447c39f7111f1415e8f44660911d00bb61568780)
+++ frontend/src/pages/Dashboard/pages/CustomCategory/components/TaskFormModal.jsx	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -0,0 +1,244 @@
+import React, { useEffect, useState } from "react";
+import { MdClose } from "react-icons/md";
+
+export default function TaskFormModal({
+  isOpen,
+  onClose,
+  onSubmit,
+  task = null,
+  isLoading = false,
+}) {
+  const isEditing = !!task;
+  const [formData, setFormData] = useState({
+    name: "",
+    description: "",
+    dueDate: "",
+    priority: "MEDIUM",
+    status: "NOT_STARTED",
+  });
+  const [errors, setErrors] = useState({});
+
+  // Initialize form with task data when editing
+  useEffect(() => {
+    if (task) {
+      setFormData({
+        name: task.name || "",
+        description: task.description || "",
+        dueDate: task.dueDate || "",
+        priority: task.priority || "MEDIUM",
+        status: task.status || "NOT_STARTED",
+      });
+    } else {
+      setFormData({
+        name: "",
+        description: "",
+        dueDate: "",
+        priority: "MEDIUM",
+        status: "NOT_STARTED",
+      });
+    }
+    setErrors({});
+  }, [task, isOpen]);
+
+  const handleChange = (e) => {
+    const { name, value } = e.target;
+    setFormData((prev) => ({ ...prev, [name]: value }));
+    // Clear error for this field
+    if (errors[name]) {
+      setErrors((prev) => ({ ...prev, [name]: null }));
+    }
+  };
+
+  const validate = () => {
+    const newErrors = {};
+    if (!formData.name.trim()) {
+      newErrors.name = "Task name is required";
+    }
+    if (formData.name.length > 200) {
+      newErrors.name = "Task name must be 200 characters or less";
+    }
+    if (formData.dueDate && new Date(formData.dueDate) < new Date()) {
+      const today = new Date().toISOString().split('T')[0];
+      if (formData.dueDate < today) {
+        newErrors.dueDate = "Due date cannot be in the past";
+      }
+    }
+    return newErrors;
+  };
+
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+    const newErrors = validate();
+    if (Object.keys(newErrors).length > 0) {
+      setErrors(newErrors);
+      return;
+    }
+
+    const payload = {
+      name: formData.name.trim(),
+      description: formData.description.trim() || null,
+      dueDate: formData.dueDate || null,
+      priority: formData.priority,
+    };
+
+    // Only include status if editing
+    if (isEditing) {
+      payload.status = formData.status;
+    }
+
+    try {
+      await onSubmit(payload);
+      onClose();
+    } catch (error) {
+      console.error("Form submission error:", error);
+    }
+  };
+
+  if (!isOpen) return null;
+
+  return (
+    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4">
+      <div className="w-full max-w-md rounded-lg border border-white/10 bg-neutral-900 p-6 shadow-xl">
+        {/* Header */}
+        <div className="mb-4 flex items-center justify-between">
+          <h2 className="text-lg font-bold text-white">
+            {isEditing ? "Edit Task" : "Create New Task"}
+          </h2>
+          <button
+            onClick={onClose}
+            className="rounded-md p-1 text-white/60 hover:bg-white/10 hover:text-white"
+            title="Close"
+          >
+            <MdClose className="size-5" />
+          </button>
+        </div>
+
+        {/* Form */}
+        <form onSubmit={handleSubmit} className="space-y-4">
+          {/* Name */}
+          <div>
+            <label className="block text-sm font-medium text-white/80 mb-1">
+              Task Name <span className="text-red-400">*</span>
+            </label>
+            <input
+              type="text"
+              name="name"
+              value={formData.name}
+              onChange={handleChange}
+              placeholder="Enter task name"
+              maxLength={200}
+              className={`w-full rounded-lg border bg-black/40 px-3 py-2 text-sm text-white outline-none transition ${
+                errors.name
+                  ? "border-red-500/50 focus:border-red-400"
+                  : "border-white/10 focus:border-green-400"
+              }`}
+              disabled={isLoading}
+            />
+            {errors.name && (
+              <p className="mt-1 text-xs text-red-400">{errors.name}</p>
+            )}
+            <p className="mt-1 text-xs text-white/40">
+              {formData.name.length}/200
+            </p>
+          </div>
+
+          {/* Description */}
+          <div>
+            <label className="block text-sm font-medium text-white/80 mb-1">
+              Description
+            </label>
+            <textarea
+              name="description"
+              value={formData.description}
+              onChange={handleChange}
+              placeholder="Enter task description (optional)"
+              rows={3}
+              className="w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2 text-sm text-white outline-none transition focus:border-green-400"
+              disabled={isLoading}
+            />
+          </div>
+
+          {/* Priority */}
+          <div>
+            <label className="block text-sm font-medium text-white/80 mb-1">
+              Priority
+            </label>
+            <select
+              name="priority"
+              value={formData.priority}
+              onChange={handleChange}
+              className="w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2 text-sm text-white outline-none transition focus:border-green-400"
+              disabled={isLoading}
+            >
+              <option value="LOW">Low</option>
+              <option value="MEDIUM">Medium</option>
+              <option value="HIGH">High</option>
+            </select>
+          </div>
+
+          {/* Due Date */}
+          <div>
+            <label className="block text-sm font-medium text-white/80 mb-1">
+              Due Date
+            </label>
+            <input
+              type="date"
+              name="dueDate"
+              value={formData.dueDate}
+              onChange={handleChange}
+              className={`w-full rounded-lg border bg-black/40 px-3 py-2 text-sm text-white outline-none transition ${
+                errors.dueDate
+                  ? "border-red-500/50 focus:border-red-400"
+                  : "border-white/10 focus:border-green-400"
+              }`}
+              disabled={isLoading}
+            />
+            {errors.dueDate && (
+              <p className="mt-1 text-xs text-red-400">{errors.dueDate}</p>
+            )}
+          </div>
+
+          {/* Status (only for editing) */}
+          {isEditing && (
+            <div>
+              <label className="block text-sm font-medium text-white/80 mb-1">
+                Status
+              </label>
+              <select
+                name="status"
+                value={formData.status}
+                onChange={handleChange}
+                className="w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2 text-sm text-white outline-none transition focus:border-green-400"
+                disabled={isLoading}
+              >
+                <option value="NOT_STARTED">Not Started</option>
+                <option value="IN_PROGRESS">In Progress</option>
+                <option value="FINISHED">Finished</option>
+              </select>
+            </div>
+          )}
+
+          {/* Buttons */}
+          <div className="flex gap-3 pt-4">
+            <button
+              type="button"
+              onClick={onClose}
+              className="flex-1 rounded-lg border border-white/10 bg-transparent px-4 py-2 text-sm font-medium text-white transition hover:bg-white/5"
+              disabled={isLoading}
+            >
+              Cancel
+            </button>
+            <button
+              type="submit"
+              className="flex-1 rounded-lg bg-green-400 px-4 py-2 text-sm font-medium text-black transition hover:bg-green-300 disabled:opacity-50"
+              disabled={isLoading}
+            >
+              {isLoading ? "Saving..." : isEditing ? "Update Task" : "Create Task"}
+            </button>
+          </div>
+        </form>
+      </div>
+    </div>
+  );
+}
+
Index: frontend/src/pages/Dashboard/pages/Discipline/DisciplineTracking.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/DisciplineTracking.jsx	(revision 42da64dc0d28f9380336816f6fb82c7572d0021d)
+++ frontend/src/pages/Dashboard/pages/Discipline/DisciplineTracking.jsx	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -293,4 +293,5 @@
 
   const isTodayClosed = useMemo(() => {
+    console.log('todayIso:', todayIso);
     return (dailyCompletions ?? []).some((dc) => dc?.date === todayIso);
   }, [dailyCompletions, todayIso]);
Index: frontend/src/pages/Dashboard/pages/Finance/components/NewIncomeForm.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/components/NewIncomeForm.jsx	(revision 42da64dc0d28f9380336816f6fb82c7572d0021d)
+++ frontend/src/pages/Dashboard/pages/Finance/components/NewIncomeForm.jsx	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -4,4 +4,5 @@
   const [date, setDate] = useState(() => {
     const d = new Date();
+    console.log('Date:', d);
     return d.toISOString().slice(0, 10);
   });
Index: frontend/src/pages/Dashboard/pages/Training/NewTrainingSession.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/NewTrainingSession.jsx	(revision 42da64dc0d28f9380336816f6fb82c7572d0021d)
+++ frontend/src/pages/Dashboard/pages/Training/NewTrainingSession.jsx	(revision 447c39f7111f1415e8f44660911d00bb61568780)
@@ -18,4 +18,5 @@
   const [autoCalculateCalories, setAutoCalculateCalories] = useState(true);
   const [calories, setCalories] = useState("");
+  const [date, setDate] = useState(() => new Date().toISOString().slice(0, 10));
 
   const [error, setError] = useState("");
@@ -95,4 +96,11 @@
     }
 
+    // Date must not be in the future (allow past or today)
+    const todayStr = new Date().toISOString().slice(0, 10);
+    if (!date || date > todayStr) {
+      setError("Date cannot be in the future.");
+      return;
+    }
+
     const caloriesNum = calories === "" ? NaN : Number(calories);
     if (!autoCalculateCalories) {
@@ -108,4 +116,5 @@
         type,
         durationMinutes: durationNum,
+        date,
         autoCalculateCalories,
         calories: autoCalculateCalories ? null : caloriesNum,
@@ -145,5 +154,5 @@
           ) : null}
 
-          <div className="mt-4 grid grid-cols-1 gap-4 md:grid-cols-2">
+          <div className="mt-4 grid grid-cols-1 gap-4 md:grid-cols-3">
             <WorkoutTypeSelect
               workoutTypes={workoutTypes}
@@ -165,4 +174,18 @@
                 disabled={isLoading}
               />
+            </div>
+
+            <div>
+              <label className="label">Date</label>
+              <input
+                type="date"
+                className="input input-bordered w-full"
+                value={date}
+                onChange={(e) => setDate(e.target.value)}
+                max={new Date().toISOString().slice(0, 10)}
+                required
+                disabled={isLoading}
+              />
+              <p className="text-xs opacity-70 mt-1">Choose a past date or today (no future dates).</p>
             </div>
           </div>
