diff --git a/src/components/App/AppBar/index.tsx b/src/components/App/AppBar/index.tsx index 9c5908c1f..212da1ce2 100644 --- a/src/components/App/AppBar/index.tsx +++ b/src/components/App/AppBar/index.tsx @@ -23,7 +23,7 @@ export const AppBar = () => { )} - Second Brain + Second Brain diff --git a/src/components/App/SideBar/AiSearch/index.tsx b/src/components/App/SideBar/AiSearch/index.tsx new file mode 100644 index 000000000..69cdf6f8f --- /dev/null +++ b/src/components/App/SideBar/AiSearch/index.tsx @@ -0,0 +1,70 @@ +import { FormProvider, useForm } from 'react-hook-form' +import styled from 'styled-components' +import SearchIcon from '~/components/Icons/SearchIcon' +import { SearchBar } from '~/components/SearchBar' +import { Flex } from '~/components/common/Flex' +import { useDataStore } from '~/stores/useDataStore' +import { useUserStore } from '~/stores/useUserStore' +import { colors } from '~/utils' + +export const AiSearch = () => { + const form = useForm<{ search: string }>({ mode: 'onChange' }) + const { fetchData, setAbortRequests } = useDataStore((s) => s) + const { setBudget } = useUserStore((s) => s) + const { reset } = form + + const handleSubmit = form.handleSubmit(({ search }) => { + fetchData(setBudget, setAbortRequests, search) + reset({ search: '' }) + }) + + return ( + + + + + { + handleSubmit() + }} + > + + + + + + ) +} + +const AiSearchWrapper = styled(Flex)` + position: sticky; + bottom: 0; + padding: 12px; + border-top: 1px solid ${colors.black}; +` + +const Search = styled(Flex).attrs({ + direction: 'row', + justify: 'center', + align: 'center', +})` + flex-grow: 1; +` + +const InputButton = styled(Flex).attrs({ + align: 'center', + justify: 'center', + p: 5, +})` + font-size: 32px; + color: ${colors.mainBottomIcons}; + cursor: pointer; + transition-duration: 0.2s; + margin-left: -42px; + z-index: 2; + + &:hover { + /* background-color: ${colors.gray200}; */ + } +` diff --git a/src/components/App/SideBar/index.tsx b/src/components/App/SideBar/index.tsx index 12c44583b..66d56479f 100644 --- a/src/components/App/SideBar/index.tsx +++ b/src/components/App/SideBar/index.tsx @@ -1,5 +1,6 @@ import { Slide } from '@mui/material' import clsx from 'clsx' +import { isEmpty } from 'lodash' import React, { forwardRef, useEffect, useRef, useState } from 'react' import { useFormContext } from 'react-hook-form' import { ClipLoader } from 'react-spinners' @@ -22,8 +23,8 @@ import { useDataStore, useFilteredNodes } from '~/stores/useDataStore' import { useFeatureFlagStore } from '~/stores/useFeatureFlagStore' import { useSelectedNode, useUpdateSelectedNode } from '~/stores/useGraphStore' import { colors } from '~/utils/colors' +import { AiSearch } from './AiSearch' import { AiSummaryDetails } from './AiSummary/AiSummaryDetail' -import { AiSummarySkeleton } from './AiSummary/AiSummarySkeleton' import { LatestView } from './Latest' import { EpisodeSkeleton } from './Relevance/EpisodeSkeleton' import { SideBarSubView } from './SidebarSubView' @@ -44,17 +45,14 @@ type ContentProp = { // eslint-disable-next-line react/display-name const Content = forwardRef(({ onSubmit, subViewOpen }, ref) => { const { isFetching: isLoading, setSidebarFilter, setFilters } = useDataStore((s) => s) - const { aiSummaryIsLoading, aiSummaryAnswers } = useAiSummaryStore((s) => s) + const { aiSummaryAnswers } = useAiSummaryStore((s) => s) const setSelectedNode = useUpdateSelectedNode() const filteredNodes = useFilteredNodes() const { setSidebarOpen, currentSearch: searchTerm, clearSearch, searchFormValue } = useAppStore((s) => s) - const [trendingTopicsFeatureFlag, chatInterfaceFeatureFlag] = useFeatureFlagStore((s) => [ - s.trendingTopicsFeatureFlag, - s.chatInterfaceFeatureFlag, - ]) + const [trendingTopicsFeatureFlag] = useFeatureFlagStore((s) => [s.trendingTopicsFeatureFlag]) const { setValue, watch } = useFormContext() const componentRef = useRef(null) @@ -121,7 +119,6 @@ const Content = forwardRef(({ onSubmit, subViewOpen return ( - @@ -201,19 +198,14 @@ const Content = forwardRef(({ onSubmit, subViewOpen )} - {chatInterfaceFeatureFlag && - (aiSummaryIsLoading ? ( - - ) : ( - <> - {Object.keys(aiSummaryAnswers).map((i: string) => ( - - ))} - - ))} + {Object.keys(aiSummaryAnswers).map((i: string) => ( + + ))} + {isLoading ? : } + {!isEmpty(aiSummaryAnswers) ? : null} ) }) diff --git a/src/components/App/UniverseQuestion/index.tsx b/src/components/App/UniverseQuestion/index.tsx index 2e05c0c32..e4ad7f19c 100644 --- a/src/components/App/UniverseQuestion/index.tsx +++ b/src/components/App/UniverseQuestion/index.tsx @@ -7,6 +7,7 @@ import { useEffect, useState } from 'react' import ArrowForwardIcon from '~/components/Icons/ArrowForwardIcon' import ExploreIcon from '~/components/Icons/ExploreIcon' import { getAboutData } from '~/network/fetchSourcesData' +import { useAiSummaryStore } from '~/stores/useAiSummaryStore' import { useAppStore } from '~/stores/useAppStore' import { useDataStore } from '~/stores/useDataStore' import { useUserStore } from '~/stores/useUserStore' @@ -18,6 +19,7 @@ export const UniverseQuestion = () => { const { fetchData, setAbortRequests } = useDataStore((s) => s) const [setBudget] = useUserStore((s) => [s.setBudget]) const setUniverseQuestionIsOpen = useAppStore((s) => s.setUniverseQuestionIsOpen) + const resetAiSummaryAnswer = useAiSummaryStore((s) => s.resetAiSummaryAnswer) useEffect(() => { const fetchSeedQuestions = async () => { @@ -37,6 +39,7 @@ export const UniverseQuestion = () => { const handleSubmitQuestion = async (questionToSubmit: string) => { if (questionToSubmit) { + resetAiSummaryAnswer() setUniverseQuestionIsOpen() } diff --git a/src/components/SearchBar/index.tsx b/src/components/SearchBar/index.tsx index 2a492a342..e0ef41be8 100644 --- a/src/components/SearchBar/index.tsx +++ b/src/components/SearchBar/index.tsx @@ -1,4 +1,3 @@ -import React from 'react' import { useFormContext } from 'react-hook-form' import styled, { css } from 'styled-components' import { colors } from '~/utils/colors' @@ -6,6 +5,7 @@ import { colors } from '~/utils/colors' type Props = { loading?: boolean onSubmit?: () => void + placeholder?: string } const Input = styled.input.attrs(() => ({ @@ -58,7 +58,7 @@ const Input = styled.input.attrs(() => ({ `} ` -export const SearchBar = ({ loading, onSubmit }: Props) => { +export const SearchBar = ({ loading, onSubmit, placeholder = 'Search' }: Props) => { const { register, watch } = useFormContext() const typing = watch('search') @@ -78,7 +78,7 @@ export const SearchBar = ({ loading, onSubmit }: Props) => { onSubmit?.() } }} - placeholder="Search" + placeholder={placeholder} type="text" /> ) diff --git a/src/stores/useAiSummaryStore/index.ts b/src/stores/useAiSummaryStore/index.ts index 66f30dacd..f2b965265 100644 --- a/src/stores/useAiSummaryStore/index.ts +++ b/src/stores/useAiSummaryStore/index.ts @@ -7,24 +7,20 @@ type AIAnswer = { } export type AiSummaryStore = { - aiSummaryIsLoading: boolean aiSummaryAnswers: AIAnswer setAiSummaryAnswer: (key: string, answer: AIEntity) => void - setAiSummaryIsLoading: (status: boolean) => void + resetAiSummaryAnswer: () => void getAiSummaryAnswer: (key: string) => string getKeyExist: (key: string) => boolean } const defaultData = { - aiSummaryRequest: '', - aiSummaryIsLoading: false, aiSummaryAnswers: {}, } export const useAiSummaryStore = create()( devtools((set, get) => ({ ...defaultData, - setAiSummaryIsLoading: (status) => set({ aiSummaryIsLoading: status }), setAiSummaryAnswer: (key, answer) => { const summaryAnswers = get().aiSummaryAnswers @@ -34,6 +30,9 @@ export const useAiSummaryStore = create()( set({ aiSummaryAnswers: clone }) }, + resetAiSummaryAnswer: () => { + set({ aiSummaryAnswers: {} }) + }, getAiSummaryAnswer: (key) => { const summaryAnswers = get().aiSummaryAnswers