spb/internetpressure
Public
TypeScript 36.3%
Python 31.8%
Go 18%
JavaScript 9.8%
Shell 1.9%
SQL 1.4%
CSS 0.5%
1'use client';23import { createContext, useCallback, useContext, useMemo, type ReactNode } from 'react';4import { formatTime, type TimeMode, type TimeStyle } from './format';5import { useStoredValue } from './storage';67interface TimeCtx {8 mode: TimeMode;9 setMode: (m: TimeMode) => void;10 format: (ts: string | number | Date | null | undefined, style?: TimeStyle) => string;11}1213const Ctx = createContext<TimeCtx>({ mode: 'utc', setMode: () => {}, format: (ts, style) => formatTime(ts, 'utc', style) });14const KEY = 'ip.time-mode';1516/** UTC on the server and on first paint; the stored preference is read after hydration through an external store. */17export function TimeProvider({ children }: { children: ReactNode }) {18 const [stored, setStored] = useStoredValue(KEY, 'utc');19 const mode: TimeMode = stored === 'local' ? 'local' : 'utc';20 const setMode = useCallback((m: TimeMode) => setStored(m), [setStored]);21 const value = useMemo<TimeCtx>(() => ({ mode, setMode, format: (ts, style) => formatTime(ts, mode, style) }), [mode, setMode]);22 return <Ctx.Provider value={value}>{children}</Ctx.Provider>;23}2425export function useTime() {26 return useContext(Ctx);27}2829/** Inline timestamp that follows the UTC/local toggle. */30export function Time({ ts, style = 'short', className }: { ts: string | number | Date | null | undefined; style?: TimeStyle; className?: string }) {31 const { format } = useTime();32 return (33 <time dateTime={ts ? new Date(ts).toISOString() : undefined} className={className} suppressHydrationWarning>34 {format(ts, style)}35 </time>36 );37}38