-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(fe): add chat and Q&A management slices with session store (#28)
* feat: add chatting slice and types for chat management * feat: add QA slice and types for question and reply management * feat: add session management slice and store * feat: add reset functionality to chatting and QA slices, and integrate into session slice * feat: update QA slice to use Question and Reply objects for removal and upvoting
- Loading branch information
Showing
10 changed files
with
194 additions
and
0 deletions.
There are no files selected for viewing
21 changes: 21 additions & 0 deletions
21
apps/client/src/features/session/chatting/chatting.slice.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { StateCreator } from 'zustand'; | ||
|
||
import { Chat } from '@/features/session/chatting'; | ||
|
||
export interface ChattingSlice { | ||
chatting: Chat[]; | ||
resetChatting: () => void; | ||
addChatting: (chat: Chat) => void; | ||
} | ||
|
||
export const createChattingSlice: StateCreator< | ||
ChattingSlice, | ||
[], | ||
[], | ||
ChattingSlice | ||
> = (set) => ({ | ||
chatting: [], | ||
resetChatting: () => set({ chatting: [] }), | ||
addChatting: (chat) => | ||
set((state) => ({ chatting: [...state.chatting, chat] })), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export interface Chat { | ||
id: string; | ||
body: string; | ||
user: { | ||
token: string; | ||
nickname: string; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './chatting.type'; | ||
export * from './chatting.slice'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './session.store'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './qa.type'; | ||
export * from './qa.slice'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { StateCreator } from 'zustand/index'; | ||
|
||
import { Question, Reply } from '@/features/session/qa/qa.type'; | ||
|
||
export interface QASlice { | ||
questions: Question[]; | ||
resetQuestions: () => void; | ||
addQuestion: (question: Question) => void; | ||
updateQuestion: (question: Question) => void; | ||
removeQuestion: (question: Question) => void; | ||
upvoteQuestion: (question: Question) => void; | ||
addReply: (reply: Reply) => void; | ||
updateReply: (reply: Reply) => void; | ||
removeReply: (reply: Reply) => void; | ||
upvoteReply: (reply: Reply) => void; | ||
} | ||
|
||
export const createQASlice: StateCreator<QASlice, [], [], QASlice> = (set) => ({ | ||
questions: [], | ||
resetQuestions: () => set({ questions: [] }), | ||
addQuestion: (question) => | ||
set((state) => ({ ...state, questions: [...state.questions, question] })), | ||
updateQuestion: (question) => | ||
set((state) => ({ | ||
...state, | ||
questions: state.questions.map((q) => | ||
q.id === question.id ? question : q, | ||
), | ||
})), | ||
removeQuestion: (question) => | ||
set((state) => ({ | ||
...state, | ||
questions: state.questions.filter((q) => q.id !== question.id), | ||
})), | ||
upvoteQuestion: (question) => | ||
set((state) => ({ | ||
...state, | ||
questions: state.questions.map((q) => | ||
q.id === question.id ? { ...q, upvotes: q.upvotes + 1 } : q, | ||
), | ||
})), | ||
addReply: (reply) => | ||
set((state) => ({ | ||
...state, | ||
questions: state.questions.map((q) => | ||
q.id === reply.questionId | ||
? { ...q, replies: [...q.replies, reply] } | ||
: q, | ||
), | ||
})), | ||
updateReply: (reply) => | ||
set((state) => ({ | ||
...state, | ||
questions: state.questions.map((q) => | ||
q.id === reply.questionId | ||
? { | ||
...q, | ||
replies: q.replies.map((r) => (r.id === reply.id ? reply : r)), | ||
} | ||
: q, | ||
), | ||
})), | ||
removeReply: (reply) => | ||
set((state) => ({ | ||
...state, | ||
questions: state.questions.map((q) => ({ | ||
...q, | ||
replies: q.replies.filter((r) => r.id !== reply.id), | ||
})), | ||
})), | ||
upvoteReply: (reply) => | ||
set((state) => ({ | ||
...state, | ||
questions: state.questions.map((q) => ({ | ||
...q, | ||
replies: q.replies.map((r) => | ||
r.id === reply.id ? { ...r, upvotes: r.upvotes + 1 } : r, | ||
), | ||
})), | ||
})), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Session } from '@/features/session'; | ||
|
||
export interface Question { | ||
id: number; | ||
sessionId: Session['id']; | ||
body: string; | ||
closed: boolean; | ||
pinned: boolean; | ||
upvotes: number; | ||
replies: Reply[]; | ||
user: { | ||
token: string; | ||
nickname: string; | ||
}; | ||
createdAt: string; | ||
} | ||
|
||
export interface Reply { | ||
id: number; | ||
questionId: Question['id']; | ||
body: string; | ||
user: { | ||
token: string; | ||
nickname: string; | ||
}; | ||
upvotes: number; | ||
createdAt: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { StateCreator } from 'zustand/index'; | ||
|
||
import { ChattingSlice } from '@/features/session/chatting'; | ||
import { QASlice } from '@/features/session/qa'; | ||
import { Session } from '@/features/session/session.type'; | ||
|
||
export interface SessionSlice { | ||
session?: Session; | ||
reset: () => void; | ||
setSession: (session: Session) => void; | ||
} | ||
|
||
export const createSessionSlice: StateCreator< | ||
SessionSlice & QASlice & ChattingSlice, | ||
[], | ||
[], | ||
SessionSlice | ||
> = (set, get) => ({ | ||
session: undefined, | ||
reset: () => { | ||
get().resetQuestions(); | ||
get().resetChatting(); | ||
set({ session: undefined }); | ||
}, | ||
setSession: (session) => set({ session }), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { create } from 'zustand'; | ||
|
||
import { | ||
ChattingSlice, | ||
createChattingSlice, | ||
} from '@/features/session/chatting'; | ||
import { createQASlice, QASlice } from '@/features/session/qa'; | ||
import { | ||
createSessionSlice, | ||
SessionSlice, | ||
} from '@/features/session/session.slice'; | ||
|
||
export type SessionStore = SessionSlice & QASlice & ChattingSlice; | ||
|
||
export const useSessionStore = create<SessionStore>()((...a) => ({ | ||
...createQASlice(...a), | ||
...createChattingSlice(...a), | ||
...createSessionSlice(...a), | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export interface Session { | ||
id: string; | ||
title: string; | ||
expiredAt: string; | ||
createdAt: string; | ||
} |