Skip to content
Draft
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
1 change: 1 addition & 0 deletions .Jules/JULES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# JULES Standard
7 changes: 7 additions & 0 deletions .Jules/guardian/2026-07-23/session-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## 2026-07-23 - Consolidated Date Utilities

**Target:** src/lib/date.ts and src/lib/format.ts
**Learning:** Found scattered date formatting utilities when they should be centralized in the format library based on JULES guidelines. Consolidating these prevents duplicate helper implementations later.
**Action:** Merged `getDateLocale`, `formatDistanceToNow`, and `formatDate` from `src/lib/date.ts` into `src/lib/format.ts`. Updated 9 downstream file imports and merged corresponding tests.
**JULES Check:** Verified no Autonomous task conflicts in `task-log.md`.
**Conflicts Avoided:** No active Autonomous tasks on date or format modules.
44 changes: 44 additions & 0 deletions .Jules/task-log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
## 2026-04-16 17:04 - [GUARDIAN] Session started

- Directory: .Jules/guardian/2026-04-16
- Phase: PRE-FLIGHT
- JULES Check: COMPLETE

## 2026-04-09 16:36 - [GUARDIAN] Session started

- Directory: .Jules/guardian/2026-04-09
- Phase: PRE-FLIGHT
- JULES Check: COMPLETE

## 2026-04-09 17:08 - [GUARDIAN] Verification complete

- Tests: ✓
- Types: ✓
- Lint: ✓
- Build: ✓

## 2026-04-09 17:08 - [GUARDIAN] Consolidated formatting utilities

- Merged `src/components/ide/utils.ts` into `src/lib/format.ts`
- Updated import in `src/components/ide/prompt-ide.tsx`
- Deleted `src/components/ide/utils.ts`

## 2026-07-23 17:31 - [GUARDIAN] Session started

- Directory: .Jules/guardian/2026-07-23
- Phase: PRE-FLIGHT
- JULES Check: COMPLETE

## 2026-07-23 17:35 - [GUARDIAN] Verification complete

- Tests: ✓
- Types: ✓
- Lint: ✓
- Build: ✓

## 2026-07-23 17:35 - [GUARDIAN] Consolidated date utilities

- Merged `src/lib/date.ts` into `src/lib/format.ts`
- Updated 9 files with new import paths
- Deleted `src/lib/date.ts`
- Merged `src/__tests__/lib/date.test.ts` into `src/__tests__/lib/format.test.ts`
147 changes: 0 additions & 147 deletions src/__tests__/lib/date.test.ts

This file was deleted.

155 changes: 154 additions & 1 deletion src/__tests__/lib/format.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { describe, it, expect } from "vitest";
import { prettifyJson, isValidJson, toYaml } from "@/lib/format";
import {
prettifyJson,
isValidJson,
toYaml,
getDateLocale,
formatDistanceToNow,
formatDate,
} from "@/lib/format";
import { vi, beforeEach, afterEach } from "vitest";
import { enUS, tr, es, zhCN, ja, arSA } from "date-fns/locale";

