Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Es4 discovery library - Revamp #182

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .firebaserc
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
}
}
},
"etags": {}
"etags": {},
"dataconnectEmulatorConfig": {}
}
9 changes: 9 additions & 0 deletions frontend/assets/svg/ReadyPlayerMeAvatar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions frontend/assets/svg/StarGroupIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions frontend/assets/svg/Union.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions frontend/assets/svg/UnionPurple.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/assets/svg/add-block2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions frontend/constants/personas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const categorizePersonas = [
{
title: 'Math Tutor',
description:
'From now on, I want you to act as a math tutor. I will be asking you questions related to various mathematical concepts, including algebra, geometry, calculus, and statistics. Please provide detailed explanations, step-by-step solutions, and relevant examples for each topic we discuss.',
},
{
title: 'Biology Tutor',
description:
'Please act as my biology tutor. I will ask you about topics such as cell biology, genetics, evolution, ecology, and human anatomy. Provide comprehensive explanations, diagrams, and examples to help me understand these biological concepts.',
},
{
title: 'Programming Tutor',
description:
'I want you to be my programming tutor. I will ask you about various programming languages, coding concepts, algorithms, and debugging techniques. Provide clear explanations, code examples, and step-by-step guidance for writing and understanding code.',
},
{
title: 'Music Tutor',
description:
'Act as a music tutor for our conversation. I will ask you about music theory, instruments, composition, and performance techniques. Provide detailed explanations, sheet music examples, and exercises to help me understand and improve my musical abilities.',
},
];

export default categorizePersonas;
6 changes: 6 additions & 0 deletions frontend/constants/routes_ids.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const ROUTES_IDS = {
HOME: 'home',
DISCOVERY: 'discovery',
CHAT: 'chat',
};
export default ROUTES_IDS;
27 changes: 23 additions & 4 deletions frontend/layouts/MainAppLayout/ MainAppLayout.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';

import { Grid, useMediaQuery } from '@mui/material';
import Head from 'next/head';

import { useRouter } from 'next/router';
import { useDispatch, useSelector } from 'react-redux';

import AppDisabled from '@/components/AppDisabled';
import Loader from '@/components/Loader';

import DiscoveryLibraryWindow from '@/templates/Chat/DiscoveryLibraryWindow';

import ROUTES from '@/constants/routes';

import NavBar from './NavBar';

import styles from './styles';

import { setLoading } from '@/redux/slices/authSlice';
Expand All @@ -28,7 +34,8 @@ const MainAppLayout = (props) => {

const auth = useSelector((state) => state.auth);
const user = useSelector((state) => state.user);

const [isDiscoveryOpen, setDiscoveryOpen] = useState(false);
const router = useRouter();
const isTabletScreen = useMediaQuery((theme) =>
theme.breakpoints.down('laptop')
);
Expand All @@ -49,12 +56,24 @@ const MainAppLayout = (props) => {
);
};

const handleDiscoveryToggle = () => {
setDiscoveryOpen((prev) => !prev);
};

const isDiscoveryPage = router.pathname === ROUTES.DISCOVERY;

const renderApp = () => {
return (
<>
<NavBar />
<NavBar
toggleDiscovery={handleDiscoveryToggle}
isDiscoveryOpen={isDiscoveryOpen}
/>
<Grid {...styles.contentGridProps(extraContentProps, isToolPage)}>
{children}
{children}{' '}
{isDiscoveryPage && (
<DiscoveryLibraryWindow isDiscoveryOpen={isDiscoveryOpen} />
)}
</Grid>
</>
);
Expand Down
37 changes: 23 additions & 14 deletions frontend/layouts/MainAppLayout/NavBar/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { Avatar, Button, Grid, Typography } from '@mui/material';
import { useState } from 'react';

import { Avatar, Button, Grid, Slide, Typography } from '@mui/material';
import { signOut } from 'firebase/auth';
import { useRouter } from 'next/router';

import { useSelector } from 'react-redux';

import DiscoveryLibrary from '@/templates/Chat/DiscoveryLibrary';

import ChatIcon from '@/assets/svg/ChatIcon.svg';
// import DiscoveryIcon from '@/assets/svg/DiscoveryIcon.svg';
import DiscoveryIcon from '@/assets/svg/DiscoveryIcon.svg';
import HomeIcon from '@/assets/svg/HomeMenuIcon.svg';
import LogoutIcon from '@/assets/svg/LogoutIcon.svg';

import ROUTES from '@/constants/routes';
import ROUTES_IDS from '@/constants/routes_ids';

import styles from './styles';

Expand All @@ -22,19 +27,19 @@ const PAGES = [
name: 'Home',
link: ROUTES.HOME,
icon: <HomeIcon />,
id: 'home',
id: ROUTES_IDS.HOME,
},
/* {
{
name: 'Discovery',
link: ROUTES.DISCOVERY,
icon: <DiscoveryIcon />,
id: 'discovery',
}, */
id: ROUTES_IDS.DISCOVERY,
},
{
name: 'Chat',
link: ROUTES.CHAT,
icon: <ChatIcon />,
id: 'chat',
id: ROUTES_IDS.CHAT,
},
];

