diff --git a/src/app/components/ServiceButton.tsx b/src/app/components/ServiceButton.tsx index 2662026..40baa0e 100644 --- a/src/app/components/ServiceButton.tsx +++ b/src/app/components/ServiceButton.tsx @@ -3,14 +3,11 @@ import React, { useEffect, useState, ReactNode } from 'react'; export default function ServiceButton({ url, checkUrl, className, icon, name, desc, access, disabled }: { url: string, checkUrl?: string, className: string, icon: ReactNode, name: string, desc: string, access?: 'public' | 'private' | 'on_request', disabled?: boolean }) { - const [status, setStatus] = useState<'pending' | 'up' | 'down'>(disabled ? 'up' : 'pending'); + const [status, setStatus] = useState<'pending' | 'up' | 'down'>('pending'); useEffect(() => { - // Disabled buttons are decorative: skip the health check and stay green. - if (disabled) { - setStatus('up'); - return; - } + // Disabled buttons are decorative: skip the health check. + if (disabled) return; const checkStatus = async () => { try { @@ -25,9 +22,11 @@ export default function ServiceButton({ url, checkUrl, className, icon, name, de checkStatus(); }, [url, checkUrl, disabled]); - const statusColor = status === 'up' ? '#4ade80' : status === 'down' ? '#ef4444' : '#9ca3af'; - const statusGlow = status === 'up' ? 'rgba(74, 222, 128, 0.9)' : status === 'down' ? 'rgba(239, 68, 68, 0.9)' : 'transparent'; - const statusLabel = status === 'up' ? 'Active' : status === 'down' ? 'Dead' : 'Checking...'; + // Disabled buttons always read as green without a state update in the effect. + const effectiveStatus = disabled ? 'up' : status; + const statusColor = effectiveStatus === 'up' ? '#4ade80' : effectiveStatus === 'down' ? '#ef4444' : '#9ca3af'; + const statusGlow = effectiveStatus === 'up' ? 'rgba(74, 222, 128, 0.9)' : effectiveStatus === 'down' ? 'rgba(239, 68, 68, 0.9)' : 'transparent'; + const statusLabel = effectiveStatus === 'up' ? 'Active' : effectiveStatus === 'down' ? 'Dead' : 'Checking...'; const isFriend = className === 'friend'; const content = ( diff --git a/src/app/components/ThemeScript.tsx b/src/app/components/ThemeScript.tsx new file mode 100644 index 0000000..2546edf --- /dev/null +++ b/src/app/components/ThemeScript.tsx @@ -0,0 +1,30 @@ +"use client"; + +import { useRef } from "react"; +import { useServerInsertedHTML } from "next/navigation"; + +// Runs before paint so the saved theme and the phone/desktop split are applied +// without a flash. It is injected with useServerInsertedHTML so the