VocRT / frontend /src /redux /slices /chatsSlice.ts
Anurag
version-2 initial version
5306da4
import api from "@/api/apiClient";
import apiClient from "@/api/apiClient";
import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit";
export interface Chat {
id: string;
title: string;
createdAt: string;
lastUpdatedAt: string;
chat: [];
context: [];
prompt?: "";
}
interface ChatsState {
chats: Chat[];
activeChat: string | null;
searchQuery: string;
creatingChat: boolean;
error: string;
chatsLoading: boolean;
}
const initialState: ChatsState = {
chats: [],
activeChat: null,
searchQuery: "",
creatingChat: false,
error: null,
chatsLoading: false,
};
interface createChatResponseType {
success: boolean;
sessionId: string;
message: string;
}
interface getChatResponseType {
success: boolean;
chats: [];
message: string;
}
export const createChat = createAsyncThunk(
"chat/create-chat",
async (sessionId: string, { rejectWithValue }) => {
try {
const response: createChatResponseType = await api.post(
"/chat/create-chat",
{
sessionId,
}
);
if (!response.success) {
rejectWithValue("Error creating new chat.");
}
return response?.sessionId;
} catch (error: any) {
return rejectWithValue(
error.response?.data?.message || "creating chat failed"
);
}
}
);
export const renameChat = createAsyncThunk(
"chat/rename-chat",
async (data: { sessionId: string; title: string }, { rejectWithValue }) => {
try {
const response: createChatResponseType = await api.post(
"/chat/rename-chat",
data
);
if (!response.success) {
rejectWithValue("Error creating new chat.");
}
// @ts-expect-error any
return response?.rename;
} catch (error: any) {
return rejectWithValue(
error.response?.data?.message || "creating chat failed"
);
}
}
);
export const getChats = createAsyncThunk(
"chat/get-chats",
async (_, { rejectWithValue }) => {
try {
const response: getChatResponseType = await api.post("/chat/get-chats", {
sessionId: "adakjn",
});
if (!response.success) {
rejectWithValue("Error getting chats.");
}
return response?.chats;
} catch (error: any) {
return rejectWithValue(
error.response?.data?.message || "getting chats failed"
);
}
}
);
export const chatsSlice = createSlice({
name: "chats",
initialState,
reducers: {
setActiveChat: (state, action: PayloadAction<string>) => {
state.activeChat = action.payload;
},
deleteChat: (state, action: PayloadAction<string>) => {
const deletedIndex = state.chats.findIndex(
(chat) => chat.id === action.payload
);
state.chats = state.chats.filter((chat) => chat.id !== action.payload);
if (state.activeChat === action.payload) {
if (state.chats.length > 0) {
const newIndex = Math.min(deletedIndex, state.chats.length - 1);
state.activeChat = state.chats[newIndex].id;
} else {
state.activeChat = null;
}
}
},
setSearchQuery: (state, action: PayloadAction<string>) => {
state.searchQuery = action.payload;
},
updateChatTimestamp: (state, action: PayloadAction<string>) => {
const chat = state.chats.find((c) => c.id === action.payload);
if (chat) {
chat.lastUpdatedAt = new Date().toISOString();
}
},
},
extraReducers: (builder) => {
builder
.addCase(createChat.pending, (state) => {
state.creatingChat = true;
state.error = null;
})
.addCase(createChat.fulfilled, (state, action: PayloadAction<string>) => {
const newChatId = action.payload;
const newChat = {
id: newChatId,
title: "New Chat",
createdAt: new Date().toISOString(),
lastUpdatedAt: new Date().toISOString(),
};
state.chats.unshift(newChat);
state.activeChat = newChatId;
})
.addCase(createChat.rejected, (state, action) => {
state.creatingChat = false;
state.error = action.payload as string;
})
.addCase(getChats.pending, (state) => {
state.chatsLoading = true;
state.error = null;
})
.addCase(getChats.fulfilled, (state, action: PayloadAction<any>) => {
state.chats = action.payload;
})
.addCase(getChats.rejected, (state, action) => {
state.chatsLoading = false;
state.error = action.payload as string;
})
.addCase(renameChat.pending, (state) => {
state.chatsLoading = true;
state.error = null;
})
.addCase(renameChat.fulfilled, (state, action: PayloadAction<any>) => {
const chat = state.chats.find((c) => c.id === action.payload.id);
if (chat) {
chat.title = action.payload.title;
chat.lastUpdatedAt = new Date().toISOString();
}
})
.addCase(renameChat.rejected, (state, action) => {
state.chatsLoading = false;
state.error = action.payload as string;
});
},
});
export const {
setActiveChat,
deleteChat,
setSearchQuery,
updateChatTimestamp,
} = chatsSlice.actions;
export default chatsSlice.reducer;