diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/Editor/hooks/useCreateEditorState.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/Editor/hooks/useCreateEditorState.ts index 1d87c78aa..097bbb855 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/Editor/hooks/useCreateEditorState.ts +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/Editor/hooks/useCreateEditorState.ts @@ -6,12 +6,15 @@ import { Text } from "@tiptap/extension-text"; import { Extension, useEditor } from "@tiptap/react"; import { useTranslation } from "react-i18next"; +import { useUserSettingsContext } from "@/lib/context/UserSettingsProvider/hooks/useUserSettingsContext"; + import { useBrainMention } from "./useBrainMention"; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const useCreateEditorState = (placeholder?: string) => { const { t } = useTranslation(["chat"]); const { BrainMention, items } = useBrainMention(); + const { remainingCredits } = useUserSettingsContext(); const PreventEnter = Extension.create({ addKeyboardShortcuts: () => { @@ -24,7 +27,7 @@ export const useCreateEditorState = (placeholder?: string) => { const editor = useEditor( { - autofocus: true, + autofocus: !!remainingCredits, onFocus: () => { editor?.commands.focus("end"); }, diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/index.module.scss b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/index.module.scss index c4d4a770b..7ba74506a 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/index.module.scss +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/index.module.scss @@ -13,9 +13,11 @@ .chat_wrapper { display: flex; padding: Spacings.$spacing05; + padding-top: 0; - &.with_brain { - padding-top: 0; + &.disabled { + pointer-events: none; + opacity: 0.4; } } -} \ No newline at end of file +} 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 c4cb535b3..883ca0588 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/index.tsx +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/index.tsx @@ -4,6 +4,7 @@ import { CurrentBrain } from "@/lib/components/CurrentBrain/CurrentBrain"; import Icon from "@/lib/components/ui/Icon/Icon"; import { LoaderIcon } from "@/lib/components/ui/LoaderIcon/LoaderIcon"; import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext"; +import { useUserSettingsContext } from "@/lib/context/UserSettingsProvider/hooks/useUserSettingsContext"; import { ChatEditor } from "./components/ChatEditor/ChatEditor"; import { useChatInput } from "./hooks/useChatInput"; @@ -12,10 +13,11 @@ import styles from "./index.module.scss"; export const ChatInput = (): JSX.Element => { const { setMessage, submitQuestion, generatingAnswer, message } = useChatInput(); + const { remainingCredits } = useUserSettingsContext(); const { currentBrain } = useBrainContext(); const handleSubmitQuestion = () => { - if (message.trim() !== "") { + if (message.trim() !== "" && remainingCredits && currentBrain) { submitQuestion(); } }; @@ -30,12 +32,14 @@ export const ChatInput = (): JSX.Element => { }} >
- +
{ name="followUp" size="large" color="accent" - disabled={!message} + disabled={!message || !remainingCredits || !currentBrain} handleHover={true} onClick={handleSubmitQuestion} /> diff --git a/frontend/app/search/page.module.scss b/frontend/app/search/page.module.scss index 347c0c3a1..115d77276 100644 --- a/frontend/app/search/page.module.scss +++ b/frontend/app/search/page.module.scss @@ -53,23 +53,6 @@ } } } - - .shortcuts_card_wrapper { - background-color: var(--background-2); - padding: Spacings.$spacing05; - gap: Spacings.$spacing03; - border-radius: Radius.$big; - - .shortcut_wrapper { - display: flex; - align-items: center; - gap: Spacings.$spacing02; - - .shortcut { - color: var(--primary-0); - } - } - } } } @@ -105,4 +88,4 @@ display: flex; gap: Spacings.$spacing05; } -} \ No newline at end of file +} diff --git a/frontend/app/search/page.tsx b/frontend/app/search/page.tsx index aeacce697..973b07bd2 100644 --- a/frontend/app/search/page.tsx +++ b/frontend/app/search/page.tsx @@ -72,13 +72,6 @@ const Search = (): JSX.Element => {
-
-
- Press - @ - to select a brain -
-
diff --git a/frontend/lib/components/CurrentBrain/CurrentBrain.module.scss b/frontend/lib/components/CurrentBrain/CurrentBrain.module.scss index d20332ea9..82f587d31 100644 --- a/frontend/lib/components/CurrentBrain/CurrentBrain.module.scss +++ b/frontend/lib/components/CurrentBrain/CurrentBrain.module.scss @@ -1,12 +1,20 @@ @use "styles/Spacings.module.scss"; @use "styles/Typography.module.scss"; -.current_brain_wrapper { +%header_style { background-color: var(--background-2); padding-inline: Spacings.$spacing05; padding-block: Spacings.$spacing01; font-size: Typography.$small; - color: var(--text-1); +} + +@mixin textColor($color) { + color: var(--#{$color}); +} + +.current_brain_wrapper { + @extend %header_style; + @include textColor(text-1); .brain_infos { display: flex; @@ -20,7 +28,8 @@ align-items: center; @include Typography.EllipsisOverflow; - .title { + .title, + .brain_name { white-space: nowrap; } @@ -35,10 +44,27 @@ } .brain_name { - color: var(--text-3); + @include textColor(text-3); @include Typography.EllipsisOverflow; } } } } -} \ No newline at end of file +} + +.no_brain_selected, +.no_credits_left { + @extend %header_style; +} + +.no_brain_selected { + @include textColor(warning); + + .strong { + font-weight: 800; + } +} + +.no_credits_left { + @include textColor(dangerous); +} diff --git a/frontend/lib/components/CurrentBrain/CurrentBrain.tsx b/frontend/lib/components/CurrentBrain/CurrentBrain.tsx index 49a9e4fb2..edf86cb20 100644 --- a/frontend/lib/components/CurrentBrain/CurrentBrain.tsx +++ b/frontend/lib/components/CurrentBrain/CurrentBrain.tsx @@ -9,10 +9,12 @@ import { Icon } from "../ui/Icon/Icon"; interface CurrentBrainProps { allowingRemoveBrain: boolean; + remainingCredits: number | null; } export const CurrentBrain = ({ allowingRemoveBrain, + remainingCredits, }: CurrentBrainProps): JSX.Element => { const { currentBrain, setCurrentBrainId } = useBrainContext(); const { isDarkMode } = useUserSettingsContext(); @@ -20,8 +22,24 @@ export const CurrentBrain = ({ setCurrentBrainId(null); }; + if (!remainingCredits) { + return ( +
+ + You’ve run out of credits! Upgrade your plan now to continue chatting. + +
+ ); + } + if (!currentBrain) { - return <>; + return ( +
+ + Press @ to select a Brain + +
+ ); } return ( diff --git a/frontend/lib/components/ui/SearchBar/SearchBar.module.scss b/frontend/lib/components/ui/SearchBar/SearchBar.module.scss index 2570055f2..93a2a3f1f 100644 --- a/frontend/lib/components/ui/SearchBar/SearchBar.module.scss +++ b/frontend/lib/components/ui/SearchBar/SearchBar.module.scss @@ -18,9 +18,11 @@ align-items: center; justify-content: space-between; padding: Spacings.$spacing05; + padding-top: 0; - &.with_brain { - padding-top: 0; + &.disabled { + pointer-events: none; + opacity: 0.3; } .search_icon { @@ -36,4 +38,4 @@ } } } -} \ No newline at end of file +} diff --git a/frontend/lib/components/ui/SearchBar/SearchBar.tsx b/frontend/lib/components/ui/SearchBar/SearchBar.tsx index 74d4da52f..e49e8036b 100644 --- a/frontend/lib/components/ui/SearchBar/SearchBar.tsx +++ b/frontend/lib/components/ui/SearchBar/SearchBar.tsx @@ -6,6 +6,7 @@ import { useChatInput } from "@/app/chat/[chatId]/components/ActionsBar/componen import { useChat } from "@/app/chat/[chatId]/hooks/useChat"; import { useChatContext } from "@/lib/context"; import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext"; +import { useUserSettingsContext } from "@/lib/context/UserSettingsProvider/hooks/useUserSettingsContext"; import styles from "./SearchBar.module.scss"; @@ -23,6 +24,7 @@ export const SearchBar = ({ const { setMessages } = useChatContext(); const { addQuestion } = useChat(); const { currentBrain, setCurrentBrainId } = useBrainContext(); + const { remainingCredits } = useUserSettingsContext(); useEffect(() => { setCurrentBrainId(null); @@ -33,7 +35,7 @@ export const SearchBar = ({ }, [message]); const submit = async (): Promise => { - if (!searching) { + if (!!remainingCredits && !!currentBrain && !searching) { setSearching(true); setMessages([]); try { @@ -50,18 +52,15 @@ export const SearchBar = ({ }; return ( -
- +
+
void submit()} />