i18n(es): translate page/component toasts (follow, delete, reports, sync, review queue)
This commit is contained in:
parent
2e9cbfba2b
commit
94a6628faa
7 changed files with 83 additions and 33 deletions
|
|
@ -13,6 +13,7 @@ import {
|
||||||
import { useDeleteEntity } from '@/hooks/useDeleteEntity';
|
import { useDeleteEntity } from '@/hooks/useDeleteEntity';
|
||||||
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
|
import { useTranslation } from '@/contexts/language';
|
||||||
import { isAdminPubkey } from '@/lib/admins';
|
import { isAdminPubkey } from '@/lib/admins';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import type { NostrEvent } from '@nostrify/nostrify';
|
import type { NostrEvent } from '@nostrify/nostrify';
|
||||||
|
|
@ -60,6 +61,7 @@ export function DeleteEntityDialog({
|
||||||
}: DeleteEntityDialogProps) {
|
}: DeleteEntityDialogProps) {
|
||||||
const { user } = useCurrentUser();
|
const { user } = useCurrentUser();
|
||||||
const { mutateAsync: deleteEntity, isPending } = useDeleteEntity();
|
const { mutateAsync: deleteEntity, isPending } = useDeleteEntity();
|
||||||
|
const { t } = useTranslation();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
||||||
|
|
@ -98,8 +100,8 @@ export function DeleteEntityDialog({
|
||||||
if (redirectTo) navigate(redirectTo);
|
if (redirectTo) navigate(redirectTo);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast({
|
toast({
|
||||||
title: 'Delete failed',
|
title: t('toastsUi.deleteFailed'),
|
||||||
description: error instanceof Error ? error.message : 'Something went wrong',
|
description: error instanceof Error ? error.message : t('toastsUi.somethingWentWrong'),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { useFollowActions, useIsFollowing } from '@/hooks/useFollowing';
|
||||||
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||||
import { useAuthor } from '@/hooks/useAuthor';
|
import { useAuthor } from '@/hooks/useAuthor';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
|
import { useTranslation } from '@/contexts/language';
|
||||||
import { genUserName } from '@/lib/genUserName';
|
import { genUserName } from '@/lib/genUserName';
|
||||||
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
|
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
|
||||||
|
|
||||||
|
|
@ -23,6 +24,7 @@ interface FounderFollowProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FounderFollow({ className, size = 'md', showBadge = true }: FounderFollowProps) {
|
export function FounderFollow({ className, size = 'md', showBadge = true }: FounderFollowProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { user } = useCurrentUser();
|
const { user } = useCurrentUser();
|
||||||
const { follow } = useFollowActions();
|
const { follow } = useFollowActions();
|
||||||
const isFollowing = useIsFollowing(FOUNDER_PUBKEY);
|
const isFollowing = useIsFollowing(FOUNDER_PUBKEY);
|
||||||
|
|
@ -66,8 +68,8 @@ export function FounderFollow({ className, size = 'md', showBadge = true }: Foun
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
toast({
|
toast({
|
||||||
title: 'Login Required',
|
title: t('toastsUi.loginRequired'),
|
||||||
description: 'Please log in to follow the founder',
|
description: t('toastsUi.loginToFollowFounder'),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|
@ -75,8 +77,8 @@ export function FounderFollow({ className, size = 'md', showBadge = true }: Foun
|
||||||
|
|
||||||
if (isFollowing) {
|
if (isFollowing) {
|
||||||
toast({
|
toast({
|
||||||
title: 'Already Following',
|
title: t('toastsUi.alreadyFollowing'),
|
||||||
description: `You're already following ${displayName}!`,
|
description: t('toastsUi.alreadyFollowingDesc', { name: displayName }),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -91,15 +93,15 @@ export function FounderFollow({ className, size = 'md', showBadge = true }: Foun
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[FounderFollow] Failed to follow:', error);
|
console.error('[FounderFollow] Failed to follow:', error);
|
||||||
}
|
}
|
||||||
}, [user, isFollowing, follow, displayName, cleanup, toast]);
|
}, [user, isFollowing, follow, displayName, cleanup, toast, t]);
|
||||||
|
|
||||||
const handleHoldStart = useCallback((e: React.TouchEvent | React.MouseEvent) => {
|
const handleHoldStart = useCallback((e: React.TouchEvent | React.MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (isFollowing) {
|
if (isFollowing) {
|
||||||
toast({
|
toast({
|
||||||
title: 'Already Following',
|
title: t('toastsUi.alreadyFollowing'),
|
||||||
description: `You're already following ${displayName}!`,
|
description: t('toastsUi.alreadyFollowingDesc', { name: displayName }),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +122,7 @@ export function FounderFollow({ className, size = 'md', showBadge = true }: Foun
|
||||||
|
|
||||||
// Timeout as backup
|
// Timeout as backup
|
||||||
holdTimer.current = setTimeout(handleHoldComplete, HOLD_DURATION);
|
holdTimer.current = setTimeout(handleHoldComplete, HOLD_DURATION);
|
||||||
}, [isFollowing, displayName, handleHoldComplete, toast]);
|
}, [isFollowing, displayName, handleHoldComplete, toast, t]);
|
||||||
|
|
||||||
const handleHoldEnd = useCallback(() => {
|
const handleHoldEnd = useCallback(() => {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { NSchema as n } from '@nostrify/nostrify';
|
||||||
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||||
import { useAppContext } from '@/hooks/useAppContext';
|
import { useAppContext } from '@/hooks/useAppContext';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
|
import { useTranslation } from '@/contexts/language';
|
||||||
|
|
||||||
// Citrine local relay (Android app by greenart7c3)
|
// Citrine local relay (Android app by greenart7c3)
|
||||||
const CITRINE_URL = 'ws://localhost:4869';
|
const CITRINE_URL = 'ws://localhost:4869';
|
||||||
|
|
@ -40,6 +41,7 @@ async function isCitrineAvailable(): Promise<boolean> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NostrSync() {
|
export function NostrSync() {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { nostr } = useNostr();
|
const { nostr } = useNostr();
|
||||||
const { user } = useCurrentUser();
|
const { user } = useCurrentUser();
|
||||||
const { logins } = useNostrLogin();
|
const { logins } = useNostrLogin();
|
||||||
|
|
@ -248,8 +250,8 @@ export function NostrSync() {
|
||||||
// New account — no profile published yet, nothing to sync.
|
// New account — no profile published yet, nothing to sync.
|
||||||
} else {
|
} else {
|
||||||
toast({
|
toast({
|
||||||
title: 'Could not load profile',
|
title: t('toastsUi.couldNotLoadProfile'),
|
||||||
description: 'Check your internet connection and try refreshing.',
|
description: t('toastsUi.couldNotLoadProfileDesc'),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,17 @@ import { useRecentReports, reportTargetMeta, type RecentReport } from '@/hooks/u
|
||||||
import { useAdminHide, useAdminVerify, useAdminClear } from '@/hooks/useAdminHide';
|
import { useAdminHide, useAdminVerify, useAdminClear } from '@/hooks/useAdminHide';
|
||||||
import { useAdminModeration } from '@/hooks/useAdminModeration';
|
import { useAdminModeration } from '@/hooks/useAdminModeration';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
|
import { useTranslation } from '@/contexts/language';
|
||||||
import { genUserName } from '@/lib/genUserName';
|
import { genUserName } from '@/lib/genUserName';
|
||||||
|
|
||||||
/** "3 h ago" — small enough to keep local. */
|
/** "3 h ago" — uses the shared `routeUi.age*` keys so it localizes. */
|
||||||
function ago(unixSeconds: number): string {
|
function ago(unixSeconds: number, t: (key: string, params?: Record<string, string | number>) => string): string {
|
||||||
const mins = Math.round((Date.now() / 1000 - unixSeconds) / 60);
|
const mins = Math.round((Date.now() / 1000 - unixSeconds) / 60);
|
||||||
if (mins < 1) return 'just now';
|
if (mins < 1) return t('routeUi.ageJustNow');
|
||||||
if (mins < 60) return `${mins} min ago`;
|
if (mins < 60) return t('routeUi.ageMinAgo', { count: mins });
|
||||||
const hours = Math.round(mins / 60);
|
const hours = Math.round(mins / 60);
|
||||||
if (hours < 24) return `${hours} h ago`;
|
if (hours < 24) return t('routeUi.ageHourAgo', { count: hours });
|
||||||
return `${Math.round(hours / 24)} d ago`;
|
return t('routeUi.ageDayAgo', { count: Math.round(hours / 24) });
|
||||||
}
|
}
|
||||||
|
|
||||||
function Reporter({ pubkey }: { pubkey: string }) {
|
function Reporter({ pubkey }: { pubkey: string }) {
|
||||||
|
|
@ -37,6 +38,7 @@ function Reporter({ pubkey }: { pubkey: string }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ReportRow({ report }: { report: RecentReport }) {
|
function ReportRow({ report }: { report: RecentReport }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { hideContent, isPending: hiding } = useAdminHide();
|
const { hideContent, isPending: hiding } = useAdminHide();
|
||||||
const { confirmContent, isPending: confirming } = useAdminVerify();
|
const { confirmContent, isPending: confirming } = useAdminVerify();
|
||||||
const { clearVerdict, isPending: clearing } = useAdminClear();
|
const { clearVerdict, isPending: clearing } = useAdminClear();
|
||||||
|
|
@ -56,8 +58,8 @@ function ReportRow({ report }: { report: RecentReport }) {
|
||||||
toast({ title });
|
toast({ title });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast({
|
toast({
|
||||||
title: 'Could not complete that',
|
title: t('toastsUi.couldNotComplete'),
|
||||||
description: e instanceof Error ? e.message : 'Try again.',
|
description: e instanceof Error ? e.message : t('toastsUi.tryAgainLower'),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -74,17 +76,17 @@ function ReportRow({ report }: { report: RecentReport }) {
|
||||||
{hidden && (
|
{hidden && (
|
||||||
<Badge className="border border-red-500/40 bg-red-500/10 text-[10px] font-bold uppercase tracking-wide text-red-300">
|
<Badge className="border border-red-500/40 bg-red-500/10 text-[10px] font-bold uppercase tracking-wide text-red-300">
|
||||||
<EyeOff className="mr-1 h-3 w-3" />
|
<EyeOff className="mr-1 h-3 w-3" />
|
||||||
Hidden
|
{t('toastsUi.hiddenToast')}
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
{verified && (
|
{verified && (
|
||||||
<Badge className="border border-emerald-500/40 bg-emerald-500/10 text-[10px] font-bold uppercase tracking-wide text-emerald-300">
|
<Badge className="border border-emerald-500/40 bg-emerald-500/10 text-[10px] font-bold uppercase tracking-wide text-emerald-300">
|
||||||
<BadgeCheck className="mr-1 h-3 w-3" />
|
<BadgeCheck className="mr-1 h-3 w-3" />
|
||||||
Confirmed
|
{t('toastsUi.confirmed')}
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
<span className="text-[11px] text-gray-500">
|
<span className="text-[11px] text-gray-500">
|
||||||
reported by <Reporter pubkey={report.reporter} /> · {ago(report.createdAt)}
|
{t('miscUi.reportedBy')} <Reporter pubkey={report.reporter} /> · {ago(report.createdAt, t)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -129,12 +131,12 @@ function ReportRow({ report }: { report: RecentReport }) {
|
||||||
id: target.id,
|
id: target.id,
|
||||||
reason: `reported (${report.reason}) by ${report.reporter}`,
|
reason: `reported (${report.reason}) by ${report.reporter}`,
|
||||||
}),
|
}),
|
||||||
'Hidden',
|
t('toastsUi.hiddenToast'),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{hiding ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <EyeOff className="h-3.5 w-3.5" />}
|
{hiding ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <EyeOff className="h-3.5 w-3.5" />}
|
||||||
Hide
|
{t('common.hide')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{target && !hidden && !verified && (
|
{target && !hidden && !verified && (
|
||||||
|
|
@ -145,12 +147,12 @@ function ReportRow({ report }: { report: RecentReport }) {
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
void act(
|
void act(
|
||||||
() => confirmContent({ coord, id: target.id, reason: 'report reviewed — no action' }),
|
() => confirmContent({ coord, id: target.id, reason: 'report reviewed — no action' }),
|
||||||
'Confirmed',
|
t('toastsUi.confirmed'),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{confirming ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <BadgeCheck className="h-3.5 w-3.5" />}
|
{confirming ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <BadgeCheck className="h-3.5 w-3.5" />}
|
||||||
Dismiss report
|
{t('miscUi.dismissReport')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{target && (hidden || verified) && (
|
{target && (hidden || verified) && (
|
||||||
|
|
@ -162,12 +164,12 @@ function ReportRow({ report }: { report: RecentReport }) {
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
void act(
|
void act(
|
||||||
() => clearVerdict({ coord, id: target.id, reason: 'verdict retracted' }),
|
() => clearVerdict({ coord, id: target.id, reason: 'verdict retracted' }),
|
||||||
'Undone',
|
t('toastsUi.undone'),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{clearing ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Undo2 className="h-3.5 w-3.5" />}
|
{clearing ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Undo2 className="h-3.5 w-3.5" />}
|
||||||
Undo
|
{t('common.undo')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{target && meta?.path && target.identifier && (
|
{target && meta?.path && target.identifier && (
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ const en = {
|
||||||
clear: 'Clear',
|
clear: 'Clear',
|
||||||
clearFilters: 'Clear Filters',
|
clearFilters: 'Clear Filters',
|
||||||
clearAll: 'Clear All',
|
clearAll: 'Clear All',
|
||||||
|
hide: 'Hide',
|
||||||
|
undo: 'Undo',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
|
|
@ -6860,6 +6862,8 @@ walletUi: {
|
||||||
collective: 'Collective',
|
collective: 'Collective',
|
||||||
collectiveDesc: 'Crew, studio or company',
|
collectiveDesc: 'Crew, studio or company',
|
||||||
membersLabel: 'Members',
|
membersLabel: 'Members',
|
||||||
|
dismissReport: 'Dismiss report',
|
||||||
|
reportedBy: 'reported by',
|
||||||
entityMembersHint: 'Add the Nostr accounts of your crew. Each member confirms their own spot with their key — until then they show as “pending”.',
|
entityMembersHint: 'Add the Nostr accounts of your crew. Each member confirms their own spot with their key — until then they show as “pending”.',
|
||||||
entityVerifiedHint: 'Membership is verified per member — nobody can be added to your crew without confirming from their own account.',
|
entityVerifiedHint: 'Membership is verified per member — nobody can be added to your crew without confirming from their own account.',
|
||||||
entityInvalidPubkey: 'Enter a valid npub, nprofile, or 64-char hex pubkey.',
|
entityInvalidPubkey: 'Enter a valid npub, nprofile, or 64-char hex pubkey.',
|
||||||
|
|
@ -7056,6 +7060,23 @@ walletUi: {
|
||||||
paymentReceivedDesc: 'Successfully received {{amount}} sats!',
|
paymentReceivedDesc: 'Successfully received {{amount}} sats!',
|
||||||
paymentSent: 'Payment sent',
|
paymentSent: 'Payment sent',
|
||||||
paymentSentDesc: 'Lightning payment completed successfully',
|
paymentSentDesc: 'Lightning payment completed successfully',
|
||||||
|
loginRequired: 'Login Required',
|
||||||
|
loginToFollowFounder: 'Please log in to follow the founder',
|
||||||
|
alreadyFollowing: 'Already Following',
|
||||||
|
alreadyFollowingDesc: "You're already following {{name}}!",
|
||||||
|
couldNotComplete: 'Could not complete that',
|
||||||
|
tryAgainLower: 'Try again.',
|
||||||
|
couldNotLoadProfile: 'Could not load profile',
|
||||||
|
couldNotLoadProfileDesc: 'Check your internet connection and try refreshing.',
|
||||||
|
undone: 'Undone',
|
||||||
|
undoneDesc: 'Back to neutral — not hidden, not vouched.',
|
||||||
|
confirmed: 'Confirmed',
|
||||||
|
confirmedDesc: 'Vouched for — it drops off this queue.',
|
||||||
|
hiddenToast: 'Hidden',
|
||||||
|
couldNotUndo: 'Could not undo',
|
||||||
|
couldNotConfirm: 'Could not confirm',
|
||||||
|
deleteFailed: 'Delete failed',
|
||||||
|
somethingWentWrong: 'Something went wrong',
|
||||||
},
|
},
|
||||||
cardUi: {
|
cardUi: {
|
||||||
save: 'Save card to Nostr',
|
save: 'Save card to Nostr',
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,8 @@ const es = {
|
||||||
clear: 'Limpiar',
|
clear: 'Limpiar',
|
||||||
clearFilters: 'Limpiar Filtros',
|
clearFilters: 'Limpiar Filtros',
|
||||||
clearAll: 'Limpiar Todo',
|
clearAll: 'Limpiar Todo',
|
||||||
|
hide: 'Ocultar',
|
||||||
|
undo: 'Deshacer',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
|
|
@ -6860,6 +6862,8 @@ walletUi: {
|
||||||
collective: 'Colectivo',
|
collective: 'Colectivo',
|
||||||
collectiveDesc: 'Crew, estudio o empresa',
|
collectiveDesc: 'Crew, estudio o empresa',
|
||||||
membersLabel: 'Miembros',
|
membersLabel: 'Miembros',
|
||||||
|
dismissReport: 'Descartar reporte',
|
||||||
|
reportedBy: 'reportado por',
|
||||||
entityMembersHint: 'Añade las cuentas Nostr de tu crew. Cada miembro confirma su propio spot con su clave — hasta entonces aparecen como “pendientes”.',
|
entityMembersHint: 'Añade las cuentas Nostr de tu crew. Cada miembro confirma su propio spot con su clave — hasta entonces aparecen como “pendientes”.',
|
||||||
entityVerifiedHint: 'La membresía se verifica por miembro — nadie puede añadirse a tu crew sin confirmarlo desde su propia cuenta.',
|
entityVerifiedHint: 'La membresía se verifica por miembro — nadie puede añadirse a tu crew sin confirmarlo desde su propia cuenta.',
|
||||||
entityInvalidPubkey: 'Introduce un npub, nprofile o clave hex de 64 caracteres válidos.',
|
entityInvalidPubkey: 'Introduce un npub, nprofile o clave hex de 64 caracteres válidos.',
|
||||||
|
|
@ -7056,6 +7060,23 @@ walletUi: {
|
||||||
paymentReceivedDesc: '¡Recibidos {{amount}} sats con éxito!',
|
paymentReceivedDesc: '¡Recibidos {{amount}} sats con éxito!',
|
||||||
paymentSent: 'Pago enviado',
|
paymentSent: 'Pago enviado',
|
||||||
paymentSentDesc: 'Pago Lightning completado correctamente',
|
paymentSentDesc: 'Pago Lightning completado correctamente',
|
||||||
|
loginRequired: 'Inicio de sesión requerido',
|
||||||
|
loginToFollowFounder: 'Inicia sesión para seguir al fundador',
|
||||||
|
alreadyFollowing: 'Ya lo sigues',
|
||||||
|
alreadyFollowingDesc: '¡Ya sigues a {{name}}!',
|
||||||
|
couldNotComplete: 'No se pudo completar eso',
|
||||||
|
tryAgainLower: 'Inténtalo de nuevo.',
|
||||||
|
couldNotLoadProfile: 'No se pudo cargar el perfil',
|
||||||
|
couldNotLoadProfileDesc: 'Revisa tu conexión a internet y prueba a actualizar.',
|
||||||
|
undone: 'Deshecho',
|
||||||
|
undoneDesc: 'Vuelto a neutro — ni oculto ni avalado.',
|
||||||
|
confirmed: 'Confirmado',
|
||||||
|
confirmedDesc: 'Avalado — sale de esta cola.',
|
||||||
|
hiddenToast: 'Oculto',
|
||||||
|
couldNotUndo: 'No se pudo deshacer',
|
||||||
|
couldNotConfirm: 'No se pudo confirmar',
|
||||||
|
deleteFailed: 'Falló la eliminación',
|
||||||
|
somethingWentWrong: 'Algo salió mal',
|
||||||
},
|
},
|
||||||
cardUi: {
|
cardUi: {
|
||||||
save: 'Guardar carné en Nostr',
|
save: 'Guardar carné en Nostr',
|
||||||
|
|
|
||||||
|
|
@ -399,8 +399,8 @@ function QueueList({
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
void act(
|
void act(
|
||||||
() => clearVerdict({ coord, id: row.id, reason: 'verdict retracted' }),
|
() => clearVerdict({ coord, id: row.id, reason: 'verdict retracted' }),
|
||||||
{ title: 'Undone', description: 'Back to neutral — not hidden, not vouched.' },
|
{ title: t('toastsUi.undone'), description: t('toastsUi.undoneDesc') },
|
||||||
'Could not undo',
|
t('toastsUi.couldNotUndo'),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
@ -416,8 +416,8 @@ function QueueList({
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
void act(
|
void act(
|
||||||
() => confirmContent({ coord, id: row.id, reason: 'looks legit after review' }),
|
() => confirmContent({ coord, id: row.id, reason: 'looks legit after review' }),
|
||||||
{ title: 'Confirmed', description: 'Vouched for — it drops off this queue.' },
|
{ title: t('toastsUi.confirmed'), description: t('toastsUi.confirmedDesc') },
|
||||||
'Could not confirm',
|
t('toastsUi.couldNotConfirm'),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue