Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:dartilesm/makify into feature/su…
Browse files Browse the repository at this point in the history
…pabase-dev-environment
  • Loading branch information
dartilesm committed Sep 14, 2024
2 parents ab862cb + 1cbb243 commit e6dafdd
Show file tree
Hide file tree
Showing 20 changed files with 725 additions and 76 deletions.
240 changes: 240 additions & 0 deletions apps/chat-with-pdf/app/components/header/app-tour.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
"use client";

import {
Button,
Card,
CardContent,
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@makify/ui";
import { cn } from "@makify/ui/lib/utils";
import { EmblaCarouselType } from "embla-carousel";
import { motion } from "framer-motion";
import { LightbulbIcon } from "lucide-react";
import { useEffect, useRef, useState } from "react";

const newFeatures = [
{
title: "Download chat history",
description:
"You can now download your chat history as a PDF document for easy sharing.",
image: "/download-example.gif",
},
{
title: "Bookmark your favorite messages",
description:
"Bookmark your favorite messages to easily find them later. See all your bookmarks in one place in the chat header.",
video: "/bookmark-message-example.mp4",
},
{
title: "Quick actions on messages",
description:
"You can now quickly copy, regenerate (only the last message), bookmark messages from the toolbar below each message.",
image: "/quick-actions-example.jpeg",
},
{
title: "Page number references",
description:
"See where the message is based onas dasd sad as the PDF document page number*. ",
image: "/page-references.example.jpeg",
},
{
title: "Contextual queries",
description:
"Highlight a text in the PDF document and ask a question about it to the AI assistant.",
video: "/contextual-queries-example.mp4",
},
{
title: "Got an idea? Found an error? Share it with us!",
description:
"You can now provide feedback directly from the app. Click on the feedback button on the header.",
image: "/feedback-example.jpeg",
},
];

const carouselAnimationVariants = {
initial: {
opacity: 0,
},
animate: {
opacity: 1,
},
exit: {
opacity: 0,
},
};

export function AppTour() {
const [dialogOpen, setDialogOpen] = useState(false);
const [carouselApi, setCarouselApi] = useState<
EmblaCarouselType | undefined
>();
const [currentSlideIndex, setCurrentSlideIndex] = useState(0);

useEffect(handleCarouselApi, [carouselApi]);

function handleCarouselApi() {
if (carouselApi) {
carouselApi.on("init", handleOnSlideChange);
carouselApi.on("reInit", handleOnSlideChange);
carouselApi.on("select", handleOnSlideChange);
}
}

function handleOnSlideChange() {
if (carouselApi) {
setCurrentSlideIndex(carouselApi.selectedScrollSnap());
}
}

function handleToggleDialog() {
window.localStorage.setItem("app-tour-opened", "true");
setDialogOpen((prev) => !prev);
}

const appTourOpened = window.localStorage.getItem("app-tour-opened");

return (
<Dialog open={dialogOpen} onOpenChange={handleToggleDialog}>
<TooltipProvider delayDuration={0}>
<Tooltip>
<div>
<DialogTrigger asChild>
<TooltipTrigger asChild>
<Button variant="outline" size="icon" className="relative">
{!appTourOpened && (
<span className="absolute right-0 top-0 flex h-2 w-2">
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-yellow-400 opacity-75"></span>
<span className="relative inline-flex h-2 w-2 rounded-full bg-yellow-400"></span>
</span>
)}

<LightbulbIcon className="h-4 w-4" />
<span className="sr-only">See what's new!</span>
</Button>
</TooltipTrigger>
</DialogTrigger>
<Carousel setApi={setCarouselApi}>
<DialogContent className="flex flex-col">
<DialogHeader>
<DialogTitle>See what you can do</DialogTitle>
</DialogHeader>
<div className="m-auto flex max-w-full flex-col gap-2 [--slide-height:19rem] [--slide-size:90%] [--slide-spacing:1rem]">
<div className="w-full overflow-hidden">
<CarouselContent className="flex [touch-action:pan-y_pinch-zoom]">
{newFeatures.map((_, index) => (
<CarouselItem
key={index}
className="min-w-0 flex-[0_0_var(--slide-size)] pl-[var(--slide-spacing)] [transform:translate3d(0,0,0)]"
>
<div className="p-1">
<Card className="overflow-hidden">
<CardContent className="relative flex h-72 items-center justify-center p-6">
{newFeatures[index]!.image && (
<img
className="absolute h-72 w-full object-cover"
src={newFeatures[index]!.image}
alt={newFeatures[currentSlideIndex]!.title}
/>
)}
{newFeatures[index]!.video && (
<video
id="player_html5_api"
className="absolute h-72 w-full object-cover"
muted
autoPlay
tabIndex={-1}
src={newFeatures[index]!.video}
>
Your browser does not support the video tag.
</video>
)}
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
</div>
<div className="overflow-hidden text-center">
<motion.h3
key={`title-${currentSlideIndex}`}
variants={carouselAnimationVariants}
className="mb-2 text-lg font-semibold"
initial="initial"
animate="animate"
exit="exit"
transition={{ duration: 0.5, ease: "easeInOut" }}
>
{newFeatures[currentSlideIndex]!.title}
</motion.h3>
<motion.p
key={`description-${currentSlideIndex}`}
variants={carouselAnimationVariants}
className="text-muted-foreground text-sm"
initial="initial"
animate="animate"
exit="exit"
transition={{ duration: 0.5, ease: "easeInOut" }}
>
{newFeatures[currentSlideIndex]!.description}
</motion.p>
</div>
<motion.div className="mt-2 flex justify-center">
{newFeatures.map((_, index) => (
<motion.div
className={cn("mx-1 h-2 w-2 rounded-full", {
"bg-primary": index === currentSlideIndex,
"bg-muted": index !== currentSlideIndex,
})}
aria-hidden="true"
/>
))}
</motion.div>
</div>
<DialogFooter>
<CarouselPrevious asChild>
<Button variant="outline">Previous</Button>
</CarouselPrevious>
<CarouselNext asChild>
<Button
disabled={false}
type={
currentSlideIndex === newFeatures.length - 1
? "submit"
: "button"
}
onClick={
currentSlideIndex === newFeatures.length - 1
? handleToggleDialog
: undefined
}
>
{currentSlideIndex === newFeatures.length - 1
? "Close"
: "Next"}
</Button>
</CarouselNext>
</DialogFooter>
</DialogContent>
</Carousel>
<TooltipContent>See what's new!</TooltipContent>
</div>
</Tooltip>
</TooltipProvider>
</Dialog>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export function DocumentSwitcher({ className, chats }: DocumentSwitcherProps) {
ref={buttonRef}
aria-label="Select a team"
className={cn(
"flex h-14 flex-1 justify-between gap-2 truncate",
"flex flex-1 justify-between gap-2 truncate",
className,
)}
>
Expand All @@ -94,19 +94,8 @@ export function DocumentSwitcher({ className, chats }: DocumentSwitcherProps) {
?.title
}
</span>
<span className="text-xs text-gray-500 dark:text-gray-400">
{
(selectedDocument?.documentMetadata as Record<string, any>)
?.numPages
}{" "}
page
{(selectedDocument?.documentMetadata as Record<string, any>)
?.numPages > 1
? "s"
: ""}{" "}
</span>
</div>
<ChevronsUpDownIcon className="ml-auto h-4 w-4 shrink-0 opacity-50" />
<ChevronsUpDownIcon className="ml-auto h-3 w-3 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent
Expand Down Expand Up @@ -185,7 +174,7 @@ export function DocumentSwitcher({ className, chats }: DocumentSwitcherProps) {
size="icon"
variant="ghost"
>
<PencilIcon className="h-4 w-4" />
<PencilIcon className="stroke-muted-foreground h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">Edit document</TooltipContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,49 +114,6 @@ export function NewDocumentDialog({
</DialogHeader>
{!loadingMessages.length && (
<div className="flex flex-1 flex-col gap-4">
<Alert className="border-yellow-500 text-yellow-600">
<AlertTitle>Hackathon notice</AlertTitle>
<AlertDescription>
<span>
At the moment, this app only processes text in PDF files (we
are working on processing other types of content). As a
demonstration, here are some examples for you to try:
</span>
<ul className="list-inside list-disc truncate break-words">
<li>
<a
href="https://www.uh.edu/ussc/launch/services/handouts/Handouts/Tips-On-Studying-A-Foreign-Language.pdf"
className="text-blue-600 underline"
target="_blank"
>
Tips on studying a foreign language
</a>
</li>
<li>
<a
href="https://theorganicmarketing.com/wp-content/uploads/2023/08/Twitter-has-been-replaced-by-X.pdf"
className="text-blue-600 underline"
target="_blank"
>
Twitter has been replaced by X
</a>
</li>
<li>
<a
href="https://www.onetz.de/sites/default/files/flipbook/insert/3138327/bavarian_times_november2020_klein__S35.pdf"
className="text-blue-600 underline"
target="_blank"
>
Twelve strange christmas traditions from around the world
</a>
</li>
</ul>
<span className="italic">
Copy and paste the link in the input field on the{" "}
<strong>import from link.</strong>
</span>
</AlertDescription>
</Alert>
<FormProvider {...methods}>
<form
className="flex flex-1 flex-col justify-between gap-2"
Expand Down
11 changes: 7 additions & 4 deletions apps/chat-with-pdf/app/components/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DocumentSwitcher } from "./document-switcher/document-switcher";
import { FeedbackDialog } from "./feedback-dialog";
import { ThemeSwitcher } from "./theme-switcher";
import { UserNav } from "./user-nav/user-nav";
import { AppTour } from "./app-tour";

type HeaderProps = {
chats: Tables<"Chat">[];
Expand All @@ -13,14 +14,15 @@ type HeaderProps = {
export async function Header({ chats = [] }: HeaderProps) {
return (
<header className="border-b">
<div className="flex h-20 flex-row items-center justify-between gap-2 overflow-hidden px-4 max-sm:gap-4">
<div className="col flex flex-shrink-0 flex-col gap-1 text-sm">
<div className="flex h-16 flex-row items-center justify-between gap-4 overflow-hidden px-4 max-sm:gap-4">
<div className="col flex flex-shrink-0 flex-col gap-1 text-sm leading-none">
Chat with PDF
<span className="text-muted-foreground text-right text-xs">
<span className="text-muted-foreground text-right text-[8px] leading-none">
by Makify ✨
</span>
</div>
<div className="flex flex-1 justify-center overflow-hidden">

<div className="flex h-full flex-1 justify-center overflow-hidden">
{!!chats.length && <DocumentSwitcher chats={chats} />}
</div>
<div className="flex flex-row items-center gap-2 max-sm:hidden">
Expand All @@ -32,6 +34,7 @@ export async function Header({ chats = [] }: HeaderProps) {
</Button>
}
/>
<AppTour />
<UserNav />
</div>
</div>
Expand Down
Loading

0 comments on commit e6dafdd

Please sign in to comment.