From 13c61e1b4ee45480e3e19153852eea811e3f6d39 Mon Sep 17 00:00:00 2001 From: Sudhanshu Vora Date: Tue, 1 Oct 2024 09:13:10 +0200 Subject: [PATCH] Add more apis to fetch agenda and display them --- .../components/AgendaDrawer/AgendaDrawer.tsx | 80 +++++++++ .../MeetingsDrawer/MeetingsDrawer.tsx | 2 +- frontend/src/container/Meeting/Meeting.tsx | 154 +++++++++--------- frontend/src/index.tsx | 9 +- frontend/src/utils/meetingAgenda.tsx | 30 ++++ frontend/src/utils/userProvider.jsx | 21 --- frontend/src/utils/userProvider.tsx | 30 ++++ 7 files changed, 227 insertions(+), 99 deletions(-) create mode 100644 frontend/src/components/AgendaDrawer/AgendaDrawer.tsx create mode 100644 frontend/src/utils/meetingAgenda.tsx delete mode 100644 frontend/src/utils/userProvider.jsx create mode 100644 frontend/src/utils/userProvider.tsx diff --git a/frontend/src/components/AgendaDrawer/AgendaDrawer.tsx b/frontend/src/components/AgendaDrawer/AgendaDrawer.tsx new file mode 100644 index 0000000..6fc0020 --- /dev/null +++ b/frontend/src/components/AgendaDrawer/AgendaDrawer.tsx @@ -0,0 +1,80 @@ +import React, { useEffect, useState } from "react"; +import { + Drawer, + IconButton, + List, + ListItem, + ListItemText, + Typography, + useMediaQuery, + useTheme, +} from "@mui/material"; +import FormatListBulletedIcon from "@mui/icons-material/FormatListBulleted"; +import { useAgenda } from "../../utils/meetingAgenda"; + + +export const AgendaDrawer: React.FC = () => { + const [isOpen, setIsOpen] = useState(false); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + + const { agendaItems } = useAgenda(); + + const toggleDrawer = (open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => { + if ( + event.type === "keydown" && + ((event as React.KeyboardEvent).key === "Tab" || (event as React.KeyboardEvent).key === "Shift") + ) { + return; + } + setIsOpen(open); + }; + + useEffect(() => { + if (agendaItems.length > 0 && !isMobile) { + setIsOpen(true); + } + }, [agendaItems]); + + const drawerContent = ( + + + Agenda + + {agendaItems.map((item, index) => ( + + + + ))} + + ); + + return ( + <> + {isMobile && ( + + + + )} + + {drawerContent} + + + ); +}; \ No newline at end of file diff --git a/frontend/src/components/MeetingsDrawer/MeetingsDrawer.tsx b/frontend/src/components/MeetingsDrawer/MeetingsDrawer.tsx index 7f5be06..f74f987 100644 --- a/frontend/src/components/MeetingsDrawer/MeetingsDrawer.tsx +++ b/frontend/src/components/MeetingsDrawer/MeetingsDrawer.tsx @@ -19,7 +19,7 @@ import { import HomeIcon from '@mui/icons-material/Home' import MeetingRoomIcon from '@mui/icons-material/MeetingRoom' -import './Drawer.css' +import './MeetingsDrawer.css' const fetchMeetings = async () => { const response = await fetch('https://codefusion.lholz.de/meetings/?skip=0&limit=100') diff --git a/frontend/src/container/Meeting/Meeting.tsx b/frontend/src/container/Meeting/Meeting.tsx index 27b1d9d..5fa3626 100644 --- a/frontend/src/container/Meeting/Meeting.tsx +++ b/frontend/src/container/Meeting/Meeting.tsx @@ -20,6 +20,8 @@ import SmartToyIcon from '@mui/icons-material/SmartToy'; import './Meeting.css'; import { useUser } from '../../utils/userProvider'; +import { AgendaDrawer } from '../../components/AgendaDrawer/AgendaDrawer'; +import { useAgenda } from '../../utils/meetingAgenda'; const deleteConversation = async ({ meetingId, userId }) => { const response = await fetch(`https://codefusion.lholz.de/meetings/${meetingId}/${userId}/conversation`, { @@ -59,6 +61,7 @@ const sendMessage = async ({ message, meetingId, userId }) => { export const Meeting = () => { const { id: meetingId } = useParams(); const { userId } = useUser(); + const { agendaItems, setAgendaItems } = useAgenda(); const navigate = useNavigate(); const [messages, setMessages] = useState([]); @@ -99,6 +102,7 @@ export const Meeting = () => { mutationFn: sendMessage, onSuccess: (data) => { setMessages(() => data.chat_messages); + setAgendaItems(data.agenda_items); if (data.finished) { navigate(`/meeting/${meetingId}/agenda`); @@ -126,87 +130,89 @@ export const Meeting = () => { }; return ( - - - Meeting: {meetingId} - -
- - {messages.map((message, index) => ( - - + + + Meeting: {meetingId} + +
+ + {messages.map((message, index) => ( + - - {message.author !== 'assistant' ? : } - - - {message.message} - - - - ))} -
- - -
- - setInputMessage(e.target.value)} - onKeyPress={(e) => { - if (e.key === 'Enter') { - handleSendMessage(); - } - }} - /> - + + {message.author !== 'assistant' ? : } + + + {message.message} + + + + ))} +
+ + +
+ + setInputMessage(e.target.value)} + onKeyPress={(e) => { + if (e.key === 'Enter') { + handleSendMessage(); + } + }} + /> + + - + ); }; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 835b0fc..7d3ab1a 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -12,6 +12,7 @@ import { PrepNow } from './container/PrepNow/PrepNow' import AgendaList from './container/AgendaList/AgendaList' import MeetingRoot from './container/Meeting/MeetingRoot' import { UserProvider } from './utils/userProvider' +import { AgendaProvider } from './utils/meetingAgenda' const queryClient = new QueryClient() @@ -68,9 +69,11 @@ root.render( - - - + + + + + diff --git a/frontend/src/utils/meetingAgenda.tsx b/frontend/src/utils/meetingAgenda.tsx new file mode 100644 index 0000000..d46cedd --- /dev/null +++ b/frontend/src/utils/meetingAgenda.tsx @@ -0,0 +1,30 @@ +import React, { createContext, useState, useContext, ReactNode } from 'react'; + +interface AgendaContextType { + agendaItems: string[]; + setAgendaItems: React.Dispatch>; +} + +const AgendaContext = createContext(undefined); + +interface AgendaProviderProps { + children: ReactNode; +} + +export const AgendaProvider: React.FC = ({ children }) => { + const [agendaItems, setAgendaItems] = useState([]); + + return ( + + {children} + + ); +}; + +export const useAgenda = (): AgendaContextType => { + const context = useContext(AgendaContext); + if (context === undefined) { + throw new Error('useAgenda must be used within an AgendaProvider'); + } + return context; +}; \ No newline at end of file diff --git a/frontend/src/utils/userProvider.jsx b/frontend/src/utils/userProvider.jsx deleted file mode 100644 index 348cc9e..0000000 --- a/frontend/src/utils/userProvider.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import React, { createContext, useState, useContext } from 'react'; - -const UserContext = createContext(); - -export const UserProvider = ({ children }) => { - const [userId, setUserId] = useState(2); - - return ( - - {children} - - ); -}; - -export const useUser = () => { - const context = useContext(UserContext); - if (context === undefined) { - throw new Error('useUser must be used within a UserProvider'); - } - return context; -}; \ No newline at end of file diff --git a/frontend/src/utils/userProvider.tsx b/frontend/src/utils/userProvider.tsx new file mode 100644 index 0000000..1c4a72d --- /dev/null +++ b/frontend/src/utils/userProvider.tsx @@ -0,0 +1,30 @@ +import React, { createContext, useState, useContext, ReactNode } from 'react'; + +interface UserContextType { + userId: number; + setUserId: React.Dispatch>; +} + +interface UserProviderProps { + children: ReactNode; +} + +const UserContext = createContext(undefined); + +export const UserProvider = ({ children }: UserProviderProps) => { + const [userId, setUserId] = useState(2); + + return ( + + {children} + + ); +}; + +export const useUser = (): UserContextType => { + const context = useContext(UserContext); + if (context === undefined) { + throw new Error('useUser must be used within a UserProvider'); + } + return context; +}; \ No newline at end of file