import { useEffect, useRef, useState } from 'react'; import { io, Socket } from 'socket.io-client'; interface GitStatusData { status: string; details: string; } interface GitBranchData { current_branch: string; } function isDataEnvelope(payload: unknown): payload is { data: unknown } { return ( typeof payload === 'object' && payload !== null && !Array.isArray(payload) && 'data' in payload ); } function isGitStatusData(data: unknown): data is GitStatusData { const d = data as GitStatusData; return ( !!d && typeof d === 'object' && !Array.isArray(d) && typeof d.status === 'string' && typeof d.details === 'string' ); } function isGitBranchData(data: unknown): data is GitBranchData { const d = data as GitBranchData; return ( !!d && typeof d === 'object' && !Array.isArray(d) && typeof d.current_branch === 'string' ); } interface User { email: string; name?: string; } export default function App() { const [user, setUser] = useState(null); const [statusData, setStatusData] = useState(null); const [branchData, setBranchData] = useState(null); const [statusLoading, setStatusLoading] = useState(false); const [branchLoading, setBranchLoading] = useState(false); const [statusError, setStatusError] = useState(null); const [branchError, setBranchError] = useState(null); const socketRef = useRef(null); useEffect(() => { fetch('/auth/me', { credentials: 'include' }) .then((r) => (r.ok ? r.json() : null)) .then(setUser); }, []); useEffect(() => { if (!user) return; const socket = io('/'); socketRef.current = socket; const onStatusResult = (payload: unknown) => { setStatusLoading(false); if (isDataEnvelope(payload) && isGitStatusData(payload.data)) { setStatusData({ status: payload.data.status, details: payload.data.details }); } else { setStatusData(null); setStatusError('Ugyldig svar for Git-status.'); } }; const onStatusError = () => { setStatusData(null); setStatusLoading(false); setStatusError('Kunne ikke hente Git-status.'); }; const onBranchResult = (payload: unknown) => { setBranchLoading(false); if (isDataEnvelope(payload) && isGitBranchData(payload.data)) { setBranchData({ current_branch: payload.data.current_branch }); } else { setBranchData(null); setBranchError('Ugyldig svar for aktiv branch.'); } }; const onBranchError = () => { setBranchData(null); setBranchLoading(false); setBranchError('Kunne ikke hente aktiv branch.'); }; socket.on('git:status:result', onStatusResult); socket.on('git:status:error', onStatusError); socket.on('git:branch:result', onBranchResult); socket.on('git:branch:error', onBranchError); return () => { socket.off('git:status:result', onStatusResult); socket.off('git:status:error', onStatusError); socket.off('git:branch:result', onBranchResult); socket.off('git:branch:error', onBranchError); socket.close(); socketRef.current = null; }; }, [user]); const handleGetStatus = () => { if (!socketRef.current) { setStatusData(null); setStatusLoading(false); setStatusError('Kunne ikke hente Git-status.'); return; } setStatusError(null); setStatusData(null); setStatusLoading(true); socketRef.current.emit('git:getStatus'); }; const handleGetBranch = () => { if (!socketRef.current) { setBranchData(null); setBranchLoading(false); setBranchError('Kunne ikke hente aktiv branch.'); return; } setBranchError(null); setBranchData(null); setBranchLoading(true); socketRef.current.emit('git:getBranch'); }; if (!user) { return (

OPAX

Continue with Google
); } return (
OPAX / Web TUI {user.email}

Git Status

{statusError &&

{statusError}

} {statusData && (
              Status: {statusData.status}\n\n
              Detaljer:\n{statusData.details || '(ingen endringer)'}
            
)}

Aktiv Branch

{branchError &&

{branchError}

} {branchData && (

Nåværende branch: {branchData.current_branch}

)}
); }