Refine i18n
This commit is contained in:
parent
6ab7b2089f
commit
c3e34ea629
@ -5,6 +5,7 @@ import { clsx } from 'clsx/lite';
|
|||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
import LinkWithStatus from '@/components/LinkWithStatus';
|
import LinkWithStatus from '@/components/LinkWithStatus';
|
||||||
import { IoArrowBack } from 'react-icons/io5';
|
import { IoArrowBack } from 'react-icons/io5';
|
||||||
|
import { APP_TEXT } from '@/app/config';
|
||||||
|
|
||||||
export default async function SignInPage() {
|
export default async function SignInPage() {
|
||||||
const session = await auth();
|
const session = await auth();
|
||||||
@ -27,7 +28,7 @@ export default async function SignInPage() {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<IoArrowBack className="translate-y-[1px]" />
|
<IoArrowBack className="translate-y-[1px]" />
|
||||||
Home
|
{APP_TEXT.nav.home}
|
||||||
</LinkWithStatus>
|
</LinkWithStatus>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { useAppState } from '@/state/AppState';
|
|||||||
import SignInForm from '@/auth/SignInForm';
|
import SignInForm from '@/auth/SignInForm';
|
||||||
import clsx from 'clsx/lite';
|
import clsx from 'clsx/lite';
|
||||||
import PhotoUploadWithStatus from '@/photo/PhotoUploadWithStatus';
|
import PhotoUploadWithStatus from '@/photo/PhotoUploadWithStatus';
|
||||||
|
import { APP_TEXT } from '@/app/config';
|
||||||
|
|
||||||
export default function SignInOrUploadClient({
|
export default function SignInOrUploadClient({
|
||||||
shouldResize,
|
shouldResize,
|
||||||
@ -21,10 +22,10 @@ export default function SignInOrUploadClient({
|
|||||||
)}>
|
)}>
|
||||||
<div>
|
<div>
|
||||||
{isCheckingAuth
|
{isCheckingAuth
|
||||||
? 'Loading ...'
|
? APP_TEXT.misc.loading
|
||||||
: isUserSignedIn
|
: isUserSignedIn
|
||||||
? 'Add your first photo'
|
? APP_TEXT.onboarding.setupFirstPhoto
|
||||||
: 'Sign in to upload photos'}
|
: APP_TEXT.onboarding.setupSignIn}
|
||||||
</div>
|
</div>
|
||||||
{!isCheckingAuth && isUserSignedIn === false &&
|
{!isCheckingAuth && isUserSignedIn === false &&
|
||||||
<div className="flex justify-center my-2 sm:my-4">
|
<div className="flex justify-center my-2 sm:my-4">
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
import { Photo, PhotoDateRange } from '@/photo';
|
import { Photo, PhotoDateRange } from '@/photo';
|
||||||
import { absolutePathForCameraImage, pathForCamera } from '@/app/paths';
|
import { absolutePathForCameraImage, pathForCamera } from '@/app/paths';
|
||||||
import OGTile from '@/components/OGTile';
|
import OGTile, { OGLoadingState } from '@/components/OGTile';
|
||||||
import { Camera } from '.';
|
import { Camera } from '.';
|
||||||
import { descriptionForCameraPhotos, titleForCamera } from './meta';
|
import { descriptionForCameraPhotos, titleForCamera } from './meta';
|
||||||
|
|
||||||
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
|
|
||||||
|
|
||||||
export default function CameraOGTile({
|
export default function CameraOGTile({
|
||||||
camera,
|
camera,
|
||||||
photos,
|
photos,
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export const titleForCamera = (
|
|||||||
photos: Photo[],
|
photos: Photo[],
|
||||||
explicitCount?: number,
|
explicitCount?: number,
|
||||||
) => [
|
) => [
|
||||||
APP_TEXT.category.cameraShare(
|
APP_TEXT.category.cameraTitle(
|
||||||
formatCameraText(cameraFromPhoto(photos[0], camera)),
|
formatCameraText(cameraFromPhoto(photos[0], camera)),
|
||||||
),
|
),
|
||||||
photoQuantityText(explicitCount ?? photos.length),
|
photoQuantityText(explicitCount ?? photos.length),
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { APP_TEXT } from '@/app/config';
|
||||||
import { toastWaiting } from '@/toast';
|
import { toastWaiting } from '@/toast';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useCallback, useEffect, useRef, useTransition } from 'react';
|
import { useCallback, useEffect, useRef, useTransition } from 'react';
|
||||||
@ -6,7 +7,7 @@ import { toast } from 'sonner';
|
|||||||
|
|
||||||
export default function useNavigateOrRunActionWithToast({
|
export default function useNavigateOrRunActionWithToast({
|
||||||
pathOrAction,
|
pathOrAction,
|
||||||
toastMessage = 'Loading...',
|
toastMessage = APP_TEXT.misc.loading,
|
||||||
dismissDelay = 1500,
|
dismissDelay = 1500,
|
||||||
}: {
|
}: {
|
||||||
pathOrAction?: string | (() => Promise<any> | undefined)
|
pathOrAction?: string | (() => Promise<any> | undefined)
|
||||||
|
|||||||
@ -3,11 +3,9 @@ import {
|
|||||||
absolutePathForFilmImage,
|
absolutePathForFilmImage,
|
||||||
pathForFilm,
|
pathForFilm,
|
||||||
} from '@/app/paths';
|
} from '@/app/paths';
|
||||||
import OGTile from '@/components/OGTile';
|
import OGTile, { OGLoadingState } from '@/components/OGTile';
|
||||||
import { descriptionForFilmPhotos, titleForFilm } from '.';
|
import { descriptionForFilmPhotos, titleForFilm } from '.';
|
||||||
|
|
||||||
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
|
|
||||||
|
|
||||||
export default function FilmOGTile({
|
export default function FilmOGTile({
|
||||||
film,
|
film,
|
||||||
photos,
|
photos,
|
||||||
|
|||||||
@ -3,11 +3,9 @@ import {
|
|||||||
absolutePathForFocalLengthImage,
|
absolutePathForFocalLengthImage,
|
||||||
pathForFocalLength,
|
pathForFocalLength,
|
||||||
} from '@/app/paths';
|
} from '@/app/paths';
|
||||||
import OGTile from '@/components/OGTile';
|
import OGTile, { OGLoadingState } from '@/components/OGTile';
|
||||||
import { descriptionForFocalLengthPhotos, titleForFocalLength } from '.';
|
import { descriptionForFocalLengthPhotos, titleForFocalLength } from '.';
|
||||||
|
|
||||||
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
|
|
||||||
|
|
||||||
export default function FocalLengthOGTile({
|
export default function FocalLengthOGTile({
|
||||||
focal,
|
focal,
|
||||||
photos,
|
photos,
|
||||||
|
|||||||
@ -57,7 +57,7 @@ const TEXT: I18NDeepPartial = {
|
|||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
theme: 'Tema',
|
theme: 'Tema',
|
||||||
system: 'Usar Sistema',
|
system: 'Sistema',
|
||||||
light: 'Modo Claro',
|
light: 'Modo Claro',
|
||||||
dark: 'Modo Escuro',
|
dark: 'Modo Escuro',
|
||||||
},
|
},
|
||||||
@ -93,7 +93,18 @@ const TEXT: I18NDeepPartial = {
|
|||||||
deleteConfirm: (photoTitle: string) =>
|
deleteConfirm: (photoTitle: string) =>
|
||||||
`Tem certeza que deseja excluir "${photoTitle}"?`,
|
`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: {
|
misc: {
|
||||||
|
loading: 'Carregando ...',
|
||||||
|
finishing: 'Finalizando ...',
|
||||||
|
uploading: 'Enviando',
|
||||||
repo: 'Feito com',
|
repo: 'Feito com',
|
||||||
copyPhrase: (label: string) => `${label} copiado`,
|
copyPhrase: (label: string) => `${label} copiado`,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -56,7 +56,7 @@ const TEXT = {
|
|||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
theme: 'Theme',
|
theme: 'Theme',
|
||||||
system: 'Use System',
|
system: 'System',
|
||||||
light: 'Light Mode',
|
light: 'Light Mode',
|
||||||
dark: 'Dark Mode',
|
dark: 'Dark Mode',
|
||||||
},
|
},
|
||||||
@ -92,7 +92,18 @@ const TEXT = {
|
|||||||
deleteConfirm: (photoTitle: string) =>
|
deleteConfirm: (photoTitle: string) =>
|
||||||
`Are you sure you want to delete "${photoTitle}?"`,
|
`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: {
|
misc: {
|
||||||
|
loading: 'Loading ...',
|
||||||
|
finishing: 'Finishing ...',
|
||||||
|
uploading: 'Uploading',
|
||||||
repo: 'Made with',
|
repo: 'Made with',
|
||||||
copyPhrase: (label: string) => `${label} copied`,
|
copyPhrase: (label: string) => `${label} copied`,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
import { Photo, PhotoDateRange } from '@/photo';
|
import { Photo, PhotoDateRange } from '@/photo';
|
||||||
import { absolutePathForLensImage, pathForLens } from '@/app/paths';
|
import { absolutePathForLensImage, pathForLens } from '@/app/paths';
|
||||||
import OGTile from '@/components/OGTile';
|
import OGTile, { OGLoadingState } from '@/components/OGTile';
|
||||||
import { Lens } from '.';
|
import { Lens } from '.';
|
||||||
import { titleForLens, descriptionForLensPhotos } from './meta';
|
import { titleForLens, descriptionForLensPhotos } from './meta';
|
||||||
|
|
||||||
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
|
|
||||||
|
|
||||||
export default function LensOGTile({
|
export default function LensOGTile({
|
||||||
lens,
|
lens,
|
||||||
photos,
|
photos,
|
||||||
|
|||||||
@ -5,9 +5,7 @@ import {
|
|||||||
} from '@/photo';
|
} from '@/photo';
|
||||||
import { PhotoSetCategory } from '../category';
|
import { PhotoSetCategory } from '../category';
|
||||||
import { absolutePathForPhotoImage, pathForPhoto } from '@/app/paths';
|
import { absolutePathForPhotoImage, pathForPhoto } from '@/app/paths';
|
||||||
import OGTile from '@/components/OGTile';
|
import OGTile, { OGLoadingState } from '@/components/OGTile';
|
||||||
|
|
||||||
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
|
|
||||||
|
|
||||||
export default function PhotoOGTile({
|
export default function PhotoOGTile({
|
||||||
photo,
|
photo,
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import { useRef } from 'react';
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import Spinner from '@/components/Spinner';
|
import Spinner from '@/components/Spinner';
|
||||||
import ResponsiveText from '@/components/primitives/ResponsiveText';
|
import ResponsiveText from '@/components/primitives/ResponsiveText';
|
||||||
|
import { APP_TEXT } from '@/app/config';
|
||||||
|
|
||||||
export default function PhotoUploadWithStatus({
|
export default function PhotoUploadWithStatus({
|
||||||
inputRef,
|
inputRef,
|
||||||
@ -72,10 +73,11 @@ export default function PhotoUploadWithStatus({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [resetUploadState]);
|
}, [resetUploadState]);
|
||||||
|
|
||||||
const isFinishing = isPending && shouldResetUploadStateAfterPending.current;
|
const isFinishing = isPending && shouldResetUploadStateAfterPending.current;
|
||||||
|
|
||||||
const uploadStatusText = filesLength > 1
|
const uploadStatusText = filesLength > 1
|
||||||
? `${fileUploadIndex + 1} of ${filesLength}`
|
? APP_TEXT.utility.paginate(fileUploadIndex + 1, filesLength)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -158,19 +160,19 @@ export default function PhotoUploadWithStatus({
|
|||||||
{isUploading
|
{isUploading
|
||||||
? isFinishing
|
? isFinishing
|
||||||
? <>
|
? <>
|
||||||
Finishing ...
|
{APP_TEXT.misc.finishing}
|
||||||
</>
|
</>
|
||||||
: <>
|
: <>
|
||||||
{!showButton && uploadStatusText
|
{!showButton && uploadStatusText
|
||||||
? <>
|
? <>
|
||||||
<ResponsiveText shortText={uploadStatusText}>
|
<ResponsiveText shortText={uploadStatusText}>
|
||||||
Uploading {uploadStatusText}
|
{APP_TEXT.misc.uploading} {uploadStatusText}
|
||||||
</ResponsiveText>
|
</ResponsiveText>
|
||||||
{': '}
|
{': '}
|
||||||
{fileUploadName}
|
{fileUploadName}
|
||||||
</>
|
</>
|
||||||
: <ResponsiveText shortText={fileUploadName}>
|
: <ResponsiveText shortText={fileUploadName}>
|
||||||
Uploading {fileUploadName}
|
{APP_TEXT.misc.uploading} {fileUploadName}
|
||||||
</ResponsiveText>}
|
</ResponsiveText>}
|
||||||
</>
|
</>
|
||||||
: !showButton && <>Initializing</>}
|
: !showButton && <>Initializing</>}
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import Container from '@/components/Container';
|
import Container from '@/components/Container';
|
||||||
import AppGrid from '@/components/AppGrid';
|
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 AdminAppConfiguration from '@/admin/AdminAppConfiguration';
|
||||||
import { clsx } from 'clsx/lite';
|
import { clsx } from 'clsx/lite';
|
||||||
import { HiOutlinePhotograph } from 'react-icons/hi';
|
import { HiOutlinePhotograph } from 'react-icons/hi';
|
||||||
@ -29,7 +33,9 @@ export default function PhotosEmptyState() {
|
|||||||
'font-bold text-2xl',
|
'font-bold text-2xl',
|
||||||
'text-gray-700 dark:text-gray-200',
|
'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>
|
</div>
|
||||||
{!IS_SITE_READY
|
{!IS_SITE_READY
|
||||||
? <AdminAppConfiguration simplifiedView />
|
? <AdminAppConfiguration simplifiedView />
|
||||||
@ -43,8 +49,7 @@ export default function PhotosEmptyState() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
Change this site's name and other configuration
|
{APP_TEXT.onboarding.setupConfig}
|
||||||
by editing environment variables referenced in
|
|
||||||
{' '}
|
{' '}
|
||||||
<Link
|
<Link
|
||||||
href={PATH_ADMIN_CONFIGURATION}
|
href={PATH_ADMIN_CONFIGURATION}
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import { Photo, PhotoDateRange } from '@/photo';
|
import { Photo, PhotoDateRange } from '@/photo';
|
||||||
import { absolutePathForRecipeImage, pathForRecipe } from '@/app/paths';
|
import { absolutePathForRecipeImage, pathForRecipe } from '@/app/paths';
|
||||||
import OGTile from '@/components/OGTile';
|
import OGTile, { OGLoadingState } from '@/components/OGTile';
|
||||||
import { descriptionForRecipePhotos, titleForRecipe } from '.';
|
import { descriptionForRecipePhotos, titleForRecipe } from '.';
|
||||||
|
|
||||||
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
|
|
||||||
|
|
||||||
export default function RecipeOGTile({
|
export default function RecipeOGTile({
|
||||||
recipe,
|
recipe,
|
||||||
photos,
|
photos,
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import { Photo, PhotoDateRange } from '@/photo';
|
import { Photo, PhotoDateRange } from '@/photo';
|
||||||
import { absolutePathForTagImage, pathForTag } from '@/app/paths';
|
import { absolutePathForTagImage, pathForTag } from '@/app/paths';
|
||||||
import OGTile from '@/components/OGTile';
|
import OGTile, { OGLoadingState } from '@/components/OGTile';
|
||||||
import { descriptionForTaggedPhotos, titleForTag } from '.';
|
import { descriptionForTaggedPhotos, titleForTag } from '.';
|
||||||
|
|
||||||
export type OGLoadingState = 'unloaded' | 'loading' | 'loaded' | 'failed';
|
|
||||||
|
|
||||||
export default function TagOGTile({
|
export default function TagOGTile({
|
||||||
tag,
|
tag,
|
||||||
photos,
|
photos,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user