diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/ActionsModal.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/ActionsModal.tsx new file mode 100644 index 000000000..0742ef086 --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/ActionsModal.tsx @@ -0,0 +1,42 @@ +import { PopoverAnchor } from "@radix-ui/react-popover"; +import { useState } from "react"; +import { LuPlusCircle, LuXCircle } from "react-icons/lu"; + +import Button from "@/lib/components/ui/Button"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/lib/components/ui/Popover"; + +import { ConfigModal } from "./components/ConfigModal"; + +export const ActionsModal = (): JSX.Element => { + const [isActionsModalOpened, setIsActionsModalOpened] = useState(false); + + const Icon = isActionsModalOpened ? LuXCircle : LuPlusCircle; + + return ( +
+ setIsActionsModalOpened(isOpened)} + > + + + + + + + + + +
+ ); +}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/components/Button.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/components/Button.tsx new file mode 100644 index 000000000..87f73f38a --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/components/Button.tsx @@ -0,0 +1,42 @@ +import { forwardRef } from "react"; + +import CoreButton, { + ButtonProps as CoreButtonProps, +} from "@/lib/components/ui/Button"; +import { cn } from "@/lib/utils"; + +type ButtonProps = CoreButtonProps & { + onClick?: () => void; + className?: string; + label?: string; + startIcon?: JSX.Element; + endIcon?: JSX.Element; +}; + +export const Button = forwardRef( + ( + { onClick, className, label, startIcon, endIcon, ...props }: ButtonProps, + forwardedRef + ): JSX.Element => { + return ( + +
+
+ {startIcon} + {label} +
+ {endIcon} +
+
+ ); + } +); + +Button.displayName = CoreButton.displayName; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ConfigModal/ConfigModal.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/components/ConfigModal/ConfigModal.tsx similarity index 80% rename from frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ConfigModal/ConfigModal.tsx rename to frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/components/ConfigModal/ConfigModal.tsx index 7d1406c4f..bbe66c110 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ConfigModal/ConfigModal.tsx +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/components/ConfigModal/ConfigModal.tsx @@ -1,12 +1,12 @@ -/* eslint-disable max-lines */ import { useTranslation } from "react-i18next"; -import { MdCheck, MdSettings } from "react-icons/md"; +import { LuChevronRight, LuSettings } from "react-icons/lu"; +import { MdCheck } from "react-icons/md"; -import Button from "@/lib/components/ui/Button"; import { Modal } from "@/lib/components/ui/Modal"; import { defineMaxTokens } from "@/lib/helpers/defineMaxTokens"; import { useConfigModal } from "./hooks/useConfigModal"; +import { Button } from "../Button"; export const ConfigModal = (): JSX.Element => { const { @@ -24,12 +24,11 @@ export const ConfigModal = (): JSX.Element => { - - + label={"Parametres"} + startIcon={} + endIcon={} + className="w-full" + /> } title="Chat configuration" desc="Adjust your chat settings" @@ -68,16 +67,16 @@ export const ConfigModal = (): JSX.Element => { + variant={"primary"} + label="Save" + endIcon={} + /> ); diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ConfigModal/hooks/useConfigModal.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/components/ConfigModal/hooks/useConfigModal.ts similarity index 100% rename from frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ConfigModal/hooks/useConfigModal.ts rename to frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/components/ConfigModal/hooks/useConfigModal.ts diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ConfigModal/index.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/components/ConfigModal/index.ts similarity index 100% rename from frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ConfigModal/index.ts rename to frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ActionsModal/components/ConfigModal/index.ts diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/index.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/index.ts index 07a86bb96..319b800a7 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/index.ts +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/index.ts @@ -1,2 +1 @@ -export * from "./ConfigModal"; export * from "./OnboardingQuestions"; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/index.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/index.tsx index 078e72cc2..4619e6eeb 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/index.tsx +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/index.tsx @@ -7,8 +7,8 @@ import { useKnowledgeToFeedContext } from "@/lib/context/KnowledgeToFeedProvider import { getBrainIconFromBrainType } from "@/lib/helpers/getBrainIconFromBrainType"; import { OnboardingQuestions } from "./components"; +import { ActionsModal } from "./components/ActionsModal/ActionsModal"; import { ChatEditor } from "./components/ChatEditor/ChatEditor"; -import { ConfigModal } from "./components/ConfigModal"; import { useChatInput } from "./hooks/useChatInput"; type ChatInputProps = { @@ -58,9 +58,9 @@ export const ChatInput = ({ /> -
+
diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index b43a7174f..6a6327110 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -1,6 +1,6 @@ import { createServerComponentSupabaseClient } from "@supabase/auth-helpers-nextjs"; import { Analytics as VercelAnalytics } from "@vercel/analytics/react"; -import { Inter } from "next/font/google"; +import { Outfit } from "next/font/google"; import { cookies, headers } from "next/headers"; import { ToastProvider } from "@/lib/components/ui/Toast"; @@ -10,7 +10,7 @@ import { SupabaseProvider } from "@/lib/context/SupabaseProvider"; import { App } from "./App"; import "./globals.css"; -const inter = Inter({ subsets: ["latin"] }); +const inter = Outfit({ subsets: ["latin"], weight: "400" }); export const metadata = { title: "Quivr - Get a Second Brain with Generative AI", diff --git a/frontend/app/user/components/LanguageDropDown/LanguageDropDown.tsx b/frontend/app/user/components/LanguageDropDown/LanguageDropDown.tsx deleted file mode 100644 index 592039294..000000000 --- a/frontend/app/user/components/LanguageDropDown/LanguageDropDown.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { FaLanguage } from "react-icons/fa"; -import { MdCheck } from "react-icons/md"; - -import Popover from "@/lib/components/ui/Popover"; - -import { useLanguageHook } from "./hooks/useLanguageHook"; - -export const LanguageDropDown = (): JSX.Element => { - const { allLanguages, currentLanguage, change } = useLanguageHook(); - - return ( - <> - {/* Add the brain icon and dropdown */} -
- - - - } - CloseTrigger={false} - > -
-
- {Object.keys(allLanguages).map((lang) => { - return ( -
- -
- ); - })} -
-
-
-
- - ); -}; diff --git a/frontend/app/user/components/LanguageDropDown/index.ts b/frontend/app/user/components/LanguageDropDown/index.ts deleted file mode 100644 index 6d2192323..000000000 --- a/frontend/app/user/components/LanguageDropDown/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./LanguageDropDown"; diff --git a/frontend/app/user/components/LanguageDropDown/LanguageSelect.tsx b/frontend/app/user/components/LanguageSelect/LanguageSelect.tsx similarity index 100% rename from frontend/app/user/components/LanguageDropDown/LanguageSelect.tsx rename to frontend/app/user/components/LanguageSelect/LanguageSelect.tsx diff --git a/frontend/app/user/components/LanguageDropDown/__tests__/LanguageSelect.test.tsx b/frontend/app/user/components/LanguageSelect/__tests__/LanguageSelect.test.tsx similarity index 100% rename from frontend/app/user/components/LanguageDropDown/__tests__/LanguageSelect.test.tsx rename to frontend/app/user/components/LanguageSelect/__tests__/LanguageSelect.test.tsx diff --git a/frontend/app/user/components/LanguageDropDown/hooks/useLanguageHook.ts b/frontend/app/user/components/LanguageSelect/hooks/useLanguageHook.ts similarity index 100% rename from frontend/app/user/components/LanguageDropDown/hooks/useLanguageHook.ts rename to frontend/app/user/components/LanguageSelect/hooks/useLanguageHook.ts diff --git a/frontend/app/user/page.tsx b/frontend/app/user/page.tsx index 42cf2a0a4..2ba9e2dcd 100644 --- a/frontend/app/user/page.tsx +++ b/frontend/app/user/page.tsx @@ -9,7 +9,7 @@ import { redirectToLogin } from "@/lib/router/redirectToLogin"; import { StripePricingOrManageButton, UserStatistics } from "./components"; import { ApiKeyConfig } from "./components/ApiKeyConfig"; -import LanguageSelect from "./components/LanguageDropDown/LanguageSelect"; +import LanguageSelect from "./components/LanguageSelect/LanguageSelect"; import { LogoutModal } from "./components/LogoutCard/LogoutModal"; import ThemeSelect from "./components/ThemeSelect/ThemeSelect"; diff --git a/frontend/lib/components/UserToInvite.tsx b/frontend/lib/components/UserToInvite.tsx index adfe9b2d1..045bad91d 100644 --- a/frontend/lib/components/UserToInvite.tsx +++ b/frontend/lib/components/UserToInvite.tsx @@ -70,6 +70,8 @@ export const UserToInvite = ({ onChange={setSelectedRole} value={selectedRole} options={translatedOptions} + popoverSide="bottom" + popoverClassName="w-36" /> ); diff --git a/frontend/lib/components/ui/Button.tsx b/frontend/lib/components/ui/Button.tsx index 6bb0f9899..1fbc7e2de 100644 --- a/frontend/lib/components/ui/Button.tsx +++ b/frontend/lib/components/ui/Button.tsx @@ -68,7 +68,6 @@ const Button = forwardRef( {children} {isLoading && } ); - const buttonElement = ; if (tooltip !== undefined) { return ( diff --git a/frontend/lib/components/ui/Popover.tsx b/frontend/lib/components/ui/Popover.tsx index 365639534..98ee59d9e 100644 --- a/frontend/lib/components/ui/Popover.tsx +++ b/frontend/lib/components/ui/Popover.tsx @@ -1,71 +1,29 @@ -"use client"; import * as PopoverPrimitive from "@radix-ui/react-popover"; -import { AnimatePresence, motion } from "framer-motion"; -import { ReactNode, useState } from "react"; +import * as React from "react"; -import Button from "./Button"; +import { cn } from "@/lib/utils"; -interface PopoverProps { - children?: ReactNode; - Trigger: ReactNode; - ActionTrigger?: ReactNode; - CloseTrigger?: ReactNode; -} +const Popover = PopoverPrimitive.Root; -const Popover = ({ - children, - Trigger, - ActionTrigger, - CloseTrigger, -}: PopoverProps): JSX.Element => { - const [open, setOpen] = useState(false); +const PopoverTrigger = PopoverPrimitive.Trigger; - return ( - - {Trigger} - - {open && ( - - - -
{children}
-
- {ActionTrigger !== undefined && ( - - {ActionTrigger} - - )} - - {CloseTrigger === undefined ? ( - - ) : ( - CloseTrigger - )} - -
- -
-
-
- )} -
-
- ); -}; +const PopoverContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( + + + +)); +PopoverContent.displayName = PopoverPrimitive.Content.displayName; -export default Popover; +export { Popover, PopoverContent, PopoverTrigger }; diff --git a/frontend/lib/components/ui/Select.tsx b/frontend/lib/components/ui/Select.tsx index 901d19863..9926c7e01 100644 --- a/frontend/lib/components/ui/Select.tsx +++ b/frontend/lib/components/ui/Select.tsx @@ -1,7 +1,13 @@ +/*eslint complexity: ["error", 10]*/ + /* eslint-disable max-lines */ import { BsCheckCircleFill } from "react-icons/bs"; -import Popover from "@/lib/components/ui/Popover"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/lib/components/ui/Popover"; import { cn } from "@/lib/utils"; export type SelectOptionProps = { @@ -17,6 +23,8 @@ type SelectProps = { readOnly?: boolean; className?: string; emptyLabel?: string; + popoverClassName?: string; + popoverSide?: "top" | "bottom" | "left" | "right" | undefined; }; const selectedStyle = "rounded-lg bg-black text-white"; @@ -29,6 +37,8 @@ export const Select = ({ readOnly = false, className, emptyLabel, + popoverClassName, + popoverSide, }: SelectProps): JSX.Element => { const selectedValueLabel = options.find( (option) => option.value === value @@ -74,8 +84,8 @@ export const Select = ({ )}
- + - } - CloseTrigger={
} - > -
    - {options.map((option) => ( -
  • onChange(option.value)} - > -
    + +
      + {options.map((option) => ( +
    • onChange(option.value)} > - - {option.label} - - {value === option.value && } -
    -
  • - ))} -
+
+ + {option.label} + + {value === option.value && } +
+ + ))} + +
diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 7ee29d0d9..cc43b5c67 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -16,7 +16,8 @@ module.exports = { }, colors: { black: "#11243E", - primary: "#7A27FD", + primary: "#6142D4", + accent: "#13ABBA", "chat-bg-gray": "#D9D9D9", "msg-gray": "#9B9B9B", "msg-header-gray": "#8F8F8F",