feat(04-02): add CreateThreadModal and uiStore modal state

- Add createThreadModalOpen state to uiStore with open/close actions
- Create CreateThreadModal with name input and category dropdown
- Modal submits via useCreateThread with name + categoryId
- Fix pre-existing formatting in uiStore.ts (spaces to tabs)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-15 16:36:51 +01:00
parent 4a31a16e0e
commit eb79ab671e
2 changed files with 218 additions and 67 deletions

View File

@@ -1,88 +1,96 @@
import { create } from "zustand";
interface UIState {
// Item panel state
panelMode: "closed" | "add" | "edit";
editingItemId: number | null;
confirmDeleteItemId: number | null;
// Item panel state
panelMode: "closed" | "add" | "edit";
editingItemId: number | null;
confirmDeleteItemId: number | null;
openAddPanel: () => void;
openEditPanel: (itemId: number) => void;
closePanel: () => void;
openConfirmDelete: (itemId: number) => void;
closeConfirmDelete: () => void;
openAddPanel: () => void;
openEditPanel: (itemId: number) => void;
closePanel: () => void;
openConfirmDelete: (itemId: number) => void;
closeConfirmDelete: () => void;
// Candidate panel state
candidatePanelMode: "closed" | "add" | "edit";
editingCandidateId: number | null;
confirmDeleteCandidateId: number | null;
// Candidate panel state
candidatePanelMode: "closed" | "add" | "edit";
editingCandidateId: number | null;
confirmDeleteCandidateId: number | null;
openCandidateAddPanel: () => void;
openCandidateEditPanel: (id: number) => void;
closeCandidatePanel: () => void;
openConfirmDeleteCandidate: (id: number) => void;
closeConfirmDeleteCandidate: () => void;
openCandidateAddPanel: () => void;
openCandidateEditPanel: (id: number) => void;
closeCandidatePanel: () => void;
openConfirmDeleteCandidate: (id: number) => void;
closeConfirmDeleteCandidate: () => void;
// Resolution dialog state
resolveThreadId: number | null;
resolveCandidateId: number | null;
// Resolution dialog state
resolveThreadId: number | null;
resolveCandidateId: number | null;
openResolveDialog: (threadId: number, candidateId: number) => void;
closeResolveDialog: () => void;
openResolveDialog: (threadId: number, candidateId: number) => void;
closeResolveDialog: () => void;
// Setup-related UI state
itemPickerOpen: boolean;
openItemPicker: () => void;
closeItemPicker: () => void;
// Setup-related UI state
itemPickerOpen: boolean;
openItemPicker: () => void;
closeItemPicker: () => void;
confirmDeleteSetupId: number | null;
openConfirmDeleteSetup: (id: number) => void;
closeConfirmDeleteSetup: () => void;
confirmDeleteSetupId: number | null;
openConfirmDeleteSetup: (id: number) => void;
closeConfirmDeleteSetup: () => void;
// Create thread modal
createThreadModalOpen: boolean;
openCreateThreadModal: () => void;
closeCreateThreadModal: () => void;
}
export const useUIStore = create<UIState>((set) => ({
// Item panel
panelMode: "closed",
editingItemId: null,
confirmDeleteItemId: null,
// Item panel
panelMode: "closed",
editingItemId: null,
confirmDeleteItemId: null,
openAddPanel: () => set({ panelMode: "add", editingItemId: null }),
openEditPanel: (itemId) => set({ panelMode: "edit", editingItemId: itemId }),
closePanel: () => set({ panelMode: "closed", editingItemId: null }),
openConfirmDelete: (itemId) => set({ confirmDeleteItemId: itemId }),
closeConfirmDelete: () => set({ confirmDeleteItemId: null }),
openAddPanel: () => set({ panelMode: "add", editingItemId: null }),
openEditPanel: (itemId) => set({ panelMode: "edit", editingItemId: itemId }),
closePanel: () => set({ panelMode: "closed", editingItemId: null }),
openConfirmDelete: (itemId) => set({ confirmDeleteItemId: itemId }),
closeConfirmDelete: () => set({ confirmDeleteItemId: null }),
// Candidate panel
candidatePanelMode: "closed",
editingCandidateId: null,
confirmDeleteCandidateId: null,
// Candidate panel
candidatePanelMode: "closed",
editingCandidateId: null,
confirmDeleteCandidateId: null,
openCandidateAddPanel: () =>
set({ candidatePanelMode: "add", editingCandidateId: null }),
openCandidateEditPanel: (id) =>
set({ candidatePanelMode: "edit", editingCandidateId: id }),
closeCandidatePanel: () =>
set({ candidatePanelMode: "closed", editingCandidateId: null }),
openConfirmDeleteCandidate: (id) =>
set({ confirmDeleteCandidateId: id }),
closeConfirmDeleteCandidate: () =>
set({ confirmDeleteCandidateId: null }),
openCandidateAddPanel: () =>
set({ candidatePanelMode: "add", editingCandidateId: null }),
openCandidateEditPanel: (id) =>
set({ candidatePanelMode: "edit", editingCandidateId: id }),
closeCandidatePanel: () =>
set({ candidatePanelMode: "closed", editingCandidateId: null }),
openConfirmDeleteCandidate: (id) => set({ confirmDeleteCandidateId: id }),
closeConfirmDeleteCandidate: () => set({ confirmDeleteCandidateId: null }),
// Resolution dialog
resolveThreadId: null,
resolveCandidateId: null,
// Resolution dialog
resolveThreadId: null,
resolveCandidateId: null,
openResolveDialog: (threadId, candidateId) =>
set({ resolveThreadId: threadId, resolveCandidateId: candidateId }),
closeResolveDialog: () =>
set({ resolveThreadId: null, resolveCandidateId: null }),
openResolveDialog: (threadId, candidateId) =>
set({ resolveThreadId: threadId, resolveCandidateId: candidateId }),
closeResolveDialog: () =>
set({ resolveThreadId: null, resolveCandidateId: null }),
// Setup-related UI state
itemPickerOpen: false,
openItemPicker: () => set({ itemPickerOpen: true }),
closeItemPicker: () => set({ itemPickerOpen: false }),
// Setup-related UI state
itemPickerOpen: false,
openItemPicker: () => set({ itemPickerOpen: true }),
closeItemPicker: () => set({ itemPickerOpen: false }),
confirmDeleteSetupId: null,
openConfirmDeleteSetup: (id) => set({ confirmDeleteSetupId: id }),
closeConfirmDeleteSetup: () => set({ confirmDeleteSetupId: null }),
confirmDeleteSetupId: null,
openConfirmDeleteSetup: (id) => set({ confirmDeleteSetupId: id }),
closeConfirmDeleteSetup: () => set({ confirmDeleteSetupId: null }),
// Create thread modal
createThreadModalOpen: false,
openCreateThreadModal: () => set({ createThreadModalOpen: true }),
closeCreateThreadModal: () => set({ createThreadModalOpen: false }),
}));