Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/PunctuOwlity/llms.txt

Use this file to discover all available pages before exploring further.

The Event model is the central data structure in both the web app and the Android app. In the web app it exists as a plain JavaScript object stored in localStorage; in the Android app it is a Java class whose instances are persisted in a SQLite database. Despite the different runtimes, both platforms share the same conceptual fields: a title, a date, a time, and display-ready derivatives of those values.

Web Event Object

Each event in the web app is a plain object that conforms to the following shape. All fields are written by normalizeEvent before being stored or rendered, so callers can rely on the formats described here.
id
string
required
Unique identifier for the event. For new events created in the browser, this is set to String(Date.now()). Seed events use human-readable named IDs such as "project", "birthday", "dentist", and "wedding".
day
string
required
Three-letter weekday abbreviation in uppercase, derived from fullDate via toLocaleDateString('en-US', { weekday: 'short' }).toUpperCase(). Examples: "SAT", "MON", "SUN". Falls back to "---" when the date cannot be parsed.
date
string
required
Zero-padded two-digit day-of-month number derived from fullDate. Examples: "05", "12", "14", "20". Falls back to "00" when the date cannot be parsed.
fullDate
string
required
ISO 8601 date string in YYYY-MM-DD format. This is the canonical date field used for sorting events and matching against today’s date for notifications. Example: "2025-04-12".
rawTime
string
required
24-hour time string in HH:MM format. Empty string ("") indicates an all-day event. Example: "18:30". This field is what the <input type="time"> element provides and what is stored in localStorage.
time
string
required
12-hour display-ready time string produced by normalizeEvent. Examples: "06:30PM", "01:30PM", "03:00PM". When rawTime is empty the value is "ALL DAY".
title
string
required
The human-readable event name entered by the user. Required — the add-event form will not submit without it.
category
string
required
Event category used for tab filtering on the events screen. One of "birthday", "appointment", "trip", "general", or "all". Auto-detected from the title by normalizeEvent when no explicit category is provided; see Category Auto-Detection below.
alert
boolean
required
Whether a browser notification reminder is enabled for this event. Set by the toggle switch on the add/edit form. When true and the notification permission is "granted", a Notification is fired on the event’s fullDate if it matches today’s date.

Android Event Class

The Android Event class (package com.example.punctuowlityeventtracker) is a simple value object with four private fields. It has two constructors — one for records loaded from the database (which already have an id) and one for new records about to be inserted.
MemberTypeNotes
idintAuto-increment primary key assigned by SQLite. Only present after a row is persisted.
titleStringEvent name. final after construction.
dateStringStored as MM/dd/yyyy. final after construction.
timeStringDisplay time string as entered by the user. final after construction.
Constructors
// Used when loading an existing event from the database
public Event(int id, String title, String date, String time)

// Used when creating a new event before insertion
public Event(String title, String date, String time)
Methods
getId()
int
Returns the SQLite row ID of the event.
getTitle()
String
Returns the event title.
getDate()
String
Returns the stored date string in MM/dd/yyyy format. Example: "04/12/2025".
getTime()
String
Returns the time string as stored — typically a 12-hour display value such as "06:30PM" or "ALL DAY".
getDayOfWeek()
String
Parses date using SimpleDateFormat("MM/dd/yyyy"), then formats the result with SimpleDateFormat("EEE") and calls .toUpperCase(). Returns values like "SAT" or "MON". Returns "---" on any parse failure.
getDateDay()
String
Parses date using SimpleDateFormat("MM/dd/yyyy"), then formats the result with SimpleDateFormat("dd") to extract the zero-padded day number. Returns values like "05" or "12". Returns "00" on any parse failure.

Date and Time Formats

The two platforms use different primary date formats, and each has its own storage-to-display conversion path.
Storage format: fullDate is stored as YYYY-MM-DD (ISO 8601). This is the native value produced by <input type="date">.Input formats accepted by normalizeEvent:
  • YYYY-MM-DD — matched by /^\d{4}-\d{2}-\d{2}$/
  • MM/DD/YYYY — matched by /^\d{2}\/\d{2}\/\d{4}$/, converted to YYYY-MM-DD by splitting on /
Display conversion: rawTime is transformed to a 12-hour display string:
  • Input regex: /^\d{1,2}:\d{2}$/
  • Hours ≥ 12 → suffix "PM", otherwise "AM"
  • Hour displayed as hours % 12 || 12, zero-padded to two digits
  • Empty rawTime → display value "ALL DAY"
Date display derivatives (day and date) are computed from fullDate by constructing new Date($T00:00:00) to avoid timezone shifts.

Category Auto-Detection

When normalizeEvent processes a web event that has no category field (or an empty one), it inspects the lowercased title to assign a category automatically:
Matched patternAssigned category
title includes "birthday""birthday"
title matches /(appointment|dentist|dental|doctor)/"appointment"
title matches /(trip|travel|vacation)/"trip"
no match"general"
Auto-detection only runs when event.category is falsy. If a category is already set (including "all" on seed events), it is preserved unchanged. New events created from add-event.html always store existing?.category || "general", so category correction can only come from the normalization path on first load.

Seed Events

The following array is hard-coded in app.js and used as the initial data set when no saved events exist in localStorage, or when the parse of the stored JSON fails.
const seedEvents = [
  {
    id: 'project',
    day: 'SAT',
    date: '05',
    fullDate: '2025-04-05',
    rawTime: '',
    title: 'Project Two Due',
    time: 'ALL DAY',
    category: 'all',
    alert: false
  },
  {
    id: 'birthday',
    day: 'SAT',
    date: '12',
    fullDate: '2025-04-12',
    rawTime: '18:30',
    title: "Nich's Birthday",
    time: '06:30PM',
    category: 'birthday',
    alert: true
  },
  {
    id: 'dentist',
    day: 'MON',
    date: '14',
    fullDate: '2025-04-14',
    rawTime: '13:30',
    title: 'Dentist',
    time: '01:30PM',
    category: 'appointment',
    alert: false
  },
  {
    id: 'wedding',
    day: 'SUN',
    date: '20',
    fullDate: '2025-04-20',
    rawTime: '15:00',
    title: "Jessica's Wedding",
    time: '03:00PM',
    category: 'trip',
    alert: false
  }
];

Build docs developers (and LLMs) love