feat(web): TODO-001 kill switch maintenance banner + disable timer creation

This commit is contained in:
saravanakumardb1 2026-04-18 17:56:37 -07:00
parent 8ca9e27532
commit 8bddbec43c
3 changed files with 46 additions and 15 deletions

View File

@ -1,34 +1,32 @@
'use client';
import { useEffect } from 'react';
import { createContext, useContext, useEffect, useState } from 'react';
import { usePathname } from 'next/navigation';
import { AuthProvider } from '@/lib/auth-context';
import { initTelemetry, trackPageView } from '@/lib/telemetry';
import { initFeatureFlags } from '@/lib/feature-flags';
import { initDiagnostics } from '@/lib/diagnostics';
import { checkKillSwitch } from '@/lib/kill-switch';
import { MaintenanceBanner } from '@/components/MaintenanceBanner';
import { ToastProvider } from '@bytelyst/ui';
import type { ReactNode } from 'react';
const MaintenanceContext = createContext(false);
export function useMaintenanceMode(): boolean {
return useContext(MaintenanceContext);
}
export function Providers({ children }: { children: ReactNode }) {
const pathname = usePathname();
const [isMaintenanceMode, setIsMaintenanceMode] = useState(false);
useEffect(() => {
initTelemetry();
initFeatureFlags();
initDiagnostics();
// TODO-001: Kill switch maintenance banner
// Priority: medium | Phase: 0
// When checkKillSwitch() returns disabled=true:
// 1. Set a React state flag (e.g. `isMaintenanceMode`)
// 2. Render a <MaintenanceBanner /> component at the top of the app
// 3. Disable timer creation buttons (pass flag via context or prop)
// 4. Use --cm-warning-* design tokens for the banner styling
// File to create: web/src/components/MaintenanceBanner.tsx
checkKillSwitch().then((disabled) => {
if (disabled) {
// TODO-001: Surface this in the UI (see instructions above)
}
setIsMaintenanceMode(disabled);
});
}, []);
@ -40,7 +38,12 @@ export function Providers({ children }: { children: ReactNode }) {
return (
<AuthProvider>
<ToastProvider>{children}</ToastProvider>
<MaintenanceContext.Provider value={isMaintenanceMode}>
<ToastProvider>
{isMaintenanceMode && <MaintenanceBanner />}
{children}
</ToastProvider>
</MaintenanceContext.Provider>
</AuthProvider>
);
}

View File

@ -7,6 +7,7 @@ import type { UrgencyLevel } from '@/lib/urgency';
import { CASCADE_PRESET_LABELS } from '@/lib/cascade';
import type { CascadePreset } from '@/lib/cascade';
import { X, AlarmClock, Timer, Coffee, Sparkles, CalendarDays } from 'lucide-react';
import { useMaintenanceMode } from '@/app/providers';
import { BUILT_IN_CATEGORIES, getCategoryById } from '@/lib/categories';
import { parseNaturalLanguage } from '@/lib/nl-parser';
import type { ParseResult } from '@/lib/nl-parser';
@ -21,6 +22,7 @@ interface CreateTimerModalProps {
export function CreateTimerModal({ isOpen, onClose }: CreateTimerModalProps) {
const { addAlarm, addCountdown, addPomodoro, addEvent } = useTimerStore();
const maintenanceMode = useMaintenanceMode();
const [tab, setTab] = useState<TabType>('countdown');
const [nlInput, setNlInput] = useState('');
@ -570,13 +572,14 @@ export function CreateTimerModal({ isOpen, onClose }: CreateTimerModalProps) {
{/* Create button */}
<button
onClick={handleCreate}
className="w-full py-3 rounded-xl text-sm font-semibold transition-colors cursor-pointer"
disabled={maintenanceMode}
className="w-full py-3 rounded-xl text-sm font-semibold transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed"
style={{
backgroundColor: 'var(--cm-accent)',
color: 'var(--cm-white)',
}}
>
Create {tab === 'pomodoro' ? 'Pomodoro' : tab === 'alarm' ? 'Alarm' : 'Countdown'}
{maintenanceMode ? 'Timer creation disabled (maintenance)' : `Create ${tab === 'pomodoro' ? 'Pomodoro' : tab === 'alarm' ? 'Alarm' : 'Countdown'}`}
</button>
</div>
</div>

View File

@ -0,0 +1,25 @@
'use client';
import { AlertTriangle } from 'lucide-react';
interface MaintenanceBannerProps {
message?: string;
}
export function MaintenanceBanner({ message }: MaintenanceBannerProps) {
return (
<div
role="alert"
aria-label="Maintenance mode active"
className="w-full px-4 py-3 flex items-center justify-center gap-2 text-sm font-medium"
style={{
backgroundColor: 'var(--cm-important-15)',
color: 'var(--cm-important)',
borderBottom: '1px solid var(--cm-important)',
}}
>
<AlertTriangle size={16} aria-hidden="true" />
<span>{message || 'ChronoMind is currently in maintenance mode. Timer creation is temporarily disabled.'}</span>
</div>
);
}