Refine i18n

This commit is contained in:
Sam Becker 2025-05-10 17:17:18 -05:00
parent 6ab7b2089f
commit c3e34ea629
15 changed files with 55 additions and 37 deletions

View File

@ -5,6 +5,7 @@ import { clsx } from 'clsx/lite';
import { redirect } from 'next/navigation';
import LinkWithStatus from '@/components/LinkWithStatus';
import { IoArrowBack } from 'react-icons/io5';
import { APP_TEXT } from '@/app/config';
export default async function SignInPage() {
const session = await auth();
@ -27,7 +28,7 @@ export default async function SignInPage() {
)}
>
<IoArrowBack className="translate-y-[1px]" />
Home
{APP_TEXT.nav.home}
</LinkWithStatus>
</div>
);

View File

@ -4,6 +4,7 @@ import { useAppState } from '@/state/AppState';
import SignInForm from '@/auth/SignInForm';
import clsx from 'clsx/lite';
import PhotoUploadWithStatus from '@/photo/PhotoUploadWithStatus';
import { APP_TEXT } from '@/app/config';
export default function SignInOrUploadClient({
shouldResize,
@ -21,10 +22,10 @@ export default function SignInOrUploadClient({
)}>
<div>
{isCheckingAuth
? 'Loading ...'
? APP_TEXT.misc.loading
: isUserSignedIn
? 'Add your first photo'
: 'Sign in to upload photos'}
? APP_TEXT.onboarding.setupFirstPhoto
: APP_TEXT.onboarding.setupSignIn}
</div>
{!isCheckingAuth && isUserSignedIn === false &&
<div className="flex justify-center my-2 sm:my-4">

View File

@ -1,11 +1,9 @@
import { Photo, PhotoDateRange } from '@/photo';
import { absolutePathForCameraImage, pathForCamera } from '@/app/paths';
import OGTile from '@/components/OGTile';
import OGTile, { OGLoadingState } from '@/components/OGTile';
import { Camera } from '.';
import { descriptionForCameraPhotos, titleForCamera } from './meta';
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
export default function CameraOGTile({
camera,
photos,

View File

@ -20,7 +20,7 @@ export const titleForCamera = (
photos: Photo[],
explicitCount?: number,
) => [
APP_TEXT.category.cameraShare(
APP_TEXT.category.cameraTitle(
formatCameraText(cameraFromPhoto(photos[0], camera)),
),
photoQuantityText(explicitCount ?? photos.length),

View File

@ -1,3 +1,4 @@
import { APP_TEXT } from '@/app/config';
import { toastWaiting } from '@/toast';
import { useRouter } from 'next/navigation';
import { useCallback, useEffect, useRef, useTransition } from 'react';
@ -6,7 +7,7 @@ import { toast } from 'sonner';
export default function useNavigateOrRunActionWithToast({
pathOrAction,
toastMessage = 'Loading...',
toastMessage = APP_TEXT.misc.loading,
dismissDelay = 1500,
}: {
pathOrAction?: string | (() => Promise<any> | undefined)

View File

@ -3,11 +3,9 @@ import {
absolutePathForFilmImage,
pathForFilm,
} from '@/app/paths';
import OGTile from '@/components/OGTile';
import OGTile, { OGLoadingState } from '@/components/OGTile';
import { descriptionForFilmPhotos, titleForFilm } from '.';
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
export default function FilmOGTile({
film,
photos,

View File

@ -3,11 +3,9 @@ import {
absolutePathForFocalLengthImage,
pathForFocalLength,
} from '@/app/paths';
import OGTile from '@/components/OGTile';
import OGTile, { OGLoadingState } from '@/components/OGTile';
import { descriptionForFocalLengthPhotos, titleForFocalLength } from '.';
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
export default function FocalLengthOGTile({
focal,
photos,

View File

@ -57,7 +57,7 @@ const TEXT: I18NDeepPartial = {
},
theme: {
theme: 'Tema',
system: 'Usar Sistema',
system: 'Sistema',
light: 'Modo Claro',
dark: 'Modo Escuro',
},
@ -93,7 +93,18 @@ const TEXT: I18NDeepPartial = {
deleteConfirm: (photoTitle: string) =>
`Tem certeza que deseja excluir "${photoTitle}"?`,
},
onboarding: {
setupComplete: 'Configuração Concluída!',
setupIncomplete: 'Finalizar Configuração',
setupSignIn: 'Entre para enviar fotos',
setupFirstPhoto: 'Adicione sua primeira foto',
// eslint-disable-next-line max-len
setupConfig: 'Altere o nome do site e outras configurações editando as variáveis de ambiente referenciadas em',
},
misc: {
loading: 'Carregando ...',
finishing: 'Finalizando ...',
uploading: 'Enviando',
repo: 'Feito com',
copyPhrase: (label: string) => `${label} copiado`,
},

View File

@ -56,7 +56,7 @@ const TEXT = {
},
theme: {
theme: 'Theme',
system: 'Use System',
system: 'System',
light: 'Light Mode',
dark: 'Dark Mode',
},
@ -92,7 +92,18 @@ const TEXT = {
deleteConfirm: (photoTitle: string) =>
`Are you sure you want to delete "${photoTitle}?"`,
},
onboarding: {
setupComplete: 'Setup Complete!',
setupIncomplete: 'Finish Setup',
setupSignIn: 'Sign in to upload photos',
setupFirstPhoto: 'Add your first photo',
// eslint-disable-next-line max-len
setupConfig: 'Change the site name and other configuration by editing environment variables referenced in',
},
misc: {
loading: 'Loading ...',
finishing: 'Finishing ...',
uploading: 'Uploading',
repo: 'Made with',
copyPhrase: (label: string) => `${label} copied`,
},

View File

@ -1,11 +1,9 @@
import { Photo, PhotoDateRange } from '@/photo';
import { absolutePathForLensImage, pathForLens } from '@/app/paths';
import OGTile from '@/components/OGTile';
import OGTile, { OGLoadingState } from '@/components/OGTile';
import { Lens } from '.';
import { titleForLens, descriptionForLensPhotos } from './meta';
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
export default function LensOGTile({
lens,
photos,

View File

@ -5,9 +5,7 @@ import {
} from '@/photo';
import { PhotoSetCategory } from '../category';
import { absolutePathForPhotoImage, pathForPhoto } from '@/app/paths';
import OGTile from '@/components/OGTile';
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
import OGTile, { OGLoadingState } from '@/components/OGTile';
export default function PhotoOGTile({
photo,

View File

@ -11,6 +11,7 @@ import { useRef } from 'react';
import { useEffect } from 'react';
import Spinner from '@/components/Spinner';
import ResponsiveText from '@/components/primitives/ResponsiveText';
import { APP_TEXT } from '@/app/config';
export default function PhotoUploadWithStatus({
inputRef,
@ -72,10 +73,11 @@ export default function PhotoUploadWithStatus({
}
};
}, [resetUploadState]);
const isFinishing = isPending && shouldResetUploadStateAfterPending.current;
const uploadStatusText = filesLength > 1
? `${fileUploadIndex + 1} of ${filesLength}`
? APP_TEXT.utility.paginate(fileUploadIndex + 1, filesLength)
: undefined;
return (
@ -158,19 +160,19 @@ export default function PhotoUploadWithStatus({
{isUploading
? isFinishing
? <>
Finishing ...
{APP_TEXT.misc.finishing}
</>
: <>
{!showButton && uploadStatusText
? <>
<ResponsiveText shortText={uploadStatusText}>
Uploading {uploadStatusText}
{APP_TEXT.misc.uploading} {uploadStatusText}
</ResponsiveText>
{': '}
{fileUploadName}
</>
: <ResponsiveText shortText={fileUploadName}>
Uploading {fileUploadName}
{APP_TEXT.misc.uploading} {fileUploadName}
</ResponsiveText>}
</>
: !showButton && <>Initializing</>}

View File

@ -1,6 +1,10 @@
import Container from '@/components/Container';
import AppGrid from '@/components/AppGrid';
import { IS_SITE_READY, PRESERVE_ORIGINAL_UPLOADS } from '@/app/config';
import {
APP_TEXT,
IS_SITE_READY,
PRESERVE_ORIGINAL_UPLOADS,
} from '@/app/config';
import AdminAppConfiguration from '@/admin/AdminAppConfiguration';
import { clsx } from 'clsx/lite';
import { HiOutlinePhotograph } from 'react-icons/hi';
@ -29,7 +33,9 @@ export default function PhotosEmptyState() {
'font-bold text-2xl',
'text-gray-700 dark:text-gray-200',
)}>
{!IS_SITE_READY ? 'Finish Setup' : 'Setup Complete!'}
{!IS_SITE_READY
? APP_TEXT.onboarding.setupIncomplete
: APP_TEXT.onboarding.setupComplete}
</div>
{!IS_SITE_READY
? <AdminAppConfiguration simplifiedView />
@ -43,8 +49,7 @@ export default function PhotosEmptyState() {
}}
/>
<div>
Change this site&apos;s name and other configuration
by editing environment variables referenced in
{APP_TEXT.onboarding.setupConfig}
{' '}
<Link
href={PATH_ADMIN_CONFIGURATION}

View File

@ -1,10 +1,8 @@
import { Photo, PhotoDateRange } from '@/photo';
import { absolutePathForRecipeImage, pathForRecipe } from '@/app/paths';
import OGTile from '@/components/OGTile';
import OGTile, { OGLoadingState } from '@/components/OGTile';
import { descriptionForRecipePhotos, titleForRecipe } from '.';
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
export default function RecipeOGTile({
recipe,
photos,

View File

@ -1,10 +1,8 @@
import { Photo, PhotoDateRange } from '@/photo';
import { absolutePathForTagImage, pathForTag } from '@/app/paths';
import OGTile from '@/components/OGTile';
import OGTile, { OGLoadingState } from '@/components/OGTile';
import { descriptionForTaggedPhotos, titleForTag } from '.';
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
export default function TagOGTile({
tag,
photos,