Expand All @@ -46,7 +51,8 @@ const PAGES = [
* @component
* @returns {JSX.Element} The navigation bar component.
*/
const NavBar = () => {
const NavBar = (props) => {
const { isDiscoveryOpen, toggleDiscovery } = props;
const router = useRouter();

const user = useSelector((state) => state.user.data);
Expand Down Expand Up @@ -122,13 +128,13 @@ const NavBar = () => {
chatRegex.test(pathname) || discoveryRegex.test(pathname),
].includes(true);

if (id === 'home')
if (id === ROUTES_IDS.HOME)
return isNotHomePage ? false : homeRegex.test(pathname);

// TODO: Once Discovery Feature is ready, uncomment below statement.
// if (id === 'discovery') return discoveryRegex.test(pathname);
if (id === ROUTES_IDS.DISCOVERY) return discoveryRegex.test(pathname);

if (id === 'chat') return chatRegex.test(pathname);
if (id === ROUTES_IDS.CHAT) return chatRegex.test(pathname);

return false;
};
Expand All @@ -139,8 +145,12 @@ const NavBar = () => {
* @param {string} link - The route to navigate to.
* @returns {void}
*/
const handleRoute = (link) => {
router.push(link);
const handleRoute = (link, id) => {
if (id === ROUTES_IDS.DISCOVERY && router.pathname === ROUTES.DISCOVERY) {
toggleDiscovery();
} else {
router.push(link);
}
};

return (
Expand All @@ -158,7 +168,6 @@ const NavBar = () => {
</Grid>
);
};

return (
<Grid {...styles.mainGrid}>
{renderLogo()}
Expand Down
12 changes: 12 additions & 0 deletions frontend/pages/discovery/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import MainAppLayout from '@/layouts/MainAppLayout';
import DiscoveryLibrary from '@/templates/Chat/DiscoveryLibrary';

const MarvelDiscovery = () => {
return <DiscoveryLibrary />;
};

MarvelDiscovery.getLayout = function getLayout(page) {
return <MainAppLayout>{page}</MainAppLayout>;
};

export default MarvelDiscovery;
31 changes: 31 additions & 0 deletions frontend/redux/slices/personaSlice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { createSlice } from '@reduxjs/toolkit';

import fetchPersonas from '../thunks/fetchPersona';

const personasSlice = createSlice({
name: 'personas',
initialState: {
data: [],
loading: false,
error: null,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchPersonas.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(fetchPersonas.fulfilled, (state, action) => {
state.loading = false;
state.data = action.payload;
})
.addCase(fetchPersonas.rejected, (state, action) => {
state.loading = false;
state.error = action.error.message;
});
},
});

export const { setPersonas } = personasSlice.actions;
export default personasSlice.reducer;
2 changes: 2 additions & 0 deletions frontend/redux/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { connectFunctionsEmulator, getFunctions } from 'firebase/functions';
import authReducer from './slices/authSlice';
import chatReducer from './slices/chatSlice';
import historyReducer from './slices/historySlice';
import personasReducer from './slices/personaSlice';
import toolsReducer from './slices/toolsSlice';
import userReducer from './slices/userSlice';

Expand All @@ -33,6 +34,7 @@ const store = configureStore({
tools: toolsReducer,
chat: chatReducer,
history: historyReducer,
personas: personasReducer,
},
});

Expand Down
28 changes: 28 additions & 0 deletions frontend/redux/thunks/addPersonas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { createAsyncThunk } from '@reduxjs/toolkit';

import { addDoc, collection, getDocs, getFirestore } from 'firebase/firestore';

import categorizePersonas from '@/constants/personas';

const addPersonas = createAsyncThunk('personas/add', async () => {
try {
const db = getFirestore();
const personasRef = collection(db, 'personas');
const querySnapshot = await getDocs(personasRef);
if (querySnapshot.empty) {
const addOperations = categorizePersonas.forEach(async (persona) => {
try {
const docRef = await addDoc(personasRef, persona);
return docRef;
} catch (err) {
throw new Error('Error adding persona:', err);
}
});
await Promise.all(addOperations);
}
} catch (err) {
throw new Error(err);
}
});

export default addPersonas;
22 changes: 22 additions & 0 deletions frontend/redux/thunks/fetchPersona.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createAsyncThunk } from '@reduxjs/toolkit';
import { collection, getDocs, getFirestore } from 'firebase/firestore';

const fetchPersonas = createAsyncThunk('personas/fetch', async () => {
try {
const db = getFirestore();
const personasRef = collection(db, 'personas');
const querySnapshot = await getDocs(personasRef);
if (querySnapshot.empty) {
throw new Error('No personas found!');
}
const personas = querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
return personas;
} catch (err) {
throw new Error(err);
}
});

export default fetchPersonas;
4 changes: 2 additions & 2 deletions frontend/templates/Chat/Chat.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useRef } from 'react';
import { useEffect, useRef, useState } from 'react';

import {
ArrowDownwardOutlined,
Expand Down Expand Up @@ -27,6 +27,7 @@ import { MESSAGE_ROLE, MESSAGE_TYPES } from '@/constants/bots';
import ChatHistoryWindow from './ChatHistoryWindow';
import ChatSpinner from './ChatSpinner';
import DefaultPrompt from './DefaultPrompt';
import DiscoveryLibraryWindow from './DiscoveryLibraryWindow';
import Message from './Message';
import QuickActions from './QuickActions';
import styles from './styles';
Expand Down Expand Up @@ -103,7 +104,6 @@ const ChatInterface = () => {
type: 'chat',
message,
};

// Send a chat session
const { status, data } = await createChatSession(chatPayload, dispatch);

Expand Down
Loading