Files
app/src/components/navigation/GraphNavigator.tsx
T
kcarandClaude Sonnet 4.6 b0c7758135 feat(phase-b): Supabase navigation store, snapshot service, auth wiring
navigationStore: rewritten off Neo4j db names — Supabase whiteboard_rooms table,
  setAuthInfo(token, userId) pattern, auto-creates default room per context on first use
snapshotService: rewritten to Supabase Storage REST (/storage/v1/object/authenticated/cc.users/…),
  setAccessToken() instance method, static methods take accessToken not dbName
AuthContext/NeoUserContext: auth injected into nav store, no Neo4j db names required
singlePlayerPage: loadNodeData no longer calls Neo4j; snapshot wired via accessToken
navigation types: NeoGraphNode updated for Supabase-backed tree structure
transcriptionStore/Service: getSession() removed, accessToken via AuthContext
LLMConfigModal: auth context wiring fixes
GraphNavigator/GraphSidebar: updated nav components

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-26 01:25:15 +01:00

122 lines
4.4 KiB
TypeScript

import React, { useState } from 'react';
import {
IconButton, Tooltip, Box, Menu, MenuItem,
ListItemIcon, ListItemText, Chip, styled,
} from '@mui/material';
import {
ArrowBack as ArrowBackIcon,
ArrowForward as ArrowForwardIcon,
History as HistoryIcon,
Home as HomeIcon,
CalendarToday,
DateRange,
Event,
WorkspacesOutlined,
} from '@mui/icons-material';
import { useNavigationStore } from '../../stores/navigationStore';
const NavigationRoot = styled(Box)`
display: flex;
align-items: center;
gap: 6px;
height: 100%;
`;
function getNodeIcon(nodeType: string) {
switch (nodeType) {
case 'User': return <HomeIcon fontSize="small" />;
case 'CalendarYear': return <CalendarToday fontSize="small" />;
case 'CalendarMonth': return <DateRange fontSize="small" />;
case 'CalendarDay': return <Event fontSize="small" />;
default: return <WorkspacesOutlined fontSize="small" />;
}
}
export const GraphNavigator: React.FC = () => {
const { context, goBack, goForward, isLoading } = useNavigationStore();
const [historyMenuAnchor, setHistoryMenuAnchor] = useState<null | HTMLElement>(null);
const { history } = context;
const canGoBack = history.currentIndex > 0;
const canGoForward = history.currentIndex < history.nodes.length - 1;
const currentNode = context.node;
const handleHistoryClick = (e: React.MouseEvent<HTMLElement>) => setHistoryMenuAnchor(e.currentTarget);
const handleHistoryClose = () => setHistoryMenuAnchor(null);
const handleHistoryItemClick = (index: number) => {
const delta = index - history.currentIndex;
if (delta < 0) for (let i = 0; i < -delta; i++) goBack();
else if (delta > 0) for (let i = 0; i < delta; i++) goForward();
handleHistoryClose();
};
return (
<NavigationRoot>
<Tooltip title="Back">
<span>
<IconButton onClick={goBack} disabled={!canGoBack || isLoading} size="small">
<ArrowBackIcon fontSize="small" />
</IconButton>
</span>
</Tooltip>
<Tooltip title="History">
<span>
<IconButton
onClick={handleHistoryClick}
disabled={!history.nodes.length}
size="small"
>
<HistoryIcon fontSize="small" />
</IconButton>
</span>
</Tooltip>
<Tooltip title="Forward">
<span>
<IconButton onClick={goForward} disabled={!canGoForward || isLoading} size="small">
<ArrowForwardIcon fontSize="small" />
</IconButton>
</span>
</Tooltip>
{currentNode && (
<Chip
size="small"
icon={getNodeIcon(currentNode.type)}
label={currentNode.label || currentNode.type}
variant="outlined"
sx={{ maxWidth: 200, fontSize: '0.75rem' }}
/>
)}
<Menu
anchorEl={historyMenuAnchor}
open={Boolean(historyMenuAnchor)}
onClose={handleHistoryClose}
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
transformOrigin={{ vertical: 'top', horizontal: 'center' }}
>
{history.nodes.map((node, index) => (
<MenuItem
key={`${node.id}-${index}`}
onClick={() => handleHistoryItemClick(index)}
selected={index === history.currentIndex}
dense
>
<ListItemIcon sx={{ minWidth: 32 }}>
{getNodeIcon(node.type)}
</ListItemIcon>
<ListItemText
primary={node.label || node.id}
secondary={node.type}
primaryTypographyProps={{ fontSize: '0.8rem' }}
secondaryTypographyProps={{ fontSize: '0.7rem' }}
/>
</MenuItem>
))}
</Menu>
</NavigationRoot>
);
};