describe("prettifyJson", () => {
it("should prettify valid JSON with proper indentation", () => {
Expand Down Expand Up @@ -172,3 +181,147 @@ describe("toYaml", () => {
expect(toYaml({ a: 1 })).toBe("a: 1");
});
});

describe("getDateLocale", () => {
it("should return enUS for 'en' locale", () => {
expect(getDateLocale("en")).toBe(enUS);
});

it("should return tr for 'tr' locale", () => {
expect(getDateLocale("tr")).toBe(tr);
});

it("should return es for 'es' locale", () => {
expect(getDateLocale("es")).toBe(es);
});

it("should return zhCN for 'zh' locale", () => {
expect(getDateLocale("zh")).toBe(zhCN);
});

it("should return ja for 'ja' locale", () => {
expect(getDateLocale("ja")).toBe(ja);
});

it("should return arSA for 'ar' locale", () => {
expect(getDateLocale("ar")).toBe(arSA);
});

it("should return enUS for unknown locale", () => {
expect(getDateLocale("unknown")).toBe(enUS);
expect(getDateLocale("fr")).toBe(enUS);
expect(getDateLocale("de")).toBe(enUS);
});
});

describe("formatDistanceToNow", () => {
beforeEach(() => {
// Mock the current date to ensure consistent test results
vi.useFakeTimers();
vi.setSystemTime(new Date("2024-01-15T12:00:00Z"));
});

afterEach(() => {
vi.useRealTimers();
});

it("should format a date object relative to now", () => {
const pastDate = new Date("2024-01-14T12:00:00Z");
const result = formatDistanceToNow(pastDate);
expect(result).toContain("day");
expect(result).toContain("ago");
});

it("should format a date string relative to now", () => {
const pastDateString = "2024-01-14T12:00:00Z";
const result = formatDistanceToNow(pastDateString);
expect(result).toContain("day");
expect(result).toContain("ago");
});

it("should format with different locales", () => {
const pastDate = new Date("2024-01-14T12:00:00Z");

// English
const enResult = formatDistanceToNow(pastDate, "en");
expect(enResult).toContain("ago");

// Spanish
const esResult = formatDistanceToNow(pastDate, "es");
expect(esResult).toContain("hace");

// Turkish
const trResult = formatDistanceToNow(pastDate, "tr");
expect(trResult).toContain("önce");
});

it("should handle dates from a week ago", () => {
const weekAgo = new Date("2024-01-08T12:00:00Z");
const result = formatDistanceToNow(weekAgo);
// date-fns may return "7 days ago" instead of "1 week ago"
expect(result).toMatch(/days?|week/);
expect(result).toContain("ago");
});

it("should handle dates from hours ago", () => {
const hoursAgo = new Date("2024-01-15T10:00:00Z");
const result = formatDistanceToNow(hoursAgo);
expect(result).toContain("hours");
expect(result).toContain("ago");
});

it("should default to en locale when none provided", () => {
const pastDate = new Date("2024-01-14T12:00:00Z");
const result = formatDistanceToNow(pastDate);
expect(result).toContain("ago"); // English suffix
});
});

describe("formatDate", () => {
it("should format a date object with the given format string", () => {
const date = new Date("2024-01-15T12:30:45Z");
expect(formatDate(date, "yyyy-MM-dd")).toBe("2024-01-15");
});

it("should format a date string with the given format string", () => {
const dateString = "2024-01-15T12:30:45Z";
expect(formatDate(dateString, "yyyy-MM-dd")).toBe("2024-01-15");
});

it("should format with various format strings", () => {
const date = new Date("2024-06-15T14:30:00Z");

expect(formatDate(date, "MM/dd/yyyy")).toBe("06/15/2024");
expect(formatDate(date, "dd.MM.yyyy")).toBe("15.06.2024");
expect(formatDate(date, "MMMM d, yyyy", "en")).toBe("June 15, 2024");
});

it("should format with different locales", () => {
const date = new Date("2024-06-15T14:30:00Z");

// English month name
const enResult = formatDate(date, "MMMM", "en");
expect(enResult).toBe("June");

// Spanish month name
const esResult = formatDate(date, "MMMM", "es");
expect(esResult).toBe("junio");

// Turkish month name
const trResult = formatDate(date, "MMMM", "tr");
expect(trResult).toBe("Haziran");
});

it("should handle time formatting", () => {
const date = new Date("2024-01-15T14:30:45Z");
// Test format pattern (timezone-independent)
expect(formatDate(date, "HH:mm:ss")).toMatch(/^\d{2}:\d{2}:\d{2}$/);
expect(formatDate(date, "h:mm a", "en")).toMatch(/^\d{1,2}:\d{2} [AP]M$/i);
});

it("should default to en locale when none provided", () => {
const date = new Date("2024-01-15T12:00:00Z");
const result = formatDate(date, "EEEE"); // Day of week
expect(result).toBe("Monday");
});
});
2 changes: 1 addition & 1 deletion src/app/[username]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Metadata } from "next";
import { notFound } from "next/navigation";
import Link from "next/link";
import { getTranslations, getLocale } from "next-intl/server";
import { formatDistanceToNow } from "@/lib/date";
import { formatDistanceToNow } from "@/lib/format";
import { getPromptUrl } from "@/lib/urls";
import {
Calendar,
Expand Down
2 changes: 1 addition & 1 deletion src/app/prompts/[id]/changes/[changeId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { notFound } from "next/navigation";
import Link from "next/link";
import { getTranslations, getLocale } from "next-intl/server";
import { formatDistanceToNow } from "@/lib/date";
import { formatDistanceToNow } from "@/lib/format";
import { ArrowLeft, Clock, Check, X, FileText } from "lucide-react";
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
Expand Down
2 changes: 1 addition & 1 deletion src/app/prompts/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Metadata } from "next";
import { notFound } from "next/navigation";
import Link from "next/link";
import { getTranslations, getLocale } from "next-intl/server";
import { formatDistanceToNow } from "@/lib/date";
import { formatDistanceToNow } from "@/lib/format";
import {
Clock,
Edit,
Expand Down
Loading
Loading