diff --git a/memento-note/app/(admin)/admin/settings/admin-settings-form.tsx b/memento-note/app/(admin)/admin/settings/admin-settings-form.tsx index cb5f0fb..7632bcf 100644 --- a/memento-note/app/(admin)/admin/settings/admin-settings-form.tsx +++ b/memento-note/app/(admin)/admin/settings/admin-settings-form.tsx @@ -91,11 +91,11 @@ export function AdminSettingsForm({ config }: { config: Record } else if (type === 'embeddings') setOllamaEmbeddingsModels(result.models) else setOllamaChatModels(result.models) } else { - toast.error(`Failed to fetch Ollama models: ${result.error}`) + toast.error(`${t('admin.ai.fetchModelsFailed')}: ${result.error}`) } } catch (error) { console.error(error) - toast.error('Failed to fetch Ollama models') + toast.error(t('admin.ai.fetchModelsFailed')) } finally { if (type === 'tags') setIsLoadingTagsModels(false) else if (type === 'embeddings') setIsLoadingEmbeddingsModels(false) @@ -122,11 +122,11 @@ export function AdminSettingsForm({ config }: { config: Record } else if (type === 'embeddings') setCustomEmbeddingsModels(result.models) else setCustomChatModels(result.models) } else { - toast.error(`Impossible de récupérer les modèles : ${result.error}`) + toast.error(`${t('admin.ai.fetchModelsFailed')}: ${result.error}`) } } catch (error) { console.error(error) - toast.error('Erreur lors de la récupération des modèles') + toast.error(t('admin.ai.fetchModelsFailed')) } finally { if (type === 'tags') setIsLoadingCustomTagsModels(false) else if (type === 'embeddings') setIsLoadingCustomEmbeddingsModels(false) @@ -439,7 +439,7 @@ export function AdminSettingsForm({ config }: { config: Record } fetchOllamaModels('tags', input.value) }} disabled={isLoadingTagsModels} - title="Refresh Models" + title={t('admin.ai.refreshModels')} > @@ -455,15 +455,20 @@ export function AdminSettingsForm({ config }: { config: Record } className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" > {ollamaTagsModels.length > 0 ? ( - ollamaTagsModels.map((model) => ( - - )) + <> + {!ollamaTagsModels.includes(selectedTagsModel) && selectedTagsModel && ( + + )} + {ollamaTagsModels.map((model) => ( + + ))} + ) : ( )}

- {isLoadingTagsModels ? 'Fetching models...' : t('admin.ai.selectOllamaModel')} + {isLoadingTagsModels ? t('admin.ai.fetchingModels') : t('admin.ai.selectOllamaModel')}

@@ -515,7 +520,7 @@ export function AdminSettingsForm({ config }: { config: Record } fetchCustomModels('tags', urlInput.value, keyInput.value) }} disabled={isLoadingCustomTagsModels} - title="Récupérer les modèles" + title={t('admin.ai.refreshModels')} > @@ -537,16 +542,16 @@ export function AdminSettingsForm({ config }: { config: Record } } value={selectedTagsModel} onChange={setSelectedTagsModel} - placeholder={selectedTagsModel || 'Cliquez sur ↺ pour charger les modèles'} - searchPlaceholder="Rechercher un modèle..." - emptyMessage="Aucun modèle. Cliquez sur ↺" + placeholder={selectedTagsModel || t('admin.ai.clickToLoadModels')} + searchPlaceholder={t('admin.ai.searchModel')} + emptyMessage={t('admin.ai.noModels')} />

{isLoadingCustomTagsModels - ? 'Récupération des modèles...' + ? t('admin.ai.fetchingModels') : customTagsModels.length > 0 - ? `${customTagsModels.length} modèle(s) disponible(s)` - : 'Renseignez l\'URL et cliquez sur ↺ pour charger les modèles'} + ? t('admin.ai.modelsAvailable', { count: customTagsModels.length }) + : t('admin.ai.enterUrlToLoad')}

