feat(intake): wizard on the board with a plain-box fallback
This commit is contained in:
parent
58be48a4b0
commit
d5cf51c944
3 changed files with 71 additions and 1 deletions
|
|
@ -6,6 +6,7 @@ import { TopBar } from "@/components/shell/top-bar";
|
|||
import { Board } from "@/components/board/board";
|
||||
import { getSession } from "@/lib/auth/session";
|
||||
import { loadBoard } from "@/lib/data/board";
|
||||
import { aiConfigured } from "@/lib/ai/settings";
|
||||
|
||||
export default async function BoardPage({
|
||||
params,
|
||||
|
|
@ -57,6 +58,10 @@ export default async function BoardPage({
|
|||
projectSlug={projectSlug}
|
||||
columns={board.columns}
|
||||
initialCards={board.cards}
|
||||
// Pass the AI availability through so the client manager's Inbox shows
|
||||
// the wizard when configured, the plain box when not. aiConfigured
|
||||
// returns only whether a key exists — never the key itself.
|
||||
assistantAvailable={await aiConfigured()}
|
||||
/>
|
||||
</AppShell>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import { AddCard } from "@/components/board/add-card";
|
|||
import { BoardColumn } from "@/components/board/board-column";
|
||||
import { CardTile } from "@/components/board/card-tile";
|
||||
import { ClientCardControls } from "@/components/board/client-card-controls";
|
||||
import { RequestFeature } from "@/components/intake/request-feature";
|
||||
import { useRefreshOnFocus } from "@/components/board/use-refresh-on-focus";
|
||||
import { computeDropPosition } from "@/lib/board/move";
|
||||
import type { CardRecord, ColumnRecord, Role } from "@/lib/pb/types";
|
||||
|
|
@ -91,6 +92,7 @@ export function Board({
|
|||
projectSlug,
|
||||
columns,
|
||||
initialCards,
|
||||
assistantAvailable,
|
||||
}: {
|
||||
role: Role;
|
||||
projectId: string;
|
||||
|
|
@ -98,6 +100,8 @@ export function Board({
|
|||
projectSlug: string;
|
||||
columns: ColumnRecord[];
|
||||
initialCards: CardRecord[];
|
||||
/** True when the AI provider is configured — controls the wizard vs plain box. */
|
||||
assistantAvailable: boolean;
|
||||
}) {
|
||||
const [cards, setCards] = useState<CardRecord[]>(initialCards);
|
||||
const [activeId, setActiveId] = useState<string | null>(null);
|
||||
|
|
@ -234,7 +238,7 @@ export function Board({
|
|||
/>
|
||||
))}
|
||||
</SortableContext>
|
||||
{(role === "owner" || column.is_inbox) && (
|
||||
{role === "owner" && (
|
||||
<AddCard
|
||||
role={role}
|
||||
projectId={projectId}
|
||||
|
|
@ -243,6 +247,16 @@ export function Board({
|
|||
projectSlug={projectSlug}
|
||||
/>
|
||||
)}
|
||||
|
||||
{role === "client_manager" && column.is_inbox && (
|
||||
<RequestFeature
|
||||
projectId={projectId}
|
||||
columnId={column.id}
|
||||
clientSlug={clientSlug}
|
||||
projectSlug={projectSlug}
|
||||
assistantAvailable={assistantAvailable}
|
||||
/>
|
||||
)}
|
||||
</Droppable>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
51
src/components/intake/request-feature.tsx
Normal file
51
src/components/intake/request-feature.tsx
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
|
||||
import { IntakeWizard } from "@/components/intake/intake-wizard";
|
||||
import { AddCard } from "@/components/board/add-card";
|
||||
|
||||
/**
|
||||
* The client's way in: the wizard when the assistant is available, the plain
|
||||
* request box from Plan 1c when it is not.
|
||||
*
|
||||
* The fallback is not a nicety. A client must always be able to file a request —
|
||||
* an AI outage cannot be allowed to remove a capability they already had.
|
||||
*/
|
||||
export function RequestFeature({
|
||||
projectId,
|
||||
columnId,
|
||||
clientSlug,
|
||||
projectSlug,
|
||||
assistantAvailable,
|
||||
}: {
|
||||
projectId: string;
|
||||
columnId: string;
|
||||
clientSlug: string;
|
||||
projectSlug: string;
|
||||
assistantAvailable: boolean;
|
||||
}) {
|
||||
// Flips if the interview reports the provider unavailable mid-flow.
|
||||
const [fallback, setFallback] = useState(!assistantAvailable);
|
||||
|
||||
if (fallback) {
|
||||
return (
|
||||
<AddCard
|
||||
role="client_manager"
|
||||
projectId={projectId}
|
||||
columnId={columnId}
|
||||
clientSlug={clientSlug}
|
||||
projectSlug={projectSlug}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<IntakeWizard
|
||||
projectId={projectId}
|
||||
clientSlug={clientSlug}
|
||||
projectSlug={projectSlug}
|
||||
onFallback={() => setFallback(true)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue