import { useState, useEffect } from "react";
import { useParams, useNavigate } from "react-router";
import { Masthead } from "../components/Masthead";
import { OrderList } from "../components/orders/OrderList";
import { OrderDetail } from "../components/orders/OrderDetail";
import { useOrders, useOrder } from "../hooks/useOrders";
import { useDirectives } from "../hooks/useDirectives";
import { useDogs } from "../hooks/useDogs";
import { useAuth } from "../contexts/AuthContext";
import type { OrderStatus, OrderType, OrderPriority } from "../lib/api";
export default function OrdersPage() {
const { isAuthenticated, isAuthConfigured, isLoading: authLoading } = useAuth();
const navigate = useNavigate();
const { id: selectedId } = useParams<{ id: string }>();
const [statusFilter, setStatusFilter] = useState<OrderStatus | undefined>(undefined);
const [typeFilter, setTypeFilter] = useState<OrderType | undefined>(undefined);
const { orders, loading: listLoading, create, refresh: refreshList } = useOrders(statusFilter, typeFilter);
const { order, refresh: refreshDetail, update, remove: removeOrder, linkDirective, convertToStep } = useOrder(selectedId);
const { directives } = useDirectives();
const { dogs } = useDogs(order?.directiveId ?? undefined);
const [showCreate, setShowCreate] = useState(false);
const [newTitle, setNewTitle] = useState("");
const [newDesc, setNewDesc] = useState("");
const [newPriority, setNewPriority] = useState<OrderPriority>("medium");
const [newType, setNewType] = useState<OrderType>("feature");
const [newDirectiveId, setNewDirectiveId] = useState<string>("");
useEffect(() => {
if (!authLoading && isAuthConfigured && !isAuthenticated) {
navigate("/login");
}
}, [authLoading, isAuthConfigured, isAuthenticated, navigate]);
if (authLoading) {
return (
<div className="relative z-10 h-screen flex flex-col overflow-hidden 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>
);
}
const handleCreate = async () => {
if (!newTitle.trim() || !newDirectiveId) return;
try {
const o = await create({
title: newTitle.trim(),
description: newDesc.trim() || undefined,
priority: newPriority,
orderType: newType,
directiveId: newDirectiveId,
});
setShowCreate(false);
setNewTitle("");
setNewDesc("");
setNewPriority("medium");
setNewType("feature");
setNewDirectiveId("");
navigate(`/orders/${o.id}`);
} catch (e) {
console.error("Failed to create order:", e);
}
};
const handleDelete = async () => {
if (!selectedId) return;
if (!window.confirm("Delete this order?")) return;
try {
await removeOrder();
await refreshList();
navigate("/orders");
} catch (e) {
console.error("Failed to delete:", e);
}
};
const handleUpdate = async (req: Parameters<typeof update>[0]) => {
await update(req);
await refreshList();
};
const handleLinkDirective = async (directiveId: string) => {
await linkDirective(directiveId);
await refreshList();
};
const handleConvertToStep = async () => {
await convertToStep();
await refreshList();
};
const priorityOptions: { value: OrderPriority; label: string }[] = [
{ value: "critical", label: "Critical" },
{ value: "high", label: "High" },
{ value: "medium", label: "Medium" },
{ value: "low", label: "Low" },
{ value: "none", label: "None" },
];
const typeOptions: { value: OrderType; label: string }[] = [
{ value: "feature", label: "Feature" },
{ value: "bug", label: "Bug" },
{ value: "spike", label: "Spike" },
{ value: "chore", label: "Chore" },
{ value: "improvement", label: "Improvement" },
];
return (
<div className="relative z-10 h-screen flex flex-col overflow-hidden bg-[#0a1628]">
<Masthead showNav />
<main className="flex-1 flex overflow-hidden min-h-0">
{/* Left: List */}
<div className="w-[280px] shrink-0 border-r border-dashed border-[rgba(117,170,252,0.2)] overflow-hidden flex flex-col min-h-0">
<OrderList
orders={orders}
selectedId={selectedId ?? null}
onSelect={(id) => navigate(`/orders/${id}`)}
onCreate={() => setShowCreate(true)}
statusFilter={statusFilter}
onStatusFilter={setStatusFilter}
typeFilter={typeFilter}
onTypeFilter={setTypeFilter}
/>
</div>
{/* Right: Detail or Create */}
<div className="flex-1 overflow-hidden min-h-0">
{showCreate ? (
<div className="p-4 max-w-lg h-full overflow-y-auto">
<h2 className="text-[14px] font-mono text-white font-medium mb-4">
New Order
</h2>
<div className="flex flex-col gap-3">
<div>
<label className="text-[10px] font-mono text-[#9bc3ff] uppercase tracking-wide block mb-1">
Title
</label>
<input
value={newTitle}
onChange={(e) => setNewTitle(e.target.value)}
placeholder="Order title..."
className="w-full bg-[#0a1628] border border-[rgba(117,170,252,0.2)] rounded px-2 py-1.5 text-[12px] font-mono text-white"
onKeyDown={(e) => {
if (e.key === "Enter" && newTitle.trim()) handleCreate();
}}
/>
</div>
<div>
<label className="text-[10px] font-mono text-[#9bc3ff] uppercase tracking-wide block mb-1">
Description (optional)
</label>
<textarea
value={newDesc}
onChange={(e) => setNewDesc(e.target.value)}
placeholder="Describe the order..."
rows={4}
className="w-full bg-[#0a1628] border border-[rgba(117,170,252,0.2)] rounded px-2 py-1.5 text-[12px] font-mono text-white resize-y"
/>
</div>
<div>
<label className="text-[10px] font-mono text-[#9bc3ff] uppercase tracking-wide block mb-1">
Directive *
</label>
<select
value={newDirectiveId}
onChange={(e) => setNewDirectiveId(e.target.value)}
className="w-full bg-[#0a1628] border border-[rgba(117,170,252,0.2)] rounded px-2 py-1.5 text-[12px] font-mono text-white"
>
<option value="">Select directive...</option>
{directives.map((d) => (
<option key={d.id} value={d.id}>{d.title}</option>
))}
</select>
</div>
<div className="flex gap-4">
<div className="flex-1">
<label className="text-[10px] font-mono text-[#9bc3ff] uppercase tracking-wide block mb-1">
Priority
</label>
<select
value={newPriority}
onChange={(e) => setNewPriority(e.target.value as OrderPriority)}
className="w-full bg-[#0a1628] border border-[rgba(117,170,252,0.2)] rounded px-2 py-1.5 text-[12px] font-mono text-white"
>
{priorityOptions.map((p) => (
<option key={p.value} value={p.value}>{p.label}</option>
))}
</select>
</div>
<div className="flex-1">
<label className="text-[10px] font-mono text-[#9bc3ff] uppercase tracking-wide block mb-1">
Type
</label>
<select
value={newType}
onChange={(e) => setNewType(e.target.value as OrderType)}
className="w-full bg-[#0a1628] border border-[rgba(117,170,252,0.2)] rounded px-2 py-1.5 text-[12px] font-mono text-white"
>
{typeOptions.map((t) => (
<option key={t.value} value={t.value}>{t.label}</option>
))}
</select>
</div>
</div>
<div className="flex gap-2">
<button
type="button"
onClick={handleCreate}
disabled={!newTitle.trim() || !newDirectiveId}
className="text-[11px] font-mono text-emerald-400 hover:text-emerald-300 border border-emerald-800 rounded px-3 py-1 disabled:opacity-50"
>
Create
</button>
<button
type="button"
onClick={() => setShowCreate(false)}
className="text-[11px] font-mono text-[#7788aa] hover:text-white border border-[#2a3a5a] rounded px-3 py-1"
>
Cancel
</button>
</div>
</div>
</div>
) : selectedId && order ? (
<OrderDetail
order={order}
directives={directives}
dogs={dogs}
onUpdate={handleUpdate}
onDelete={handleDelete}
onLinkDirective={handleLinkDirective}
onConvertToStep={handleConvertToStep}
onRefresh={refreshDetail}
/>
) : (
<div className="flex-1 flex items-center justify-center h-full">
<p className="text-[#556677] font-mono text-[12px]">
{listLoading
? "Loading..."
: "Select an order or create a new one"}
</p>
</div>
)}
</div>
</main>
</div>
);
}