From 99d0dc6fb08c21624b488c433e7dc27fec239c3e Mon Sep 17 00:00:00 2001 From: Till JS Date: Thu, 2 Apr 2026 13:06:55 +0200 Subject: [PATCH] fix(manacore/web): float DateStrip at bottom, remove sidebar Position DateStrip fixed above PillNav with glass blur effect. Remove MiniCalendar sidebar to give calendar view full width. Restore @clock/shared package from archive (needed by clock module). Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/clock/packages/shared/package.json | 19 +++ .../packages/shared/src/constants/index.ts | 151 ++++++++++++++++++ apps/clock/packages/shared/src/index.ts | 2 + apps/clock/packages/shared/src/types/alarm.ts | 55 +++++++ apps/clock/packages/shared/src/types/index.ts | 4 + .../clock/packages/shared/src/types/preset.ts | 42 +++++ apps/clock/packages/shared/src/types/timer.ts | 49 ++++++ .../packages/shared/src/types/world-clock.ts | 18 +++ apps/clock/packages/shared/tsconfig.json | 14 ++ .../calendar/components/DateStrip.svelte | 15 +- .../src/routes/(app)/calendar/+page.svelte | 133 ++------------- 11 files changed, 380 insertions(+), 122 deletions(-) create mode 100644 apps/clock/packages/shared/package.json create mode 100644 apps/clock/packages/shared/src/constants/index.ts create mode 100644 apps/clock/packages/shared/src/index.ts create mode 100644 apps/clock/packages/shared/src/types/alarm.ts create mode 100644 apps/clock/packages/shared/src/types/index.ts create mode 100644 apps/clock/packages/shared/src/types/preset.ts create mode 100644 apps/clock/packages/shared/src/types/timer.ts create mode 100644 apps/clock/packages/shared/src/types/world-clock.ts create mode 100644 apps/clock/packages/shared/tsconfig.json diff --git a/apps/clock/packages/shared/package.json b/apps/clock/packages/shared/package.json new file mode 100644 index 000000000..8b9961090 --- /dev/null +++ b/apps/clock/packages/shared/package.json @@ -0,0 +1,19 @@ +{ + "name": "@clock/shared", + "version": "0.2.0", + "private": true, + "type": "module", + "main": "./src/index.ts", + "exports": { + ".": "./src/index.ts", + "./types": "./src/types/index.ts", + "./constants": "./src/constants/index.ts" + }, + "scripts": { + "type-check": "tsc --noEmit", + "lint": "eslint src" + }, + "devDependencies": { + "typescript": "^5.7.2" + } +} diff --git a/apps/clock/packages/shared/src/constants/index.ts b/apps/clock/packages/shared/src/constants/index.ts new file mode 100644 index 000000000..205c25895 --- /dev/null +++ b/apps/clock/packages/shared/src/constants/index.ts @@ -0,0 +1,151 @@ +// Popular timezones with city names and coordinates for map display +export const POPULAR_TIMEZONES = [ + { + timezone: 'America/New_York', + city: 'New York', + region: 'Americas', + lat: 40.7128, + lng: -74.006, + }, + { + timezone: 'America/Los_Angeles', + city: 'Los Angeles', + region: 'Americas', + lat: 34.0522, + lng: -118.2437, + }, + { timezone: 'America/Chicago', city: 'Chicago', region: 'Americas', lat: 41.8781, lng: -87.6298 }, + { timezone: 'America/Toronto', city: 'Toronto', region: 'Americas', lat: 43.6532, lng: -79.3832 }, + { + timezone: 'America/Sao_Paulo', + city: 'São Paulo', + region: 'Americas', + lat: -23.5505, + lng: -46.6333, + }, + { + timezone: 'America/Mexico_City', + city: 'Mexico City', + region: 'Americas', + lat: 19.4326, + lng: -99.1332, + }, + { + timezone: 'America/Buenos_Aires', + city: 'Buenos Aires', + region: 'Americas', + lat: -34.6037, + lng: -58.3816, + }, + { + timezone: 'America/Vancouver', + city: 'Vancouver', + region: 'Americas', + lat: 49.2827, + lng: -123.1207, + }, + { timezone: 'Europe/London', city: 'London', region: 'Europe', lat: 51.5074, lng: -0.1278 }, + { timezone: 'Europe/Paris', city: 'Paris', region: 'Europe', lat: 48.8566, lng: 2.3522 }, + { timezone: 'Europe/Berlin', city: 'Berlin', region: 'Europe', lat: 52.52, lng: 13.405 }, + { timezone: 'Europe/Rome', city: 'Rome', region: 'Europe', lat: 41.9028, lng: 12.4964 }, + { timezone: 'Europe/Madrid', city: 'Madrid', region: 'Europe', lat: 40.4168, lng: -3.7038 }, + { timezone: 'Europe/Amsterdam', city: 'Amsterdam', region: 'Europe', lat: 52.3676, lng: 4.9041 }, + { timezone: 'Europe/Vienna', city: 'Vienna', region: 'Europe', lat: 48.2082, lng: 16.3738 }, + { timezone: 'Europe/Zurich', city: 'Zurich', region: 'Europe', lat: 47.3769, lng: 8.5417 }, + { timezone: 'Europe/Moscow', city: 'Moscow', region: 'Europe', lat: 55.7558, lng: 37.6173 }, + { timezone: 'Europe/Stockholm', city: 'Stockholm', region: 'Europe', lat: 59.3293, lng: 18.0686 }, + { timezone: 'Europe/Istanbul', city: 'Istanbul', region: 'Europe', lat: 41.0082, lng: 28.9784 }, + { timezone: 'Asia/Tokyo', city: 'Tokyo', region: 'Asia', lat: 35.6762, lng: 139.6503 }, + { timezone: 'Asia/Shanghai', city: 'Shanghai', region: 'Asia', lat: 31.2304, lng: 121.4737 }, + { timezone: 'Asia/Hong_Kong', city: 'Hong Kong', region: 'Asia', lat: 22.3193, lng: 114.1694 }, + { timezone: 'Asia/Singapore', city: 'Singapore', region: 'Asia', lat: 1.3521, lng: 103.8198 }, + { timezone: 'Asia/Seoul', city: 'Seoul', region: 'Asia', lat: 37.5665, lng: 126.978 }, + { timezone: 'Asia/Mumbai', city: 'Mumbai', region: 'Asia', lat: 19.076, lng: 72.8777 }, + { timezone: 'Asia/Dubai', city: 'Dubai', region: 'Asia', lat: 25.2048, lng: 55.2708 }, + { timezone: 'Asia/Bangkok', city: 'Bangkok', region: 'Asia', lat: 13.7563, lng: 100.5018 }, + { timezone: 'Asia/Jakarta', city: 'Jakarta', region: 'Asia', lat: -6.2088, lng: 106.8456 }, + { timezone: 'Australia/Sydney', city: 'Sydney', region: 'Oceania', lat: -33.8688, lng: 151.2093 }, + { + timezone: 'Australia/Melbourne', + city: 'Melbourne', + region: 'Oceania', + lat: -37.8136, + lng: 144.9631, + }, + { + timezone: 'Pacific/Auckland', + city: 'Auckland', + region: 'Oceania', + lat: -36.8485, + lng: 174.7633, + }, + { timezone: 'Africa/Cairo', city: 'Cairo', region: 'Africa', lat: 30.0444, lng: 31.2357 }, + { + timezone: 'Africa/Johannesburg', + city: 'Johannesburg', + region: 'Africa', + lat: -26.2041, + lng: 28.0473, + }, + { timezone: 'Africa/Lagos', city: 'Lagos', region: 'Africa', lat: 6.5244, lng: 3.3792 }, +] as const; + +// Available alarm sounds +export const ALARM_SOUNDS = [ + { id: 'default', name: 'Default', nameDE: 'Standard' }, + { id: 'gentle', name: 'Gentle', nameDE: 'Sanft' }, + { id: 'classic', name: 'Classic', nameDE: 'Klassisch' }, + { id: 'digital', name: 'Digital', nameDE: 'Digital' }, + { id: 'nature', name: 'Nature', nameDE: 'Natur' }, + { id: 'chime', name: 'Chime', nameDE: 'Glockenspiel' }, +] as const; + +// Timer presets +export const QUICK_TIMER_PRESETS = [ + { label: '1 min', seconds: 60 }, + { label: '3 min', seconds: 180 }, + { label: '5 min', seconds: 300 }, + { label: '10 min', seconds: 600 }, + { label: '15 min', seconds: 900 }, + { label: '30 min', seconds: 1800 }, + { label: '45 min', seconds: 2700 }, + { label: '1 hour', seconds: 3600 }, +] as const; + +// Default alarm presets (like iOS Clock app) +export const DEFAULT_ALARM_PRESETS = [ + { time: '06:00', label: 'Früh aufstehen', labelEN: 'Wake up early' }, + { time: '07:00', label: 'Aufwachen', labelEN: 'Wake up' }, + { time: '08:00', label: 'Morgen', labelEN: 'Morning' }, + { time: '12:00', label: 'Mittag', labelEN: 'Noon' }, + { time: '18:00', label: 'Feierabend', labelEN: 'End of work' }, + { time: '22:00', label: 'Schlafenszeit', labelEN: 'Bedtime' }, +] as const; + +// Pomodoro presets +export const POMODORO_PRESETS = [ + { + name: 'Classic Pomodoro', + nameDE: 'Klassischer Pomodoro', + workDuration: 25 * 60, + breakDuration: 5 * 60, + longBreakDuration: 15 * 60, + sessionsBeforeLongBreak: 4, + }, + { + name: 'Short Focus', + nameDE: 'Kurzer Fokus', + workDuration: 15 * 60, + breakDuration: 3 * 60, + longBreakDuration: 10 * 60, + sessionsBeforeLongBreak: 4, + }, + { + name: 'Deep Work', + nameDE: 'Tiefes Arbeiten', + workDuration: 50 * 60, + breakDuration: 10 * 60, + longBreakDuration: 30 * 60, + sessionsBeforeLongBreak: 3, + }, +] as const; diff --git a/apps/clock/packages/shared/src/index.ts b/apps/clock/packages/shared/src/index.ts new file mode 100644 index 000000000..33c8572a1 --- /dev/null +++ b/apps/clock/packages/shared/src/index.ts @@ -0,0 +1,2 @@ +export * from './types'; +export * from './constants'; diff --git a/apps/clock/packages/shared/src/types/alarm.ts b/apps/clock/packages/shared/src/types/alarm.ts new file mode 100644 index 000000000..212e10059 --- /dev/null +++ b/apps/clock/packages/shared/src/types/alarm.ts @@ -0,0 +1,55 @@ +export interface Alarm { + id: string; + userId: string; + label: string | null; + time: string; // HH:MM:SS format + enabled: boolean; + repeatDays: number[] | null; // [0-6] where 0 = Sunday + snoozeMinutes: number | null; + sound: string | null; + vibrate: boolean | null; + createdAt: string; + updatedAt: string; +} + +export interface CreateAlarmInput { + label?: string; + time: string; + enabled?: boolean; + repeatDays?: number[]; + snoozeMinutes?: number; + sound?: string; + vibrate?: boolean; +} + +export interface UpdateAlarmInput { + label?: string; + time?: string; + enabled?: boolean; + repeatDays?: number[]; + snoozeMinutes?: number; + sound?: string; + vibrate?: boolean; +} + +export type RepeatDay = 0 | 1 | 2 | 3 | 4 | 5 | 6; + +export const REPEAT_DAY_LABELS = { + 0: 'Sun', + 1: 'Mon', + 2: 'Tue', + 3: 'Wed', + 4: 'Thu', + 5: 'Fri', + 6: 'Sat', +} as const; + +export const REPEAT_DAY_LABELS_DE = { + 0: 'So', + 1: 'Mo', + 2: 'Di', + 3: 'Mi', + 4: 'Do', + 5: 'Fr', + 6: 'Sa', +} as const; diff --git a/apps/clock/packages/shared/src/types/index.ts b/apps/clock/packages/shared/src/types/index.ts new file mode 100644 index 000000000..1bd20351b --- /dev/null +++ b/apps/clock/packages/shared/src/types/index.ts @@ -0,0 +1,4 @@ +export * from './alarm'; +export * from './timer'; +export * from './world-clock'; +export * from './preset'; diff --git a/apps/clock/packages/shared/src/types/preset.ts b/apps/clock/packages/shared/src/types/preset.ts new file mode 100644 index 000000000..948adf37e --- /dev/null +++ b/apps/clock/packages/shared/src/types/preset.ts @@ -0,0 +1,42 @@ +export type PresetType = 'timer' | 'pomodoro'; + +export interface PresetSettings { + // For pomodoro presets + workDuration?: number; + breakDuration?: number; + longBreakDuration?: number; + sessionsBeforeLongBreak?: number; + // For timer presets + sound?: string; +} + +export interface Preset { + id: string; + userId: string; + type: PresetType; + name: string; + durationSeconds: number; + settings: PresetSettings | null; + createdAt: string; +} + +export interface CreatePresetInput { + type: PresetType; + name: string; + durationSeconds: number; + settings?: PresetSettings; +} + +export interface UpdatePresetInput { + name?: string; + durationSeconds?: number; + settings?: PresetSettings; +} + +// Default pomodoro settings +export const DEFAULT_POMODORO_SETTINGS: PresetSettings = { + workDuration: 25 * 60, // 25 minutes + breakDuration: 5 * 60, // 5 minutes + longBreakDuration: 15 * 60, // 15 minutes + sessionsBeforeLongBreak: 4, +}; diff --git a/apps/clock/packages/shared/src/types/timer.ts b/apps/clock/packages/shared/src/types/timer.ts new file mode 100644 index 000000000..221bb56ef --- /dev/null +++ b/apps/clock/packages/shared/src/types/timer.ts @@ -0,0 +1,49 @@ +export type TimerStatus = 'idle' | 'running' | 'paused' | 'finished'; + +export interface Timer { + id: string; + userId: string; + label: string | null; + durationSeconds: number; + remainingSeconds: number | null; + status: TimerStatus; + startedAt: string | null; + pausedAt: string | null; + sound: string | null; + createdAt: string; + updatedAt: string; +} + +export interface CreateTimerInput { + label?: string; + durationSeconds: number; + sound?: string; +} + +export interface UpdateTimerInput { + label?: string; + durationSeconds?: number; + sound?: string; +} + +export function formatDuration(seconds: number): string { + const hours = Math.floor(seconds / 3600); + const minutes = Math.floor((seconds % 3600) / 60); + const secs = seconds % 60; + + if (hours > 0) { + return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; + } + return `${minutes}:${secs.toString().padStart(2, '0')}`; +} + +export function parseDuration(formatted: string): number { + const parts = formatted.split(':').map(Number); + if (parts.length === 3) { + return parts[0] * 3600 + parts[1] * 60 + parts[2]; + } + if (parts.length === 2) { + return parts[0] * 60 + parts[1]; + } + return parts[0]; +} diff --git a/apps/clock/packages/shared/src/types/world-clock.ts b/apps/clock/packages/shared/src/types/world-clock.ts new file mode 100644 index 000000000..7a2ae55a7 --- /dev/null +++ b/apps/clock/packages/shared/src/types/world-clock.ts @@ -0,0 +1,18 @@ +export interface WorldClock { + id: string; + userId: string; + timezone: string; // IANA timezone e.g. 'America/New_York' + cityName: string; + sortOrder: number; + createdAt: string; +} + +export interface CreateWorldClockInput { + timezone: string; + cityName: string; +} + +export interface TimezoneInfo { + timezone: string; + city: string; +} diff --git a/apps/clock/packages/shared/tsconfig.json b/apps/clock/packages/shared/tsconfig.json new file mode 100644 index 000000000..b17efe376 --- /dev/null +++ b/apps/clock/packages/shared/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2021", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "skipLibCheck": true, + "declaration": true, + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/apps/manacore/apps/web/src/lib/modules/calendar/components/DateStrip.svelte b/apps/manacore/apps/web/src/lib/modules/calendar/components/DateStrip.svelte index 5b6d8717a..782ad6459 100644 --- a/apps/manacore/apps/web/src/lib/modules/calendar/components/DateStrip.svelte +++ b/apps/manacore/apps/web/src/lib/modules/calendar/components/DateStrip.svelte @@ -268,18 +268,25 @@