diff --git a/app/sign-in/page.tsx b/app/sign-in/page.tsx index 13ecc9d3..023c9274 100644 --- a/app/sign-in/page.tsx +++ b/app/sign-in/page.tsx @@ -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() { )} > - Home + {APP_TEXT.nav.home} ); diff --git a/src/admin/SignInOrUploadClient.tsx b/src/admin/SignInOrUploadClient.tsx index d6a04e31..16bc16c2 100644 --- a/src/admin/SignInOrUploadClient.tsx +++ b/src/admin/SignInOrUploadClient.tsx @@ -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({ )}>
{isCheckingAuth - ? 'Loading ...' + ? APP_TEXT.misc.loading : isUserSignedIn - ? 'Add your first photo' - : 'Sign in to upload photos'} + ? APP_TEXT.onboarding.setupFirstPhoto + : APP_TEXT.onboarding.setupSignIn}
{!isCheckingAuth && isUserSignedIn === false &&
diff --git a/src/camera/CameraOGTile.tsx b/src/camera/CameraOGTile.tsx index 5e74795f..1c67e989 100644 --- a/src/camera/CameraOGTile.tsx +++ b/src/camera/CameraOGTile.tsx @@ -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, diff --git a/src/camera/meta.ts b/src/camera/meta.ts index 7d8bcaa9..9d7b3ce8 100644 --- a/src/camera/meta.ts +++ b/src/camera/meta.ts @@ -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), diff --git a/src/components/useNavigateOrRunActionWithToast.tsx b/src/components/useNavigateOrRunActionWithToast.tsx index 9a727630..260e71a2 100644 --- a/src/components/useNavigateOrRunActionWithToast.tsx +++ b/src/components/useNavigateOrRunActionWithToast.tsx @@ -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 | undefined) diff --git a/src/film/FilmOGTile.tsx b/src/film/FilmOGTile.tsx index 399f7d08..b0db04b8 100644 --- a/src/film/FilmOGTile.tsx +++ b/src/film/FilmOGTile.tsx @@ -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, diff --git a/src/focal/FocalLengthOGTile.tsx b/src/focal/FocalLengthOGTile.tsx index 6262bd31..c3ebd695 100644 --- a/src/focal/FocalLengthOGTile.tsx +++ b/src/focal/FocalLengthOGTile.tsx @@ -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, diff --git a/src/i18n/locales/pt-br.ts b/src/i18n/locales/pt-br.ts index 77772584..cc645f83 100644 --- a/src/i18n/locales/pt-br.ts +++ b/src/i18n/locales/pt-br.ts @@ -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`, }, diff --git a/src/i18n/locales/us-en.ts b/src/i18n/locales/us-en.ts index 0182bfe5..7b57b67e 100644 --- a/src/i18n/locales/us-en.ts +++ b/src/i18n/locales/us-en.ts @@ -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`, }, diff --git a/src/lens/LensOGTile.tsx b/src/lens/LensOGTile.tsx index cf6e7263..ba286f4a 100644 --- a/src/lens/LensOGTile.tsx +++ b/src/lens/LensOGTile.tsx @@ -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, diff --git a/src/photo/PhotoOGTile.tsx b/src/photo/PhotoOGTile.tsx index aa4e2803..3bc60dfa 100644 --- a/src/photo/PhotoOGTile.tsx +++ b/src/photo/PhotoOGTile.tsx @@ -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, diff --git a/src/photo/PhotoUploadWithStatus.tsx b/src/photo/PhotoUploadWithStatus.tsx index 9f6cdc69..405e116d 100644 --- a/src/photo/PhotoUploadWithStatus.tsx +++ b/src/photo/PhotoUploadWithStatus.tsx @@ -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 ? <> - Uploading {uploadStatusText} + {APP_TEXT.misc.uploading} {uploadStatusText} {': '} {fileUploadName} : - Uploading {fileUploadName} + {APP_TEXT.misc.uploading} {fileUploadName} } : !showButton && <>Initializing} diff --git a/src/photo/PhotosEmptyState.tsx b/src/photo/PhotosEmptyState.tsx index 69a931df..3365b776 100644 --- a/src/photo/PhotosEmptyState.tsx +++ b/src/photo/PhotosEmptyState.tsx @@ -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}
{!IS_SITE_READY ? @@ -43,8 +49,7 @@ export default function PhotosEmptyState() { }} />
- Change this site's name and other configuration - by editing environment variables referenced in + {APP_TEXT.onboarding.setupConfig} {' '}