feat(phase-b): school/timetable wizards, graph nav panel, UI updates
New components: - CCGraphNavPanel: Supabase-driven navigation tree (school/timetable/calendar/classes sections), role-aware setup buttons, lazy child loading, academic/generic calendar toggle - SchoolCalendarWizard: 3-step admin-only school setup (details → term dates → daily periods) - TeacherTimetableWizard: period grid with existing slot pre-loading, edit-mode title Updated: - CCNodeSnapshotPanel: saves via Supabase storage path + accessToken - BasePanel: nav panel tab wired to CCGraphNavPanel - CCFilesPanelEnhanced: auth context fixes - CCDocumentIntelligence suite: accessToken threading, Supabase storage integration Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Box, CircularProgress, MenuItem, Select, Typography } from '@mui/material';
|
||||
import { SelectChangeEvent } from '@mui/material/Select';
|
||||
import { supabase } from '../../../supabaseClient';
|
||||
import { useAuth } from '../../../contexts/AuthContext';
|
||||
|
||||
type Manifest = {
|
||||
bucket: string;
|
||||
@@ -41,6 +41,7 @@ export const CCBundleViewer: React.FC<{
|
||||
currentPage?: number;
|
||||
combinedBundles?: Array<{ id: string }>;
|
||||
}> = ({ fileId, bundleId, currentPage, combinedBundles }) => {
|
||||
const { accessToken } = useAuth();
|
||||
const [manifest, setManifest] = useState<Manifest | null>(null);
|
||||
const [combinedManifests, setCombinedManifests] = useState<Manifest[] | null>(null);
|
||||
const [mode, setMode] = useState<Mode>('markdown_full');
|
||||
@@ -53,9 +54,9 @@ export const CCBundleViewer: React.FC<{
|
||||
const API_BASE_FALLBACK = 'http://127.0.0.1:8080';
|
||||
|
||||
const proxyUrl = useCallback(async (bucket: string, relPath: string) => {
|
||||
const token = (await supabase.auth.getSession()).data.session?.access_token || '';
|
||||
const token = accessToken || '';
|
||||
return `${API_BASE}/database/files/proxy_signed?bucket=${encodeURIComponent(bucket)}&path=${encodeURIComponent(relPath)}&token=${encodeURIComponent(token)}`;
|
||||
}, [API_BASE]);
|
||||
}, [API_BASE, accessToken]);
|
||||
|
||||
const replaceAllSafe = useCallback((s: string, search: string, replacement: string) => {
|
||||
if (!s || typeof s !== 'string') return s || '';
|
||||
@@ -222,7 +223,7 @@ export const CCBundleViewer: React.FC<{
|
||||
setManifest(null);
|
||||
if (combinedBundles && combinedBundles.length > 0) {
|
||||
try {
|
||||
const token = (await supabase.auth.getSession()).data.session?.access_token || '';
|
||||
const token = accessToken || '';
|
||||
const ms: Manifest[] = [];
|
||||
for (const b of combinedBundles) {
|
||||
const res = await fetch(`${API_BASE}/database/files/${encodeURIComponent(fileId)}/artefacts/${encodeURIComponent(b.id)}/manifest`, { headers: { Authorization: `Bearer ${token}` } });
|
||||
@@ -239,7 +240,7 @@ export const CCBundleViewer: React.FC<{
|
||||
}
|
||||
if (!bundleId) return;
|
||||
try {
|
||||
const token = (await supabase.auth.getSession()).data.session?.access_token || '';
|
||||
const token = accessToken || '';
|
||||
const res = await fetch(`${API_BASE}/database/files/${encodeURIComponent(fileId)}/artefacts/${encodeURIComponent(bundleId)}/manifest`, { headers: { Authorization: `Bearer ${token}` } });
|
||||
if (!res.ok) throw new Error(await res.text());
|
||||
const rawManifest: Manifest = await res.json();
|
||||
@@ -266,7 +267,7 @@ export const CCBundleViewer: React.FC<{
|
||||
let textParts: string[] = [];
|
||||
let jsonParts: string[] = [];
|
||||
for (const m of combinedManifests) {
|
||||
const token = (await supabase.auth.getSession()).data.session?.access_token || '';
|
||||
const token = accessToken || '';
|
||||
let rel: string | undefined;
|
||||
if (mode === 'markdown_full') rel = m.markdown_full || m.html_full || m.text_full || m.json_full;
|
||||
else if (mode === 'html_full') rel = m.html_full || m.markdown_full || m.text_full || m.json_full;
|
||||
@@ -348,7 +349,7 @@ export const CCBundleViewer: React.FC<{
|
||||
relPath = rec?.path;
|
||||
}
|
||||
if (!relPath) { setContent(''); setLoading(false); return; }
|
||||
const token = (await supabase.auth.getSession()).data.session?.access_token || '';
|
||||
const token = accessToken || '';
|
||||
const url = await proxyUrl(bucket, relPath);
|
||||
let res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
|
||||
if (!res.ok) throw new Error(await res.text());
|
||||
|
||||
Reference in New Issue
Block a user