diff --git a/frontend/src/conversation/SharedConversation.tsx b/frontend/src/conversation/SharedConversation.tsx index 9a2d8d16..dea1258f 100644 --- a/frontend/src/conversation/SharedConversation.tsx +++ b/frontend/src/conversation/SharedConversation.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useRef } from 'react'; +import { useEffect, useRef } from 'react'; import { useParams } from 'react-router-dom'; import { useNavigate } from 'react-router-dom'; import { Query } from './conversationModels'; @@ -6,19 +6,30 @@ import { useTranslation } from 'react-i18next'; import ConversationBubble from './ConversationBubble'; import Send from '../assets/send.svg'; import Spinner from '../assets/spinner.svg'; - +import { selectClientAPIKey, setClientApiKey } from './sharedConversationSlice'; +import { setIdentifier, setFetchedData } from './sharedConversationSlice'; +import { useDispatch } from 'react-redux'; +import { + selectDate, + selectTitle, + selectQueries, +} from './sharedConversationSlice'; +import { useSelector } from 'react-redux'; import { Fragment } from 'react'; const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; const SharedConversation = () => { const params = useParams(); const navigate = useNavigate(); const { identifier } = params; //identifier is a uuid, not conversationId - const [queries, setQueries] = useState([]); - const [title, setTitle] = useState(''); - const [date, setDate] = useState(''); - const [apiKey, setAPIKey] = useState(null); + + const queries = useSelector(selectQueries); + const title = useSelector(selectTitle); + const date = useSelector(selectDate); + const apiKey = useSelector(selectClientAPIKey); const inputRef = useRef(null); const { t } = useTranslation(); + const dispatch = useDispatch(); + identifier && dispatch(setIdentifier(identifier)); function formatISODate(isoDateStr: string) { const date = new Date(isoDateStr); @@ -52,19 +63,26 @@ const SharedConversation = () => { return formattedDate; } const fetchQueris = () => { - fetch(`${apiHost}/api/shared_conversation/${identifier}`) - .then((res) => { - if (res.status === 404 || res.status === 400) navigate('/pagenotfound'); - return res.json(); - }) - .then((data) => { - if (data.success) { - setQueries(data.queries); - setTitle(data.title); - setDate(formatISODate(data.timestamp)); - data.api_key && setAPIKey(data.api_key); - } - }); + identifier && + fetch(`${apiHost}/api/shared_conversation/${identifier}`) + .then((res) => { + if (res.status === 404 || res.status === 400) + navigate('/pagenotfound'); + return res.json(); + }) + .then((data) => { + if (data.success) { + dispatch( + setFetchedData({ + queries: data.queries, + title: data.title, + date: data.date, + identifier, + }), + ); + data.api_key && dispatch(setClientApiKey(data.api_key)); + } + }); }; const handlePaste = (e: React.ClipboardEvent) => { e.preventDefault(); @@ -150,7 +168,6 @@ const SharedConversation = () => { onKeyDown={(e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); - //handleQuestionSubmission(); } }} > @@ -163,7 +180,6 @@ const SharedConversation = () => {
diff --git a/frontend/src/conversation/sharedConversationSlice.ts b/frontend/src/conversation/sharedConversationSlice.ts index e69de29b..0e7bd4bd 100644 --- a/frontend/src/conversation/sharedConversationSlice.ts +++ b/frontend/src/conversation/sharedConversationSlice.ts @@ -0,0 +1,66 @@ +import { createSlice } from '@reduxjs/toolkit'; +import type { PayloadAction } from '@reduxjs/toolkit'; +import store from '../store'; +import { Query, Status } from '../conversation/conversationModels'; + +interface SharedConversationsType { + queries: Query[]; + apiKey?: string; + identifier: string | null; + status: Status; + date?: string; + title?: string; +} + +const initialState: SharedConversationsType = { + queries: [], + identifier: null, + status: 'idle', +}; + +export const sharedConversationSlice = createSlice({ + name: 'sharedConversation', + initialState, + reducers: { + setStatus(state, action: PayloadAction) { + state.status = action.payload; + }, + setIdentifier(state, action: PayloadAction) { + state.identifier = action.payload; + }, + setFetchedData( + state, + action: PayloadAction<{ + queries: Query[]; + title: string; + date: string; + identifier: string; + }>, + ) { + const { queries, title, identifier, date } = action.payload; + state.queries = queries; + state.title = title; + state.date = date; + state.identifier = identifier; + }, + setClientApiKey(state, action: PayloadAction) { + state.apiKey = action.payload; + }, + }, +}); + +export const { setStatus, setIdentifier, setFetchedData, setClientApiKey } = + sharedConversationSlice.actions; + +export const selectStatus = (state: RootState) => state.conversation.status; +export const selectClientAPIKey = (state: RootState) => + state.sharedConversation.apiKey; +export const selectQueries = (state: RootState) => + state.sharedConversation.queries; +export const selectTitle = (state: RootState) => state.sharedConversation.title; +export const selectDate = (state: RootState) => state.sharedConversation.date; + +type RootState = ReturnType; + +sharedConversationSlice; +export default sharedConversationSlice.reducer; diff --git a/frontend/src/store.ts b/frontend/src/store.ts index 5b7e7ea1..3d1408b3 100644 --- a/frontend/src/store.ts +++ b/frontend/src/store.ts @@ -1,5 +1,6 @@ import { configureStore } from '@reduxjs/toolkit'; import { conversationSlice } from './conversation/conversationSlice'; +import { sharedConversationSlice } from './conversation/sharedConversationSlice'; import { prefListenerMiddleware, prefSlice, @@ -42,6 +43,7 @@ const store = configureStore({ reducer: { preference: prefSlice.reducer, conversation: conversationSlice.reducer, + sharedConversation: sharedConversationSlice.reducer, }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(prefListenerMiddleware.middleware),