theo-agent-dashboard

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

topic.ts (1915B)


      1 import { create } from "zustand";
      2 import { api } from "../lib/api";
      3 
      4 export interface Topic {
      5   id: string;
      6   name: string;
      7   color: string;
      8   sort_order: number;
      9   created_at: number;
     10   session_count: number | null;
     11 }
     12 
     13 interface TopicState {
     14   topics: Topic[];
     15   selectedTopicId: string | null;
     16   loading: boolean;
     17   fetchTopics: () => Promise<void>;
     18   createTopic: (name: string, color?: string) => Promise<void>;
     19   updateTopic: (id: string, patch: Partial<Pick<Topic, "name" | "color" | "sort_order">>) => Promise<void>;
     20   deleteTopic: (id: string) => Promise<void>;
     21   selectTopic: (id: string | null) => void;
     22 }
     23 
     24 export const useTopicStore = create<TopicState>((set) => ({
     25   topics: [],
     26   selectedTopicId: null,
     27   loading: false,
     28 
     29   fetchTopics: async () => {
     30     set({ loading: true });
     31     try {
     32       const topics = await api.get<Topic[]>("/topics");
     33       set({ topics });
     34     } catch {
     35       // 401 handled by api helper (redirects to login)
     36     } finally {
     37       set({ loading: false });
     38     }
     39   },
     40 
     41   createTopic: async (name, color) => {
     42     try {
     43       const topic = await api.post<Topic>("/topics", { name, color });
     44       set((s) => ({ topics: [...s.topics, topic] }));
     45     } catch {
     46       // API error — don't add to list
     47     }
     48   },
     49 
     50   updateTopic: async (id, patch) => {
     51     try {
     52       const updated = await api.patch<Topic>(`/topics/${id}`, patch);
     53       set((s) => ({
     54         topics: s.topics.map((t) => (t.id === id ? updated : t)),
     55       }));
     56     } catch {
     57       // API error — don't update local state
     58     }
     59   },
     60 
     61   deleteTopic: async (id) => {
     62     try {
     63       await api.delete(`/topics/${id}`);
     64       set((s) => ({
     65         topics: s.topics.filter((t) => t.id !== id),
     66         selectedTopicId: s.selectedTopicId === id ? null : s.selectedTopicId,
     67       }));
     68     } catch {
     69       // API error — don't remove from list
     70     }
     71   },
     72 
     73   selectTopic: (id) => set({ selectedTopicId: id }),
     74 }));