'use client'; import { create } from 'zustand'; import { api } from '@/lib/api'; import type { CommentEntityType } from '@/components/comment/CommentPanel'; export interface CommentRecord { id: string; entityType: CommentEntityType; entityId: string; entityVersionId?: string | null; authorId: string; content: string; mentionedMemberIds?: string[]; createdAt: string; deletedAt?: string | null; } interface CreateCommentInput { actorId: string; entityType: CommentEntityType; entityId: string; entityVersionId?: string | null; productId?: string | null; projectId?: string | null; versionId?: string | null; content: string; mentionMemberIds?: string[]; } interface CommentState { commentsByKey: Record; loadingKeys: string[]; fetchComments: (entityType: CommentEntityType, entityId: string) => Promise; createComment: (input: CreateCommentInput) => Promise; deleteComment: (entityType: CommentEntityType, entityId: string, id: string, actorId: string) => Promise; } export function commentKey(entityType: CommentEntityType, entityId: string) { return `${entityType}:${entityId}`; } export const useCommentStore = create((set, get) => ({ commentsByKey: {}, loadingKeys: [], fetchComments: async (entityType, entityId) => { const key = commentKey(entityType, entityId); set({ loadingKeys: [...get().loadingKeys.filter((item) => item !== key), key] }); const params = new URLSearchParams({ entityType, entityId }); const rows = await api.get(`/comments?${params.toString()}`); set({ commentsByKey: { ...get().commentsByKey, [key]: rows }, loadingKeys: get().loadingKeys.filter((item) => item !== key), }); }, createComment: async (input) => { const row = await api.post('/comments', input); const key = commentKey(input.entityType, input.entityId); set({ commentsByKey: { ...get().commentsByKey, [key]: [...(get().commentsByKey[key] ?? []), row], }, }); }, deleteComment: async (entityType, entityId, id, actorId) => { const row = await api.deleteWithBody(`/comments/${id}`, { actorId }); const key = commentKey(entityType, entityId); set({ commentsByKey: { ...get().commentsByKey, [key]: (get().commentsByKey[key] ?? []).map((item) => item.id === id ? row : item).filter((item) => !item.deletedAt), }, }); }, }));