Files
TasGrid/src/App.tsx
T
tcardoza a0c67e745d
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m8s
added UPDATED indicators and task collapsing
2026-03-20 16:27:38 -05:00

155 lines
7.8 KiB
TypeScript

import { type Component, createSignal, onMount, onCleanup, createMemo, lazy, Suspense, Show } from 'solid-js';
import { Layout } from './components/Layout';
import { EmbedLayout } from './components/EmbedLayout';
import { EmbedAuthWrapper } from './components/EmbedAuthWrapper';
import { CriticalView } from './views/CriticalView';
import { AuthCallback } from './components/Auth';
import { pb } from './lib/pocketbase';
import { initStore } from './store';
// const CriticalView = lazy(() => import('./views/CriticalView').then(m => ({ default: m.CriticalView })));
const UrgencyView = lazy(() => import('./views/UrgencyView').then(m => ({ default: m.UrgencyView })));
const PriorityView = lazy(() => import('./views/PriorityView').then(m => ({ default: m.PriorityView })));
const MatrixView = lazy(() => import('./views/MatrixView').then(m => ({ default: m.MatrixView })));
const SettingsView = lazy(() => import('./views/SettingsView').then(m => ({ default: m.SettingsView })));
const SnowballView = lazy(() => import('./views/SnowballView').then(m => ({ default: m.SnowballView })));
const DigInView = lazy(() => import('./views/DigInView').then(m => ({ default: m.DigInView })));
const ProgressView = lazy(() => import('./views/ProgressView').then(m => ({ default: m.ProgressView })));
const HelpView = lazy(() => import('./views/HelpView').then(m => ({ default: m.HelpView })));
const NotepadView = lazy(() => import('./views/NotepadView').then(m => ({ default: m.NotepadView })));
const QuickEntryForm = lazy(() => import('./components/QuickEntryForm').then(m => ({ default: m.QuickEntryForm })));
const App: Component = () => {
// Basic routing state
const [currentView, setCurrentView] = createSignal("critical");
const [isAuthenticated, setIsAuthenticated] = createSignal(pb.authStore.isValid);
const [location, setLocation] = createSignal(window.location.href);
onMount(() => {
const handleLocChange = () => setLocation(window.location.href);
window.addEventListener('popstate', handleLocChange);
window.addEventListener('hashchange', handleLocChange);
let isFirstRun = true;
const removeListener = pb.authStore.onChange((token) => {
const wasAuthenticated = isAuthenticated();
setIsAuthenticated(!!token);
if (token && (isFirstRun || !wasAuthenticated)) {
initStore();
}
isFirstRun = false;
}, true);
onCleanup(() => {
removeListener();
window.removeEventListener('popstate', handleLocChange);
window.removeEventListener('hashchange', handleLocChange);
});
// Background preload of other views when idle
const idleCallback = (window as any).requestIdleCallback || ((cb: any) => setTimeout(cb, 1000));
idleCallback(() => {
// CriticalView is now static
import('./views/UrgencyView');
import('./views/PriorityView');
import('./views/MatrixView');
import('./views/SettingsView');
import('./views/SnowballView');
import('./views/DigInView');
import('./views/ProgressView');
import('./views/HelpView');
// Remove splash screen after high priority work is done
const splash = document.getElementById('splash');
if (splash) {
splash.style.opacity = '0';
setTimeout(() => splash.remove(), 500);
}
});
});
// Determine if we are in an embed route (check both path and hash for compatibility)
const isEmbed = () => {
const loc = location(); // Reactive dependency
const url = new URL(loc);
const path = url.pathname;
const hash = url.hash;
const res = path.startsWith('/embed/') || hash.startsWith('#/embed/');
console.log('[DEBUG] isEmbed check:', { res, path, hash, href: loc });
return res;
};
const getEmbedView = () => {
const loc = location(); // Reactive dependency
const url = new URL(loc);
const fullPath = url.pathname + url.hash;
let view = null;
if (fullPath.includes('/notes')) view = 'embed_notes';
else if (fullPath.includes('/quick-add')) view = 'embed_quick_add';
console.log('[DEBUG] getEmbedView detected:', view, 'Full URL context:', fullPath);
return view;
};
return (
<Show
when={isEmbed()}
fallback={
<Show when={isAuthenticated()} fallback={<AuthCallback onSuccess={() => { }} />}>
<Layout currentView={currentView()} setView={setCurrentView}>
<Suspense fallback={<div class="flex items-center justify-center h-full"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div></div>}>
<Show when={currentView() === "critical"}><CriticalView /></Show>
<Show when={currentView() === "urgency"}><UrgencyView /></Show>
<Show when={currentView() === "priority"}><PriorityView /></Show>
<Show when={currentView() === "matrix"}><MatrixView /></Show>
<Show when={currentView() === "snowball"}><SnowballView /></Show>
<Show when={currentView() === "dig_in"}><DigInView /></Show>
<Show when={currentView() === "progress"}><ProgressView /></Show>
<Show when={currentView() === "settings"}><SettingsView setView={setCurrentView} /></Show>
<Show when={currentView() === "help"}><HelpView onBack={() => setCurrentView("settings")} /></Show>
</Suspense>
</Layout>
</Show>
}
>
{(() => {
const isPublicNote = () => {
const view = getEmbedView();
const urlObj = new URL(location());
const noteId = new URLSearchParams(urlObj.search).get('noteId') ||
(urlObj.hash.includes('?') ? new URLSearchParams(urlObj.hash.substring(urlObj.hash.indexOf('?'))).get('noteId') : null);
return view === 'embed_notes' && !!noteId;
};
return (
<EmbedAuthWrapper skipAuth={isPublicNote()}>
<EmbedLayout>
<Suspense fallback={<div class="flex items-center justify-center h-full"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div></div>}>
<Show when={getEmbedView() === 'embed_notes'}>
{(() => {
const noteIdFromUrl = createMemo(() => {
const urlObj = new URL(location());
let noteId = new URLSearchParams(urlObj.search).get('noteId');
if (!noteId && urlObj.hash.includes('?')) {
const hashQueryString = urlObj.hash.substring(urlObj.hash.indexOf('?'));
noteId = new URLSearchParams(hashQueryString).get('noteId');
}
return noteId;
});
return <NotepadView selectedNoteId={noteIdFromUrl()} setSelectedNoteId={() => { }} hideNavigation={!!noteIdFromUrl()} />;
})()}
</Show>
<Show when={getEmbedView() === 'embed_quick_add'}>
<QuickEntryForm autoFocus={true} />
</Show>
</Suspense>
</EmbedLayout>
</EmbedAuthWrapper>
);
})()}
</Show>
);
};
export default App;