homepage/src/composables/useParisTime.js
Nathan Leclercq f795cc48b5 Homepage dashboard : horloge animée, todo, notes, RSS, pomodoro, recherche
- Frontend Vue 3 (Composition API) + Vite + Vue Router
- Backend Go (stdlib) : API REST todo/notes + proxy RSS + auth token
- Docker Compose : SPA nginx + backend + Miniflux + Postgres
- Widgets : horloge canvas météo, todo 3 colonnes, notes persistées,
  agrégateur RSS multi-feeds, pomodoro, recherche DuckDuckGo (Ctrl+K)
- Auth : dashboard public, todo/notes protégés par token
- Widgets expandables (mode agrandi centré)
2026-04-09 12:49:55 +02:00

89 lines
2.1 KiB
JavaScript

// Paris timezone helpers + simulated/live clock state.
//
// State is module-level (singleton) so all components share the same
// `simDate` / `isLive` without prop drilling.
import { ref, computed } from 'vue'
export const TZ = 'Europe/Paris'
export function parisComponents(d) {
const parts = new Intl.DateTimeFormat('fr-FR', {
timeZone: TZ,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
}).formatToParts(d)
const get = (t) => parseInt(parts.find((x) => x.type === t).value, 10)
return {
year: get('year'),
month: get('month'),
day: get('day'),
hour: get('hour'),
minute: get('minute'),
second: get('second'),
}
}
export function parisDateStr(d) {
const p = parisComponents(d)
const pad = (n) => String(n).padStart(2, '0')
return `${p.year}-${pad(p.month)}-${pad(p.day)}`
}
export function toInputStr(d) {
const p = parisComponents(d)
const pad = (n) => String(n).padStart(2, '0')
return `${p.year}-${pad(p.month)}-${pad(p.day)}T${pad(p.hour)}:${pad(p.minute)}:${pad(p.second)}`
}
export function getParisOffsetMs(d) {
const fmt = (tz) =>
new Intl.DateTimeFormat('en-GB', {
timeZone: tz,
hour: '2-digit',
minute: '2-digit',
hour12: false,
}).format(d)
const [uh, um] = fmt('UTC').split(':').map(Number)
const [ph, pm] = fmt(TZ).split(':').map(Number)
return ((ph * 60 + pm) - (uh * 60 + um)) * 60000
}
export function parisStrToDate(val) {
const naive = new Date(val + 'Z')
return new Date(naive.getTime() - getParisOffsetMs(naive))
}
// --- Shared singleton state ---
const simDate = ref(null)
const isLive = ref(true)
function getNow() {
return isLive.value ? new Date() : simDate.value
}
function setSimulated(date) {
simDate.value = date
isLive.value = false
}
function goLive() {
simDate.value = null
isLive.value = true
}
export function useClockState() {
return {
simDate: computed(() => simDate.value),
isLive: computed(() => isLive.value),
getNow,
setSimulated,
goLive,
}
}