Skip to content

Commit

Permalink
feat: move delete all button and restyle side menu (#375)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomwisecodes authored Nov 26, 2024
1 parent cd88576 commit 69b2371
Show file tree
Hide file tree
Showing 30 changed files with 1,057 additions and 874 deletions.
2 changes: 1 addition & 1 deletion apps/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"@oakai/exports": "*",
"@oakai/logger": "*",
"@oakai/prettier-config": "*",
"@oaknational/oak-components": "^1.44.0",
"@oaknational/oak-components": "^1.50.0",
"@oaknational/oak-consent-client": "^2.1.0",
"@portabletext/react": "^3.1.0",
"@prisma/client": "5.16.1",
Expand Down
1 change: 0 additions & 1 deletion apps/nextjs/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ import HomePage from "./home-page";

export default async function Page() {
const result = await fetchAiHomepage();

return <HomePage pageData={result} />;
}
4 changes: 3 additions & 1 deletion apps/nextjs/src/components/AppComponents/Chat/Chat/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ export type DialogTypes =
| "report-content"
| "sensitive-moderation-user-comment"
| "demo-interstitial"
| "demo-share-locked";
| "demo-share-locked"
| "clear-history"
| "clear-single-chat";
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ export default meta;
type Story = StoryObj<typeof ChatHistory>;

export const Default: Story = {
args: {
userId: "user123",
},
args: {},
};

export const WithoutUserId: Story = {
Expand Down
101 changes: 76 additions & 25 deletions apps/nextjs/src/components/AppComponents/Chat/chat-history.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,71 @@
"use client";

import * as React from "react";
import { useEffect } from "react";

import { OakIcon } from "@oaknational/oak-components";
import {
OakBox,
OakIcon,
OakLink,
OakModal,
OakModalFooter,
OakSpan,
} from "@oaknational/oak-components";
import { usePathname } from "next/navigation";

import { SidebarList } from "@/components/AppComponents/Chat/sidebar-list";
import { SheetTrigger } from "@/components/AppComponents/Chat/ui/sheet";

import { useDialog } from "../DialogContext";
import { ClearHistory } from "./clear-history";
import ChatButton from "./ui/chat-button";

export function ChatHistory() {
const ailaId = usePathname().split("aila/")[1];
const { openSidebar, setOpenSidebar } = useDialog();

useEffect(() => {
if (openSidebar) {
const style = document.createElement("style");
style.innerHTML = `
.bb-feedback-button.gleap-font.gl-block {
display: none !important;
}
`;
document.head.appendChild(style);

return () => {
document.head.removeChild(style);
};
}
}, [openSidebar]);
return (
<div className="rel mt-20 flex h-full flex-col">
<div className="my-10 flex flex-col px-7">
<SheetTrigger asChild>
<OakModal
data-testid="sidebar"
isLeftHandSide={false}
zIndex={0}
isOpen={openSidebar}
onClose={() => setOpenSidebar(false)}
footerSlot={
<OakModalFooter>
<ClearHistory isEnabled={true} />
</OakModalFooter>
}
>
<OakBox
$position="absolute"
$top="all-spacing-6"
$right="all-spacing-3"
$borderRadius="border-radius-circle"
$height="space-between-xxl"
>
<OakLink element="button" onClick={() => setOpenSidebar(false)}>
<OakSpan $opacity="transparent" $font="body-3">
Close
</OakSpan>
</OakLink>
</OakBox>
<div className="flex h-full flex-col">
<div className="my-10 flex flex-col px-7">
<ChatButton href="/aila" variant="text-link" onClick={() => {}}>
<span className="rotate-45">
<OakIcon
Expand All @@ -26,26 +76,27 @@ export function ChatHistory() {
</span>
<span>Create new lesson</span>
</ChatButton>
</SheetTrigger>
<ChatButton href="/" variant="text-link">
<span className="scale-90">
<OakIcon iconName="home" />
</span>
AI experiments page
</ChatButton>
<ChatButton
href={ailaId ? `/aila/help/?ailaId=${ailaId}` : "/aila/help"}
variant="text-link"
>
<span className="scale-90">
<OakIcon iconName="question-mark" />
</span>
Help
</ChatButton>

<ChatButton href="/" variant="text-link">
<span className="scale-90">
<OakIcon iconName="home" />
</span>
AI experiments page
</ChatButton>
<ChatButton
href={ailaId ? `/aila/help/?ailaId=${ailaId}` : "/aila/help"}
variant="text-link"
>
<span className="scale-90">
<OakIcon iconName="question-mark" />
</span>
Help
</ChatButton>
</div>
<React.Suspense>
<SidebarList />
</React.Suspense>
</div>
<React.Suspense>
<SidebarList />
</React.Suspense>
</div>
</OakModal>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import AiIcon from "@/components/SVGParts/AiIcon";
import LessonIcon from "@/components/SVGParts/LessonIcon";
import QuizIcon from "@/components/SVGParts/QuizIcon";
import SlidesIcon from "@/components/SVGParts/SlidesIcon";
import { convertTitleCaseToSentenceCase } from "@/utils/convertTitleCaseToSentenceCase";

import { handleRewordingSections } from "./export-buttons";

Expand Down Expand Up @@ -194,8 +195,3 @@ const AccordionContent = React.forwardRef<
AccordionContent.displayName = "AccordionContent";

export default ChatStartAccordion;

function convertTitleCaseToSentenceCase(titleCase: string) {
const lowerCaseTitle = titleCase.toLowerCase();
return lowerCaseTitle.charAt(0).toUpperCase() + lowerCaseTitle.slice(1);
}
98 changes: 28 additions & 70 deletions apps/nextjs/src/components/AppComponents/Chat/clear-history.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,39 @@
"use client";

import * as React from "react";
import { toast } from "react-hot-toast";

import { useRouter } from "next/navigation";
import { OakFlex, OakSpan } from "@oaknational/oak-components";

import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/AppComponents/Chat/ui/alert-dialog";
import { Button } from "@/components/AppComponents/Chat/ui/button";
import { IconSpinner } from "@/components/AppComponents/Chat/ui/icons";
import { trpc } from "@/utils/trpc";
import BinIcon from "@/components/BinIcon";

type ClearHistoryProps = Readonly<{
isEnabled: boolean;
}>;

export function ClearHistory({ isEnabled = false }: ClearHistoryProps) {
const clearChats = trpc.chat.appSessions.deleteAllChats.useMutation({
onSuccess() {
toast.success("Chat history cleared");
setOpen(false);
router.push("/");
},
onError() {
toast.error("Failed to clear chat history");
},
}).mutate;
import { useDialog } from "../DialogContext";

const [open, setOpen] = React.useState(false);
const [isPending, startTransition] = React.useTransition();
const router = useRouter();
type ClearHistoryProps = {
isEnabled: boolean;
};

export function ClearHistory({ isEnabled }: Readonly<ClearHistoryProps>) {
const { setDialogWindow, setOpenSidebar } = useDialog();
if (!isEnabled) {
return null;
}
return (
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogTrigger asChild>
<Button
variant="ghost"
disabled={!isEnabled || isPending}
className="fixed bottom-0 right-0 z-40 flex w-full justify-center bg-white p-16 pl-0 sm:w-[298px]"
>
{isPending && <IconSpinner className="mr-7" />}
<span className="text-teachersRed">Clear history</span>
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This will permanently delete your chat history and remove your data
from our servers.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>
<AlertDialogAction
disabled={isPending}
onClick={(event) => {
event.preventDefault();
startTransition(() => {
clearChats();
});
}}
>
{isPending && <IconSpinner className="mr-7 animate-spin" />}
Delete
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<OakFlex
$justifyContent="flex-start"
$gap="all-spacing-2"
$alignItems="center"
>
<BinIcon />
<button
onClick={() => {
setOpenSidebar(false);
setDialogWindow("clear-history");
}}
>
<OakSpan $font="body-3-bold" $color="black" $textDecoration="none">
Delete all lessons
</OakSpan>
</button>
</OakFlex>
);
}
10 changes: 5 additions & 5 deletions apps/nextjs/src/components/AppComponents/Chat/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import { usePathname } from "next/navigation";
import { useDemoUser } from "@/components/ContextProviders/Demo";
import OakIconLogo from "@/components/OakIconLogo";

import { useDialog } from "../DialogContext";
import { BetaTagHeader } from "./beta-tag";
import { ChatHistory } from "./chat-history";
import { SidebarMobile } from "./sidebar-mobile";
import { OpenSideBarButton } from "./open-side-bar-button";
import { UserOrLogin } from "./user-or-login";

export function Header() {
Expand All @@ -27,7 +28,7 @@ export function Header() {
const clerkMetadata = useClerkDemoMetadata();

const ailaId = usePathname().split("aila/")[1];

const { setOpenSidebar } = useDialog();
return (
<OakBox
as={"header"}
Expand Down Expand Up @@ -122,9 +123,8 @@ export function Header() {
<UserOrLogin />
</OakFlex>
<OakFlex>
<SidebarMobile>
<ChatHistory />
</SidebarMobile>
<OpenSideBarButton setOpenSidebar={setOpenSidebar} />
<ChatHistory />
</OakFlex>
</OakFlex>
</OakFlex>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use client";

import { OakFlex, OakSpan } from "@oaknational/oak-components";

import { Button } from "@/components/AppComponents/Chat/ui/button";
import { Icon } from "@/components/Icon";
import useAnalytics from "@/lib/analytics/useAnalytics";

export function OpenSideBarButton({
setOpenSidebar,
}: Readonly<{
setOpenSidebar: (value: boolean) => void;
}>) {
const { trackEvent } = useAnalytics();

return (
<Button
variant="ghost"
data-testid="sidebar-button"
className="flex items-center px-5"
onClick={() => {
setOpenSidebar(true);
trackEvent("chat:toggle_sidebar");
}}
>
<Icon icon="sidebar" size="md" />
<OakFlex $pl={"inner-padding-ssx"} $display={["none", "flex"]}>
<OakSpan $font={"body-2"}>Menu</OakSpan>
</OakFlex>

<span className="sr-only block sm:hidden">Toggle Sidebar</span>
</Button>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { OakBox, OakFlex, OakP } from "@oaknational/oak-components";
import { motion } from "framer-motion";

import type { SideBarChatItem } from "@/lib/types";

import { SidebarItem } from "./sidebar-item";

const RenderChats = (title: string, chats: SideBarChatItem[]) => (
<OakBox $ml="space-between-s">
<OakP $font="body-2-bold" $mb="space-between-s">
{title}
</OakP>
<OakFlex $mb="space-between-s" $flexDirection="column" $gap="all-spacing-2">
{chats.map((chat) => (
<motion.div key={chat.id} exit={{ opacity: 0, height: 0 }}>
<SidebarItem chat={chat} />
</motion.div>
))}
</OakFlex>
</OakBox>
);

export default RenderChats;
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const mockChat = {
id: "1",
title: "Mock chat title",
isShared: false,
updatedAt: new Date(),
};

export const Default: Story = {
Expand Down
Loading

0 comments on commit 69b2371

Please sign in to comment.