@@ -563,7 +568,7 @@ export function AdminSettingsForm({ config }: { config: Record } -

- Config value: {config.AI_PROVIDER_EMBEDDING || 'Not set (defaults to ollama)'} -

{embeddingsProvider === 'ollama' && ( @@ -611,7 +613,7 @@ export function AdminSettingsForm({ config }: { config: Record } fetchOllamaModels('embeddings', input.value) }} disabled={isLoadingEmbeddingsModels} - title="Refresh Models" + title={t('admin.ai.refreshModels')} > @@ -627,15 +629,20 @@ export function AdminSettingsForm({ config }: { config: Record } className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" > {ollamaEmbeddingsModels.length > 0 ? ( - ollamaEmbeddingsModels.map((model) => ( - - )) + <> + {!ollamaEmbeddingsModels.includes(selectedEmbeddingModel) && selectedEmbeddingModel && ( + + )} + {ollamaEmbeddingsModels.map((model) => ( + + ))} + ) : ( )}

- {isLoadingEmbeddingsModels ? 'Fetching models...' : t('admin.ai.selectEmbeddingModel')} + {isLoadingEmbeddingsModels ? t('admin.ai.fetchingModels') : t('admin.ai.selectEmbeddingModel')}

@@ -687,7 +694,7 @@ export function AdminSettingsForm({ config }: { config: Record } fetchCustomModels('embeddings', urlInput.value, keyInput.value) }} disabled={isLoadingCustomEmbeddingsModels} - title="Récupérer les modèles" + title={t('admin.ai.refreshModels')} > @@ -709,16 +716,16 @@ export function AdminSettingsForm({ config }: { config: Record } } value={selectedEmbeddingModel} onChange={setSelectedEmbeddingModel} - placeholder={selectedEmbeddingModel || 'Cliquez sur ↺ pour charger les modèles'} - searchPlaceholder="Rechercher un modèle..." - emptyMessage="Aucun modèle. Cliquez sur ↺" + placeholder={selectedEmbeddingModel || t('admin.ai.clickToLoadModels')} + searchPlaceholder={t('admin.ai.searchModel')} + emptyMessage={t('admin.ai.noModels')} />

{isLoadingCustomEmbeddingsModels - ? 'Récupération des modèles...' + ? t('admin.ai.fetchingModels') : customEmbeddingsModels.length > 0 - ? `${customEmbeddingsModels.length} modèle(s) disponible(s)` - : 'Renseignez l\'URL et cliquez sur ↺ pour charger les modèles'} + ? t('admin.ai.modelsAvailable', { count: customEmbeddingsModels.length }) + : t('admin.ai.enterUrlToLoad')}

@@ -776,7 +783,7 @@ export function AdminSettingsForm({ config }: { config: Record } fetchOllamaModels('chat', input.value) }} disabled={isLoadingChatModels} - title="Refresh Models" + title={t('admin.ai.refreshModels')} > @@ -792,15 +799,20 @@ export function AdminSettingsForm({ config }: { config: Record } className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" > {ollamaChatModels.length > 0 ? ( - ollamaChatModels.map((model) => ( - - )) + <> + {!ollamaChatModels.includes(selectedChatModel) && selectedChatModel && ( + + )} + {ollamaChatModels.map((model) => ( + + ))} + ) : ( )}

- {isLoadingChatModels ? 'Fetching models...' : t('admin.ai.selectOllamaModel')} + {isLoadingChatModels ? t('admin.ai.fetchingModels') : t('admin.ai.selectOllamaModel')}

@@ -852,7 +864,7 @@ export function AdminSettingsForm({ config }: { config: Record } fetchCustomModels('chat', urlInput.value, keyInput.value) }} disabled={isLoadingCustomChatModels} - title="Récupérer les modèles" + title={t('admin.ai.refreshModels')} > @@ -874,16 +886,16 @@ export function AdminSettingsForm({ config }: { config: Record } } value={selectedChatModel} onChange={setSelectedChatModel} - placeholder={selectedChatModel || 'Cliquez sur ↺ pour charger les modèles'} - searchPlaceholder="Rechercher un modèle..." - emptyMessage="Aucun modèle. Cliquez sur ↺" + placeholder={selectedChatModel || t('admin.ai.clickToLoadModels')} + searchPlaceholder={t('admin.ai.searchModel')} + emptyMessage={t('admin.ai.noModels')} />

