Skip to content

Commit

Permalink
Merge branch 'main' into chatbot/llamaindex-pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
batdevis committed Sep 24, 2024
2 parents 13c73e3 + b278f87 commit e89352d
Show file tree
Hide file tree
Showing 17 changed files with 531 additions and 16 deletions.
6 changes: 6 additions & 0 deletions .changeset/happy-stingrays-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"nextjs-website": minor
"storybook-app": minor
---

Add chatbot history list component
6 changes: 6 additions & 0 deletions .changeset/quick-buckets-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"nextjs-website": minor
"storybook-app": minor
---

Add chatobot layout component
5 changes: 5 additions & 0 deletions .changeset/silent-bobcats-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"nextjs-website": minor
---

Guest chatbot message
58 changes: 58 additions & 0 deletions apps/nextjs-website/src/app/profile/chatbot-history/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use client';

import { useTranslations } from 'next-intl';
import { Stack, Typography } from '@mui/material';
import React, { useEffect } from 'react';
import ChatbotHistoryLayout from '@/components/organisms/ChatbotHistoryLayout/ChatbotHistoryLayout';
import { useChatbot } from '@/helpers/chatbot.helper';
import { useUser } from '@/helpers/user.helper';
import { isChatbotActive } from '@/config';
import Spinner from '@/components/atoms/Spinner/Spinner';
import { useRouter } from 'next/navigation';

const ChatbotHistory = () => {
const t = useTranslations();
const { user, loading } = useUser();
const { paginatedSessions, paginatedSessionsLoading, getSessionsByPage } =
useChatbot(true);
const router = useRouter();

useEffect(() => {
getSessionsByPage(1);
}, [getSessionsByPage]);

if (!isChatbotActive) {
router.replace('/not-found');
return null;
}

if (!user) {
return null;
}

return (
<Stack
sx={{
padding: { xs: '40px 24px', md: '80px 40px' },
width: '100%',
maxWidth: '694px',
}}
>
<Typography variant='h4' sx={{ marginBottom: '40px' }}>
{t('profile.chatbot.title')}
</Typography>
{(loading || paginatedSessionsLoading) && <Spinner />}
{!loading && !paginatedSessionsLoading && !paginatedSessions && (
<Typography>{t('profile.chatbot.noSessions')}</Typography>
)}
{!loading && !paginatedSessionsLoading && paginatedSessions && (
<ChatbotHistoryLayout
paginatedSessions={paginatedSessions}
getSessionsByPage={getSessionsByPage}
/>
)}
</Stack>
);
};

export default ChatbotHistory;
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { defaultLocale } from '@/config';
import { Session } from '@/lib/chatbot/queries';
import {
ListItem,
ListItemButton,
Stack,
Typography,
useTheme,
} from '@mui/material';

type DateFormatOptions = {
locale?: string;
options?: Intl.DateTimeFormatOptions;
};

const DEFAULT_DATE_FORMAT = {
locale: defaultLocale,
options: {
day: 'numeric',
month: 'numeric',
year: 'numeric',
},
} satisfies DateFormatOptions;

type ChatbotHistoryListItemProps = {
session: Session;
};

const ChatbotHistoryListItem = ({ session }: ChatbotHistoryListItemProps) => {
const { palette } = useTheme();
const formattedDate = new Intl.DateTimeFormat(
DEFAULT_DATE_FORMAT.locale,
DEFAULT_DATE_FORMAT.options
).format(new Date(session.createdAt));

return (
<ListItem>
<ListItemButton
sx={{ display: 'block', width: '100%' }}
href={`/profile/${session.id}/session-history`}
>
<Stack direction='column' spacing={3}>
<Typography
color={palette.text.secondary}
fontSize='0.875rem'
fontWeight='600'
>
{formattedDate}
</Typography>
<Typography
color={palette.text.primary}
fontSize='1rem'
fontWeight='600'
noWrap
component='span'
display='block'
textOverflow='ellipsis'
>
{session.title}
</Typography>
</Stack>
</ListItemButton>
</ListItem>
);
};

export default ChatbotHistoryListItem;
11 changes: 9 additions & 2 deletions apps/nextjs-website/src/components/molecules/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { compact } from 'lodash';
import { useTranslations } from 'next-intl';
import { ChatCatbotWriting } from '@/components/atoms/ChatChatbotWriting/ChatChatbotWriting';
import { ChatSkeleton } from '@/components/atoms/ChatSkeleton/ChatSkeleton';
import { useUser } from '@/helpers/user.helper';
import { baseUrl } from '@/config';
import AlertPart from '@/components/atoms/AlertPart/AlertPart';
import { ChatbotErrorsType } from '@/helpers/chatbot.helper';

