diff --git a/api/server/routes/endpoints.js b/api/server/routes/endpoints.js index 9d679528d..b6016244c 100644 --- a/api/server/routes/endpoints.js +++ b/api/server/routes/endpoints.js @@ -113,7 +113,6 @@ router.get('/', async function (req, res) { key = require('../../data/auth.json'); } catch (e) { if (i === 0) { - console.log('No \'auth.json\' file (service account key) found in /api/data/ for PaLM models'); i++; } } @@ -121,7 +120,6 @@ router.get('/', async function (req, res) { if (process.env.PALM_KEY === 'user_provided') { palmUser = true; if (i <= 1) { - console.log('User will provide key for PaLM models'); i++; } } diff --git a/client/src/components/Auth/Login.tsx b/client/src/components/Auth/Login.tsx index 622f3ec8a..65a119de4 100644 --- a/client/src/components/Auth/Login.tsx +++ b/client/src/components/Auth/Login.tsx @@ -2,18 +2,14 @@ import React, { useEffect } from 'react'; import LoginForm from './LoginForm'; import { useAuthContext } from '~/hooks/AuthContext'; import { useNavigate } from 'react-router-dom'; - -import { useRecoilValue } from 'recoil'; -import store from '~/store'; -import { localize } from '~/localization/Translation'; +import { useLocalize } from '~/hooks'; import { useGetStartupConfig } from 'librechat-data-provider'; import { GoogleIcon, OpenIDIcon, GithubIcon, DiscordIcon } from '~/components'; function Login() { const { login, error, isAuthenticated } = useAuthContext(); const { data: startupConfig } = useGetStartupConfig(); - - const lang = useRecoilValue(store.lang); + const localize = useLocalize(); const navigate = useNavigate(); @@ -27,23 +23,23 @@ function Login() {

- {localize(lang, 'com_auth_welcome_back')} + {localize('com_auth_welcome_back')}

{error && (
- {localize(lang, 'com_auth_error_login')} + {localize('com_auth_error_login')}
)} {startupConfig?.registrationEnabled && (

{' '} - {localize(lang, 'com_auth_no_account')}{' '} + {localize('com_auth_no_account')}{' '} - {localize(lang, 'com_auth_sign_up')} + {localize('com_auth_sign_up')}

)} @@ -64,7 +60,7 @@ function Login() { href={`${startupConfig.serverDomain}/oauth/google`} > -

{localize(lang, 'com_auth_google_login')}

+

{localize('com_auth_google_login')}

@@ -96,7 +92,7 @@ function Login() { href={`${startupConfig.serverDomain}/oauth/github`} > -

{localize(lang, 'com_auth_github_login')}

+

{localize('com_auth_github_login')}

@@ -110,7 +106,7 @@ function Login() { href={`${startupConfig.serverDomain}/oauth/discord`} > -

{localize(lang, 'com_auth_discord_login')}

+

{localize('com_auth_discord_login')}

diff --git a/client/src/components/Auth/LoginForm.tsx b/client/src/components/Auth/LoginForm.tsx index c205ece32..191e3c72e 100644 --- a/client/src/components/Auth/LoginForm.tsx +++ b/client/src/components/Auth/LoginForm.tsx @@ -1,7 +1,5 @@ import { useForm } from 'react-hook-form'; -import { useRecoilValue } from 'recoil'; -import store from '~/store'; -import { localize } from '~/localization/Translation'; +import { useLocalize } from '~/hooks'; import { TLoginUser } from 'librechat-data-provider'; type TLoginFormProps = { @@ -9,7 +7,7 @@ type TLoginFormProps = { }; function LoginForm({ onSubmit }: TLoginFormProps) { - const lang = useRecoilValue(store.lang); + const localize = useLocalize(); const { register, @@ -30,20 +28,20 @@ function LoginForm({ onSubmit }: TLoginFormProps) { type="text" id="email" autoComplete="email" - aria-label={localize(lang, 'com_auth_email')} + aria-label={localize('com_auth_email')} {...register('email', { - required: localize(lang, 'com_auth_email_required'), + required: localize('com_auth_email_required'), minLength: { value: 3, - message: localize(lang, 'com_auth_email_min_length'), + message: localize('com_auth_email_min_length'), }, maxLength: { value: 120, - message: localize(lang, 'com_auth_email_max_length'), + message: localize('com_auth_email_max_length'), }, pattern: { value: /\S+@\S+\.\S+/, - message: localize(lang, 'com_auth_email_pattern'), + message: localize('com_auth_email_pattern'), }, })} aria-invalid={!!errors.email} @@ -54,7 +52,7 @@ function LoginForm({ onSubmit }: TLoginFormProps) { htmlFor="email" className="absolute left-2.5 top-4 z-10 origin-[0] -translate-y-4 scale-75 transform text-gray-500 duration-300 peer-placeholder-shown:translate-y-0 peer-placeholder-shown:scale-100 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:text-green-500" > - {localize(lang, 'com_auth_email_address')} + {localize('com_auth_email_address')} {errors.email && ( @@ -70,16 +68,16 @@ function LoginForm({ onSubmit }: TLoginFormProps) { type="password" id="password" autoComplete="current-password" - aria-label={localize(lang, 'com_auth_password')} + aria-label={localize('com_auth_password')} {...register('password', { - required: localize(lang, 'com_auth_password_required'), + required: localize('com_auth_password_required'), minLength: { value: 8, - message: localize(lang, 'com_auth_password_min_length'), + message: localize('com_auth_password_min_length'), }, maxLength: { value: 40, - message: localize(lang, 'com_auth_password_max_length'), + message: localize('com_auth_password_max_length'), }, })} aria-invalid={!!errors.password} @@ -90,7 +88,7 @@ function LoginForm({ onSubmit }: TLoginFormProps) { htmlFor="password" className="absolute left-2.5 top-4 z-10 origin-[0] -translate-y-4 scale-75 transform text-gray-500 duration-300 peer-placeholder-shown:translate-y-0 peer-placeholder-shown:scale-100 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:text-green-500" > - {localize(lang, 'com_auth_password')} + {localize('com_auth_password')} @@ -102,7 +100,7 @@ function LoginForm({ onSubmit }: TLoginFormProps) { )} - {localize(lang, 'com_auth_password_forgot')} + {localize('com_auth_password_forgot')}
diff --git a/client/src/components/Auth/Registration.tsx b/client/src/components/Auth/Registration.tsx index e859bbf82..47286f163 100644 --- a/client/src/components/Auth/Registration.tsx +++ b/client/src/components/Auth/Registration.tsx @@ -1,9 +1,7 @@ import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useForm } from 'react-hook-form'; -import { useRecoilValue } from 'recoil'; -import store from '~/store'; -import { localize } from '~/localization/Translation'; +import { useLocalize } from '~/hooks'; import { useRegisterUserMutation, TRegisterUser, @@ -15,7 +13,7 @@ function Registration() { const navigate = useNavigate(); const { data: startupConfig } = useGetStartupConfig(); - const lang = useRecoilValue(store.lang); + const localize = useLocalize(); const { register, @@ -56,7 +54,7 @@ function Registration() {

- {localize(lang, 'com_auth_create_account')} + {localize('com_auth_create_account')}

{error && (
- {localize(lang, 'com_auth_error_create')} {errorMessage} + {localize('com_auth_error_create')} {errorMessage}
)}
- {localize(lang, 'com_auth_full_name')} + {localize('com_auth_full_name')}
@@ -115,16 +113,16 @@ function Registration() { - {localize(lang, 'com_auth_username')} + {localize('com_auth_username')}
@@ -153,20 +151,20 @@ function Registration() { type="email" id="email" autoComplete="email" - aria-label={localize(lang, 'com_auth_email')} + aria-label={localize('com_auth_email')} {...register('email', { - required: localize(lang, 'com_auth_email_required'), + required: localize('com_auth_email_required'), minLength: { value: 3, - message: localize(lang, 'com_auth_email_min_length'), + message: localize('com_auth_email_min_length'), }, maxLength: { value: 120, - message: localize(lang, 'com_auth_email_max_length'), + message: localize('com_auth_email_max_length'), }, pattern: { value: /\S+@\S+\.\S+/, - message: localize(lang, 'com_auth_email_pattern'), + message: localize('com_auth_email_pattern'), }, })} aria-invalid={!!errors.email} @@ -177,7 +175,7 @@ function Registration() { htmlFor="email" className="absolute left-2.5 top-4 z-10 origin-[0] -translate-y-4 scale-75 transform text-sm text-gray-500 duration-300 peer-placeholder-shown:translate-y-0 peer-placeholder-shown:scale-100 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:text-green-500" > - {localize(lang, 'com_auth_email')} + {localize('com_auth_email')} {errors.email && ( @@ -194,16 +192,16 @@ function Registration() { id="password" data-testid="password" autoComplete="current-password" - aria-label={localize(lang, 'com_auth_password')} + aria-label={localize('com_auth_password')} {...register('password', { - required: localize(lang, 'com_auth_password_required'), + required: localize('com_auth_password_required'), minLength: { value: 8, - message: localize(lang, 'com_auth_password_min_length'), + message: localize('com_auth_password_min_length'), }, maxLength: { value: 128, - message: localize(lang, 'com_auth_password_max_length'), + message: localize('com_auth_password_max_length'), }, })} aria-invalid={!!errors.password} @@ -214,7 +212,7 @@ function Registration() { htmlFor="password" className="absolute left-2.5 top-4 z-10 origin-[0] -translate-y-4 scale-75 transform text-sm text-gray-500 duration-300 peer-placeholder-shown:translate-y-0 peer-placeholder-shown:scale-100 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:text-green-500" > - {localize(lang, 'com_auth_password')} + {localize('com_auth_password')} @@ -231,7 +229,7 @@ function Registration() { type="password" id="confirm_password" data-testid="confirm_password" - aria-label={localize(lang, 'com_auth_password_confirm')} + aria-label={localize('com_auth_password_confirm')} // uncomment to block pasting in confirm field // onPaste={(e) => { // e.preventDefault(); @@ -239,7 +237,7 @@ function Registration() { // }} {...register('confirm_password', { validate: (value) => - value === password || localize(lang, 'com_auth_password_not_match'), + value === password || localize('com_auth_password_not_match'), })} aria-invalid={!!errors.confirm_password} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" @@ -249,7 +247,7 @@ function Registration() { htmlFor="confirm_password" className="absolute left-2.5 top-4 z-10 origin-[0] -translate-y-4 scale-75 transform text-sm text-gray-500 duration-300 peer-placeholder-shown:translate-y-0 peer-placeholder-shown:scale-100 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:text-green-500" > - {localize(lang, 'com_auth_password_confirm')} + {localize('com_auth_password_confirm')} @@ -273,19 +271,19 @@ function Registration() { aria-label="Submit registration" className="w-full transform rounded-sm bg-green-500 px-4 py-3 tracking-wide text-white transition-colors duration-200 hover:bg-green-600 focus:bg-green-600 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-green-500" > - {localize(lang, 'com_auth_continue')} + {localize('com_auth_continue')}

{' '} - {localize(lang, 'com_auth_already_have_account')}{' '} + {localize('com_auth_already_have_account')}{' '} - {localize(lang, 'com_auth_login')} + {localize('com_auth_login')}

{startupConfig?.socialLoginEnabled && ( @@ -305,7 +303,7 @@ function Registration() { href={`${startupConfig.serverDomain}/oauth/google`} > -

{localize(lang, 'com_auth_google_login')}

+

{localize('com_auth_google_login')}

@@ -337,7 +335,7 @@ function Registration() { href={`${startupConfig.serverDomain}/oauth/github`} > -

{localize(lang, 'com_auth_github_login')}

+

{localize('com_auth_github_login')}

@@ -351,7 +349,7 @@ function Registration() { href={`${startupConfig.serverDomain}/oauth/discord`} > -

{localize(lang, 'com_auth_discord_login')}

+

{localize('com_auth_discord_login')}

diff --git a/client/src/components/Auth/RequestPasswordReset.tsx b/client/src/components/Auth/RequestPasswordReset.tsx index a46511711..4a97f2e5a 100644 --- a/client/src/components/Auth/RequestPasswordReset.tsx +++ b/client/src/components/Auth/RequestPasswordReset.tsx @@ -1,8 +1,6 @@ import React, { useState, useEffect } from 'react'; import { useForm } from 'react-hook-form'; -import { useRecoilValue } from 'recoil'; -import store from '~/store'; -import { localize } from '~/localization/Translation'; +import { useLocalize } from '~/hooks'; import { useRequestPasswordResetMutation, useGetStartupConfig, @@ -11,7 +9,7 @@ import { } from 'librechat-data-provider'; function RequestPasswordReset() { - const lang = useRecoilValue(store.lang); + const localize = useLocalize(); const { register, handleSubmit, @@ -44,22 +42,22 @@ function RequestPasswordReset() { useEffect(() => { if (requestPasswordReset.isSuccess) { if (config.data?.emailEnabled) { - setHeaderText(localize(lang, 'com_auth_reset_password_link_sent')); - setBodyText(localize(lang, 'com_auth_reset_password_email_sent')); + setHeaderText(localize('com_auth_reset_password_link_sent')); + setBodyText(localize('com_auth_reset_password_email_sent')); } else { - setHeaderText(localize(lang, 'com_auth_reset_password')); + setHeaderText(localize('com_auth_reset_password')); setBodyText( - {localize(lang, 'com_auth_click')}{' '} + {localize('com_auth_click')}{' '} - {localize(lang, 'com_auth_here')} + {localize('com_auth_here')} {' '} - {localize(lang, 'com_auth_to_reset_your_password')} + {localize('com_auth_to_reset_your_password')} , ); } } else { - setHeaderText(localize(lang, 'com_auth_reset_password')); + setHeaderText(localize('com_auth_reset_password')); setBodyText(undefined); } }, [requestPasswordReset.isSuccess, config.data?.emailEnabled, resetLink, lang]); @@ -73,7 +71,7 @@ function RequestPasswordReset() { className="relative mt-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700" role="alert" > - {localize(lang, 'com_auth_error_reset_password')} + {localize('com_auth_error_reset_password')} )} {bodyText ? ( @@ -96,20 +94,20 @@ function RequestPasswordReset() { type="email" id="email" autoComplete="off" - aria-label={localize(lang, 'com_auth_email')} + aria-label={localize('com_auth_email')} {...register('email', { - required: localize(lang, 'com_auth_email_required'), + required: localize('com_auth_email_required'), minLength: { value: 3, - message: localize(lang, 'com_auth_email_min_length'), + message: localize('com_auth_email_min_length'), }, maxLength: { value: 120, - message: localize(lang, 'com_auth_email_max_length'), + message: localize('com_auth_email_max_length'), }, pattern: { value: /\S+@\S+\.\S+/, - message: localize(lang, 'com_auth_email_pattern'), + message: localize('com_auth_email_pattern'), }, })} aria-invalid={!!errors.email} @@ -120,7 +118,7 @@ function RequestPasswordReset() { htmlFor="email" className="absolute left-2.5 top-4 z-10 origin-[0] -translate-y-4 scale-75 transform text-gray-500 duration-300 peer-placeholder-shown:translate-y-0 peer-placeholder-shown:scale-100 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:text-green-500" > - {localize(lang, 'com_auth_email_address')} + {localize('com_auth_email_address')} {errors.email && ( @@ -136,7 +134,7 @@ function RequestPasswordReset() { disabled={!!errors.email} className="w-full rounded-sm border border-transparent bg-green-500 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-green-600 focus:outline-none active:bg-green-500" > - {localize(lang, 'com_auth_continue')} + {localize('com_auth_continue')} diff --git a/client/src/components/Auth/ResetPassword.tsx b/client/src/components/Auth/ResetPassword.tsx index a8b8ba110..7e587bde4 100644 --- a/client/src/components/Auth/ResetPassword.tsx +++ b/client/src/components/Auth/ResetPassword.tsx @@ -4,10 +4,10 @@ import { useResetPasswordMutation, TResetPassword } from 'librechat-data-provide import { useNavigate, useSearchParams } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; import store from '~/store'; -import { localize } from '~/localization/Translation'; +import { useLocalize } from '~/hooks'; function ResetPassword() { - const lang = useRecoilValue(store.lang); + const localize = useLocalize(); const { register, handleSubmit, @@ -33,20 +33,20 @@ function ResetPassword() {

- {localize(lang, 'com_auth_reset_password_success')} + {localize('com_auth_reset_password_success')}

- {localize(lang, 'com_auth_login_with_new_password')} + {localize('com_auth_login_with_new_password')}
@@ -56,18 +56,18 @@ function ResetPassword() {

- {localize(lang, 'com_auth_reset_password')} + {localize('com_auth_reset_password')}

{resetError && (
- {localize(lang, 'com_auth_error_invalid_reset_token')}{' '} + {localize('com_auth_error_invalid_reset_token')}{' '} - {localize(lang, 'com_auth_click_here')} + {localize('com_auth_click_here')} {' '} - {localize(lang, 'com_auth_to_try_again')} + {localize('com_auth_to_try_again')}
)}
- {localize(lang, 'com_auth_password')} + {localize('com_auth_password')}
@@ -132,7 +132,7 @@ function ResetPassword() { { e.preventDefault(); @@ -140,7 +140,7 @@ function ResetPassword() { }} {...register('confirm_password', { validate: (value) => - value === password || localize(lang, 'com_auth_password_not_match'), + value === password || localize('com_auth_password_not_match'), })} aria-invalid={!!errors.confirm_password} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" @@ -150,7 +150,7 @@ function ResetPassword() { htmlFor="confirm_password" className="absolute left-2.5 top-4 z-10 origin-[0] -translate-y-4 scale-75 transform text-sm text-gray-500 duration-300 peer-placeholder-shown:translate-y-0 peer-placeholder-shown:scale-100 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:text-green-500" > - {localize(lang, 'com_auth_password_confirm')} + {localize('com_auth_password_confirm')}
{errors.confirm_password && ( @@ -176,10 +176,10 @@ function ResetPassword() { diff --git a/client/src/components/Auth/__tests__/Registration.spec.tsx b/client/src/components/Auth/__tests__/Registration.spec.tsx index 6b66f05e4..2b86c9fa0 100644 --- a/client/src/components/Auth/__tests__/Registration.spec.tsx +++ b/client/src/components/Auth/__tests__/Registration.spec.tsx @@ -77,6 +77,7 @@ test('renders registration form', () => { ); }); +// eslint-disable-next-line jest/no-commented-out-tests // test('calls registerUser.mutate on registration', async () => { // const mutate = jest.fn(); // const { getByTestId, getByRole, history } = setup({ diff --git a/client/src/components/Input/EndpointMenu/EndpointItem.tsx b/client/src/components/Input/EndpointMenu/EndpointItem.tsx index c2b699540..38e822a9f 100644 --- a/client/src/components/Input/EndpointMenu/EndpointItem.tsx +++ b/client/src/components/Input/EndpointMenu/EndpointItem.tsx @@ -4,6 +4,7 @@ import { Settings } from 'lucide-react'; import { DropdownMenuRadioItem } from '~/components'; import { getIcon } from '~/components/Endpoints'; import { SetTokenDialog } from '../SetTokenDialog'; +import { useLocalize } from '~/hooks'; import store from '~/store'; import { cn, alternateName } from '~/utils'; @@ -29,6 +30,7 @@ export default function ModelItem({ }); const isUserProvided = endpointsConfig?.[endpoint]?.userProvide; + const localize = useLocalize(); // regular model return ( @@ -62,7 +64,7 @@ export default function ModelItem({ }} > - Config Token + {localize('com_endpoint_config_token')} ) : null} diff --git a/client/src/components/Input/EndpointMenu/EndpointMenu.jsx b/client/src/components/Input/EndpointMenu/EndpointMenu.jsx index 85fbb1e0f..d7bbf439e 100644 --- a/client/src/components/Input/EndpointMenu/EndpointMenu.jsx +++ b/client/src/components/Input/EndpointMenu/EndpointMenu.jsx @@ -20,6 +20,7 @@ import { } from '~/components/ui/'; import DialogTemplate from '~/components/ui/DialogTemplate'; import { cn, cleanupPreset, getDefaultConversation } from '~/utils'; +import { useLocalize } from '~/hooks'; import store from '~/store'; @@ -145,6 +146,8 @@ export default function NewConversationMenu() { button: true, }); + const localize = useLocalize(); + return ( @@ -159,7 +162,7 @@ export default function NewConversationMenu() { > {icon} - New Topic + {localize('com_endpoint_new_topic')} @@ -171,7 +174,8 @@ export default function NewConversationMenu() { className="cursor-pointer dark:text-gray-300" onClick={() => setShowEndpoints((prev) => !prev)} > - {showEndpoints ? 'Hide ' : 'Show '} Endpoints + {showEndpoints ? localize('com_endpoint_hide') : localize('com_endpoint_show')}{' '} + {localize('com_endpoint')} ) : ( - No endpoint available. + {localize('com_endpoint_not_available')} ))} @@ -200,7 +204,8 @@ export default function NewConversationMenu() { className="mr-auto cursor-pointer " onClick={() => setShowPresets((prev) => !prev)} > - {showPresets ? 'Hide ' : 'Show '} Presets + {showPresets ? localize('com_endpoint_hide') : localize('com_endpoint_show')}{' '} + {localize('com_endpoint_examples')} @@ -214,7 +219,7 @@ export default function NewConversationMenu() { className="h-auto bg-transparent px-2 py-1 text-xs font-medium font-normal text-red-700 hover:bg-slate-200 hover:text-red-700 dark:bg-transparent dark:text-red-400 dark:hover:bg-gray-800 dark:hover:text-red-400" > */} - Clear All + {localize('com_endpoint_clear_all')} {/* */} @@ -246,7 +251,9 @@ export default function NewConversationMenu() { onDeletePreset={onDeletePreset} /> ) : ( - No preset yet. + + {localize('com_endpoint_no_presets')} + ))} diff --git a/client/src/components/Input/Footer.tsx b/client/src/components/Input/Footer.tsx index 3a9450a56..202500f60 100644 --- a/client/src/components/Input/Footer.tsx +++ b/client/src/components/Input/Footer.tsx @@ -1,8 +1,10 @@ import React from 'react'; import { useGetStartupConfig } from 'librechat-data-provider'; +import { useLocalize } from '~/hooks'; export default function Footer() { const { data: config } = useGetStartupConfig(); + const localize = useLocalize(); return (
@@ -14,7 +16,7 @@ export default function Footer() { > {config?.appTitle || 'LibreChat'} v0.5.7 - {' - '}. All AI conversations in one place. Pay per call and not per month. + {' - '}. {localize('com_ui_pay_per_call')}
); } diff --git a/client/src/components/Input/GenerationButtons.tsx b/client/src/components/Input/GenerationButtons.tsx index 6e14b2246..71479febe 100644 --- a/client/src/components/Input/GenerationButtons.tsx +++ b/client/src/components/Input/GenerationButtons.tsx @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars import { cn, removeFocusOutlines } from '~/utils/'; type GenerationButtonsProps = { diff --git a/client/src/components/Nav/ClearConvos.tsx b/client/src/components/Nav/ClearConvos.tsx index 07eb5bfb5..fa9844974 100644 --- a/client/src/components/Nav/ClearConvos.tsx +++ b/client/src/components/Nav/ClearConvos.tsx @@ -4,15 +4,14 @@ import DialogTemplate from '~/components/ui/DialogTemplate'; import { ClearChatsButton } from './SettingsTabs/'; import { useClearConversationsMutation } from 'librechat-data-provider'; import store from '~/store'; -import { useRecoilValue } from 'recoil'; -import { localize } from '~/localization/Translation'; +import { useLocalize } from '~/hooks'; const ClearConvos = ({ open, onOpenChange }) => { const { newConversation } = store.useConversation(); const { refreshConversations } = store.useConversations(); const clearConvosMutation = useClearConversationsMutation(); const [confirmClear, setConfirmClear] = useState(false); - const lang = useRecoilValue(store.lang); + const localize = useLocalize(); const clearConvos = useCallback(() => { if (confirmClear) { @@ -34,10 +33,10 @@ const ClearConvos = ({ open, onOpenChange }) => { return ( { const [open, setOpen] = useState(false); - const lang = useRecoilValue(store.lang); + const localize = useLocalize(); const conversation = useRecoilValue(store.conversation) || {}; @@ -35,7 +35,7 @@ const ExportConversation = forwardRef(() => { onClick={clickHandler} > - {localize(lang, 'com_nav_export_conversation')} + {localize('com_nav_export_conversation')} diff --git a/client/src/components/Nav/MobileNav.jsx b/client/src/components/Nav/MobileNav.jsx index 4e7567004..be1d14c48 100644 --- a/client/src/components/Nav/MobileNav.jsx +++ b/client/src/components/Nav/MobileNav.jsx @@ -1,14 +1,13 @@ import React from 'react'; import { useRecoilValue } from 'recoil'; - import store from '~/store'; -import { localize } from '~/localization/Translation'; +import { useLocalize } from '~/hooks'; export default function MobileNav({ setNavVisible }) { const conversation = useRecoilValue(store.conversation); const { newConversation } = store.useConversation(); const { title = 'New Chat' } = conversation || {}; - const lang = useRecoilValue(store.lang); + const localize = useLocalize(); return (
@@ -17,7 +16,7 @@ export default function MobileNav({ setNavVisible }) { className="-ml-0.5 -mt-0.5 inline-flex h-10 w-10 items-center justify-center rounded-md hover:text-gray-900 focus:outline-none focus:ring-0 focus:ring-inset focus:ring-white dark:hover:text-white" onClick={() => setNavVisible((prev) => !prev)} > - {localize(lang, 'com_nav_open_sidebar')} + {localize('com_nav_open_sidebar')}

- {title || localize(lang, 'com_ui_new_chat')} + {title || localize('com_ui_new_chat')}

- {user?.name || localize(lang, 'com_nav_user')} + {user?.name || localize('com_nav_user')}
@@ -82,7 +82,7 @@ export default function NavLinks() { exportable ? 'cursor-pointer text-white' : 'cursor-not-allowed text-white/50', )} svg={() => } - text={localize(lang, 'com_nav_export_conversation')} + text={localize('com_nav_export_conversation')} clickHandler={clickHandler} /> @@ -91,7 +91,7 @@ export default function NavLinks() { } - text={localize(lang, 'com_nav_help_faq')} + text={localize('com_nav_help_faq')} clickHandler={() => window.open('https://docs.librechat.ai/', '_blank')} /> @@ -99,7 +99,7 @@ export default function NavLinks() { } - text={localize(lang, 'com_nav_settings')} + text={localize('com_nav_settings')} clickHandler={() => setShowSettings(true)} /> diff --git a/client/src/components/Nav/NewChat.jsx b/client/src/components/Nav/NewChat.jsx index 024b08f63..9a2f43025 100644 --- a/client/src/components/Nav/NewChat.jsx +++ b/client/src/components/Nav/NewChat.jsx @@ -1,11 +1,10 @@ import React from 'react'; import store from '~/store'; -import { useRecoilValue } from 'recoil'; -import { localize } from '~/localization/Translation'; +import { useLocalize } from '~/hooks'; export default function NewChat() { const { newConversation } = store.useConversation(); - const lang = useRecoilValue(store.lang); + const localize = useLocalize(); const clickHandler = () => { // dispatch(setInputValue('')); @@ -33,7 +32,7 @@ export default function NewChat() { - {localize(lang, 'com_ui_new_chat')} + {localize('com_ui_new_chat')} ); } diff --git a/client/src/components/Plugins/Store/PluginAuthForm.tsx b/client/src/components/Plugins/Store/PluginAuthForm.tsx index 175c37b49..711cd8f68 100644 --- a/client/src/components/Plugins/Store/PluginAuthForm.tsx +++ b/client/src/components/Plugins/Store/PluginAuthForm.tsx @@ -23,10 +23,10 @@ function PluginAuthForm({ plugin, onSubmit }: TPluginAuthFormProps) { className="col-span-1 flex w-full flex-col items-start justify-start gap-2" method="POST" onSubmit={handleSubmit((auth) => - onSubmit({ pluginKey: plugin!.pluginKey, action: 'install', auth }), + onSubmit({ pluginKey: plugin?.pluginKey, action: 'install', auth }), )} > - {plugin!.authConfig?.map((config: TPluginAuthConfig, i: number) => ( + {plugin?.authConfig?.map((config: TPluginAuthConfig, i: number) => (