import { useState, useCallback, useEffect } from "react";
import { useParams, useNavigate } from "react-router";
import { Masthead } from "../components/Masthead";
import { useDirectives } from "../hooks/useDirectives";
import { useDirectiveDetail } from "../hooks/useDirectiveDetail";
import { useAuth } from "../contexts/AuthContext";
import type {
DirectiveSummary,
CreateDirectiveRequest,
AutonomyLevel,
} from "../lib/api";
import { DirectiveList } from "../components/directives/DirectiveList";
import { DirectiveDetail } from "../components/directives/DirectiveDetail";
import { CreateDirectiveModal } from "../components/directives/CreateDirectiveModal";
export default function DirectivesPage() {
const { isAuthenticated, isAuthConfigured, isLoading: authLoading } = useAuth();
const navigate = useNavigate();
// Redirect to login if not authenticated (when auth is configured)
useEffect(() => {
if (!authLoading && isAuthConfigured && !isAuthenticated) {
navigate("/login");
}
}, [authLoading, isAuthConfigured, isAuthenticated, navigate]);
// Show loading while checking auth
if (authLoading) {
return (
<div className="relative z-10 min-h-screen flex flex-col bg-[#0a1628]">
<Masthead showNav />
<main className="flex-1 flex items-center justify-center">
<p className="text-[#7788aa] font-mono text-sm">Loading...</p>
</main>
</div>
);
}
// Don't render if not authenticated (will redirect)
if (isAuthConfigured && !isAuthenticated) {
return null;
}
return <DirectivesPageContent />;
}
function DirectivesPageContent() {
const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
const {
directives,
loading,
error,
createNewDirective,
archiveExistingDirective,
} = useDirectives();
const {
directive: directiveDetail,
graph: directiveGraph,
loading: detailLoading,
refresh: refreshDetail,
start: handleStart,
pause: handlePause,
resume: handleResume,
stop: handleStop,
} = useDirectiveDetail(id);
const [isCreating, setIsCreating] = useState(false);
const handleSelect = useCallback(
(directiveId: string) => {
navigate(`/directives/${directiveId}`);
},
[navigate]
);
const handleBack = useCallback(() => {
navigate("/directives");
}, [navigate]);
const handleCreate = useCallback(() => {
setIsCreating(true);
}, []);
const handleCreateSubmit = useCallback(
async (goal: string, repositoryUrl: string | undefined, autonomyLevel: AutonomyLevel) => {
const data: CreateDirectiveRequest = {
goal: goal.trim(),
repositoryUrl: repositoryUrl?.trim() || undefined,
autonomyLevel,
};
try {
const result = await createNewDirective(data);
if (result) {
setIsCreating(false);
navigate(`/directives/${result.id}`);
}
} catch (err) {
console.error("Failed to create directive:", err);
}
},
[createNewDirective, navigate]
);
const handleCreateCancel = useCallback(() => {
setIsCreating(false);
}, []);
const handleArchive = useCallback(
async (directive: DirectiveSummary) => {
if (confirm(`Are you sure you want to archive this directive?`)) {
const success = await archiveExistingDirective(directive.id);
if (success && directive.id === id) {
navigate("/directives");
}
}
},
[archiveExistingDirective, id, navigate]
);
return (
<div className="relative z-10 min-h-screen flex flex-col bg-[#0a1628]">
<Masthead showNav />
<main className="flex-1 flex flex-col p-4 pt-2 gap-4 overflow-hidden">
{error && (
<div className="p-3 bg-red-400/10 border border-red-400/30 text-red-400 font-mono text-sm">
{error}
</div>
)}
{/* Create directive modal */}
{isCreating && (
<CreateDirectiveModal
onSubmit={handleCreateSubmit}
onCancel={handleCreateCancel}
/>
)}
<div className="flex-1 grid grid-cols-[350px_1fr] gap-4 min-h-0">
{/* Directive list */}
<DirectiveList
directives={directives}
loading={loading}
onSelect={handleSelect}
onCreate={handleCreate}
selectedId={id}
onArchive={handleArchive}
/>
{/* Directive detail or empty state */}
{directiveDetail ? (
<DirectiveDetail
directive={directiveDetail}
graph={directiveGraph}
loading={detailLoading}
onBack={handleBack}
onRefresh={refreshDetail}
onStart={handleStart}
onPause={handlePause}
onResume={handleResume}
onStop={handleStop}
/>
) : (
<div className="panel h-full flex items-center justify-center">
<div className="text-center">
<p className="font-mono text-sm text-[#555] mb-4">
Select a directive or create a new one
</p>
<button
onClick={handleCreate}
className="px-4 py-2 font-mono text-xs text-[#dbe7ff] bg-[#0f3c78] border border-[#3f6fb3] hover:bg-[#153667] transition-colors uppercase"
>
+ New Directive
</button>
</div>
</div>
)}
</div>
</main>
</div>
);
}