Expand All @@ -35,9 +37,14 @@ const Chat = ({
const t = useTranslations();
const { palette } = useTheme();
const [instantScroll, setInstantScroll] = useState(scrollToBottom);
const { user } = useUser();
const messages = useMemo(
() => [
firstMessage(t('chatBot.welcomeMessage')),
firstMessage(
user
? t('chatBot.welcomeMessage')
: t('chatBot.guestMessage', { host: baseUrl })
),
...compact(
queries.flatMap((q) => [
q.question && q.queriedAt
Expand All @@ -61,7 +68,7 @@ const Chat = ({
])
),
],
[queries, t]
[queries, t, user]
) satisfies Message[];

const scrollRef = useRef<HTMLDivElement>(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {
capitalize,
Divider,
List,
ListItem,
Palette,
Typography,
useTheme,
} from '@mui/material';
import { defaultLocale } from '@/config';
import ChatbotHistoryListItem from '@/components/atoms/ChatbotHistoryListItem/ChatbotHistoryListItem';
import { Session } from '@/lib/chatbot/queries';

type DateFormatOptions = {
locale?: string;
options?: Intl.DateTimeFormatOptions;
};

const DEFAULT_DATE_FORMAT = {
locale: defaultLocale,
options: {
month: 'long',
year: 'numeric',
},
} satisfies DateFormatOptions;

type ChatbotHistoryList = {
sessionsList: Session[];
};

const ChatbotHistoryList = ({ sessionsList }: ChatbotHistoryList) => {
const { palette } = useTheme();
const uniqueDates = Array.from(
new Set(
sessionsList.map((session) =>
new Intl.DateTimeFormat(
DEFAULT_DATE_FORMAT.locale,
DEFAULT_DATE_FORMAT.options
).format(new Date(session.createdAt))
)
)
);

return (
<List>
{dateDividerSessionsItemsInterpolation(
uniqueDates,
sessionsList,
palette
)}
</List>
);
};

export default ChatbotHistoryList;

function dateDividerSessionsItemsInterpolation(
dateDividers: string[],
sessionsList: Session[],
palette: Palette
) {
const items = dateDividers.map((date) => {
const sessions = sessionsList.filter(
(session: Session) =>
new Intl.DateTimeFormat(
DEFAULT_DATE_FORMAT.locale,
DEFAULT_DATE_FORMAT.options
).format(new Date(session.createdAt)) === date
);
return sessions.map((session: Session) => session);
});
return items.flatMap((sameMonthItems) => (
<>
<ListItem>
<Typography
key={sameMonthItems[0].createdAt}
color={palette.text.primary}
fontSize='1.5rem'
fontWeight='700'
sx={{ padding: '1rem' }}
>
{capitalize(
new Intl.DateTimeFormat(
DEFAULT_DATE_FORMAT.locale,
DEFAULT_DATE_FORMAT.options
).format(new Date(sameMonthItems[0].createdAt))
)}
</Typography>
</ListItem>
{sameMonthItems.map((item, index) => [
<ChatbotHistoryListItem key={item.id} session={item} />,
<>
{sameMonthItems.length - 1 !== index && (
<Divider component='li' sx={{ marginX: '32px' }} />
)}
</>,
])}
</>
));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import ChatbotHistoryList from '@/components/molecules/ChatbotHistoryList/ChatbotHistoryList';
import { PaginatedSessions } from '@/lib/chatbot/queries';
import { Box, Pagination, Stack } from '@mui/material';
import { useEffect } from 'react';

type ChatbotHistoryLayoutProps = {
paginatedSessions: PaginatedSessions;
getSessionsByPage: (page: number) => null;
};

const ChatbotHistoryLayout = ({
paginatedSessions,
getSessionsByPage,
}: ChatbotHistoryLayoutProps) => {
useEffect(() => {
getSessionsByPage(1);
});

return (
<Stack direction='column' display='block'>
<ChatbotHistoryList sessionsList={paginatedSessions.items} />
<Box display='flex' marginY='1rem' width='100%' justifyContent='center'>
<Pagination
count={paginatedSessions.pages}
page={paginatedSessions.page}
onChange={(_, page) => getSessionsByPage(page)}
hidePrevButton={paginatedSessions.page === 1}
hideNextButton={paginatedSessions.page === paginatedSessions.pages}
/>
</Box>
</Stack>
);
};

export default ChatbotHistoryLayout;
15 changes: 11 additions & 4 deletions apps/nextjs-website/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,21 @@ export const amplifyConfig = {
authenticationFlowType: 'CUSTOM_AUTH',
};

export const profileMenuItems: readonly {
readonly label: string;
readonly href: string;
}[] = [
const defaultItems = [
{ label: 'personalData.title', href: '/profile/personal-data' },
{ label: 'agreements.title', href: '/profile/agreements' },
];

export const profileMenuItems: readonly {
readonly label: string;
readonly href: string;
}[] = isChatbotActive
? [
...defaultItems,
{ label: 'chatbot.title', href: '/profile/chatbot-history' },
]
: defaultItems;

export const snackbarAutoHideDurationMs = 10_000;

export const baseUrl = isProduction
Expand Down
Loading

0 comments on commit e89352d

Please sign in to comment.