diff --git a/src/components/App/AppBar/index.tsx b/src/components/App/AppBar/index.tsx index 1ba3d1374..da1bf7f7f 100644 --- a/src/components/App/AppBar/index.tsx +++ b/src/components/App/AppBar/index.tsx @@ -1,43 +1,21 @@ -import { useEffect, useState } from 'react' import styled from 'styled-components' import { Flex } from '~/components/common/Flex' import { Text } from '~/components/common/Text' import { Stats } from '~/components/Stats' -import { getAboutData, TAboutParams } from '~/network/fetchSourcesData' +import { useAppStore } from '~/stores/useAppStore' import { colors } from '~/utils/colors' import { media } from '~/utils/media' -const defaultData = { - description: '', - mission_statement: '', - search_term: '', - title: '', -} - export const AppBar = () => { - const [initialValues, setInitialValues] = useState(defaultData) - - useEffect(() => { - const init = async () => { - try { - const response = await getAboutData() - - setInitialValues(response) - } catch (error) { - console.warn(error) - } - } - - init() - }, []) + const appMetaData = useAppStore((s) => s.appMetaData) return (
<> - {initialValues.title && ( + {appMetaData.title && ( - {initialValues.title} + {appMetaData.title} )} diff --git a/src/components/App/SecondarySidebar/About/index.tsx b/src/components/App/SecondarySidebar/About/index.tsx index 02c65faaf..f783120da 100644 --- a/src/components/App/SecondarySidebar/About/index.tsx +++ b/src/components/App/SecondarySidebar/About/index.tsx @@ -1,9 +1,7 @@ -import { useEffect, useState } from 'react' -import { ClipLoader } from 'react-spinners' import styled from 'styled-components' import { Flex } from '~/components/common/Flex' import { Text } from '~/components/common/Text' -import { getAboutData, TAboutParams } from '~/network/fetchSourcesData' +import { useAppStore } from '~/stores/useAppStore' import { useUserStore } from '~/stores/useUserStore' import { colors } from '~/utils/colors' import { AboutAdminView } from './AdminView' @@ -16,50 +14,18 @@ export const requiredRule = { }, } -const defaultData = { - description: '', - mission_statement: '', - search_term: '', - title: '', -} - export const About = () => { const [isAdmin] = useUserStore((s) => [s.isAdmin]) - const [loading, setLoading] = useState(false) - const [initialValues, setInitialValues] = useState(defaultData) - - useEffect(() => { - const init = async () => { - setLoading(true) - - try { - const response = await getAboutData() - - setInitialValues(response) - } catch (error) { - console.warn(error) - } finally { - setLoading(false) - } - } - - init() - }, []) + const appMetaData = useAppStore((s) => s.appMetaData) return ( About - {loading ? ( - - - - ) : ( - - {!isAdmin ? : } - - )} + + {!isAdmin ? : } + ) } diff --git a/src/components/App/Splash/index.tsx b/src/components/App/Splash/index.tsx index 1ae3d2d35..2dc036ce4 100644 --- a/src/components/App/Splash/index.tsx +++ b/src/components/App/Splash/index.tsx @@ -5,19 +5,20 @@ import styled from 'styled-components' import { Flex } from '~/components/common/Flex' import { Text } from '~/components/common/Text' import { TAboutParams, getAboutData, getStats } from '~/network/fetchSourcesData' +import { useAppStore } from '~/stores/useAppStore' import { colors } from '~/utils' import { SphereAnimation } from './SpiningSphere' import { AnimatedTextContent } from './animated' -import { Message, initialAboutState, initialMessageData } from './constants' +import { Message, initialMessageData } from './constants' type Props = { handleLoading: React.Dispatch> } export const Splash = memo(({ handleLoading }: Props) => { - const [about, setAbout] = useState(initialAboutState) const [message, setMessage] = useState(initialMessageData) const [progress, setProgress] = useState(0) + const [appMetaData, setAppMetaData] = [useAppStore((s) => s.appMetaData), useAppStore((s) => s.setAppMetaData)] useEffect(() => { let timeoutId: NodeJS.Timeout @@ -34,7 +35,7 @@ export const Splash = memo(({ handleLoading }: Props) => { setProgress((prev) => prev + 15) - setAbout(aboutResponse) + setAppMetaData(aboutResponse) setMessage( initialMessageData.map(({ key, ...rest }) => ({ @@ -75,7 +76,7 @@ export const Splash = memo(({ handleLoading }: Props) => { - {about.title && {about.title}} + {appMetaData.title && {appMetaData.title}} Second Brain diff --git a/src/components/SettingsModal/SettingsView/General/index.tsx b/src/components/SettingsModal/SettingsView/General/index.tsx index 1b1b57b1b..61442e87f 100644 --- a/src/components/SettingsModal/SettingsView/General/index.tsx +++ b/src/components/SettingsModal/SettingsView/General/index.tsx @@ -7,6 +7,7 @@ import { Flex } from '~/components/common/Flex' import { TextInput } from '~/components/common/TextInput' import { requiredRule } from '~/constants' import { TAboutParams, postAboutData } from '~/network/fetchSourcesData' +import { useAppStore } from '~/stores/useAppStore' import { colors } from '~/utils/colors' type Props = { @@ -16,10 +17,15 @@ type Props = { export const General: FC = ({ initialValues }) => { const form = useForm({ defaultValues: initialValues, mode: 'onSubmit' }) const { isSubmitting } = form.formState + const setAppMetaData = useAppStore((s) => s.setAppMetaData) const onSubmit = form.handleSubmit(async (data) => { try { - await postAboutData(data) + const res = (await postAboutData(data)) as Awaited<{ status: string }> + + if (res.status === 'success') { + setAppMetaData(data) + } } catch (error) { console.warn(error) } diff --git a/src/components/SettingsModal/SettingsView/index.tsx b/src/components/SettingsModal/SettingsView/index.tsx index 78b66bf25..f83804405 100644 --- a/src/components/SettingsModal/SettingsView/index.tsx +++ b/src/components/SettingsModal/SettingsView/index.tsx @@ -2,11 +2,11 @@ import Tab from '@mui/material/Tab' import Tabs from '@mui/material/Tabs' import * as React from 'react' -import { useEffect, useState } from 'react' +import { useState } from 'react' import styled from 'styled-components' import { Flex } from '~/components/common/Flex' import { Text } from '~/components/common/Text' -import { TAboutParams, getAboutData } from '~/network/fetchSourcesData' +import { useAppStore } from '~/stores/useAppStore' import { useUserStore } from '~/stores/useUserStore' import { colors } from '~/utils/colors' import { UserPermissions } from '../UserPermissions' @@ -19,13 +19,6 @@ interface TabPanelProps { value: number } -const defaultData = { - description: '', - mission_statement: '', - search_term: '', - title: '', -} - const TabPanel = (props: TabPanelProps) => { const { children, value, index, ...other } = props @@ -55,27 +48,8 @@ type Props = { export const SettingsView: React.FC = ({ onClose }) => { const [value, setValue] = useState(0) - const [isAdmin] = useUserStore((s) => [s.isAdmin]) - const [loading, setLoading] = useState(false) - const [initialValues, setInitialValues] = useState(defaultData) - - useEffect(() => { - const init = async () => { - setLoading(true) - - try { - const response = await getAboutData() - - setInitialValues(response) - } catch (error) { - console.warn(error) - } finally { - setLoading(false) - } - } - - init() - }, []) + const [isAdmin, pubKey] = useUserStore((s) => [s.isAdmin, s.setPubKey, s.pubKey]) + const appMetaData = useAppStore((s) => s.appMetaData) const getSettingsLabel = () => (isAdmin ? 'Admin Settings' : 'Settings') @@ -83,11 +57,24 @@ export const SettingsView: React.FC = ({ onClose }) => { {getSettingsLabel()} + {resolveAdminActions()} {children} ) + const resolveAdminActions = () => { + if (!pubKey) { + return null + } + + if (isAdmin) { + return null + } + + return <> + } + const handleChange = (event: React.SyntheticEvent, newValue: number) => { setValue(newValue) } @@ -101,14 +88,16 @@ export const SettingsView: React.FC = ({ onClose }) => { {isAdmin && } - - - {!loading ? : <>} - - - {!loading ? : <>} - - + {isAdmin && ( + <> + + + + + + + + )} diff --git a/src/stores/useAppStore/index.ts b/src/stores/useAppStore/index.ts index 9694b90bb..39d830d45 100644 --- a/src/stores/useAppStore/index.ts +++ b/src/stores/useAppStore/index.ts @@ -1,4 +1,6 @@ import create from 'zustand' +import { initialAboutState } from '~/components/App/Splash/constants' +import { TAboutParams } from '~/network/fetchSourcesData' export type SecondarySidebarActiveTab = '' | 'sentiment' | 'sources' | 'about' @@ -11,6 +13,7 @@ type AppStore = { transcriptIsOpen: boolean flagErrorIsOpen: boolean relevanceIsSelected: boolean + appMetaData: TAboutParams clearSearch: () => void setCurrentSearch: (_: string) => void setRelevanceSelected: (_: boolean) => void @@ -18,6 +21,7 @@ type AppStore = { setSidebarOpen: (_: boolean) => void setTranscriptOpen: (_: boolean) => void setFlagErrorOpen: (_: boolean) => void + setAppMetaData: (val: TAboutParams) => void } const defaultData = { @@ -29,6 +33,7 @@ const defaultData = { sidebarIsOpen: true, theme: 'light' as const, transcriptIsOpen: false, + appMetaData: initialAboutState, } export const useAppStore = create((set, get) => ({ @@ -47,4 +52,5 @@ export const useAppStore = create((set, get) => ({ transcriptIsOpen: !sidebarIsOpen ? false : get().transcriptIsOpen, }), setTranscriptOpen: (transcriptIsOpen) => set({ transcriptIsOpen }), + setAppMetaData: (appMetaData) => set({ appMetaData }), }))