{isLoadingCustomChatModels - ? 'Récupération des modèles...' + ? t('admin.ai.fetchingModels') : customChatModels.length > 0 - ? `${customChatModels.length} modèle(s) disponible(s)` - : 'Renseignez l\'URL et cliquez sur ↺ pour charger les modèles'} + ? t('admin.ai.modelsAvailable', { count: customChatModels.length }) + : t('admin.ai.enterUrlToLoad')}

@@ -1105,7 +1117,7 @@ export function AdminSettingsForm({ config }: { config: Record } onClick={handleTestSearch} disabled={isTestingSearch} > - {isTestingSearch ? 'Test en cours…' : 'Tester la recherche web'} + {isTestingSearch ? t('admin.tools.testing') : t('admin.tools.testSearch')} diff --git a/memento-note/app/(admin)/admin/settings/page.tsx b/memento-note/app/(admin)/admin/settings/page.tsx index 4b23f30..087242b 100644 --- a/memento-note/app/(admin)/admin/settings/page.tsx +++ b/memento-note/app/(admin)/admin/settings/page.tsx @@ -1,20 +1,13 @@ import { getSystemConfig } from '@/app/actions/admin-settings' import { AdminSettingsForm } from './admin-settings-form' +import { SettingsHeader } from './settings-header' export default async function AdminSettingsPage() { const config = await getSystemConfig() return (
-
-

- Settings -

-

- Configure application-wide settings -

-
- +
diff --git a/memento-note/app/(admin)/admin/settings/settings-header.tsx b/memento-note/app/(admin)/admin/settings/settings-header.tsx new file mode 100644 index 0000000..194dc36 --- /dev/null +++ b/memento-note/app/(admin)/admin/settings/settings-header.tsx @@ -0,0 +1,17 @@ +'use client' + +import { useLanguage } from '@/lib/i18n' + +export function SettingsHeader() { + const { t } = useLanguage() + return ( +
+

+ {t('admin.settings')} +

+

+ {t('admin.settingsDescription')} +

+
+ ) +} diff --git a/memento-note/app/actions/register.ts b/memento-note/app/actions/register.ts index 9154ebe..3d28e02 100644 --- a/memento-note/app/actions/register.ts +++ b/memento-note/app/actions/register.ts @@ -9,7 +9,11 @@ import { getSystemConfig } from '@/lib/config'; const RegisterSchema = z.object({ email: z.string().email(), password: z.string().min(6), + confirmPassword: z.string().min(6), name: z.string().min(2), +}).refine((data) => data.password === data.confirmPassword, { + message: 'Passwords do not match', + path: ['confirmPassword'], }); export async function register(prevState: string | undefined, formData: FormData) { @@ -24,6 +28,7 @@ export async function register(prevState: string | undefined, formData: FormData const validatedFields = RegisterSchema.safeParse({ email: formData.get('email'), password: formData.get('password'), + confirmPassword: formData.get('confirmPassword'), name: formData.get('name'), }); diff --git a/memento-note/components/register-form.tsx b/memento-note/components/register-form.tsx index 82fb832..40a22ed 100644 --- a/memento-note/components/register-form.tsx +++ b/memento-note/components/register-form.tsx @@ -84,6 +84,25 @@ export function RegisterForm() { />
+
+ +
+ +
+