'use client'
import React, { useState, useEffect, useRef } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import Window from './Window'
import { Globe, Clock as ClockIcon, Type, Plus } from 'lucide-react'
interface ClockProps {
onClose: () => void
onMinimize?: () => void
onMaximize?: () => void
onFocus?: () => void
zIndex?: number
}
// Helper to get smooth time
const useSmoothTime = () => {
const [time, setTime] = useState(new Date())
useEffect(() => {
let frameId: number
const update = () => {
setTime(new Date())
frameId = requestAnimationFrame(update)
}
update()
return () => cancelAnimationFrame(frameId)
}, [])
return time
}
const AnalogFace = ({ time, city, offset, isSmall = false }: { time: Date, city?: string, offset?: number, isSmall?: boolean }) => {
// Calculate time with offset if provided
const displayTime = offset !== undefined
? new Date(time.getTime() + (time.getTimezoneOffset() * 60000) + (3600000 * offset))
: time
const seconds = displayTime.getSeconds() + displayTime.getMilliseconds() / 1000
const minutes = displayTime.getMinutes() + seconds / 60
const hours = displayTime.getHours() % 12 + minutes / 60
return (
{/* Clock Face Markings */}
{[...Array(12)].map((_, i) => (
{!isSmall && (
{i === 0 ? 12 : i}
)}
))}
{/* Hands Container */}
{/* Hour Hand */}
{/* Minute Hand */}
{/* Second Hand (Orange) */}
{/* Tail of second hand */}
{/* Center Cap */}
{/* Labels */}
{city || 'Local Time'}
{offset !== undefined
? (offset === 0 ? 'Today' : `${offset > 0 ? '+' : ''}${offset}HRS`)
: displayTime.toLocaleDateString(undefined, { weekday: 'short', month: 'short', day: 'numeric' })
}
{!isSmall && (
{displayTime.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: false })}
)}
)
}
// List of available cities with offsets
const AVAILABLE_CITIES = [
{ city: 'San Francisco', offset: -8, region: 'USA' },
{ city: 'New York', offset: -5, region: 'USA' },
{ city: 'London', offset: 0, region: 'UK' },
{ city: 'Paris', offset: 1, region: 'Europe' },
{ city: 'Berlin', offset: 1, region: 'Europe' },
{ city: 'Moscow', offset: 3, region: 'Russia' },
{ city: 'Dubai', offset: 4, region: 'UAE' },
{ city: 'Mumbai', offset: 5.5, region: 'India' },
{ city: 'Singapore', offset: 8, region: 'Asia' },
{ city: 'Tokyo', offset: 9, region: 'Japan' },
{ city: 'Sydney', offset: 11, region: 'Australia' },
{ city: 'Auckland', offset: 13, region: 'New Zealand' },
{ city: 'Honolulu', offset: -10, region: 'USA' },
{ city: 'Rio de Janeiro', offset: -3, region: 'Brazil' },
]
const ClockContent = () => {
const time = useSmoothTime()
const [activeTab, setActiveTab] = useState<'world' | 'analog' | 'digital'>('world')
const [showAddCity, setShowAddCity] = useState(false)
const [searchQuery, setSearchQuery] = useState('')
const [worldClocks, setWorldClocks] = useState([
{ city: 'Cupertino', offset: -8 },
{ city: 'New York', offset: -5 },
{ city: 'London', offset: 0 },
{ city: 'Tokyo', offset: 9 },
])
const tabs = [
{ id: 'world', label: 'World Clock', icon: Globe },
{ id: 'analog', label: 'Analog', icon: ClockIcon },
{ id: 'digital', label: 'Digital', icon: Type },
]
const filteredCities = AVAILABLE_CITIES.filter(c =>
c.city.toLowerCase().includes(searchQuery.toLowerCase()) &&
!worldClocks.some(wc => wc.city === c.city)
)
const addCity = (city: typeof AVAILABLE_CITIES[0]) => {
setWorldClocks([...worldClocks, { city: city.city, offset: city.offset }])
setShowAddCity(false)
setSearchQuery('')
}
return (
{/* macOS-style Toolbar */}
{tabs.map((tab) => {
const Icon = tab.icon
const isActive = activeTab === tab.id
return (
)
})}
{/* Content Area */}
{activeTab === 'world' && !showAddCity && (
{worldClocks.map((clock) => (
))}
{/* Add Button */}
)}
{activeTab === 'world' && showAddCity && (
{filteredCities.map((city) => (
))}
{filteredCities.length === 0 && (
No cities found
)}
)}
{activeTab === 'analog' && (
)}
{activeTab === 'digital' && (
{time.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit' })}
{time.getSeconds().toString().padStart(2, '0')}
{time.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' })}
)}
)
}
export function Clock({ onClose, onMinimize, onMaximize, onFocus, zIndex }: ClockProps) {
return (
)
}