+ );
+ })}
{ setShowIdentityModal(false); setPendingAction(null); }}
diff --git a/frontend/src/contexts/GalleryAuthContext.tsx b/frontend/src/contexts/GalleryAuthContext.tsx
index 85acfae5..8b70da34 100644
--- a/frontend/src/contexts/GalleryAuthContext.tsx
+++ b/frontend/src/contexts/GalleryAuthContext.tsx
@@ -11,6 +11,7 @@ import {
setActiveGallerySlug,
storeGalleryToken,
} from '../utils/galleryAuthStorage';
+import type { GalleryAccessLevel } from '../types';
interface GalleryEvent {
id: number;
@@ -37,7 +38,10 @@ const normalizeEvent = (incoming: GalleryEvent | null | undefined): GalleryEvent
interface GalleryAuthContextType {
isAuthenticated: boolean;
event: GalleryEvent | null;
+ accessLevel: GalleryAccessLevel;
+ isClient: boolean;
login: (slug: string, password?: string, recaptchaToken?: string | null) => Promise;
+ clientLogin: (slug: string, password: string) => Promise;
logout: () => void;
isLoading: boolean;
error: string | null;
@@ -60,6 +64,7 @@ interface GalleryAuthProviderProps {
export const GalleryAuthProvider: React.FC = ({ children }) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [event, setEvent] = useState(null);
+ const [accessLevel, setAccessLevel] = useState('guest');
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const [routeError, setRouteError] = useState(null);
@@ -188,6 +193,14 @@ export const GalleryAuthProvider: React.FC = ({ childr
}
}
+ // Restore access level from session storage
+ const storedAccessLevel = sessionStorage.getItem(`gallery_access_level_${currentSlug}`);
+ if (storedAccessLevel === 'client') {
+ setAccessLevel('client');
+ } else {
+ setAccessLevel('guest');
+ }
+
const initialise = async () => {
try {
setIsLoading(true);
@@ -285,15 +298,43 @@ export const GalleryAuthProvider: React.FC = ({ childr
}
};
+ const clientLoginFn = async (slug: string, password: string) => {
+ try {
+ setRouteError(null);
+ setError(null);
+ setIsLoading(true);
+ const response = await authService.clientLogin(slug, password);
+ if (response.token) {
+ storeGalleryToken(slug, response.token);
+ }
+ setActiveGallerySlug(slug);
+ const normalizedEvent = normalizeEvent(response.event);
+ setEvent(normalizedEvent);
+ if (normalizedEvent) {
+ sessionStorage.setItem(`gallery_event_${slug}`, JSON.stringify(normalizedEvent));
+ }
+ setAccessLevel(response.accessLevel || 'client');
+ sessionStorage.setItem(`gallery_access_level_${slug}`, 'client');
+ setIsAuthenticated(true);
+ } catch (err: any) {
+ setError(err.response?.data?.error || 'Invalid PIN');
+ throw err;
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
const logout = () => {
const currentSlug = routeInfo.slug;
if (currentSlug) {
sessionStorage.removeItem(`gallery_event_${currentSlug}`);
+ sessionStorage.removeItem(`gallery_access_level_${currentSlug}`);
clearGalleryToken(currentSlug);
}
authService.galleryLogout(currentSlug || undefined);
setIsAuthenticated(false);
setEvent(null);
+ setAccessLevel('guest');
clearActiveGallerySlug();
};
@@ -302,7 +343,10 @@ export const GalleryAuthProvider: React.FC = ({ childr
value={{
isAuthenticated,
event,
+ accessLevel,
+ isClient: accessLevel === 'client',
login,
+ clientLogin: clientLoginFn,
logout,
isLoading,
error: routeError ?? error,
diff --git a/frontend/src/i18n/locales/de.json b/frontend/src/i18n/locales/de.json
index 31d0f5b2..0cc825d8 100644
--- a/frontend/src/i18n/locales/de.json
+++ b/frontend/src/i18n/locales/de.json
@@ -1758,6 +1758,13 @@
"username": "Benutzernamen wählen",
"password": "Passwort erstellen",
"submit": "Konto erstellen"
+ },
+ "photos": {
+ "hidden": "Versteckt",
+ "hideSelected": "Ausblenden",
+ "showSelected": "Einblenden",
+ "hiddenSuccess": "Fotos für Gäste ausgeblendet",
+ "visibleSuccess": "Fotos jetzt für Gäste sichtbar"
}
},
"permissions": {
@@ -2576,6 +2583,31 @@
"exportFiltered": "Gefilterte Fotos exportieren",
"hint": "Fotos auswählen oder Filter anwenden zum Exportieren"
},
+ "clientAccess": {
+ "title": "Kundenzugang",
+ "description": "Geben Sie Ihre PIN ein, um Fotos vor der Veröffentlichung zu überprüfen und auszuwählen.",
+ "pinLabel": "Kunden-PIN",
+ "pinPlaceholder": "PIN eingeben",
+ "enterPin": "Geben Sie die PIN ein, die Sie erhalten haben",
+ "invalidPin": "Ungültige PIN. Bitte versuchen Sie es erneut.",
+ "loginFailed": "Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut.",
+ "loginButton": "Zugang erhalten",
+ "guestHint": "Nur Fotos ansehen?",
+ "guestLink": "Zur Gästegalerie",
+ "banner": "Kundenmodus",
+ "visibleCount": "{{visible}} von {{total}} Fotos für Gäste sichtbar",
+ "hideSelected": "Ausgewählte ausblenden",
+ "showSelected": "Ausgewählte einblenden",
+ "adminTitle": "Kundenzugang",
+ "enableToggle": "Kundenzugang aktivieren",
+ "enableDescription": "Ermöglichen Sie Kunden, Fotos zu überprüfen und auszublenden, bevor die Galerie mit den Gästen geteilt wird.",
+ "pinHelperText": "Der Kunde verwendet diese PIN, um die Überprüfungsseite aufzurufen.",
+ "pinUpdated": "Kunden-PIN aktualisiert",
+ "setPin": "PIN festlegen",
+ "linkLabel": "Kundenzugangs-Link",
+ "regenerateToken": "Link neu generieren",
+ "tokenRegenerated": "Kundenzugangs-Link neu generiert"
+ },
"adminLogin": {
"title": "Admin-Anmeldung",
"subtitle": "Melden Sie sich an, um Ihre Fotogalerien zu verwalten",
diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json
index 29911f9a..5f001149 100644
--- a/frontend/src/i18n/locales/en.json
+++ b/frontend/src/i18n/locales/en.json
@@ -1471,6 +1471,13 @@
"username": "Choose a Username",
"password": "Create Password",
"submit": "Create Account"
+ },
+ "photos": {
+ "hidden": "Hidden",
+ "hideSelected": "Hide",
+ "showSelected": "Show",
+ "hiddenSuccess": "Photos hidden from guests",
+ "visibleSuccess": "Photos now visible to guests"
}
},
"permissions": {
@@ -2337,5 +2344,30 @@
"needHelp": "Need help? Contact",
"poweredBy": "Powered by PicPeak",
"devModeHint": "Development Mode: Use email: admin@example.com, password: admin123"
+ },
+ "clientAccess": {
+ "title": "Client Access",
+ "description": "Review photos and manage visibility before the gallery is shared with guests.",
+ "pinLabel": "Client PIN",
+ "pinPlaceholder": "Enter your client PIN",
+ "enterPin": "Please enter your client PIN",
+ "invalidPin": "Invalid PIN. Please try again.",
+ "loginFailed": "Authentication failed. Please try again.",
+ "loginButton": "Access Gallery",
+ "guestHint": "Looking for the guest gallery?",
+ "guestLink": "Go to guest view",
+ "banner": "Client Mode",
+ "visibleCount": "{{visible}} of {{total}} photos visible to guests",
+ "hideSelected": "Hide Selected",
+ "showSelected": "Show Selected",
+ "adminTitle": "Client Access",
+ "enableToggle": "Enable Client Access",
+ "enableDescription": "Allow clients to review and hide photos before the gallery is shared with guests.",
+ "pinHelperText": "The client will use this PIN to access the review page.",
+ "pinUpdated": "Client PIN updated",
+ "setPin": "Set PIN",
+ "linkLabel": "Client Access Link",
+ "regenerateToken": "Regenerate link",
+ "tokenRegenerated": "Client access link regenerated"
}
}
diff --git a/frontend/src/i18n/locales/pt.json b/frontend/src/i18n/locales/pt.json
index 9303f58f..b37991aa 100644
--- a/frontend/src/i18n/locales/pt.json
+++ b/frontend/src/i18n/locales/pt.json
@@ -1,72 +1,72 @@
{
"userManagement": {
- "title": "Gerenciamento de Usuarios",
- "subtitle": "Gerenciar usuarios administradores e convites",
- "loading": "Carregando usuarios...",
- "loadError": "Falha ao carregar usuarios. Por favor, tente novamente.",
- "inviteUser": "Convidar Usuario",
+ "title": "Gerenciamento de Usuários",
+ "subtitle": "Gerencie usuários administradores e convites",
+ "loading": "Carregando usuários...",
+ "loadError": "Falha ao carregar usuários. Por favor, tente novamente.",
+ "inviteUser": "Convidar Usuário",
"createInvitation": "Criar Convite",
- "email": "Endereco de Email",
+ "email": "Endereço de email",
"emailPlaceholder": "usuario@exemplo.com",
- "role": "Funcao",
- "selectRole": "Selecione uma funcao",
+ "role": "Função",
+ "selectRole": "Selecione uma função",
"sendInvitation": "Enviar Convite",
- "editUser": "Editar Usuario",
- "editingUser": "Editando usuario",
- "saveChanges": "Salvar Alteracoes",
- "deactivateUser": "Desativar Usuario",
+ "editUser": "Editar Usuário",
+ "editingUser": "Editando usuário",
+ "saveChanges": "Salvar Alterações",
+ "deactivateUser": "Desativar Usuário",
"cancelInvitation": "Cancelar Convite",
"invitationSent": "Convite enviado com sucesso",
"invitationError": "Falha ao enviar convite",
"invitationCancelled": "Convite cancelado",
"cancelInvitationError": "Falha ao cancelar convite",
- "userUpdated": "Usuario atualizado com sucesso",
- "updateUserError": "Falha ao atualizar usuario",
- "userDeactivated": "Usuario desativado com sucesso",
- "deactivateUserError": "Falha ao desativar usuario",
- "noRole": "Sem Funcao",
+ "userUpdated": "Usuário atualizado com sucesso",
+ "updateUserError": "Falha ao atualizar usuário",
+ "userDeactivated": "Usuário desativado com sucesso",
+ "deactivateUserError": "Falha ao desativar usuário",
+ "noRole": "Sem Função",
"neverLoggedIn": "Nunca fez login",
"expired": "Expirado",
"deactivate": "Desativar",
"cancel": "Cancelar",
"tabs": {
- "users": "Usuarios",
+ "users": "Usuários",
"invitations": "Convites"
},
"stats": {
- "totalUsers": "Total de Usuarios",
- "activeUsers": "Usuarios Ativos",
+ "totalUsers": "Total de Usuários",
+ "activeUsers": "Usuários Ativos",
"pendingInvitations": "Convites Pendentes",
- "inactiveUsers": "Usuarios Inativos"
+ "inactiveUsers": "Usuários Inativos"
},
"status": {
"active": "Ativo",
"inactive": "Inativo"
},
"table": {
- "user": "Usuario",
+ "user": "Usuário",
"email": "Email",
- "role": "Funcao",
+ "role": "Função",
"status": "Status",
- "lastLogin": "Ultimo Login",
- "actions": "Acoes",
+ "lastLogin": "Último Login",
+ "actions": "Ações",
"invitedBy": "Convidado Por",
"expires": "Expira"
},
"validation": {
- "emailRequired": "Email e obrigatorio",
- "emailInvalid": "Formato de email invalido",
- "roleRequired": "Funcao e obrigatoria"
+ "emailRequired": "Email é obrigatório",
+ "emailInvalid": "Formato de email inválido",
+ "roleRequired": "Função é obrigatória"
},
- "searchUsersPlaceholder": "Buscar usuarios...",
+ "searchUsersPlaceholder": "Buscar usuários...",
"searchInvitationsPlaceholder": "Buscar convites...",
- "noUsers": "Nenhum usuario encontrado",
- "noUsersFound": "Nenhum usuario corresponde a sua busca",
+ "noUsers": "Nenhum usuário encontrado",
+ "noUsersFound": "Nenhum usuário corresponde à sua busca",
"noInvitations": "Nenhum convite pendente",
- "noInvitationsFound": "Nenhum convite corresponde a sua busca",
+ "noInvitationsFound": "Nenhum convite corresponde à sua busca",
"confirmDeactivate": {
- "title": "Desativar Usuario",
- "message": "Tem certeza que deseja desativar {{name}}? Ele(a) nao podera mais fazer login."
+ "title": "Desativar Usuário",
+ "message": "Tem certeza que deseja desativar {{name}}? Ele(a) não poderá mais fazer login."
},
"confirmCancelInvitation": {
"title": "Cancelar Convite",
@@ -85,9 +85,9 @@
"filter": "Filtrar",
"sortBy": "Ordenar por",
"yes": "Sim",
- "no": "Nao",
+ "no": "Não",
"back": "Voltar",
- "next": "Proximo",
+ "next": "Próximo",
"previous": "Anterior",
"close": "Fechar",
"logout": "Sair",
@@ -100,22 +100,22 @@
"uploaded": "Enviado",
"photo": "foto",
"photos": "fotos",
- "video": "video",
- "videos": "videos",
- "media": "midia",
+ "video": "vídeo",
+ "videos": "vídeos",
+ "media": "mídia",
"restore": "Restaurar",
- "actions": "Acoes",
+ "actions": "Ações",
"refresh": "Atualizar",
- "preview": "Visualizar",
+ "preview": "Pré-visualização",
"processing": "Processando...",
"upload": "Enviar",
"days": "dias",
"customize": "Personalizar",
"hide": "Ocultar",
"unknown": "Desconhecido",
- "notSet": "Nao definido",
+ "notSet": "Não definido",
"of": "de",
- "up": "Acima",
+ "up": "Cima",
"select": "Selecionar",
"selected": "Selecionado",
"chunk": "Lote",
@@ -124,56 +124,56 @@
"upload": {
"photoCategory": "Categoria da Foto",
"noCategory": "Sem categoria",
- "eventSpecific": "(Especifico do evento)",
+ "eventSpecific": "(Específico do evento)",
"clickToUpload": "Clique para enviar ou arraste e solte",
- "fileRequirements": "JPEG, PNG ou WebP (max 50MB por arquivo, {{limit}} arquivos por envio)",
- "fileRequirementsMedia": "Imagens JPEG, PNG ou WebP, mais videos MP4/MOV/WEBM (max 50MB por arquivo, {{limit}} arquivos por envio)",
- "unsupportedFiles": "Alguns arquivos foram ignorados porque o formato nao e suportado (use JPEG/PNG/WebP/MP4/MOV/WEBM).",
+ "fileRequirements": "JPEG, PNG ou WebP (máx. 50MB por arquivo, {{limit}} arquivos por envio)",
+ "fileRequirementsMedia": "Imagens JPEG, PNG ou WebP, além de vídeos MP4/MOV/WEBM (máx. 50MB por arquivo, {{limit}} arquivos por envio)",
+ "unsupportedFiles": "Alguns arquivos foram ignorados porque o formato não é compatível (use JPEG/PNG/WebP/MP4/MOV/WEBM).",
"selectedFiles": "Arquivos selecionados",
"uploading": "Enviando...",
- "uploadComplete": "Envio concluido!",
+ "uploadComplete": "Envio concluído!",
"uploadFailed": "Falha no envio",
"someFilesFailed": "Alguns arquivos falharam ao enviar",
"uploadPhotos": "Enviar Fotos",
- "uploadMedia": "Enviar Fotos e Videos",
+ "uploadMedia": "Enviar Fotos e Vídeos",
"importExternal": "Importar de Pasta Externa",
- "externalImportInfo": "Todas as fotos da pasta selecionada serao importadas.",
- "selectExternalFolder": "Selecione pasta externa em /external-media",
+ "externalImportInfo": "Todas as imagens da pasta selecionada serão importadas.",
+ "selectExternalFolder": "Selecionar pasta externa em /external-media",
"importFromSelectedFolder": "Importar da pasta selecionada",
- "maxFilesReached": "Maximo de {{limit}} arquivos permitidos",
- "someFilesSkipped": "Apenas mais {{allowed}} arquivos podem ser adicionados (limite {{limit}})",
- "tooManyFiles": "Maximo de {{limit}} arquivos podem ser enviados de uma vez",
+ "maxFilesReached": "Máximo de {{limit}} arquivos permitido",
+ "someFilesSkipped": "Apenas {{allowed}} arquivo(s) pode(m) ser adicionado(s) (limite {{limit}})",
+ "tooManyFiles": "Máximo de {{limit}} arquivos podem ser enviados de uma vez",
"limitInfo": "{{selected}} de {{limit}} arquivos selecionados ({{remaining}} restantes)",
"limitReached": "Limite de envio atingido ({{limit}} arquivos por lote)",
"uploadingChunks": "Enviando {{count}} arquivos em {{total}} lotes...",
- "mediaCategory": "Categoria de midia",
+ "mediaCategory": "Categoria de mídia",
"uploadAction": "Enviar {{count}} arquivos"
},
"navigation": {
"dashboard": "Painel",
"events": "Eventos",
"archives": "Arquivos",
- "settings": "Configuracoes",
+ "settings": "Configurações",
"eventTypes": "Tipos de Evento",
- "branding": "Marca",
- "analytics": "Analiticos",
- "emailSettings": "Config. de Email",
- "backup": "Backup e Restauracao",
- "cmsPages": "Paginas CMS",
- "users": "Usuarios"
+ "branding": "Identidade Visual",
+ "analytics": "Análises",
+ "emailSettings": "Configurações de Email",
+ "backup": "Backup e Restauração",
+ "cmsPages": "Páginas CMS",
+ "users": "Usuários"
},
"archives": {
"title": "Arquivos",
- "subtitle": "Gerenciar galerias de fotos arquivadas",
+ "subtitle": "Gerencie galerias de fotos arquivadas",
"loadingArchives": "Carregando arquivos...",
"totalArchives": "Total de Arquivos",
"storageUsed": "Armazenamento Usado",
"totalPhotos": "Total de Fotos",
- "avgArchiveSize": "Tamanho Medio do Arquivo",
+ "avgArchiveSize": "Tamanho Médio do Arquivo",
"searchPlaceholder": "Buscar arquivos...",
"allTypes": "Todos os Tipos",
"wedding": "Casamento",
- "birthday": "Aniversario",
+ "birthday": "Aniversário",
"corporate": "Corporativo",
"other": "Outro",
"sortByDate": "Ordenar por Data",
@@ -182,10 +182,10 @@
"tableHeaders": {
"event": "Evento",
"type": "Tipo",
- "archivedDate": "Data de Arquivamento",
+ "archivedDate": "Data de Arquivo",
"size": "Tamanho",
"photos": "Fotos",
- "actions": "Acoes"
+ "actions": "Ações"
},
"noArchivesFound": "Nenhum arquivo encontrado",
"eventDateNA": "Data do evento: N/D",
@@ -193,26 +193,26 @@
"download": "Baixar",
"restore": "Restaurar",
"delete": "Excluir",
- "showing": "Mostrando {{from}} a {{to}} de {{total}} arquivos",
- "page": "Pagina {{current}} de {{total}}",
+ "showing": "Exibindo {{from}} a {{to}} de {{total}} arquivos",
+ "page": "Página {{current}} de {{total}}",
"storageManagement": "Gerenciamento de Armazenamento",
- "storageInfo": "Arquivos sao armazenados permanentemente a menos que sejam excluidos manualmente. Considere implementar uma politica de retencao para gerenciar custos de armazenamento.",
- "confirmRestore": "Tem certeza que deseja restaurar este arquivo? O evento ficara ativo novamente.",
- "confirmDelete": "Tem certeza que deseja excluir permanentemente este arquivo? Esta acao nao pode ser desfeita.",
+ "storageInfo": "Os arquivos são armazenados permanentemente, a menos que sejam excluídos manualmente. Considere implementar uma política de retenção para gerenciar os custos de armazenamento.",
+ "confirmRestore": "Tem certeza que deseja restaurar este arquivo? O evento ficará ativo novamente.",
+ "confirmDelete": "Tem certeza que deseja excluir permanentemente este arquivo? Esta ação não pode ser desfeita.",
"restoreSuccess": "Arquivo restaurado com sucesso",
- "deleteSuccess": "Arquivo excluido permanentemente"
+ "deleteSuccess": "Arquivo excluído permanentemente"
},
"auth": {
"login": "Entrar",
"password": "Senha",
"enterPassword": "Digite a Senha da Galeria",
"passwordPlaceholder": "Digite a senha da galeria",
- "invalidPassword": "Senha invalida",
+ "invalidPassword": "Senha inválida",
"wrongPassword": "Senha incorreta. Por favor, verifique sua senha e tente novamente.",
- "tooManyAttempts": "Muitas tentativas de login. Por favor, tente novamente mais tarde.",
- "sessionExpired": "Sessao expirada",
+ "tooManyAttempts": "Muitas tentativas de login malsucedidas. Por favor, tente novamente mais tarde.",
+ "sessionExpired": "Sessão expirada",
"pleaseEnterPassword": "Por favor, digite uma senha",
- "passwordHint": "A senha foi fornecida pelo organizador do evento. Entre em contato se voce nao a possui."
+ "passwordHint": "A senha foi fornecida pelo organizador do evento. Entre em contato com ele se você não a tiver."
},
"gallery": {
"title": "Galeria de Fotos",
@@ -224,7 +224,7 @@
"dayRemaining": "1 dia restante",
"hoursRemaining": "{{hours}} horas restantes",
"expiredMessage": "Esta galeria expirou em {{date}}",
- "contactOrganizer": "Por favor, entre em contato com o organizador do evento se precisar de acesso a estas fotos.",
+ "contactOrganizer": "Por favor, entre em contato com o organizador do evento se precisar de acesso a essas fotos.",
"searchPhotos": "Buscar fotos por nome de arquivo...",
"sortByDate": "Ordenar por Data",
"sortByName": "Ordenar por Nome",
@@ -232,11 +232,11 @@
"allPhotos": "Todas as Fotos",
"filter": "Filtrar",
"feedbackFilter": "Filtro de Feedback",
- "all": "Todos",
- "liked": "Curtidos",
- "favorited": "Favoritos",
+ "all": "Todas",
+ "liked": "Curtidas",
+ "favorited": "Favoritadas",
"favorites": "Favoritos",
- "downloadSelected": "Baixar {{count}} Selecionados",
+ "downloadSelected": "Baixar {{count}} Selecionadas",
"shareGallery": "Compartilhar Galeria",
"needHelp": "Precisa de ajuda? Entre em contato em",
"noPhotosFound": "Nenhuma foto encontrada",
@@ -246,8 +246,8 @@
"expiredOn": "Esta galeria expirou em {{date}}.",
"expiresIn": "A galeria expira em {{count}} dia",
"expiresIn_plural": "A galeria expira em {{count}} dias",
- "downloadBefore": "Baixe suas fotos antes que nao estejam mais disponiveis.",
- "publicGalleryTitle": "Esta galeria e acessivel publicamente",
+ "downloadBefore": "Baixe suas fotos antes que elas não estejam mais disponíveis.",
+ "publicGalleryTitle": "Esta galeria é de acesso público",
"publicGallerySubtitle": "Carregando as fotos agora...",
"viewGallery": "Ver Galeria",
"downloadAll": "Baixar Tudo",
@@ -257,114 +257,114 @@
"downloadedPhotos_plural": "{{count}} fotos baixadas!",
"downloadError": "Algumas fotos falharam ao baixar",
"selectPhotos": "Selecionar Fotos",
- "cancelSelection": "Cancelar Selecao",
- "photosSelected": "{{count}} selecionado(s)",
+ "cancelSelection": "Cancelar Seleção",
+ "photosSelected": "{{count}} selecionadas",
"selectAll": "Selecionar Tudo",
"deselectAll": "Desmarcar Tudo",
- "deleteSelected": "Excluir Selecionados",
+ "deleteSelected": "Excluir Selecionadas",
"photosCount": "{{count}} foto",
"photosCount_plural": "{{count}} fotos",
"searchByFilename": "Buscar por nome de arquivo...",
"uncategorized": "Sem categoria",
- "sortAscending": "Ordem crescente",
- "sortDescending": "Ordem decrescente",
- "remaining": "restante(s)",
- "selectPhotosHint": "Dica: Use Ctrl+Clique (Cmd+Clique no Mac) para selecionar varias fotos rapidamente",
+ "sortAscending": "Ordenar crescente",
+ "sortDescending": "Ordenar decrescente",
+ "remaining": "restantes",
+ "selectPhotosHint": "Dica: Use Ctrl+Clique (Cmd+Clique no Mac) para selecionar várias fotos rapidamente",
"filters": "Filtros",
"openFilters": "Abrir filtros",
"toggleSidebar": "Alternar barra lateral",
"toggleMenu": "Alternar menu",
"allCategories": "Todas as Categorias",
"categories": "Categorias",
- "mediaType": "Midia",
- "allMedia": "Toda midia",
+ "mediaType": "Mídia",
+ "allMedia": "Toda a mídia",
"photosOnly": "Fotos",
- "videosOnly": "Videos",
+ "videosOnly": "Vídeos",
"download": "Baixar",
- "noMedia": "Nenhuma midia enviada ainda",
+ "noMedia": "Nenhuma mídia enviada ainda",
"searchPlaceholder": "Buscar fotos...",
"sortBy": "Ordenar Por",
"sortByCaptureDate": "Ordenar por Data de Captura",
- "sortByRating": "Ordenar por Avaliacao",
+ "sortByRating": "Ordenar por Avaliação",
"photoGallery": "Galeria de Fotos",
"photos": "Fotos",
"allRightsReserved": "Todos os direitos reservados",
- "searchMemories": "Buscar memorias...",
+ "searchMemories": "Buscar memórias...",
"thankYou": "Obrigado",
- "thankYouMessage": "Por fazer parte da nossa historia e tornar nosso dia especial inesquecivel.",
+ "thankYouMessage": "Por fazer parte da nossa história e tornar nosso dia especial inesquecível.",
"feedback": {
"title": "Feedback",
- "shareThoughts": "Compartilhe seus pensamentos sobre \"{{name}}\"",
+ "shareThoughts": "Compartilhe sua opinião sobre \"{{name}}\"",
"rateThisMoment": "Avalie este momento",
- "comments": "Comentarios",
- "noComments": "Nenhum comentario ainda. Seja o primeiro!",
+ "comments": "Comentários",
+ "noComments": "Nenhum comentário ainda. Seja o primeiro!",
"yourName": "Seu nome",
"yourEmail": "Seu email",
"writeLovelyNote": "Escreva uma mensagem carinhosa...",
- "postComment": "Publicar Comentario",
- "anonymous": "Anonimo"
+ "postComment": "Publicar Comentário",
+ "anonymous": "Anônimo"
}
},
"categories": {
"title": "Categorias de Fotos",
"global": "Categorias Globais",
- "eventSpecific": "Categorias do Evento",
+ "eventSpecific": "Categorias Específicas do Evento",
"addCategory": "Adicionar Categoria",
- "organizationInfo": "Organize suas fotos em categorias. Categorias ajudam os convidados a navegar e encontrar tipos especificos de fotos.",
- "eventSpecificCategories": "Categorias Especificas do Evento",
- "noEventSpecificCategories": "Nenhuma categoria especifica do evento. Categorias globais estao disponiveis por padrao.",
- "globalCategoriesAlwaysAvailable": "Categorias Globais (sempre disponiveis):",
+ "organizationInfo": "Organize suas fotos em categorias. As categorias ajudam os convidados a navegar e encontrar tipos específicos de fotos.",
+ "eventSpecificCategories": "Categorias Específicas do Evento",
+ "noEventSpecificCategories": "Sem categorias específicas do evento. As categorias globais estão disponíveis por padrão.",
+ "globalCategoriesAlwaysAvailable": "Categorias Globais (sempre disponíveis):",
"deleteCategoryTitle": "Excluir categoria",
"categoryCreatedSuccess": "Categoria criada com sucesso",
- "categoryDeletedSuccess": "Categoria excluida com sucesso",
+ "categoryDeletedSuccess": "Categoria excluída com sucesso",
"failedToCreateCategory": "Falha ao criar categoria",
"failedToDeleteCategory": "Falha ao excluir categoria",
"categoryName": "Nome da categoria",
"noCategory": "Sem categoria",
- "noCategoriesYet": "Nenhuma categoria ainda. Crie sua primeira categoria para organizar fotos.",
- "deleteConfirm": "Tem certeza que deseja excluir \"{{name}}\"?",
- "cannotDelete": "Nao e possivel excluir categoria com fotos. Por favor, reatribua as fotos primeiro.",
+ "noCategoriesYet": "Nenhuma categoria ainda. Crie sua primeira categoria para organizar as fotos.",
+ "deleteConfirm": "Tem certeza de que deseja excluir \"{{name}}\"?",
+ "cannotDelete": "Não é possível excluir uma categoria com fotos. Reatribua as fotos primeiro.",
"setCoverPhoto": "Definir Foto de Capa",
"removeCoverPhoto": "Remover Foto de Capa",
"coverPhotoSet": "Foto de capa definida com sucesso",
"coverPhotoRemoved": "Foto de capa removida",
"failedToSetCoverPhoto": "Falha ao definir foto de capa",
- "categoryHeroHint": "Se nenhuma foto de capa for definida para uma categoria, a foto hero padrao sera usada."
+ "categoryHeroHint": "Se nenhuma foto de capa for definida para uma categoria, a foto hero padrão será utilizada."
},
"events": {
"title": "Eventos",
"create": "Criar",
"createEvent": "Criar Evento",
- "totalViews": "Total de Visualizacoes",
+ "totalViews": "Total de Visualizações",
"totalDownloads": "Total de Downloads",
- "uniqueVisitors": "Visitantes Unicos",
+ "uniqueVisitors": "Visitantes Únicos",
"createNewEvent": "Criar Novo Evento",
"setupNewGallery": "Configure uma nova galeria de fotos para seu evento",
"createNewEventSubtitle": "Configure uma nova galeria de fotos para seu evento",
- "eventNamePlaceholder": "ex., Casamento do Joao e Maria",
- "welcomeMessageOptional": "Mensagem de Boas-vindas (Opcional)",
- "welcomeMessagePlaceholder": "Bem-vindos ao nosso dia especial! Fique a vontade para baixar e compartilhar estas memorias...",
+ "eventNamePlaceholder": "Ex.: Casamento de João e Maria",
+ "welcomeMessageOptional": "Mensagem de Boas-Vindas (Opcional)",
+ "welcomeMessagePlaceholder": "Bem-vindo(a) ao nosso dia especial! Sinta-se à vontade para baixar e compartilhar essas memórias...",
"hostEmailPlaceholder": "cliente@exemplo.com",
"adminEmailPlaceholder": "admin@exemplo.com",
- "securityAndAccess": "Seguranca e Acesso",
- "accessAndSecurity": "Acesso e Seguranca",
+ "securityAndAccess": "Segurança e Acesso",
+ "accessAndSecurity": "Acesso e Segurança",
"enterPassword": "Digite a senha",
"passwordPlaceholder": "Digite uma senha segura",
"confirmPasswordPlaceholder": "Confirme a senha",
- "galleryExpiresOn": "A galeria expira em {{date}}",
- "guestsWillReceiveWarning": "Os convidados receberao um email de aviso 7 dias antes da expiracao.",
+ "galleryExpiresOn": "A galeria expirará em {{date}}",
+ "guestsWillReceiveWarning": "Os convidados receberão um email de aviso 7 dias antes da expiração.",
"types": {
"wedding": "Casamento",
- "birthday": "Aniversario",
+ "birthday": "Aniversário",
"corporate": "Corporativo",
"other": "Outro"
},
"themes": {
- "default": "Padrao",
+ "default": "Padrão",
"oceanBlue": "Azul Oceano",
"royalPurple": "Roxo Real",
- "roseGold": "Rose Gold",
- "sunsetAmber": "Ambar do Por do Sol"
+ "roseGold": "Ouro Rosé",
+ "sunsetAmber": "Âmbar Pôr do Sol"
},
"eventDetails": "Detalhes do Evento",
"eventName": "Nome do Evento",
@@ -372,10 +372,10 @@
"eventDate": "Data do Evento",
"hostEmail": "Email do Cliente",
"hostName": "Nome do Cliente",
- "hostNamePlaceholder": "Joao Silva",
- "adminEmail": "Email do Admin",
- "adminNotificationEmail": "Email de Notificacao do Admin",
- "expirationDate": "Data de Expiracao",
+ "hostNamePlaceholder": "João Silva",
+ "adminEmail": "Email do Administrador",
+ "adminNotificationEmail": "Email de Notificação do Administrador",
+ "expirationDate": "Data de Expiração",
"active": "Ativo",
"archived": "Arquivado",
"photoCount": "{{count}} fotos",
@@ -386,114 +386,114 @@
"viewGallery": "Ver Galeria",
"uploadPhotos": "Enviar Fotos",
"archiveEvent": "Arquivar Evento",
- "archiveConfirm": "Tem certeza que deseja arquivar este evento? Esta acao nao pode ser desfeita.",
+ "archiveConfirm": "Tem certeza de que deseja arquivar este evento? Esta ação não pode ser desfeita.",
"extendExpiration": "Estender {{days}} Dias",
"backToEvents": "Voltar aos Eventos",
"loadingEventDetails": "Carregando detalhes do evento...",
- "saveChanges": "Salvar Alteracoes",
+ "saveChanges": "Salvar Alterações",
"eventExpired": "Este evento expirou",
"eventExpiresIn": "Este evento expira em {{days}} dias",
- "guestsNoAccess": "Os convidados nao podem mais acessar a galeria. Considere arquivar este evento.",
+ "guestsNoAccess": "Os convidados não podem mais acessar a galeria. Considere arquivar este evento.",
"warningEmailsSent": "Emails de aviso foram enviados ao cliente.",
- "overview": "Visao Geral",
+ "overview": "Visão Geral",
"photos": "Fotos",
"categories": "Categorias",
- "eventInformation": "Informacoes do Evento",
+ "eventInformation": "Informações do Evento",
"sourceMode": "Modo de Origem",
"sourceModeManaged": "Gerenciado (enviar para o PicPeak)",
"sourceModeReference": "Referenciar pasta externa",
"sourceModeHelp": "Use o modo gerenciado para uploads diretos ou aponte para uma pasta /external-media montada ao usar armazenamento local.",
"externalFolder": "Pasta Externa",
- "externalFolderHint": "Estas pastas sao lidas da montagem /external-media dentro do seu container ou host.",
- "externalFolderRequired": "Por favor, selecione uma pasta externa antes de salvar.",
- "welcomeMessage": "Mensagem de Boas-vindas",
+ "externalFolderHint": "Essas pastas são lidas do ponto de montagem /external-media dentro do seu container ou host.",
+ "externalFolderRequired": "Selecione uma pasta externa antes de salvar.",
+ "welcomeMessage": "Mensagem de Boas-Vindas",
"noWelcomeMessage": "Nenhuma mensagem de boas-vindas definida",
"created": "Criado",
"expires": "Expira",
- "shareWithGuests": "Compartilhe este link com os convidados. Eles precisarao da senha para acessar a galeria.",
- "shareWithGuestsPublic": "Compartilhe este link com os convidados. Nenhuma senha e necessaria para esta galeria.",
+ "shareWithGuests": "Compartilhe este link com os convidados. Eles precisarão da senha para acessar a galeria.",
+ "shareWithGuestsPublic": "Compartilhe este link com os convidados. Nenhuma senha é necessária para esta galeria.",
"resetGalleryPassword": "Redefinir Senha da Galeria",
- "resendCreationEmail": "Reenviar Email de Criacao",
- "creationEmailResent": "Email de criacao foi enfileirado para envio",
- "failedToResendEmail": "Falha ao reenviar email de criacao",
- "photoStatistics": "Estatisticas de Fotos",
+ "resendCreationEmail": "Reenviar Email de Criação",
+ "creationEmailResent": "Email de criação foi colocado na fila para envio",
+ "failedToResendEmail": "Falha ao reenviar email de criação",
+ "photoStatistics": "Estatísticas de Fotos",
"totalPhotos": "Total de Fotos",
"managePhotos": "Gerenciar Fotos",
- "actions": "Acoes",
- "archivingInfo": "O arquivamento criara um arquivo ZIP de todas as fotos e removera a galeria do acesso publico.",
- "statistics": "Estatisticas",
- "views": "Visualizacoes",
+ "actions": "Ações",
+ "archivingInfo": "O arquivamento criará um arquivo ZIP de todas as fotos e removerá a galeria do acesso público.",
+ "statistics": "Estatísticas",
+ "views": "Visualizações",
"downloads": "Downloads",
- "noStatistics": "Nenhuma estatistica disponivel ainda",
+ "noStatistics": "Nenhuma estatística disponível ainda",
"archiveStatus": "Status do Arquivo",
"archivedOn": "Arquivado Em",
"downloadArchive": "Baixar Arquivo",
"loadingPhotos": "Carregando fotos...",
"photoCategories": "Categorias de Fotos",
- "organizeCategoriesInfo": "Organize suas fotos em categorias. Categorias ajudam os convidados a navegar e encontrar tipos especificos de fotos.",
- "categoriesTip": "Dica: Categorias sao especificas para cada evento. Voce tambem pode criar categorias globais em Configuracoes.",
- "contactInformation": "Informacoes de Contato",
- "hostEmailHelp": "O cliente recebera notificacoes de criacao e expiracao da galeria",
- "adminEmailHelp": "Recebera notificacoes do sistema e confirmacoes de arquivamento",
- "securityAccess": "Seguranca e Acesso",
+ "organizeCategoriesInfo": "Organize suas fotos em categorias. As categorias ajudam os convidados a navegar e encontrar tipos específicos de fotos.",
+ "categoriesTip": "Dica: As categorias são específicas para cada evento. Você pode criar categorias personalizadas como \"Cerimônia\", \"Recepção\", \"Retratos\", etc.",
+ "contactInformation": "Informações de Contato",
+ "hostEmailHelp": "O cliente receberá notificações de criação e expiração da galeria",
+ "adminEmailHelp": "Receberá notificações do sistema e confirmações de arquivamento",
+ "securityAccess": "Segurança e Acesso",
"galleryPassword": "Senha da Galeria",
"requirePasswordToggle": "Exigir senha para esta galeria",
- "requirePasswordToggleHelp": "Desative isto se quiser compartilhar a galeria sem senha. Qualquer pessoa com o link podera ver as fotos.",
- "publicGalleryWarning": "Galerias publicas sao acessiveis a qualquer pessoa com o link. Considere ativar marcas d'agua nos downloads e monitorar a atividade.",
- "passwordHelperText": "Voce pode usar datas como \"04.07.2025\" ou qualquer texto com 6+ caracteres",
+ "requirePasswordToggleHelp": "Desative isso se quiser compartilhar a galeria sem senha. Qualquer pessoa com o link poderá ver as fotos.",
+ "publicGalleryWarning": "Galerias públicas são acessíveis a qualquer pessoa com o link. Considere ativar marcas d'água nos downloads e monitorar a atividade.",
+ "passwordHelperText": "Você pode usar datas como \"04.07.2025\" ou qualquer texto com 6+ caracteres",
"confirmPassword": "Confirmar Senha",
"showPasswords": "Mostrar senhas",
"newPasswordLabel": "Nova Senha da Galeria",
- "gallerySettings": "Configuracoes da Galeria",
+ "gallerySettings": "Configurações da Galeria",
"themeAndStyle": "Tema e Estilo",
"colorTheme": "Tema de Cores",
- "galleryExpiration": "Expiracao da Galeria",
- "galleryExpiresIn": "Galeria Expira Em",
- "daysAfterEvent": "dias apos a data do evento",
+ "galleryExpiration": "Expiração da Galeria",
+ "galleryExpiresIn": "A Galeria Expira Em",
+ "daysAfterEvent": "dias após a data do evento",
"expiresOn": "Expira em",
- "galleryWillExpireOn": "A galeria expira em {{date}}",
- "expirationWarning": "Os convidados receberao um email de aviso 7 dias antes da expiracao.",
- "noExpiration": "Sem Expiracao",
- "noExpirationHelp": "Esta galeria permanecera ativa ate ser arquivada manualmente.",
+ "galleryWillExpireOn": "A galeria expirará em {{date}}",
+ "expirationWarning": "Os convidados receberão um email de aviso 7 dias antes da expiração.",
+ "noExpiration": "Sem Expiração",
+ "noExpirationHelp": "Esta galeria permanecerá ativa até ser arquivada manualmente.",
"photoCap": "Limite de Fotos",
"photoCapHelp": "Número máximo de fotos permitidas. 0 = ilimitado",
- "userUploads": "Configuracoes de Upload do Usuario",
+ "userUploads": "Configurações de Upload de Convidados",
"allowUserUploads": "Permitir que convidados enviem fotos",
- "allowUserUploadsHelp": "Permitir que convidados enviem suas proprias fotos para esta galeria",
- "allowUserUploadsDescription": "Permitir que convidados enviem suas proprias fotos para esta galeria",
+ "allowUserUploadsHelp": "Habilitar convidados a enviar suas próprias fotos para esta galeria",
+ "allowUserUploadsDescription": "Habilitar convidados a enviar suas próprias fotos para esta galeria",
"uploadCategory": "Categoria de Upload",
- "selectCategory": "Selecione uma categoria para uploads dos usuarios",
- "uploadCategoryHelp": "Todas as fotos enviadas pelos usuarios serao adicionadas a esta categoria",
- "userUploadWarning": "Uploads dos usuarios serao moderados e podem ser removidos pelos administradores a qualquer momento.",
+ "selectCategory": "Selecione uma categoria para uploads de convidados",
+ "uploadCategoryHelp": "Todas as fotos enviadas por convidados serão adicionadas a esta categoria",
+ "userUploadWarning": "Os uploads de convidados serão moderados e podem ser removidos por administradores a qualquer momento.",
"allowDownloads": "Permitir download de fotos",
"allowDownloadsHelp": "Permitir que convidados baixem fotos desta galeria",
- "downloadPermissions": "Permissoes de Download",
+ "downloadPermissions": "Permissões de Download",
"downloadsEnabled": "Downloads Habilitados",
"downloadsDisabled": "Downloads Desabilitados",
- "downloadProtection": "Protecao de Download",
- "disableRightClick": "Bloquear menu do botao direito",
- "watermarkDownloads": "Adicionar marca d'agua aos downloads",
- "enableDevtoolsProtection": "Detectar ferramentas de desenvolvedor",
- "useCanvasRendering": "Renderizacao canvas (protecao avancada)",
- "protectionInfo": "Os recursos de protecao ajudam a prevenir downloads nao autorizados, mas nao podem bloquear todos os metodos.",
- "protectionLevelBasic": "Basico - Apenas bloqueio de clique direito",
- "protectionLevelStandard": "Padrao - Atalhos de teclado bloqueados",
- "protectionLevelEnhanced": "Aprimorado - Deteccao de captura de tela",
- "protectionLevelMaximum": "Maximo - Deteccao de DevTools e renderizacao canvas",
- "heroLogoSettings": "Configuracoes do Logo Hero",
- "heroLogoVisible": "Exibir logo na secao hero",
+ "downloadProtection": "Proteção de Download",
+ "disableRightClick": "Bloquear menu de contexto (botão direito)",
+ "watermarkDownloads": "Adicionar marca d'água aos downloads",
+ "enableDevtoolsProtection": "Detectar ferramentas do desenvolvedor",
+ "useCanvasRendering": "Renderização em canvas (proteção avançada)",
+ "protectionInfo": "Os recursos de proteção ajudam a evitar downloads não autorizados, mas não podem bloquear todos os métodos.",
+ "protectionLevelBasic": "Básico - Apenas bloqueio de clique direito",
+ "protectionLevelStandard": "Padrão - Atalhos de teclado bloqueados",
+ "protectionLevelEnhanced": "Aprimorado - Detecção de print screen",
+ "protectionLevelMaximum": "Máximo - Detecção de DevTools e renderização em canvas",
+ "heroLogoSettings": "Configurações do Logo Hero",
+ "heroLogoVisible": "Exibir logo na seção hero",
"heroLogoSize": "Tamanho do Logo",
"heroLogoSizeSmall": "Pequeno",
- "heroLogoSizeMedium": "Medio",
+ "heroLogoSizeMedium": "Médio",
"heroLogoSizeLarge": "Grande",
"heroLogoSizeXLarge": "Extra Grande",
- "heroLogoPosition": "Posicao do Logo",
- "heroLogoPositionTop": "Topo (acima do titulo)",
- "heroLogoPositionCenter": "Centro (entre titulo e datas)",
- "heroLogoPositionBottom": "Inferior (abaixo das datas)",
- "heroLogoInfo": "Estas configuracoes se aplicam quando a galeria usa o layout Hero. Voce pode ocultar o logo ou personalizar seu tamanho e posicao.",
+ "heroLogoPosition": "Posição do Logo",
+ "heroLogoPositionTop": "Topo (acima do título)",
+ "heroLogoPositionCenter": "Centro (entre o título e as datas)",
+ "heroLogoPositionBottom": "Rodapé (abaixo das datas)",
+ "heroLogoInfo": "Essas configurações se aplicam quando a galeria usa o layout Hero. Você pode ocultar o logo ou personalizar seu tamanho e posição.",
"eventCustomLogo": "Logo Personalizado do Evento",
- "eventCustomLogoDescription": "Envie um logo personalizado para este evento. Isto substitui o logo de marca global apenas para esta galeria.",
+ "eventCustomLogoDescription": "Envie um logo personalizado para este evento. Isso substitui o logo de identidade visual global somente para esta galeria.",
"uploadEventLogo": "Enviar Logo",
"replaceLogo": "Substituir",
"removeLogo": "Remover",
@@ -501,25 +501,25 @@
"eventLogoUploadFailed": "Falha ao enviar logo do evento",
"eventLogoRemoved": "Logo do evento removido com sucesso",
"eventLogoRemoveFailed": "Falha ao remover logo do evento",
- "heroLogoVisibleLabel": "Logo visivel",
+ "heroLogoVisibleLabel": "Logo visível",
"heroLogoSizeLabel": "Tamanho",
- "heroLogoPositionLabel": "Posicao",
+ "heroLogoPositionLabel": "Posição",
"heroLogoHidden": "Logo oculto",
"heroPhoto": "Foto Hero",
- "heroPhotoHelp": "Selecione uma foto hero padrao para a galeria. Voce pode substituir isso por categoria.",
+ "heroPhotoHelp": "Selecione uma foto hero padrão para a galeria. Você pode substituí-la por categoria.",
"selectHeroPhoto": "Selecionar Foto Hero",
"noHeroPhotoSelected": "Nenhuma foto hero selecionada",
"heroPhotoSelected": "Foto hero selecionada",
- "heroImageAnchor": "Posicao de Corte da Imagem Hero",
- "heroImageAnchorDescription": "Clique na imagem para definir o ponto focal de corte.",
+ "heroImageAnchor": "Posição de Corte da Imagem Hero",
+ "heroImageAnchorDescription": "Clique na imagem para definir o ponto focal do corte.",
"heroImageAnchorTop": "Topo",
"heroImageAnchorCenter": "Centro",
- "heroImageAnchorBottom": "Inferior",
- "heroPreview": "Visualizacao hero",
- "noPhotosAvailable": "Nenhuma foto disponivel",
- "processingRequest": "Processando sua solicitacao...",
+ "heroImageAnchorBottom": "Rodapé",
+ "heroPreview": "Pré-visualização Hero",
+ "noPhotosAvailable": "Nenhuma foto disponível",
+ "processingRequest": "Processando sua solicitação...",
"eventTypeWedding": "Casamento",
- "eventTypeBirthday": "Aniversario",
+ "eventTypeBirthday": "Aniversário",
"eventTypeCorporate": "Corporativo",
"eventTypeOther": "Outro",
"days30": "30 dias",
@@ -528,14 +528,14 @@
"days365": "1 ano",
"inactive": "Inativo",
"expired": "Expirado",
- "daysLeft": "{{count}}d restante(s)",
- "daysLeft_plural": "{{count}}d restante(s)",
+ "daysLeft": "({{count}} dia restante)",
+ "daysLeft_plural": "({{count}} dias restantes)",
"subtitle": "Gerencie suas galerias de fotos e eventos",
"loadingEvents": "Carregando eventos...",
"failedToLoadEvents": "Falha ao carregar eventos",
"tryAgain": "Tentar Novamente",
"bulkArchiveSuccess": "{{count}} eventos arquivados com sucesso",
- "bulkArchivePartial": "{{success}} eventos arquivados, {{failed}} falharam",
+ "bulkArchivePartial": "{{success}} eventos arquivados, {{failed}} com falha",
"searchEventsPlaceholder": "Buscar eventos...",
"all": "Todos",
"expiring": "Expirando",
@@ -543,9 +543,9 @@
"eventsSelected_plural": "{{count}} eventos selecionados",
"clear": "Limpar",
"archiveSelected": "Arquivar Selecionados",
- "publicAccess": "Acesso publico",
+ "publicAccess": "Acesso público",
"passwordProtected": "Protegido por senha",
- "newPasswordRequired": "Por favor, defina uma senha antes de ativar a protecao.",
+ "newPasswordRequired": "Por favor, defina uma senha antes de habilitar a proteção.",
"event": "Evento",
"type": "Tipo",
"date": "Data",
@@ -561,320 +561,320 @@
"archiveEventAction": "Arquivar Evento",
"downloadArchiveAction": "Baixar Arquivo",
"deleteEvent": "Excluir Evento",
- "deleteEventConfirm": "Tem certeza que deseja excluir este evento?",
- "downloadArchiveSoon": "Download de arquivo em breve",
+ "deleteEventConfirm": "Tem certeza de que deseja excluir este evento?",
+ "downloadArchiveSoon": "Download do arquivo em breve",
"eventExpiredMessage": "Este evento expirou",
- "guestsCannotAccessGallery": "Os convidados nao podem mais acessar a galeria. Considere arquivar este evento.",
+ "guestsCannotAccessGallery": "Os convidados não podem mais acessar a galeria. Considere arquivar este evento.",
"warningEmailsHaveBeenSent": "Emails de aviso foram enviados ao cliente.",
"extendSevenDays": "Estender 7 Dias",
- "welcomeMessageLabel": "Mensagem de Boas-vindas",
+ "welcomeMessageLabel": "Mensagem de Boas-Vindas",
"noWelcomeMessageSet": "Nenhuma mensagem de boas-vindas definida",
"createdOn": "Criado",
"copy": "Copiar",
"copied": "Copiado!",
- "organizingPhotosInfo": "Organize suas fotos em categorias. Categorias ajudam os convidados a navegar e encontrar tipos especificos de fotos.",
+ "organizingPhotosInfo": "Organize suas fotos em categorias. As categorias ajudam os convidados a navegar e encontrar tipos específicos de fotos.",
"archiveStatusTitle": "Status do Arquivo",
- "downloadingArchive": "Baixando arquivo {{name}}...",
+ "downloadingArchive": "Baixando arquivo de {{name}}...",
"downloadStarted": "Download iniciado",
"failedToDownloadArchive": "Falha ao baixar arquivo",
- "statisticsNotAvailable": "Nenhuma estatistica disponivel ainda",
+ "statisticsNotAvailable": "Nenhuma estatística disponível ainda",
"photoFilters": "Filtros de Fotos",
- "noStatisticsAvailableYet": "Nenhuma estatistica disponivel ainda",
+ "noStatisticsAvailableYet": "Nenhuma estatística disponível ainda",
"addPlus": "Adicionar+",
"galleryTheme": "Tema da Galeria",
"customizeTheme": "Personalizar Tema",
"noThemeSet": "Nenhum tema configurado",
"customizingTheme": "Personalizando tema da galeria",
"customizingThemeFor": "Personalizando tema para {{event}}",
- "customCssTemplate": "Template CSS Personalizado",
- "customCssTemplateDesc": "Aplique um template CSS personalizado para estilizar a galeria com efeitos visuais unicos.",
- "noTemplate": "Sem Template",
- "useThemeOnly": "Usar apenas predefinicao de tema",
- "customTemplate": "Template Personalizado",
+ "customCssTemplate": "Modelo de CSS Personalizado",
+ "customCssTemplateDesc": "Aplique um modelo de CSS personalizado para estilizar a galeria com efeitos visuais únicos.",
+ "noTemplate": "Sem Modelo",
+ "useThemeOnly": "Usar apenas o tema predefinido",
+ "customTemplate": "Modelo Personalizado",
"rename": {
"button": "Renomear",
"title": "Renomear Evento",
"validating": "Validando novo nome...",
"renamingFiles": "Renomeando arquivos...",
- "complete": "Concluido!",
+ "complete": "Concluído!",
"failed": "Falha ao renomear",
"filesRenamed": "{{count}} arquivos atualizados",
"confirm": "Renomear Evento"
}
},
"settings": {
- "title": "Configuracoes do Sistema",
- "subtitle": "Configure as configuracoes e preferencias do sistema",
- "loadingSettings": "Carregando configuracoes...",
+ "title": "Configurações do Sistema",
+ "subtitle": "Defina as configurações e preferências globais do sistema",
+ "loadingSettings": "Carregando configurações...",
"general": {
"title": "Geral",
- "siteConfiguration": "Configuracao do Site",
+ "siteConfiguration": "Configuração do Site",
"siteUrl": "URL do Site",
- "siteUrlHelp": "Usado para gerar links de galeria em emails",
- "defaultExpiration": "Expiracao Padrao (dias)",
- "defaultExpirationHelp": "Quanto tempo as galerias permanecem ativas por padrao",
- "maxFileSize": "Tamanho Maximo do Arquivo (MB)",
- "maxFileSizeHelp": "Tamanho maximo por foto enviada",
- "maxFilesPerUpload": "Max Arquivos por Upload",
- "maxFilesPerUploadHelp": "Numero maximo de fotos permitidas em um unico lote de envio (1-{{max}}).",
+ "siteUrlHelp": "Usado para gerar links de galeria nos emails",
+ "defaultExpiration": "Expiração Padrão (dias)",
+ "defaultExpirationHelp": "Por quanto tempo as galerias permanecem ativas por padrão",
+ "maxFileSize": "Tamanho Máximo de Arquivo (MB)",
+ "maxFileSizeHelp": "Tamanho máximo por foto enviada",
+ "maxFilesPerUpload": "Máximo de Arquivos por Upload",
+ "maxFilesPerUploadHelp": "Número máximo de fotos permitidas em um único lote de upload (1-{{max}}).",
"allowedFileTypes": "Tipos de Arquivo Permitidos",
- "allowedFileTypesHelp": "Lista de extensoes de arquivo separadas por virgula",
- "featureToggles": "Recursos",
- "enableAnalytics": "Ativar rastreamento de analiticos",
- "enableRegistration": "Permitir auto-registro para admins",
+ "allowedFileTypesHelp": "Lista de extensões de arquivo separadas por vírgula",
+ "featureToggles": "Alternância de Recursos",
+ "enableAnalytics": "Habilitar rastreamento de análises",
+ "enableRegistration": "Permitir auto-registro para administradores",
"enableShortGalleryUrls": "Usar URLs curtas de galeria",
"enableShortGalleryUrlsHelp": "Remove o slug do evento dos novos links de compartilhamento, mantendo os links existentes funcionando.",
- "maintenanceMode": "Ativar modo de manutencao",
+ "maintenanceMode": "Habilitar modo de manutenção",
"language": "Idioma",
- "defaultLanguage": "Idioma Padrao",
+ "defaultLanguage": "Idioma Padrão",
"defaultLanguageHelp": "Idioma exibido para convidados antes do login",
- "defaultWelcomeMessage": "Mensagem de Boas-vindas Padrao",
- "welcomeMessage": "Mensagem de Boas-vindas",
- "welcomeMessagePlaceholder": "Digite uma mensagem de boas-vindas padrao que sera incluida nos emails de criacao da galeria",
- "welcomeMessageHelp": "Esta mensagem sera incluida em todos os emails de criacao de galeria, a menos que seja substituida ao criar um evento",
- "saveSettings": "Salvar Configuracoes Gerais",
- "saveGeneralSettings": "Salvar Configuracoes Gerais",
+ "defaultWelcomeMessage": "Mensagem de Boas-Vindas Padrão",
+ "welcomeMessage": "Mensagem de Boas-Vindas",
+ "welcomeMessagePlaceholder": "Digite uma mensagem de boas-vindas padrão que será incluída nos emails de criação de galeria",
+ "welcomeMessageHelp": "Esta mensagem será incluída em todos os emails de criação de galeria, a menos que seja substituída ao criar um evento",
+ "saveSettings": "Salvar Configurações Gerais",
+ "saveGeneralSettings": "Salvar Configurações Gerais",
"dateTimeFormat": "Formato de Data e Hora",
"dateFormat": "Formato de Data",
- "dateFormatHelp": "Como as datas sao exibidas em emails e em todo o aplicativo",
- "accountSection": "Conta do Admin",
- "accountUsername": "Nome de Usuario do Admin",
- "accountUsernameHelp": "Exibido na interface de administracao e usado em logs de atividade.",
- "accountUsernameRequired": "Nome de usuario e obrigatorio",
- "accountUsernameLength": "Nome de usuario deve ter pelo menos 3 caracteres",
- "accountEmail": "Email do Admin",
- "accountEmailHelp": "Usado para login e recebimento de notificacoes de seguranca.",
- "accountEmailRequired": "Endereco de email e obrigatorio",
- "accountEmailInvalid": "Digite um endereco de email valido",
- "accountSaveButton": "Salvar dados da conta",
- "accountSaveSuccess": "Dados da conta atualizados"
+ "dateFormatHelp": "Como as datas são exibidas nos emails e em todo o aplicativo",
+ "accountSection": "Conta do Administrador",
+ "accountUsername": "Nome de Usuário do Administrador",
+ "accountUsernameHelp": "Exibido na interface administrativa e usado nos registros de atividade.",
+ "accountUsernameRequired": "Nome de usuário é obrigatório",
+ "accountUsernameLength": "O nome de usuário deve ter pelo menos 3 caracteres",
+ "accountEmail": "email do Administrador",
+ "accountEmailHelp": "Usado para login e recebimento de notificações de segurança.",
+ "accountEmailRequired": "O endereço de email é obrigatório",
+ "accountEmailInvalid": "Digite um endereço de email válido",
+ "accountSaveButton": "Salvar detalhes da conta",
+ "accountSaveSuccess": "Detalhes da conta atualizados"
},
"publicSite": {
- "tabLabel": "Site Publico",
- "badge": "Pagina Publica",
- "title": "Pagina Publica de Destino",
- "subtitle": "Publique uma pagina de destino personalizada para convidados quando visitarem seu dominio.",
- "loading": "Carregando configuracoes do site publico...",
- "enabled": "Ativado",
- "disabled": "Desativado",
- "htmlLabel": "HTML da Pagina de Destino",
- "htmlPlaceholder": "Forneca a marcacao HTML para o hero, secoes e chamadas para acao da sua pagina de destino.",
- "htmlHelp": "O HTML bruto e sanitizado ao salvar. Tags inseguras, scripts inline e atributos nao permitidos sao removidos automaticamente. Tokens como {{company_name}}, {{company_tagline}} e {{support_email}} serao substituidos por valores das configuracoes de Marca.",
+ "tabLabel": "Site Público",
+ "badge": "Landing Pública",
+ "title": "Página de Landing Pública",
+ "subtitle": "Publique uma página de landing personalizada para convidados quando visitarem seu domínio.",
+ "loading": "Carregando configurações do site público...",
+ "enabled": "Habilitado",
+ "disabled": "Desabilitado",
+ "htmlLabel": "HTML da Página de Landing",
+ "htmlPlaceholder": "Forneça o código HTML para o hero, seções e chamadas para ação da sua página de landing.",
+ "htmlHelp": "O HTML bruto é sanitizado ao salvar. Tags inseguras, scripts inline e atributos não permitidos são removidos automaticamente. Tokens como {{company_name}}, {{company_tagline}} e {{support_email}} serão substituídos pelos valores das configurações de Identidade Visual.",
"cssLabel": "CSS Personalizado",
- "cssPlaceholder": "Substituicoes de CSS opcionais para ajustar layout, cores ou tipografia.",
- "cssHelp": "Importacoes e URLs JavaScript sao removidas. Use seletores CSS padrao para substituir o estilo padrao.",
- "saveCta": "Salvar site publico",
+ "cssPlaceholder": "Substituições CSS opcionais para ajustar layout, cores ou tipografia.",
+ "cssHelp": "Imports e URLs de JavaScript são removidos. Use seletores CSS padrão para substituir o estilo padrão.",
+ "saveCta": "Salvar site público",
"saving": "Salvando...",
- "saveSuccess": "Configuracoes do site publico salvas.",
- "saveError": "Falha ao salvar configuracoes do site publico.",
- "resetCta": "Restaurar padrao",
- "resetting": "Restaurando...",
- "resetSuccess": "Template do site publico restaurado para os padroes.",
- "resetError": "Falha ao restaurar template do site publico.",
- "previewTitle": "Visualizacao ao Vivo",
- "previewSandboxed": "Visualizacao em sandbox",
- "previewDisabled": "Ative o site publico para ver a visualizacao ao vivo.",
- "sanitizationNotice": "Scripts, iframes e atributos inseguros sao removidos antes da publicacao. Apenas HTML seguro, links e imagens sao permitidos.",
- "htmlRequired": "Forneca conteudo HTML antes de ativar o site publico."
+ "saveSuccess": "Configurações do site público salvas.",
+ "saveError": "Falha ao salvar configurações do site público.",
+ "resetCta": "Redefinir para o padrão",
+ "resetting": "Redefinindo...",
+ "resetSuccess": "Modelo do site público redefinido para os padrões.",
+ "resetError": "Falha ao redefinir modelo do site público.",
+ "previewTitle": "Pré-visualização ao Vivo",
+ "previewSandboxed": "Pré-visualização em sandbox",
+ "previewDisabled": "Habilite o site público para ver a pré-visualização ao vivo.",
+ "sanitizationNotice": "Scripts, frames incorporados e atributos inseguros são removidos antes da publicação. Apenas HTML seguro, links e imagens são permitidos.",
+ "htmlRequired": "Forneça conteúdo HTML antes de habilitar o site público."
},
"storage": {
"title": "Armazenamento",
- "overview": "Visao Geral do Armazenamento",
- "totalUsed": "Total Usado",
+ "overview": "Visão Geral do Armazenamento",
+ "totalUsed": "Total Utilizado",
"archiveStorage": "Armazenamento de Arquivos",
"storageLimit": "Limite de Armazenamento",
- "storageLimitHelper": "Defina um limite para o uso de armazenamento de fotos. Este limite e consultivo e sera destacado quando atingido.",
+ "storageLimitHelper": "Defina um limite para o uso de armazenamento de fotos. Este limite é indicativo e será destacado quando atingido.",
"softLimitInputLabel": "Limite (GB)",
- "softLimitHelper": "Digite o uso maximo preferido de armazenamento em gigabytes.",
+ "softLimitHelper": "Digite o uso máximo de armazenamento preferido em gigabytes.",
"recommendedSoftLimit": "Limite Sugerido",
"diskCapacity": "Capacidade do Disco",
- "diskCapacityReported": "Capacidade do Disco (reportada)",
- "diskAvailable": "Disponivel",
- "diskAvailableReported": "Disponivel (reportado)",
+ "diskCapacityReported": "Capacidade do Disco (informada)",
+ "diskAvailable": "Disponível",
+ "diskAvailableReported": "Disponível (informado)",
"diskFree": "Livre",
- "diskFreeReported": "Livre (reportado)",
- "diskMetricsUnavailable": "Metricas de disco nao estao disponiveis no Docker Desktop ou ambientes virtualizados.",
+ "diskFreeReported": "Livre (informado)",
+ "diskMetricsUnavailable": "As métricas de disco não estão disponíveis no Docker Desktop ou em ambientes virtualizados.",
"applyRecommended": "Usar recomendado",
- "applyAvailable": "Corresponder ao disponivel",
- "invalidSoftLimit": "Digite um numero valido para o limite.",
+ "applyAvailable": "Corresponder disponível",
+ "invalidSoftLimit": "Digite um número válido para o limite.",
"saveSoftLimit": "Salvar limite",
- "limitNotEnforced": "Este limite e apenas consultivo e nao e aplicado automaticamente.",
- "overrideTitle": "Substituicao manual de capacidade",
- "diskOverrideEnvNote": "A capacidade do disco e controlada por variaveis de ambiente e nao pode ser editada aqui.",
- "diskOverrideSettingsHelp": "Defina valores de capacidade personalizados quando o Docker reportar numeros irreais.",
+ "limitNotEnforced": "Este limite é apenas indicativo e não é aplicado automaticamente.",
+ "overrideTitle": "Substituição manual de capacidade",
+ "diskOverrideEnvNote": "A capacidade do disco é controlada por variáveis de ambiente e não pode ser editada aqui.",
+ "diskOverrideSettingsHelp": "Defina valores de capacidade personalizados quando o Docker reportar números irreais.",
"overrideCapacityLabel": "Capacidade total (GB)",
- "overrideCapacityHelper": "Deixe em branco para usar a leitura automatica.",
- "overrideAvailableLabel": "Espaco disponivel (GB)",
- "overrideAvailableHelper": "Opcional. Deixe em branco para calcular a partir da capacidade total menos o armazenamento usado.",
- "saveOverride": "Salvar substituicao de capacidade",
- "capacityRequiredForAvailable": "Digite uma capacidade total antes de definir o espaco disponivel.",
- "availableExceedsCapacity": "O espaco disponivel nao pode exceder a capacidade total.",
+ "overrideCapacityHelper": "Deixe em branco para usar a leitura automática.",
+ "overrideAvailableLabel": "Espaço disponível (GB)",
+ "overrideAvailableHelper": "Opcional. Deixe em branco para calcular a partir da capacidade total menos o armazenamento utilizado.",
+ "saveOverride": "Salvar substituição de capacidade",
+ "capacityRequiredForAvailable": "Digite uma capacidade total antes de definir o espaço disponível.",
+ "availableExceedsCapacity": "O espaço disponível não pode exceder a capacidade total.",
"storageUsage": "Uso de Armazenamento",
"storageByEvent": "Armazenamento por Evento",
"storageManagement": "Gerenciamento de Armazenamento",
- "storageManagementHelp": "Considere arquivar ou excluir eventos antigos para liberar espaco de armazenamento. Eventos arquivados sao comprimidos e usam menos armazenamento que galerias ativas.",
+ "storageManagementHelp": "Considere arquivar ou excluir eventos antigos para liberar espaço de armazenamento. Eventos arquivados são comprimidos e usam menos armazenamento do que galerias ativas.",
"noEventsUsingStorage": "Nenhum evento usando armazenamento",
"unlimited": "Ilimitado"
},
"security": {
- "title": "Seguranca",
- "passwordSettings": "Configuracoes de Senha",
- "minPasswordLength": "Comprimento Minimo da Senha",
- "minPasswordLengthHelp": "Numero minimo de caracteres para senhas de galeria",
+ "title": "Segurança",
+ "passwordSettings": "Configurações de Senha",
+ "minPasswordLength": "Comprimento Mínimo da Senha",
+ "minPasswordLengthHelp": "Número mínimo de caracteres para senhas de galeria",
"passwordComplexity": "Complexidade da Senha",
- "passwordComplexityHelp": "Nivel de seguranca exigido para senhas de galeria",
+ "passwordComplexityHelp": "Nível de segurança exigido para senhas de galeria",
"complexitySimple": "Simples (6+ caracteres, qualquer texto)",
- "complexityModerate": "Moderada (8+ caracteres, maiusculas/minusculas/numeros)",
- "complexityStrong": "Forte (12+ caracteres, maiusculas/minusculas/numeros)",
+ "complexityModerate": "Moderado (8+ caracteres, maiúsculas/números)",
+ "complexityStrong": "Forte (12+ caracteres, maiúsculas/minúsculas/números)",
"complexityVeryStrong": "Muito Forte (12+ caracteres, todos os tipos de caracteres)",
- "sessionAuth": "Sessao e Autenticacao",
- "sessionTimeout": "Tempo Limite da Sessao (minutos)",
- "sessionTimeoutHelp": "Tempo limite da sessao do admin em minutos",
- "maxLoginAttempts": "Max Tentativas de Login",
- "maxLoginAttemptsHelp": "Maximo de tentativas de login falhadas por IP antes do bloqueio",
+ "sessionAuth": "Sessão e Autenticação",
+ "sessionTimeout": "Tempo Limite de Sessão (minutos)",
+ "sessionTimeoutHelp": "Tempo limite de sessão do administrador em minutos",
+ "maxLoginAttempts": "Máximo de Tentativas de Login",
+ "maxLoginAttemptsHelp": "Máximo de tentativas de login com falha por IP antes do bloqueio",
"attemptWindowMinutes": "Janela de Tentativas (minutos)",
- "attemptWindowMinutesHelp": "Quanto tempo olhar para tras ao contar tentativas de login falhadas",
- "lockoutDurationMinutes": "Duracao do Bloqueio (minutos)",
- "lockoutDurationMinutesHelp": "Quanto tempo a galeria ou conta permanece bloqueada apos muitas falhas",
- "enable2FA": "Ativar autenticacao de dois fatores para admins",
- "recaptchaSettings": "Configuracoes do reCAPTCHA",
- "enableRecaptcha": "Ativar reCAPTCHA para formularios de login",
+ "attemptWindowMinutesHelp": "Quanto tempo considerar ao contabilizar tentativas de login com falha",
+ "lockoutDurationMinutes": "Duração do Bloqueio (minutos)",
+ "lockoutDurationMinutesHelp": "Por quanto tempo a galeria ou conta fica bloqueada após muitas tentativas falhas",
+ "enable2FA": "Habilitar autenticação de dois fatores para administradores",
+ "recaptchaSettings": "Configurações de reCAPTCHA",
+ "enableRecaptcha": "Habilitar reCAPTCHA para formulários de login",
"siteKey": "Chave do Site",
- "siteKeyHelp": "Sua chave de site reCAPTCHA v2 (publica)",
+ "siteKeyHelp": "Sua chave de site reCAPTCHA v2 (pública)",
"secretKey": "Chave Secreta",
- "secretKeyHelp": "Sua chave secreta reCAPTCHA v2 (manter privada)",
+ "secretKeyHelp": "Sua chave secreta reCAPTCHA v2 (mantenha privada)",
"recaptchaHelp": "Obtenha suas chaves reCAPTCHA em",
- "saveSettings": "Salvar Configuracoes de Seguranca",
- "saveSecuritySettings": "Salvar Configuracoes de Seguranca"
+ "saveSettings": "Salvar Configurações de Segurança",
+ "saveSecuritySettings": "Salvar Configurações de Segurança"
},
"categories": {
"title": "Categorias",
"about": "Sobre Categorias de Fotos",
- "aboutText": "Categorias globais estao disponiveis para todos os eventos. Voce tambem pode criar categorias especificas ao editar eventos individuais. Categorias ajudam a organizar fotos e permitem que convidados filtrem fotos por tipo na visualizacao da galeria."
+ "aboutText": "As categorias globais estão disponíveis para todos os eventos. Você também pode criar categorias específicas do evento ao editar eventos individuais. As categorias ajudam a organizar as fotos e permitem que os convidados filtrem fotos por tipo na visualização da galeria."
},
"systemStatus": {
"title": "Status do Sistema",
- "storageOverview": "Visao Geral do Armazenamento",
- "systemInfo": "Informacoes do Sistema",
- "databaseInfo": "Informacoes do Banco de Dados",
+ "storageOverview": "Visão Geral do Armazenamento",
+ "systemInfo": "Informações do Sistema",
+ "databaseInfo": "Informações do Banco de Dados",
"platform": "Plataforma",
- "nodeVersion": "Versao do Node",
- "uptime": "Tempo Ativo",
- "cpuCores": "Nucleos da CPU",
- "memoryUsage": "Uso de Memoria",
- "memoryUsed": "Memoria Usada",
+ "nodeVersion": "Versão do Node",
+ "uptime": "Tempo de Atividade",
+ "cpuCores": "Núcleos de CPU",
+ "memoryUsage": "Uso de Memória",
+ "memoryUsed": "Memória Utilizada",
"photos": "Fotos",
- "admins": "Admins",
+ "admins": "Administradores",
"dbSize": "Tamanho do Banco de Dados",
- "services": "Servicos em Segundo Plano",
+ "services": "Serviços em Segundo Plano",
"fileWatcher": "Monitoramento de Arquivos",
"fileWatcherDesc": "Monitora novas fotos",
- "expirationChecker": "Verificador de Expiracao",
+ "expirationChecker": "Verificador de Expiração",
"expirationCheckerDesc": "Arquiva galerias expiradas",
"emailProcessor": "Processador de Email",
- "emailProcessorDesc": "Envia emails enfileirados",
+ "emailProcessorDesc": "Envia emails na fila",
"emailQueue": "Status da Fila de Email",
"pending": "Pendente",
"sent": "Enviado",
- "failed": "Falhou",
- "lastUpdate": "Ultima atualizacao"
+ "failed": "Com Falha",
+ "lastUpdate": "Última atualização"
},
"photoDimensions": {
- "title": "Dimensoes das Fotos",
+ "title": "Dimensões das Fotos",
"totalPhotos": "Total de Fotos",
- "withDimensions": "Com Dimensoes",
- "missingDimensions": "Dimensoes Ausentes",
- "repairButton": "Reparar Dimensoes",
+ "withDimensions": "Com Dimensões",
+ "missingDimensions": "Dimensões Ausentes",
+ "repairButton": "Reparar Dimensões",
"repairing": "Reparando...",
- "alreadyRunning": "O reparo ja esta em execucao",
- "started": "Iniciado reparo de {{count}} fotos",
- "noneToRepair": "Todas as fotos ja possuem dimensoes",
- "resultSuccess": "Ultimo reparo: {{success}} atualizadas, {{failed}} falharam",
- "description": "Preencher largura/altura ausentes para fotos enviadas antes do rastreamento de dimensoes ser adicionado. Necessario para layouts Masonry e Mosaic."
+ "alreadyRunning": "O reparo já está em andamento",
+ "started": "Iniciou o reparo de {{count}} fotos",
+ "noneToRepair": "Todas as fotos já possuem dimensões",
+ "resultSuccess": "Último reparo: {{success}} atualizadas, {{failed}} com falha",
+ "description": "Preencha largura/altura ausentes para fotos enviadas antes da implementação do rastreamento de dimensões. Necessário para os layouts Masonry e Mosaico."
},
"updateNotifications": {
- "title": "Notificacoes de Atualizacao",
- "description": "Receba notificacoes por email quando novas versoes do PicPeak estiverem disponiveis.",
- "enableEmails": "Ativar notificacoes por email",
- "enableEmailsDesc": "Enviar email para admins quando uma nova versao estiver disponivel",
- "recipients": "Destinatarios de Email",
+ "title": "Notificações de Atualização",
+ "description": "Receba notificações por email quando novas versões do PicPeak estiverem disponíveis.",
+ "enableEmails": "Habilitar notificações por email",
+ "enableEmailsDesc": "Enviar email aos administradores quando uma nova versão estiver disponível",
+ "recipients": "Destinatários do Email",
"recipientsPlaceholder": "admin@exemplo.com, outro@exemplo.com",
- "recipientsHelper": "Enderecos de email separados por virgula. Deixe vazio para enviar a todos os usuarios admin.",
- "lastNotified": "Ultima notificacao enviada para a versao: {{version}}",
+ "recipientsHelper": "Endereços de email separados por vírgula. Deixe em branco para enviar a todos os usuários administradores.",
+ "lastNotified": "Última notificação enviada para a versão: {{version}}",
"checkNow": "Verificar e Notificar",
"sendTest": "Enviar Email de Teste",
- "saved": "Configuracoes salvas",
- "saveError": "Falha ao salvar configuracoes",
- "emailSent": "Email de notificacao enviado para {{count}} destinatarios",
- "emailFailed": "Falha ao enviar notificacao",
- "checkSuccess": "Notificacao enviada para nova versao",
- "checkNoAction": "Nenhuma notificacao necessaria: {{reason}}",
- "checkError": "Falha ao verificar atualizacoes"
+ "saved": "Configurações salvas",
+ "saveError": "Falha ao salvar configurações",
+ "emailSent": "Email de notificação enviado para {{count}} destinatários",
+ "emailFailed": "Falha ao enviar notificação",
+ "checkSuccess": "Notificação enviada para nova versão",
+ "checkNoAction": "Nenhuma notificação necessária: {{reason}}",
+ "checkError": "Falha ao verificar atualizações"
},
"events": {
- "title": "Criacao de Eventos",
- "requiredFields": "Campos Obrigatorios",
- "requiredFieldsDescription": "Configure quais campos de contato sao obrigatorios ao criar novos eventos.",
+ "title": "Criação de Eventos",
+ "requiredFields": "Campos Obrigatórios",
+ "requiredFieldsDescription": "Configure quais campos de contato são obrigatórios ao criar novos eventos.",
"requireCustomerName": "Exigir nome do cliente",
- "requireCustomerNameHelp": "Nome do cliente deve ser fornecido para novos eventos",
+ "requireCustomerNameHelp": "O nome do cliente deve ser fornecido para novos eventos",
"requireCustomerEmail": "Exigir email do cliente",
- "requireCustomerEmailHelp": "Email do cliente deve ser fornecido para novos eventos",
- "customerEmailWarning": "Necessario para enviar convites da galeria",
- "requireAdminEmail": "Exigir email do admin",
- "requireAdminEmailHelp": "Email do admin deve ser fornecido para novos eventos",
- "adminEmailWarning": "Necessario para receber notificacoes do evento",
+ "requireCustomerEmailHelp": "O email do cliente deve ser fornecido para novos eventos",
+ "customerEmailWarning": "Obrigatório para enviar convites de galeria",
+ "requireAdminEmail": "Exigir email do administrador",
+ "requireAdminEmailHelp": "O email do administrador deve ser fornecido para novos eventos",
+ "adminEmailWarning": "Obrigatório para receber notificações de eventos",
"requireEventDate": "Exigir data do evento",
- "requireEventDateHelp": "Data do evento deve ser fornecida ao criar eventos",
- "eventDateWarning": "URLs da galeria usarao identificadores aleatorios em vez de datas",
- "requireExpiration": "Exigir data de expiracao",
- "requireExpirationHelp": "Galerias devem ter uma data de expiracao",
- "expirationWarning": "Galerias sem expiracao permanecerao ativas ate serem arquivadas manualmente",
- "saveSettings": "Salvar Configuracoes de Eventos",
+ "requireEventDateHelp": "A data do evento deve ser fornecida ao criar eventos",
+ "eventDateWarning": "As URLs da galeria usarão identificadores aleatórios em vez de datas",
+ "requireExpiration": "Exigir data de expiração",
+ "requireExpirationHelp": "As galerias devem ter uma data de expiração",
+ "expirationWarning": "Galerias sem expiração permanecerão ativas até serem arquivadas manualmente",
+ "saveSettings": "Salvar Configurações de Eventos",
"noteTitle": "Nota",
- "noteText": "Estas configuracoes afetam apenas a criacao de novos eventos. Eventos existentes nao sao afetados. O comportamento padrao exige todos os campos."
+ "noteText": "Essas configurações afetam apenas a criação de novos eventos. Eventos existentes não são afetados. O comportamento padrão exige todos os campos."
},
"imageSecurity": {
- "title": "Protecao de Imagem",
- "saveSuccess": "Configuracoes de seguranca de imagem salvas",
- "saveError": "Falha ao salvar configuracoes",
- "loadError": "Falha ao carregar configuracoes de seguranca de imagem",
- "defaultProtection": "Configuracoes de Protecao Padrao",
- "defaultProtectionHelp": "Estas configuracoes se aplicam a todos os novos eventos. Eventos individuais podem substituir estes padroes.",
- "protectionLevel": "Nivel de Protecao Padrao",
- "imageQuality": "Qualidade de Imagem Padrao",
- "fragmentationLevel": "Nivel de Fragmentacao",
- "enableDevtools": "Ativar deteccao de DevTools por padrao",
- "enableCanvas": "Ativar renderizacao canvas por padrao (protecao avancada)",
- "rateLimiting": "Limitacao de Taxa",
- "rateLimitingHelp": "Limite quantas imagens podem ser solicitadas para prevenir raspagem.",
- "requestsPerMinute": "Solicitacoes por minuto",
- "requestsPer5Minutes": "Solicitacoes por 5 min",
- "requestsPerHour": "Solicitacoes por hora",
- "securityMonitoring": "Monitoramento de Seguranca",
+ "title": "Proteção de Imagens",
+ "saveSuccess": "Configurações de segurança de imagem salvas",
+ "saveError": "Falha ao salvar configurações",
+ "loadError": "Falha ao carregar configurações de segurança de imagem",
+ "defaultProtection": "Configurações de Proteção Padrão",
+ "defaultProtectionHelp": "Essas configurações se aplicam a todos os novos eventos. Eventos individuais podem substituir esses padrões.",
+ "protectionLevel": "Nível de Proteção Padrão",
+ "imageQuality": "Qualidade de Imagem Padrão",
+ "fragmentationLevel": "Nível de Fragmentação",
+ "enableDevtools": "Habilitar detecção de DevTools por padrão",
+ "enableCanvas": "Habilitar renderização em canvas por padrão (proteção avançada)",
+ "rateLimiting": "Limitação de Taxa",
+ "rateLimitingHelp": "Limite quantas imagens podem ser solicitadas para evitar raspagem.",
+ "requestsPerMinute": "Solicitações por minuto",
+ "requestsPer5Minutes": "Solicitações por 5 min",
+ "requestsPerHour": "Solicitações por hora",
+ "securityMonitoring": "Monitoramento de Segurança",
"suspiciousThreshold": "Limite de atividade suspeita",
- "autoBlockThreshold": "Limite de bloqueio automatico",
- "enableMonitoring": "Ativar monitoramento de seguranca",
+ "autoBlockThreshold": "Limite de bloqueio automático",
+ "enableMonitoring": "Habilitar monitoramento de segurança",
"blockSuspiciousIps": "Bloquear automaticamente IPs suspeitos",
- "logEvents": "Registrar eventos de seguranca no banco de dados",
- "infoTitle": "Sobre Protecao de Imagem",
- "infoText": "Estes recursos de protecao ajudam a prevenir download e copia casual, mas nao podem bloquear todos os metodos. Usuarios determinados ainda podem encontrar formas de capturar imagens. Considere usar marcas d'agua e acordos legais para protecao abrangente."
+ "logEvents": "Registrar eventos de segurança no banco de dados",
+ "infoTitle": "Sobre Proteção de Imagens",
+ "infoText": "Esses recursos de proteção ajudam a evitar downloads e cópias não autorizados, mas não podem bloquear todos os métodos. Usuários determinados ainda podem encontrar formas de capturar imagens. Considere usar marcas d'água e contratos legais para proteção abrangente."
},
"moderation": {
- "title": "Moderacao",
+ "title": "Moderação",
"wordFilters": "Filtros de Palavras",
- "description": "Gerencie palavras que devem ser filtradas ou bloqueadas em comentarios",
+ "description": "Gerencie palavras que devem ser filtradas ou bloqueadas nos comentários",
"addFilter": "Adicionar Novo Filtro",
- "enterWord": "Digite a palavra para filtrar",
+ "enterWord": "Digite a palavra a filtrar",
"searchFilters": "Buscar filtros...",
"filterAdded": "Filtro de palavra adicionado com sucesso",
- "filterExists": "Este filtro de palavra ja existe",
+ "filterExists": "Este filtro de palavra já existe",
"addError": "Falha ao adicionar filtro de palavra",
"filterUpdated": "Filtro de palavra atualizado com sucesso",
"updateError": "Falha ao atualizar filtro de palavra",
- "filterDeleted": "Filtro de palavra excluido com sucesso",
+ "filterDeleted": "Filtro de palavra excluído com sucesso",
"deleteError": "Falha ao excluir filtro de palavra",
"wordRequired": "Por favor, digite uma palavra para filtrar",
- "confirmDelete": "Tem certeza que deseja excluir este filtro de palavra?",
+ "confirmDelete": "Tem certeza de que deseja excluir este filtro de palavra?",
"loading": "Carregando filtros de palavras...",
"noMatchingFilters": "Nenhum filtro correspondente encontrado",
"noFilters": "Nenhum filtro de palavra configurado ainda",
@@ -882,19 +882,19 @@
"severityModerate": "Moderado",
"severityHigh": "Alto",
"severityBlock": "Bloquear",
- "severityLevels": "Niveis de Severidade",
- "lowDescription": "Palavra e marcada para revisao mas nao e bloqueada automaticamente",
- "moderateDescription": "Comentario requer aprovacao manual antes de ficar visivel",
- "highDescription": "Comentario e automaticamente ocultado e requer revisao do admin",
- "blockDescription": "Comentario e rejeitado imediatamente e nao pode ser enviado"
+ "severityLevels": "Níveis de Severidade",
+ "lowDescription": "A palavra é sinalizada para revisão, mas não bloqueada automaticamente",
+ "moderateDescription": "O comentário requer aprovação manual antes de ser visível",
+ "highDescription": "O comentário é ocultado automaticamente e requer revisão do administrador",
+ "blockDescription": "O comentário é rejeitado imediatamente e não pode ser enviado"
},
"styling": {
"title": "CSS Personalizado"
},
"thumbnails": {
"title": "Miniaturas",
- "dimensionsTitle": "Dimensoes e Qualidade das Miniaturas",
- "dimensionsHelp": "Configure o tamanho e qualidade das miniaturas geradas automaticamente. Valores maiores produzem visualizacoes melhores, mas aumentam o armazenamento e o tempo de carregamento.",
+ "dimensionsTitle": "Dimensões e Qualidade das Miniaturas",
+ "dimensionsHelp": "Configure o tamanho e a qualidade das miniaturas geradas automaticamente. Valores mais altos produzem pré-visualizações de melhor aparência, mas aumentam o armazenamento e os tempos de carregamento.",
"width": "Largura (px)",
"widthHelp": "50-1000 pixels",
"height": "Altura (px)",
@@ -903,124 +903,124 @@
"qualityHelp": "1-100, maior = melhor qualidade mas arquivos maiores",
"format": "Formato",
"fit": "Modo de Ajuste",
- "fitHelp": "Como as imagens sao redimensionadas para caber nas dimensoes da miniatura. \"Cobrir\" corta para preencher, \"Conter\" se ajusta dentro dos limites.",
+ "fitHelp": "Como as imagens são redimensionadas para caber nas dimensões da miniatura. \"Cobrir\" corta para preencher, \"Conter\" cabe dentro dos limites.",
"fit_cover": "Cobrir (cortar para preencher)",
- "fit_contain": "Conter (ajustar dentro)",
+ "fit_contain": "Conter (caber dentro)",
"fit_fill": "Preencher (esticar)",
- "fit_inside": "Dentro (encolher para caber)",
- "fit_outside": "Fora (expandir para cobrir)",
+ "fit_inside": "Interior (reduzir para caber)",
+ "fit_outside": "Exterior (expandir para cobrir)",
"regenerateTitle": "Regenerar Miniaturas",
- "regenerateHelp": "Apos alterar as configuracoes de miniaturas, regenere todas as miniaturas existentes para aplicar a nova configuracao. Isto roda em segundo plano e pode demorar para galerias grandes.",
+ "regenerateHelp": "Após alterar as configurações de miniaturas, regenere todas as miniaturas existentes para aplicar a nova configuração. Isso é executado em segundo plano e pode demorar para galerias grandes.",
"regenerateButton": "Regenerar Todas as Miniaturas",
- "regenerateStarted": "Regeneracao de miniaturas iniciada",
- "regenerateError": "Falha ao iniciar regeneracao de miniaturas",
- "saveSuccess": "Configuracoes de miniaturas salvas",
- "saveError": "Falha ao salvar configuracoes de miniaturas",
- "loadError": "Falha ao carregar configuracoes de miniaturas",
+ "regenerateStarted": "Regeneração de miniaturas iniciada",
+ "regenerateError": "Falha ao iniciar regeneração de miniaturas",
+ "saveSuccess": "Configurações de miniaturas salvas",
+ "saveError": "Falha ao salvar configurações de miniaturas",
+ "loadError": "Falha ao carregar configurações de miniaturas",
"infoTitle": "Sobre Miniaturas",
- "infoText": "Miniaturas sao imagens de visualizacao menores geradas a partir dos originais. Aumentar o tamanho ou qualidade melhora a aparencia das fotos na grade da galeria, mas usa mais armazenamento e largura de banda. Apos alterar as configuracoes, use \"Regenerar Todas as Miniaturas\" para atualizar fotos existentes."
+ "infoText": "As miniaturas são imagens de pré-visualização menores geradas a partir dos originais. Aumentar o tamanho ou a qualidade melhora a aparência das fotos na grade da galeria, mas usa mais armazenamento e largura de banda. Após alterar as configurações, use \"Regenerar Todas as Miniaturas\" para atualizar as fotos existentes."
},
"seo": {
- "title": "SEO e Robots",
- "indexingTitle": "Indexacao por Mecanismos de Busca",
- "allowIndexing": "Permitir indexacao por mecanismos de busca",
- "allowIndexingHelp": "Quando desativado, todos os rastreadores sao bloqueados via robots.txt. Recomendado desativar para plataformas privadas de fotos.",
+ "title": "SEO e Robôs",
+ "indexingTitle": "Indexação por Mecanismos de Busca",
+ "allowIndexing": "Permitir indexação por mecanismos de busca",
+ "allowIndexingHelp": "Quando desabilitado, todos os rastreadores são bloqueados via robots.txt. Recomendado desativado para plataformas de fotos privadas.",
"sitemapUrl": "URL do Sitemap",
"sitemapUrlHelp": "Opcional. Adicionado ao robots.txt se fornecido.",
"aiBlockingTitle": "Bloqueio de IA e Bots",
"blockAiCrawlers": "Bloquear rastreadores de IA/LLM",
- "blockAiCrawlersHelp": "Impedir que bots de treinamento de IA acessem seu conteudo.",
+ "blockAiCrawlersHelp": "Impedir que bots de treinamento de IA acessem seu conteúdo.",
"blockedAgents": "Agentes de IA bloqueados",
"addAgentPlaceholder": "Digite o nome do agente...",
- "blockSocialBots": "Bloquear bots de pre-visualizacao de redes sociais",
- "blockSocialBotsHelp": "Impedir pre-visualizacoes de links no Twitter, Facebook, LinkedIn, etc.",
+ "blockSocialBots": "Bloquear bots de pré-visualização de redes sociais",
+ "blockSocialBotsHelp": "Impedir pré-visualizações de links no Twitter, Facebook, LinkedIn, etc.",
"metaTagsTitle": "Meta Tags e Regras Personalizadas",
"metaNoindex": "Adicionar meta tag noindex",
- "metaNoindexHelp": "Informa aos mecanismos de busca para nao indexar paginas (nivel HTML, complementa robots.txt).",
+ "metaNoindexHelp": "Informa aos mecanismos de busca para não indexar páginas (nível HTML, complementa robots.txt).",
"metaNofollow": "Adicionar meta tag nofollow",
- "metaNofollowHelp": "Informa aos mecanismos de busca para nao seguir links nas paginas.",
+ "metaNofollowHelp": "Informa aos mecanismos de busca para não seguir links nas páginas.",
"metaNoai": "Adicionar meta tag noai/noimageai",
- "metaNoaiHelp": "Sinaliza que o conteudo nao deve ser usado para treinamento de IA.",
- "customRules": "Regras personalizadas do robots.txt",
+ "metaNoaiHelp": "Sinaliza que o conteúdo não deve ser usado para treinamento de IA.",
+ "customRules": "Regras personalizadas de robots.txt",
"ruleAgentPlaceholder": "User-agent",
- "rulePathPlaceholder": "Caminho de bloqueio",
- "showPreview": "Mostrar visualizacao do robots.txt",
- "hidePreview": "Ocultar visualizacao do robots.txt",
- "saveSettings": "Salvar Configuracoes de SEO"
+ "rulePathPlaceholder": "Caminho para Disallow",
+ "showPreview": "Mostrar pré-visualização do robots.txt",
+ "hidePreview": "Ocultar pré-visualização do robots.txt",
+ "saveSettings": "Salvar Configurações de SEO"
},
"analytics": {
- "title": "Analiticos",
- "umamiIntegration": "Integracao com Umami Analytics",
- "enableUmami": "Ativar Umami Analytics",
+ "title": "Análises",
+ "umamiIntegration": "Integração com Umami Analytics",
+ "enableUmami": "Habilitar Umami Analytics",
"umamiUrl": "URL do Umami",
- "umamiUrlHelp": "A URL da sua instancia Umami (ex., https://analytics.seudominio.com)",
+ "umamiUrlHelp": "A URL da sua instância do Umami (ex.: https://analytics.seudominio.com)",
"websiteId": "ID do Site",
- "websiteIdHelp": "Seu ID de site Umami (encontrado no painel do Umami)",
+ "websiteIdHelp": "O ID do seu site no Umami (encontrado no painel do Umami)",
"shareUrl": "URL de Compartilhamento (Opcional)",
- "shareUrlHelp": "URL publica de compartilhamento para incorporar o painel completo (criar no Umami)",
- "umamiInfo": "Sobre Umami Analytics",
- "umamiInfoText": "Umami e uma plataforma de analiticos de codigo aberto focada em privacidade. Rastreia visualizacoes de pagina, visitantes unicos e eventos personalizados sem usar cookies.",
- "learnMore": "Saiba mais sobre Umami",
- "saveAnalyticsSettings": "Salvar Configuracoes de Analiticos",
- "backendAnalytics": "Analiticos do Backend",
- "backendAnalyticsText": "O sistema tambem rastreia analiticos basicos no servidor para monitoramento de seguranca e desempenho.",
- "tracked": "Metricas Rastreadas",
- "galleryViews": "Visualizacoes de pagina da galeria",
+ "shareUrlHelp": "URL pública de compartilhamento para incorporar o painel completo (criar no Umami)",
+ "umamiInfo": "Sobre o Umami Analytics",
+ "umamiInfoText": "O Umami é uma plataforma de análises open-source focada em privacidade. Rastreia visualizações de página, visitantes únicos e eventos personalizados sem usar cookies.",
+ "learnMore": "Saiba mais sobre o Umami",
+ "saveAnalyticsSettings": "Salvar Configurações de Análises",
+ "backendAnalytics": "Análises do Backend",
+ "backendAnalyticsText": "O sistema também rastreia análises básicas no lado do servidor para monitoramento de segurança e desempenho.",
+ "tracked": "Métricas Rastreadas",
+ "galleryViews": "Visualizações de página da galeria",
"photoDownloads": "Downloads individuais e em massa",
- "uniqueVisitors": "Visitantes unicos por IP",
- "deviceTypes": "Tipos de dispositivo a partir de user agents",
+ "uniqueVisitors": "Visitantes únicos por IP",
+ "deviceTypes": "Tipos de dispositivo por user agents",
"privacy": "Privacidade",
- "privacyText": "Enderecos IP sao hasheados para privacidade. Nenhum dado pessoal e armazenado. Dados de analiticos sao retidos por 90 dias."
+ "privacyText": "Os endereços IP são hasheados para privacidade. Nenhum dado pessoal é armazenado. Os dados de análises são retidos por 90 dias."
}
},
"analytics": {
- "title": "Painel de Analiticos",
- "titleSimple": "Analiticos",
- "subtitle": "Acompanhe o desempenho da galeria e o engajamento dos visitantes",
- "detailedSubtitle": "Analiticos detalhados fornecidos pelo Umami",
- "loadingAnalytics": "Carregando analiticos...",
- "showSummaryView": "Mostrar Visao Resumida",
+ "title": "Painel de Análises",
+ "titleSimple": "Análises",
+ "subtitle": "Acompanhe o desempenho das galerias e o engajamento dos visitantes",
+ "detailedSubtitle": "Análises detalhadas fornecidas pelo Umami",
+ "loadingAnalytics": "Carregando análises...",
+ "showSummaryView": "Mostrar Visão Resumida",
"fullDashboard": "Painel Completo",
"refresh": "Atualizar",
- "last7Days": "Ultimos 7 dias",
- "last30Days": "Ultimos 30 dias",
- "last90Days": "Ultimos 90 dias",
- "pageViews": "Visualizacoes de Pagina",
- "uniqueVisitors": "Visitantes Unicos",
+ "last7Days": "Últimos 7 dias",
+ "last30Days": "Últimos 30 dias",
+ "last90Days": "Últimos 90 dias",
+ "pageViews": "Visualizações de Página",
+ "uniqueVisitors": "Visitantes Únicos",
"totalDownloads": "Total de Downloads",
- "topGallery": "Galeria Principal",
- "topPages": "Paginas Principais",
- "views": "visualizacoes",
- "visitors": "visitantes unicos",
+ "topGallery": "Galeria Mais Visitada",
+ "topPages": "Páginas Mais Visitadas",
+ "views": "visualizações",
+ "visitors": "visitantes únicos",
"topDownloadsByGallery": "Top Downloads por Galeria",
- "deviceBreakdown": "Distribuicao de Dispositivos",
+ "deviceBreakdown": "Distribuição por Dispositivo",
"desktop": "Desktop",
- "mobile": "Celular",
+ "mobile": "Mobile",
"tablet": "Tablet",
"storageUsage": "Uso de Armazenamento",
- "used": "Usado",
+ "used": "Utilizado",
"of": "de",
"totalPhotos": "Total de Fotos",
"activeEvents": "Eventos Ativos",
- "notConfigured": "Umami Analytics Nao Configurado",
- "configureInstructions": "Para ver dados reais de analiticos, configure o Umami nas variaveis de ambiente e configuracoes do painel admin.",
- "noData": "Nenhum dado disponivel",
- "percentChange": "{{percent}}% em relacao ao periodo anterior"
+ "notConfigured": "Umami Analytics Não Configurado",
+ "configureInstructions": "Para ver dados reais de análises, configure o Umami nas variáveis de ambiente e nas configurações do painel administrativo.",
+ "noData": "Nenhum dado disponível",
+ "percentChange": "{{percent}}% em relação ao período anterior"
},
"branding": {
- "title": "Marca e Temas",
- "titleFull": "Marca e Personalizacao",
- "subtitle": "Personalize a aparencia das suas galerias",
- "loadingBranding": "Carregando configuracoes de marca...",
+ "title": "Identidade Visual e Temas",
+ "titleFull": "Identidade Visual e Personalização",
+ "subtitle": "Personalize a aparência das suas galerias",
+ "loadingBranding": "Carregando configurações de identidade visual...",
"themeAndStyle": "Tema e Estilo",
- "companyInfo": "Informacoes da Empresa",
+ "companyInfo": "Informações da Empresa",
"companyName": "Nome da Empresa",
- "companyNameHelp": "Exibido nos cabecalhos da galeria e emails",
+ "companyNameHelp": "Exibido nos cabeçalhos das galerias e nos emails",
"companyTagline": "Slogan da Empresa",
- "companyTaglineHelp": "Uma breve descricao do seu negocio",
+ "companyTaglineHelp": "Uma breve descrição do seu negócio",
"supportEmail": "Email de Suporte",
- "supportEmailHelp": "Email de contato para suporte aos convidados",
- "footerText": "Texto do Rodape",
+ "supportEmailHelp": "email de contato para suporte aos convidados",
+ "footerText": "Texto do Rodapé",
"footerTextHelp": "Exibido na parte inferior das galerias",
"logo": "Logo",
"currentLogo": "Logo atual",
@@ -1032,137 +1032,137 @@
"uploadFavicon": "Enviar Favicon",
"removeFavicon": "Remover Favicon",
"faviconHelp": "Formato PNG ou ICO, tamanho recomendado: 32x32px",
- "watermark": "Marca d'agua",
- "watermarkSettings": "Configuracoes de Marca d'agua",
- "enableWatermarks": "Ativar Marcas d'agua",
- "watermarkHelp": "Adicione o nome da sua empresa como marca d'agua nas fotos baixadas",
- "watermarkLogo": "Logo da Marca d'agua",
- "currentWatermark": "Marca d'agua atual",
- "uploadWatermarkLogo": "Enviar Logo da Marca d'agua",
- "watermarkPosition": "Posicao da Marca d'agua",
+ "watermark": "Marca d'Água",
+ "watermarkSettings": "Configurações de Marca d'Água",
+ "enableWatermarks": "Habilitar Marcas d'Água",
+ "watermarkHelp": "Adicione o nome da sua empresa como marca d'água nas fotos baixadas",
+ "watermarkLogo": "Logo da Marca d'Água",
+ "currentWatermark": "Marca d'água atual",
+ "uploadWatermarkLogo": "Enviar Logo para Marca d'Água",
+ "watermarkPosition": "Posição da Marca d'Água",
"topLeft": "Superior Esquerdo",
"topRight": "Superior Direito",
"center": "Centro",
"bottomLeft": "Inferior Esquerdo",
"bottomRight": "Inferior Direito",
- "watermarkOpacity": "Opacidade da Marca d'agua",
- "watermarkSize": "Tamanho da Marca d'agua",
+ "watermarkOpacity": "Opacidade da Marca d'Água",
+ "watermarkSize": "Tamanho da Marca d'Água",
"theme": "Tema",
"galleryTheme": "Tema da Galeria",
- "themeCustomization": "Personalizacao do Tema",
+ "themeCustomization": "Personalização do Tema",
"selectPreset": "Selecione um tema predefinido",
"colors": "Cores",
- "primaryColor": "Cor Primaria",
- "secondaryColor": "Cor Secundaria",
+ "primaryColor": "Cor Primária",
+ "secondaryColor": "Cor Secundária",
"accentColor": "Cor de Destaque",
"backgroundColor": "Cor de Fundo",
"textColor": "Cor do Texto",
"colorMode": "Modo de Cor",
"colorModeLight": "Claro",
"colorModeDark": "Escuro",
- "colorModeAuto": "Automatico",
- "colorModeHelp": "Automatico segue a preferencia do sistema do visitante.",
+ "colorModeAuto": "Automático",
+ "colorModeHelp": "Automático segue a preferência do sistema do visitante.",
"customCSS": "CSS Personalizado",
- "preview": "Visualizar",
- "previewInNewTab": "Visualizar em Nova Aba",
+ "preview": "Pré-visualização",
+ "previewInNewTab": "Pré-visualizar em Nova Aba",
"reset": "Redefinir",
- "saveChanges": "Salvar Alteracoes",
- "applyLivePreview": "Aplicar alteracoes imediatamente (Visualizacao ao Vivo)",
- "eventSpecificThemes": "Temas Especificos do Evento",
- "eventThemesInfo": "Voce pode substituir estas configuracoes globais de tema para eventos individuais ao cria-los ou edita-los.",
- "themePresets": "Predefinicoes de Tema",
+ "saveChanges": "Salvar Alterações",
+ "applyLivePreview": "Aplicar alterações imediatamente (Pré-visualização ao Vivo)",
+ "eventSpecificThemes": "Temas Específicos do Evento",
+ "eventThemesInfo": "Você pode substituir essas configurações de tema globais para eventos individuais ao criá-los ou editá-los.",
+ "themePresets": "Temas Predefinidos",
"galleryLayout": "Layout da Galeria",
"layoutDescriptions": {
- "grid": "Layout de grade classico com tamanhos de foto consistentes",
+ "grid": "Layout de grade clássico com tamanhos de foto uniformes",
"masonry": "Layout estilo Pinterest com alturas variadas",
- "carousel": "Apresentacao em tela cheia com navegacao",
+ "carousel": "Slideshow em tela cheia com navegação",
"timeline": "Fotos organizadas por data",
"hero": "Imagem em destaque com grade abaixo",
- "mosaic": "Layout artistico com tamanhos variados",
- "justified": "Layout baseado em linhas preservando proporcoes",
+ "mosaic": "Layout artístico com tamanhos mistos",
+ "justified": "Layout baseado em linhas preservando as proporções",
"gallery-premium": "Tema claro elegante com hero e masonry (Beta)",
- "gallery-story": "Tema escuro cinematico com secoes de cena (Beta)"
+ "gallery-story": "Tema escuro cinematográfico com seções de cenas (Beta)"
},
- "layoutSettings": "Configuracoes de Layout",
- "photoSpacing": "Espacamento de Fotos",
+ "layoutSettings": "Configurações de Layout",
+ "photoSpacing": "Espaçamento das Fotos",
"spacing": {
- "tight": "Apertado",
+ "tight": "Compacto",
"normal": "Normal",
- "relaxed": "Espaco"
+ "relaxed": "Espaçado"
},
- "photoAnimation": "Animacao de Fotos",
+ "photoAnimation": "Animação das Fotos",
"animation": {
"none": "Nenhuma",
- "fade": "Desvanecer",
+ "fade": "Fade",
"scale": "Escala",
- "slide": "Deslizar"
+ "slide": "Deslizamento"
},
"columns": "Colunas",
- "mobile": "Celular",
+ "mobile": "Mobile",
"tablet": "Tablet",
"desktop": "Desktop",
- "enableAutoplay": "Ativar Reproducao Automatica",
- "autoplayInterval": "Intervalo de Reproducao (segundos)",
+ "enableAutoplay": "Habilitar Reprodução Automática",
+ "autoplayInterval": "Intervalo de Reprodução Automática (segundos)",
"groupPhotosBy": "Agrupar Fotos Por",
"grouping": {
"day": "Dia",
"week": "Semana",
- "month": "Mes"
+ "month": "Mês"
},
"masonryMode": "Modo de Layout",
"masonryModeOptions": {
"columns": "Colunas (estilo Pinterest)",
- "rows": "Linhas (justificado personalizado)",
- "flickr": "Flickr (justificado consagrado)",
- "justified": "Google Photos (algoritmo Knuth-Plass)"
+ "rows": "Linhas (Justified personalizado)",
+ "flickr": "Flickr (Justified testado)",
+ "justified": "Google Fotos (algoritmo Knuth-Plass)"
},
"masonryModeHint": {
"columns": "Colunas verticais estilo Pinterest com alturas variadas",
- "rows": "Layout justificado personalizado baseado em linhas",
- "flickr": "Algoritmo de layout justificado de codigo aberto do Flickr",
- "justified": "Linhas estilo Google Photos usando algoritmo Knuth-Plass para quebras otimas"
+ "rows": "Layout justified por linhas personalizado",
+ "flickr": "Algoritmo de layout justified open-source do Flickr",
+ "justified": "Layout de linhas estilo Google Fotos usando o algoritmo Knuth-Plass para quebras otimizadas"
},
"targetRowHeight": "Altura Alvo da Linha",
- "targetRowHeightHint": "Altura em pixels (150-400). Fotos serao dimensionadas para caber nas linhas.",
- "lastRowBehavior": "Alinhamento da Ultima Linha",
+ "targetRowHeightHint": "Altura em pixels (150-400). As fotos serão dimensionadas para caber nas linhas.",
+ "lastRowBehavior": "Alinhamento da Última Linha",
"lastRowOptions": {
- "left": "Alinhado a esquerda",
+ "left": "Alinhado à esquerda",
"center": "Centralizado",
- "justify": "Justificado (esticar)"
+ "justify": "Justified (esticado)"
},
- "showHeroSection": "Mostrar Secao Hero",
- "showHeroSectionHint": "Exibir uma imagem hero em destaque acima da galeria justificada",
- "heroHeight": "Altura da Secao Hero",
+ "showHeroSection": "Mostrar Seção Hero",
+ "showHeroSectionHint": "Exibir uma imagem hero em destaque acima da galeria justified",
+ "heroHeight": "Altura da Seção Hero",
"heroHeightOptions": {
"small": "Pequena (40-50%)",
- "medium": "Media (50-70%)",
+ "medium": "Média (50-70%)",
"large": "Grande (60-80%)"
},
- "heroOverlayOpacity": "Opacidade da Sobreposicao Hero",
- "heroOverlayHint": "Escurecer a imagem hero para melhorar a legibilidade do texto",
+ "heroOverlayOpacity": "Opacidade do Overlay Hero",
+ "heroOverlayHint": "Escureça a imagem hero para melhorar a legibilidade do texto",
"typographyAndStyle": "Tipografia e Estilo",
"bodyFont": "Fonte do Corpo",
- "headingFont": "Fonte do Titulo",
- "sameAsBody": "Mesma do corpo",
+ "headingFont": "Fonte dos Títulos",
+ "sameAsBody": "Igual ao corpo",
"fontSize": "Tamanho da Fonte",
"fontSizes": {
"small": "Pequeno",
"normal": "Normal",
"large": "Grande"
},
- "borderRadius": "Raio da Borda",
+ "borderRadius": "Arredondamento das Bordas",
"borderRadiusOptions": {
"none": "Nenhum",
"small": "Pequeno",
- "medium": "Medio",
+ "medium": "Médio",
"large": "Grande"
},
"shadowStyle": "Estilo de Sombra",
"shadowOptions": {
- "none": "Nenhum",
+ "none": "Nenhuma",
"subtle": "Sutil",
"normal": "Normal",
- "dramatic": "Dramatico"
+ "dramatic": "Dramática"
},
"backgroundPattern": "Fundo",
"backgroundOptions": {
@@ -1171,84 +1171,84 @@
"grid": "Grade",
"waves": "Ondas"
},
- "customCSSHelp": "Avancado: Adicione CSS personalizado para customizar ainda mais a aparencia",
+ "customCSSHelp": "Avançado: Adicione CSS personalizado para personalizar ainda mais a aparência",
"cssInstructions": {
"title": "Como usar CSS Personalizado",
- "variables": "Variaveis CSS do Tema",
- "variablesDesc": "Use estas variaveis CSS para combinar com suas predefinicoes de tema:",
- "layouts": "Layouts Personalizados de Galeria",
- "layoutsDesc": "Direcione elementos da galeria com estes seletores:",
+ "variables": "Variáveis CSS do Tema",
+ "variablesDesc": "Use essas variáveis CSS para corresponder aos seus temas predefinidos:",
+ "layouts": "Layouts de Galeria Personalizados",
+ "layoutsDesc": "Direcione elementos da galeria com esses seletores:",
"glassEffect": "Efeito Glassmorphism",
- "glassEffectDesc": "Crie efeitos modernos de vidro:",
+ "glassEffectDesc": "Crie efeitos de vidro modernos:",
"tip": "Dica",
- "tipText": "Use Templates CSS em Configuracoes > Templates CSS para designs pre-construidos como Apple Liquid Glass."
+ "tipText": "Use Modelos de CSS em Configurações > Modelos CSS para designs pré-construídos como Apple Liquid Glass."
},
- "resetToDefault": "Restaurar Padrao",
+ "resetToDefault": "Redefinir para Padrão",
"applyTheme": "Aplicar Tema",
"customTheme": "Tema Personalizado",
"customizeTheme": "Personalizar Tema",
"saveTheme": "Salvar Tema",
- "previewLayout": "Visualizar Layout",
- "livePreview": "Visualizacao ao Vivo",
- "heroPlaceholderText": "A foto hero do seu evento aparecera aqui",
+ "previewLayout": "Pré-visualizar Layout",
+ "livePreview": "Pré-visualização ao Vivo",
+ "heroPlaceholderText": "A foto hero do seu evento aparecerá aqui",
"whiteLabel": "White Label",
- "hidePoweredBy": "Ocultar marca \"Powered by PicPeak\"",
- "hidePoweredByHelp": "Remover a atribuicao PicPeak dos rodapes da galeria para uma experiencia totalmente white-label",
- "logoCustomization": "Personalizacao do Logo",
+ "hidePoweredBy": "Ocultar marca \"Desenvolvido por PicPeak\"",
+ "hidePoweredByHelp": "Remover a atribuição do PicPeak dos rodapés das galerias para uma experiência totalmente white-label",
+ "logoCustomization": "Personalização do Logo",
"changeLogo": "Alterar Logo",
"logoSizeSmall": "Pequeno (32px)",
- "logoSizeMedium": "Medio (48px)",
+ "logoSizeMedium": "Médio (48px)",
"logoSizeLarge": "Grande (64px)",
"logoSizeXLarge": "Extra Grande (96px)",
"logoSizeCustom": "Personalizado",
- "logoMaxHeight": "Altura Maxima (pixels)",
- "logoMaxHeightHelp": "Defina uma altura maxima personalizada para o logo (20-200 pixels)",
- "logoPosition": "Posicao do Logo no Cabecalho",
+ "logoMaxHeight": "Altura Máxima (pixels)",
+ "logoMaxHeightHelp": "Defina uma altura máxima personalizada para o logo (20-200 pixels)",
+ "logoPosition": "Posição do Logo no Cabeçalho",
"positionLeft": "Esquerda",
"positionCenter": "Centro",
"positionRight": "Direita",
- "logoDisplayMode": "Modo de Exibicao",
+ "logoDisplayMode": "Modo de Exibição",
"logoOnly": "Apenas Logo",
"textOnly": "Apenas Nome da Empresa",
"logoAndText": "Logo e Nome da Empresa",
- "showLogoInHeader": "Mostrar logo no cabecalho da galeria",
- "showLogoInHeaderHelp": "Exibir o logo na barra principal do cabecalho",
- "showLogoInHero": "Mostrar logo na secao hero",
- "showLogoInHeroHelp": "Exibir o logo nas secoes hero (para layouts nao-grade)",
- "headerStyle": "Estilo do Cabecalho",
- "headerStyleDescription": "Escolha como o cabecalho da galeria aparece. O estilo do cabecalho e independente do layout das fotos.",
+ "showLogoInHeader": "Mostrar logo no cabeçalho da galeria",
+ "showLogoInHeaderHelp": "Exibir o logo na barra de cabeçalho principal",
+ "showLogoInHero": "Mostrar logo na seção hero",
+ "showLogoInHeroHelp": "Exibir o logo nas seções hero (para layouts não-grade)",
+ "headerStyle": "Estilo do Cabeçalho",
+ "headerStyleDescription": "Escolha como o cabeçalho da galeria é exibido. O estilo do cabeçalho é independente do layout das fotos.",
"headerStyleOptions": {
"hero": "Imagem Hero",
- "standard": "Banner Padrao",
+ "standard": "Banner Padrão",
"minimal": "Minimalista",
- "none": "Sem Cabecalho"
+ "none": "Sem Cabeçalho"
},
"headerStyleDescriptions": {
- "hero": "Imagem em altura total com sobreposicao de informacoes do evento",
- "standard": "Banner classico com detalhes do evento",
- "minimal": "Cabecalho compacto com informacoes essenciais",
- "none": "Ocultar cabecalho completamente"
+ "hero": "Imagem em altura total com sobreposição de informações do evento",
+ "standard": "Banner clássico com detalhes do evento",
+ "minimal": "Cabeçalho compacto com informações essenciais",
+ "none": "Ocultar cabeçalho completamente"
},
"heroDividerStyle": "Estilo do Divisor",
- "heroDividerDescription": "Escolha como a transicao entre a imagem hero e o conteudo da galeria aparece.",
+ "heroDividerDescription": "Escolha como é a transição entre a imagem hero e o conteúdo da galeria.",
"dividerOptions": {
"wave": "Onda",
"straight": "Reto",
- "angle": "Angulo",
+ "angle": "Ângulo",
"curve": "Curva",
"none": "Nenhum"
},
"controlsStyle": "Estilo dos Controles",
- "controlsStyleDescription": "Escolha como os filtros e controles da galeria sao exibidos.",
+ "controlsStyleDescription": "Escolha como os filtros e controles da galeria são exibidos.",
"controlsStyleOptions": {
- "classic": "Classico",
+ "classic": "Clássico",
"sidebar": "Barra Lateral"
},
"controlsStyleDescriptions": {
- "classic": "Barra de filtros inline abaixo do cabecalho",
- "sidebar": "Botao de menu abre barra lateral com filtros"
+ "classic": "Barra de filtros inline abaixo do cabeçalho",
+ "sidebar": "Botão de menu abre barra lateral com filtros"
},
- "controlsStyleHeroWarning": "Barra lateral e recomendada para cabecalhos hero para evitar que os controles aparecam acima da imagem hero."
+ "controlsStyleHeroWarning": "A barra lateral é recomendada para cabeçalhos hero para evitar que os controles apareçam acima da imagem hero."
},
"admin": {
"title": "Painel Admin",
@@ -1262,172 +1262,172 @@
"storagePercent": "{{percent}}% do limite {{limit}}",
"storageSoftLimitConfigured": "Limite configurado: {{limit}}",
"storageSoftLimitRecommended": "Limite sugerido: {{limit}}",
- "version": "Versao",
+ "version": "Versão",
"archivedEvents": "Eventos Arquivados",
- "systemHealth": "Saude do Sistema",
+ "systemHealth": "Saúde do Sistema",
"health": {
- "healthy": "Saudavel",
- "warning": "Alerta",
+ "healthy": "Saudável",
+ "warning": "Aviso",
"error": "Erro",
"checking": "Verificando..."
},
"updates": {
- "available": "Atualizacao Disponivel",
- "newVersion": "Versao {{version}} esta disponivel",
+ "available": "Atualização Disponível",
+ "newVersion": "A versão {{version}} está disponível",
"currentVersion": "Atual: {{version}}",
"channel": "Canal: {{channel}}",
- "channelStable": "Estavel",
+ "channelStable": "Estável",
"channelBeta": "Beta",
"beta": "BETA",
- "viewReleaseNotes": "Ver Notas de Lancamento",
- "updateAvailableShort": "v{{version}} disponivel",
- "checkForUpdates": "Verificar Atualizacoes",
- "upToDate": "Voce esta atualizado",
- "lastChecked": "Ultima verificacao: {{time}}",
+ "viewReleaseNotes": "Ver Notas de Versão",
+ "updateAvailableShort": "v{{version}} disponível",
+ "checkForUpdates": "Verificar Atualizações",
+ "upToDate": "Você está atualizado",
+ "lastChecked": "Última verificação: {{time}}",
"updateNow": "Atualizar Agora",
"updateDialog": {
"title": "Atualizar PicPeak",
"detectedEnv": "Ambiente Detectado",
"beforeUpdating": "Antes de atualizar:",
- "updateCommands": "Comandos de Atualizacao:",
- "afterUpdating": "Apos atualizar:",
+ "updateCommands": "Comandos de Atualização:",
+ "afterUpdating": "Após atualizar:",
"copyAllCommands": "Copiar Todos os Comandos",
- "completeChecklist": "Complete a lista de verificacao antes de atualizar",
- "error": "Falha ao carregar instrucoes de atualizacao"
+ "completeChecklist": "Complete a lista de verificação antes de atualizar",
+ "error": "Falha ao carregar as instruções de atualização"
}
},
- "notifications": "Notificacoes",
- "viewAllNotifications": "Ver todas as notificacoes",
- "noNotifications": "Nenhuma nova notificacao",
+ "notifications": "Notificações",
+ "viewAllNotifications": "Ver todas as notificações",
+ "noNotifications": "Nenhuma notificação nova",
"markAllRead": "Marcar todas como lidas",
- "clearAll": "Limpar todas",
+ "clearAll": "Limpar tudo",
"close": "Fechar",
- "noNotificationsMessage": "Sem notificacoes",
+ "noNotificationsMessage": "Nenhuma notificação",
"notificationMessages": {
"eventCreated": "Novo evento \"{{eventName}}\" foi criado",
"eventArchived": "Evento \"{{eventName}}\" foi arquivado",
"eventUpdated": "Evento \"{{eventName}}\" foi atualizado",
- "eventDeleted": "Evento \"{{eventName}}\" foi excluido",
+ "eventDeleted": "Evento \"{{eventName}}\" foi excluído",
"photosUploaded": "{{count}} fotos enviadas para \"{{eventName}}\"",
- "photoDeleted": "Foto excluida de \"{{eventName}}\"",
- "photosBulkDeleted": "{{count}} fotos excluidas de \"{{eventName}}\"",
- "eventExpiring": "Evento \"{{eventName}}\" expira em {{days}} dias",
- "eventExpired": "Evento \"{{eventName}}\" expirou",
+ "photoDeleted": "Foto excluída de \"{{eventName}}\"",
+ "photosBulkDeleted": "{{count}} fotos excluídas de \"{{eventName}}\"",
+ "eventExpiring": "O evento \"{{eventName}}\" expira em {{days}} dias",
+ "eventExpired": "O evento \"{{eventName}}\" expirou",
"passwordChanged": "Senha alterada por {{actorName}}",
"passwordReset": "Senha redefinida para \"{{eventName}}\"",
- "settingsUpdated": "Configuracoes de {{type}} atualizadas",
- "emailTemplateUpdated": "Template de email \"{{template}}\" atualizado",
+ "settingsUpdated": "Configurações de {{type}} atualizadas",
+ "emailTemplateUpdated": "Modelo de email \"{{template}}\" atualizado",
"bulkDownload": "{{count}} fotos baixadas de \"{{eventName}}\"",
"storageWarning": "Uso de armazenamento em {{percentage}}%",
- "adminLogout": "Admin {{actorName}} fez logout",
+ "adminLogout": "Admin {{actorName}} encerrou a sessão",
"categoryCreated": "Categoria \"{{name}}\" criada para \"{{eventName}}\"",
"categoryUpdated": "Categoria \"{{name}}\" atualizada para \"{{eventName}}\"",
- "categoryDeleted": "Categoria \"{{name}}\" excluida de \"{{eventName}}\"",
- "cmsPageUpdated": "Pagina CMS \"{{slug}}\" atualizada",
- "emailConfigUpdated": "Configuracao de email atualizada",
+ "categoryDeleted": "Categoria \"{{name}}\" excluída de \"{{eventName}}\"",
+ "cmsPageUpdated": "Página CMS \"{{slug}}\" atualizada",
+ "emailConfigUpdated": "Configuração de email atualizada",
"faviconUploaded": "Favicon enviado",
- "brandingUpdated": "Configuracoes de marca atualizadas",
- "generalSettingsUpdated": "Configuracoes gerais atualizadas",
- "securitySettingsUpdated": "Configuracoes de seguranca atualizadas",
- "themeUpdated": "Configuracoes de tema atualizadas",
+ "brandingUpdated": "Configurações de identidade visual atualizadas",
+ "generalSettingsUpdated": "Configurações gerais atualizadas",
+ "securitySettingsUpdated": "Configurações de segurança atualizadas",
+ "themeUpdated": "Configurações de tema atualizadas",
"archiveDownloaded": "Arquivo baixado para \"{{eventName}}\"",
- "archiveDeleted": "Arquivo excluido para \"{{eventName}}\"",
+ "archiveDeleted": "Arquivo excluído para \"{{eventName}}\"",
"archiveRestored": "Arquivo restaurado para \"{{eventName}}\"",
"systemActivity": "Atividade do sistema: {{type}}",
"adminProfileUpdated": "Perfil admin atualizado por {{actorName}}"
},
"notificationToasts": {
- "markedAllRead": "Todas as notificacoes marcadas como lidas",
- "clearedAll": "{{count}} notificacoes limpas",
+ "markedAllRead": "Todas as notificações marcadas como lidas",
+ "clearedAll": "{{count}} notificações apagadas",
"profileUpdated": "Perfil admin atualizado"
},
"markAsRead": "Marcar como lida",
"markAllAsRead": "Marcar todas como lidas",
- "notificationSettings": "Configuracoes de Notificacao",
+ "notificationSettings": "Configurações de Notificação",
"changePassword": "Alterar Senha",
"darkMode": "Mudar para modo escuro",
"lightMode": "Mudar para modo claro",
"accountSettings": {
"title": "Conta admin",
"description": "Atualize as credenciais usadas para entrar no PicPeak.",
- "username": "Nome de usuario",
+ "username": "Nome de usuário",
"usernamePlaceholder": "Admin",
"email": "Email",
- "emailPlaceholder": "admin@exemplo.com",
+ "emailPlaceholder": "admin@example.com",
"updateButton": "Atualizar perfil"
},
- "profileUpdateError": "Nao foi possivel atualizar o perfil admin. Por favor, tente novamente.",
+ "profileUpdateError": "Não foi possível atualizar o perfil admin. Por favor, tente novamente.",
"loadingDashboard": "Carregando painel...",
"activeEvents": "Eventos Ativos",
"expiringSoon": "Expirando em Breve",
- "next7Days": "Proximos 7 dias",
- "totalViews": "Total de Visualizacoes",
+ "next7Days": "Próximos 7 dias",
+ "totalViews": "Total de Visualizações",
"downloads": "Downloads",
"percentFromLastWeek": "{{percent}}% da semana passada",
- "dashboardSubtitle": "Bem-vindo de volta! Veja o que esta acontecendo com suas galerias.",
+ "dashboardSubtitle": "Bem-vindo de volta! Veja o que está acontecendo com suas galerias.",
"eventsExpiringSoon": "Eventos Expirando em Breve",
- "noEventsExpiring": "Nenhum evento expirando nos proximos 7 dias",
+ "noEventsExpiring": "Nenhum evento expirando nos próximos 7 dias",
"daysLeft": "{{count}} dia restante",
"daysLeft_plural": "{{count}} dias restantes",
"viewAllExpiringEvents": "Ver todos os {{count}} eventos expirando",
"noRecentActivity": "Nenhuma atividade recente",
- "viewAllActivity": "Ver toda atividade",
- "quickActions": "Acoes Rapidas",
+ "viewAllActivity": "Ver toda a atividade",
+ "quickActions": "Ações Rápidas",
"viewArchives": "Ver Arquivos",
- "analytics": "Analiticos",
+ "analytics": "Análises",
"activities": {
"event_created": "Novo evento criado: {{eventName}}",
"photos_uploaded": "{{count}} fotos enviadas para {{eventName}}",
"event_archived": "Evento arquivado: {{eventName}}",
"archive_restored": "Arquivo restaurado: {{eventName}}",
- "archive_deleted": "Arquivo excluido: {{eventName}}",
+ "archive_deleted": "Arquivo excluído: {{eventName}}",
"archive_downloaded": "Arquivo baixado: {{eventName}}",
- "email_config_updated": "Configuracao de email atualizada",
- "email_template_updated": "Template de email atualizado: {{template}}",
- "branding_updated": "Configuracoes de marca atualizadas",
- "theme_updated": "Configuracoes de tema atualizadas",
+ "email_config_updated": "Configuração de email atualizada",
+ "email_template_updated": "Modelo de email atualizado: {{template}}",
+ "branding_updated": "Configurações de identidade visual atualizadas",
+ "theme_updated": "Configurações de tema atualizadas",
"bulk_download": "{{count}} fotos baixadas de {{eventName}}",
"gallery_password_entry": "Senha inserida para {{eventName}}",
- "expiration_warning_viewed": "Aviso de expiracao visualizado para {{eventName}}",
- "feedback_settings_updated": "Configuracoes de feedback atualizadas",
+ "expiration_warning_viewed": "Aviso de expiração visualizado para {{eventName}}",
+ "feedback_settings_updated": "Configurações de feedback atualizadas",
"feedback_moderated": "Feedback moderado",
- "feedback_deleted": "Feedback excluido",
+ "feedback_deleted": "Feedback excluído",
"photo_like": "Foto curtida em {{eventName}}",
"photo_favorite": "Foto favoritada em {{eventName}}",
"photo_rating": "Foto avaliada em {{eventName}}",
"photo_comment": "Foto comentada em {{eventName}}",
- "guest_feedback_like": "Convidado curtiu uma foto em {{eventName}}",
- "guest_feedback_favorite": "Convidado favoritou uma foto em {{eventName}}",
- "guest_feedback_rating": "Convidado avaliou uma foto em {{eventName}}",
- "guest_feedback_comment": "Convidado comentou uma foto em {{eventName}}",
- "word_filter_added": "Filtro de palavra adicionado",
- "external_import_completed": "Importacao de midia externa concluida ({{imported}} importados, {{skipped}} ignorados)",
- "bulk_archive_completed": "Arquivamento em massa concluido",
+ "guest_feedback_like": "Visitante curtiu uma foto em {{eventName}}",
+ "guest_feedback_favorite": "Visitante favoritou uma foto em {{eventName}}",
+ "guest_feedback_rating": "Visitante avaliou uma foto em {{eventName}}",
+ "guest_feedback_comment": "Visitante comentou em uma foto em {{eventName}}",
+ "word_filter_added": "Filtro de palavras adicionado",
+ "external_import_completed": "Importação de mídia externa concluída ({{imported}} importadas, {{skipped}} ignoradas)",
+ "bulk_archive_completed": "Arquivamento em massa concluído",
"event_activated": "Evento ativado: {{eventName}}",
"event_deactivated": "Evento desativado: {{eventName}}",
- "photo_deleted": "Foto excluida de {{eventName}}",
- "photos_bulk_deleted": "{{count}} fotos excluidas de {{eventName}}",
- "settings_updated": "Configuracoes atualizadas",
+ "photo_deleted": "Foto excluída de {{eventName}}",
+ "photos_bulk_deleted": "{{count}} fotos excluídas de {{eventName}}",
+ "settings_updated": "Configurações atualizadas",
"event_updated": "Evento atualizado: {{eventName}}",
"event_renamed": "Evento renomeado: {{eventName}}",
- "event_deleted": "Evento excluido: {{eventName}}",
+ "event_deleted": "Evento excluído: {{eventName}}",
"password_changed": "Senha alterada",
- "email_resent": "Email de criacao reenviado para: {{eventName}}",
+ "email_resent": "Email de criação reenviado para: {{eventName}}",
"category_created": "Categoria criada: {{categoryName}}",
"category_updated": "Categoria atualizada: {{categoryName}}",
- "category_deleted": "Categoria excluida: {{categoryName}}",
- "general_settings_updated": "Configuracoes gerais atualizadas",
+ "category_deleted": "Categoria excluída: {{categoryName}}",
+ "general_settings_updated": "Configurações gerais atualizadas",
"favicon_uploaded": "Favicon enviado",
- "analytics_settings_updated": "Configuracoes de analiticos atualizadas",
- "cms_page_updated": "Pagina CMS atualizada: {{page}}",
- "security_settings_updated": "Configuracoes de seguranca atualizadas",
+ "analytics_settings_updated": "Configurações de análise atualizadas",
+ "cms_page_updated": "Página CMS atualizada: {{page}}",
+ "security_settings_updated": "Configurações de segurança atualizadas",
"password_reset": "Senha redefinida para: {{eventName}}",
- "admin_logout": "Admin {{actorName}} fez logout",
+ "admin_logout": "Admin {{actorName}} encerrou a sessão",
"system_activity": "Atividade do sistema: {{type}}",
"unknown": "Atividade desconhecida"
},
- "userManagement": "Gerenciamento de Usuarios",
- "inviteUser": "Convidar Usuario",
+ "userManagement": "Gerenciamento de Usuários",
+ "inviteUser": "Convidar Usuário",
"pendingInvitations": "Convites Pendentes",
"roles": {
"super_admin": "Super Admin",
@@ -1440,225 +1440,232 @@
"inactive": "Inativo"
},
"inviteForm": {
- "email": "Endereco de Email",
- "role": "Funcao",
+ "email": "Endereço de Email",
+ "role": "Função",
"send": "Enviar Convite"
},
"acceptInvite": {
"title": "Aceitar Convite de Admin",
- "username": "Escolha um Nome de Usuario",
+ "username": "Escolha um Nome de Usuário",
"password": "Criar Senha",
"submit": "Criar Conta"
+ },
+ "photos": {
+ "hidden": "Oculta",
+ "hideSelected": "Ocultar",
+ "showSelected": "Exibir",
+ "hiddenSuccess": "Fotos ocultadas dos visitantes",
+ "visibleSuccess": "Fotos agora visíveis aos visitantes"
}
},
"permissions": {
- "insufficient": "Voce nao tem permissao para realizar esta acao",
- "viewOnly": "Apenas Visualizacao"
+ "insufficient": "Você não tem permissão para realizar esta ação",
+ "viewOnly": "Somente Visualização"
},
"acceptInvitation": {
"title": "Aceitar Convite",
- "subtitle": "Crie sua conta de admin",
+ "subtitle": "Crie sua conta admin",
"validating": "Validando convite...",
- "invalidToken": "Convite Invalido",
- "invalidTokenMessage": "Este link de convite e invalido ou expirou. Por favor, entre em contato com seu administrador para um novo convite.",
+ "invalidToken": "Convite Inválido",
+ "invalidTokenMessage": "Este link de convite é inválido ou expirou. Entre em contato com seu administrador para um novo convite.",
"expiredToken": "Convite Expirado",
- "expiredTokenMessage": "Este convite expirou. Por favor, solicite um novo convite ao seu administrador.",
- "alreadyUsed": "Convite Ja Utilizado",
- "alreadyUsedMessage": "Este convite ja foi usado para criar uma conta.",
- "invitedAs": "Voce foi convidado como",
- "expiresAt": "O convite expira",
- "usernameLabel": "Nome de Usuario",
- "usernamePlaceholder": "Escolha um nome de usuario",
- "usernameHelp": "3-50 caracteres, apenas letras, numeros, sublinhados e hifens",
+ "expiredTokenMessage": "Este convite expirou. Solicite um novo convite ao seu administrador.",
+ "alreadyUsed": "Convite Já Utilizado",
+ "alreadyUsedMessage": "Este convite já foi usado para criar uma conta.",
+ "invitedAs": "Você foi convidado como",
+ "expiresAt": "O convite expira em",
+ "usernameLabel": "Nome de usuário",
+ "usernamePlaceholder": "Escolha um nome de usuário",
+ "usernameHelp": "3-50 caracteres, apenas letras, números, sublinhados e hífens",
"passwordLabel": "Senha",
"passwordPlaceholder": "Crie uma senha forte",
"confirmPasswordLabel": "Confirmar Senha",
"confirmPasswordPlaceholder": "Confirme sua senha",
- "passwordStrength": "Forca da senha",
+ "passwordStrength": "Força da senha",
"requirements": {
"title": "Requisitos da senha:",
"minLength": "Pelo menos 12 caracteres",
- "uppercase": "Pelo menos uma letra maiuscula",
- "lowercase": "Pelo menos uma letra minuscula",
- "number": "Pelo menos um numero",
+ "uppercase": "Pelo menos uma letra maiúscula",
+ "lowercase": "Pelo menos uma letra minúscula",
+ "number": "Pelo menos um número",
"special": "Pelo menos um caractere especial"
},
"strength": {
"weak": "Fraca",
- "fair": "Razoavel",
+ "fair": "Razoável",
"good": "Boa",
"strong": "Forte"
},
"createAccount": "Criar Conta",
"creating": "Criando conta...",
"success": "Conta Criada!",
- "successMessage": "Sua conta foi criada com sucesso. Voce ja pode fazer login com suas credenciais.",
- "redirecting": "Redirecionando para login em {{seconds}}...",
+ "successMessage": "Sua conta foi criada com sucesso. Agora você pode entrar com suas credenciais.",
+ "redirecting": "Redirecionando para o login em {{seconds}}...",
"goToLogin": "Ir para Login",
- "contactAdminMessage": "Por favor, entre em contato com seu administrador para solicitar um novo convite.",
- "passwordsMatch": "Senhas conferem",
- "alreadyHaveAccount": "Ja possui uma conta?",
+ "contactAdminMessage": "Entre em contato com seu administrador para solicitar um novo convite.",
+ "passwordsMatch": "As senhas coincidem",
+ "alreadyHaveAccount": "Já tem uma conta?",
"signIn": "Entrar",
"errors": {
- "usernameRequired": "Nome de usuario e obrigatorio",
- "usernameTooShort": "Nome de usuario deve ter pelo menos 3 caracteres",
- "usernameTooLong": "Nome de usuario deve ter no maximo 50 caracteres",
- "usernameInvalid": "Nome de usuario pode conter apenas letras, numeros, sublinhados e hifens",
- "passwordRequired": "Senha e obrigatoria",
- "passwordTooShort": "Senha deve ter pelo menos 12 caracteres",
- "passwordsDoNotMatch": "Senhas nao conferem",
+ "usernameRequired": "Nome de usuário é obrigatório",
+ "usernameTooShort": "O nome de usuário deve ter pelo menos 3 caracteres",
+ "usernameTooLong": "O nome de usuário deve ter no máximo 50 caracteres",
+ "usernameInvalid": "O nome de usuário só pode conter letras, números, sublinhados e hífens",
+ "passwordRequired": "Senha é obrigatória",
+ "passwordTooShort": "A senha deve ter pelo menos 12 caracteres",
+ "passwordsDoNotMatch": "As senhas não coincidem",
"confirmPasswordRequired": "Por favor, confirme sua senha",
- "usernameTaken": "Este nome de usuario ja esta em uso",
- "emailTaken": "Uma conta com este email ja existe",
+ "usernameTaken": "Este nome de usuário já está em uso",
+ "emailTaken": "Já existe uma conta com este email",
"genericError": "Falha ao criar conta. Por favor, tente novamente."
}
},
"errors": {
- "notFound": "Nao Encontrado",
- "galleryNotFound": "Galeria Nao Encontrada",
- "galleryNotFoundMessage": "Esta galeria nao existe ou foi removida.",
+ "notFound": "Não Encontrado",
+ "galleryNotFound": "Galeria Não Encontrada",
+ "galleryNotFoundMessage": "Esta galeria não existe ou foi removida.",
"galleryArchived": "Galeria Arquivada",
- "galleryArchivedMessage": "Esta galeria foi arquivada e nao esta mais acessivel. Por favor, entre em contato com o organizador do evento se precisar de acesso a estas fotos.",
- "unauthorized": "Nao Autorizado",
- "forbidden": "Proibido",
- "serverError": "Erro do Servidor",
+ "galleryArchivedMessage": "Esta galeria foi arquivada e não está mais acessível. Entre em contato com o organizador do evento se precisar de acesso a estas fotos.",
+ "unauthorized": "Não Autorizado",
+ "forbidden": "Acesso Negado",
+ "serverError": "Erro no Servidor",
"somethingWentWrong": "Algo deu errado",
"tryAgainLater": "Por favor, tente novamente mais tarde",
- "refreshPage": "Atualizar Pagina",
+ "refreshPage": "Recarregar Página",
"oopsSomethingWentWrong": "Ops! Algo deu errado",
- "unexpectedError": "Encontramos um erro inesperado. Nao se preocupe, seus dados estao seguros.",
- "goToHomepage": "Ir para a Pagina Inicial",
+ "unexpectedError": "Encontramos um erro inesperado. Não se preocupe, seus dados estão seguros.",
+ "goToHomepage": "Ir para a Página Inicial",
"errorDetails": "Detalhes do Erro",
- "requiredFields": "Por favor, preencha todos os campos obrigatorios",
- "enterTestEmail": "Por favor, digite um endereco de email de teste",
+ "requiredFields": "Por favor, preencha todos os campos obrigatórios",
+ "enterTestEmail": "Por favor, insira um endereço de email de teste",
"failedToCreateEvent": "Falha ao criar evento",
"eventCreationFailed": "Falha ao criar evento",
- "networkError": "Erro de rede. Por favor, verifique sua conexao e tente novamente.",
- "sessionExpired": "Sessao expirada. Por favor, faca login novamente."
+ "networkError": "Erro de rede. Por favor, verifique sua conexão e tente novamente.",
+ "sessionExpired": "Sessão expirada. Por favor, faça login novamente."
},
"validation": {
- "eventNameRequired": "Nome do evento e obrigatorio",
- "hostEmailRequired": "Email do cliente e obrigatorio",
- "hostNameRequired": "Nome do cliente e obrigatorio",
- "adminEmailRequired": "Email do admin e obrigatorio",
- "invalidEmailFormat": "Formato de email invalido",
- "passwordRequired": "Senha e obrigatoria",
- "passwordMinLength": "Senha deve ter pelo menos 6 caracteres",
- "passwordsDoNotMatch": "Senhas nao conferem",
- "passwordSecurityRequirements": "Senha nao atende aos requisitos de seguranca",
- "expirationRange": "Expiracao deve ser entre 1 e 365 dias"
+ "eventNameRequired": "O nome do evento é obrigatório",
+ "hostEmailRequired": "O email do cliente é obrigatório",
+ "hostNameRequired": "O nome do cliente é obrigatório",
+ "adminEmailRequired": "O email do admin é obrigatório",
+ "invalidEmailFormat": "Formato de email inválido",
+ "passwordRequired": "Senha é obrigatória",
+ "passwordMinLength": "A senha deve ter pelo menos 6 caracteres",
+ "passwordsDoNotMatch": "As senhas não coincidem",
+ "passwordSecurityRequirements": "A senha não atende aos requisitos de segurança",
+ "expirationRange": "A expiração deve ser entre 1 e 365 dias"
},
"legal": {
"impressum": "Aviso Legal",
- "datenschutz": "Politica de Privacidade",
- "termsOfService": "Termos de Servico",
- "cookiePolicy": "Politica de Cookies"
+ "datenschutz": "Política de Privacidade",
+ "termsOfService": "Termos de Serviço",
+ "cookiePolicy": "Política de Cookies"
},
"toast": {
- "saveSuccess": "Alteracoes salvas com sucesso",
- "saveError": "Falha ao salvar alteracoes",
- "deleteSuccess": "Excluido com sucesso",
+ "saveSuccess": "Alterações salvas com sucesso",
+ "saveError": "Falha ao salvar alterações",
+ "deleteSuccess": "Excluído com sucesso",
"deleteError": "Falha ao excluir",
- "uploadSuccess": "Upload concluido com sucesso",
+ "uploadSuccess": "Upload concluído com sucesso",
"uploadError": "Falha no upload",
"loginSuccess": "Login realizado com sucesso",
"loginError": "Falha no login",
"passwordChanged": "Senha alterada com sucesso",
- "linkCopied": "Link copiado para a area de transferencia",
+ "linkCopied": "Link copiado para a área de transferência",
"eventCreated": "Evento criado com sucesso",
"eventUpdated": "Evento atualizado com sucesso",
"eventArchived": "Evento arquivado com sucesso",
- "settingsSaved": "Configuracoes salvas com sucesso",
+ "settingsSaved": "Configurações salvas com sucesso",
"themeUpdated": "Tema atualizado com sucesso",
- "brandingUpdated": "Marca atualizada com sucesso",
+ "brandingUpdated": "Identidade visual atualizada com sucesso",
"categoryAdded": "Categoria adicionada com sucesso",
- "categoryDeleted": "Categoria excluida com sucesso",
+ "categoryDeleted": "Categoria excluída com sucesso",
"categoryUpdated": "Categoria atualizada com sucesso",
- "emailConfigSaved": "Configuracao de email salva com sucesso",
+ "emailConfigSaved": "Configuração de email salva com sucesso",
"testEmailSent": "Email de teste enviado com sucesso",
- "pageUpdated": "Pagina atualizada com sucesso",
+ "pageUpdated": "Página atualizada com sucesso",
"archiveRestored": "Arquivo restaurado com sucesso",
- "archiveDeleted": "Arquivo excluido permanentemente"
+ "archiveDeleted": "Arquivo excluído permanentemente"
},
"email": {
- "title": "Configuracao de Email",
- "subtitle": "Configure as configuracoes de email para notificacoes",
- "loadingSettings": "Carregando configuracoes de email...",
- "smtpConfiguration": "Configuracao SMTP",
+ "title": "Configuração de Email",
+ "subtitle": "Configure as definições de email para notificações",
+ "loadingSettings": "Carregando configurações de email...",
+ "smtpConfiguration": "Configuração SMTP",
"smtpHost": "Host SMTP",
- "smtpHostHelp": "Nome do host do seu servidor de email",
+ "smtpHostHelp": "O nome do host do seu servidor de email",
"smtpPort": "Porta SMTP",
- "smtpPortHelp": "Geralmente 587 para TLS, 465 para SSL, 25 para nao criptografado",
+ "smtpPortHelp": "Geralmente 587 para TLS, 465 para SSL, 25 para sem criptografia",
"smtpSecure": "Usar SSL/TLS",
- "smtpSecureHelp": "Ativar para transmissao segura de email",
- "smtpUsername": "Usuario SMTP",
- "smtpUsernameHelp": "Nome de usuario da sua conta de email",
+ "smtpSecureHelp": "Ative para transmissão segura de email",
+ "smtpUsername": "Usuário SMTP",
+ "smtpUsernameHelp": "O nome de usuário da sua conta de email",
"smtpPassword": "Senha SMTP",
- "smtpPasswordHelp": "Senha da sua conta de email",
+ "smtpPasswordHelp": "A senha da sua conta de email",
"fromDetails": "Detalhes do Remetente",
"fromEmail": "Email do Remetente",
- "fromEmailHelp": "Endereco de email que aparece como remetente",
+ "fromEmailHelp": "Endereço de email que aparece como remetente",
"fromName": "Nome do Remetente",
"fromNameHelp": "Nome que aparece como remetente",
- "testConfiguration": "Testar Configuracao",
- "testEmail": "Endereco de Email de Teste",
- "testEmailHelp": "Envie um email de teste para verificar as configuracoes",
+ "testConfiguration": "Testar Configuração",
+ "testEmail": "Endereço de Email de Teste",
+ "testEmailHelp": "Envie um email de teste para verificar as configurações",
"sendTestEmail": "Enviar Email de Teste",
- "saveConfiguration": "Salvar Configuracao",
- "emailTemplates": "Templates de Email",
- "templateVariables": "Variaveis Disponiveis",
- "previewTemplate": "Visualizar Template",
- "smtpSettings": "Configuracoes SMTP",
+ "saveConfiguration": "Salvar Configuração",
+ "emailTemplates": "Modelos de Email",
+ "templateVariables": "Variáveis Disponíveis",
+ "previewTemplate": "Pré-visualizar Modelo",
+ "smtpSettings": "Configurações SMTP",
"testEmailSuccess": "Email de teste enviado com sucesso",
- "saveSmtpSettings": "Salvar Configuracoes SMTP",
+ "saveSmtpSettings": "Salvar Configurações SMTP",
"testEmailSection": "Email de Teste",
"beforeTesting": "Antes de testar:",
- "saveSmtpFirst": "Salve suas configuracoes SMTP primeiro",
- "ensureFirewall": "Certifique-se de que seu firewall permite SMTP de saida",
- "gmailAppPassword": "Para Gmail, use uma senha especifica do aplicativo",
- "testEmailAddressLabel": "Endereco de Email de Teste",
+ "saveSmtpFirst": "Salve suas configurações SMTP primeiro",
+ "ensureFirewall": "Certifique-se de que seu firewall permite SMTP de saída",
+ "gmailAppPassword": "Para Gmail, use uma senha específica de aplicativo",
+ "testEmailAddressLabel": "Endereço de Email de Teste",
"sendTestEmailButton": "Enviar Email de Teste",
- "commonSmtpSettings": "Configuracoes SMTP Comuns:",
- "editTemplate": "Editar Template",
- "templateName": "Nome do Template",
+ "commonSmtpSettings": "Configurações SMTP Comuns:",
+ "editTemplate": "Editar Modelo",
+ "templateName": "Nome do Modelo",
"subjectLine": "Linha de Assunto",
"emailBody": "Corpo do Email",
- "preview": "Visualizar",
+ "preview": "Pré-visualizar",
"save": "Salvar",
- "saveChanges": "Salvar Alteracoes",
- "templates": "Templates",
- "variableHelp": "Use estas variaveis no seu template. Elas serao substituidas por valores reais quando os emails forem enviados.",
+ "saveChanges": "Salvar Alterações",
+ "templates": "Modelos",
+ "variableHelp": "Use estas variáveis no seu modelo. Elas serão substituídas pelos valores reais quando os emails forem enviados.",
"port": "Porta",
- "security": "Seguranca",
- "username": "Nome de usuario",
+ "security": "Segurança",
+ "username": "Usuário",
"password": "Senha",
"enterPassword": "Digite a senha",
- "required": "obrigatorio",
+ "required": "obrigatório",
"ignoreSslErrors": "Ignorar erros de certificado SSL/TLS",
- "ignoreSslWarning": "Aviso: Desabilitar verificacao de certificado torna a conexao vulneravel a ataques man-in-the-middle. Ative somente se voce confia no servidor SMTP e entende as implicacoes de seguranca.",
- "brandingTitle": "Identidade Visual do E-mail",
- "brandingDescription": "Personalize as cores dos modelos de e-mail. As alteracoes se aplicam ao cabecalho, botoes, links e fundo do rodape.",
- "primaryColor": "Cor Primaria",
- "primaryColorHint": "Usada no cabecalho, botoes e links",
- "secondaryColor": "Fundo do Rodape",
- "secondaryColorHint": "Usada no fundo da secao de rodape",
- "saveEmailColors": "Salvar Cores do E-mail",
+ "ignoreSslWarning": "Aviso: Desativar a verificação de certificado torna a conexão vulnerável a ataques man-in-the-middle. Ative isso somente se você confia no servidor SMTP e compreende as implicações de segurança.",
+ "brandingTitle": "Identidade Visual do Email",
+ "brandingDescription": "Personalize as cores usadas nos modelos de email. As alterações se aplicam à barra de cabeçalho, botões, links e fundo do rodapé.",
+ "primaryColor": "Cor Primária",
+ "primaryColorHint": "Usada para cabeçalho, botões e links",
+ "secondaryColor": "Fundo do Rodapé",
+ "secondaryColorHint": "Usada para o fundo da seção de rodapé",
+ "saveEmailColors": "Salvar Cores do Email",
"editor": {
"bold": "Negrito",
- "italic": "Italico",
+ "italic": "Itálico",
"bulletList": "Lista com Marcadores",
"numberedList": "Lista Numerada",
- "blockquote": "Citacao",
+ "blockquote": "Citação",
"link": "Adicionar Link",
"horizontalRule": "Linha Horizontal",
- "alignLeft": "Alinhar a Esquerda",
+ "alignLeft": "Alinhar à Esquerda",
"alignCenter": "Centralizar",
- "alignRight": "Alinhar a Direita",
- "clearFormatting": "Limpar Formatacao",
+ "alignRight": "Alinhar à Direita",
+ "clearFormatting": "Limpar Formatação",
"undo": "Desfazer",
"redo": "Refazer",
- "insertVariable": "Inserir Variavel",
- "sourceMode": "Codigo",
+ "insertVariable": "Inserir Variável",
+ "sourceMode": "Código",
"visualMode": "Visual",
"enterUrl": "Digite a URL...",
"addLink": "Adicionar",
@@ -1666,92 +1673,92 @@
}
},
"cms": {
- "title": "Paginas CMS",
- "subtitle": "Gerenciar paginas legais e informativas",
- "loadingPages": "Carregando paginas...",
- "pages": "Paginas",
- "previewLinks": "Links de Visualizacao",
- "englishVersion": "Versao em Ingles",
- "germanVersion": "Versao em Alemao",
+ "title": "Páginas CMS",
+ "subtitle": "Gerencie páginas legais e informativas",
+ "loadingPages": "Carregando páginas...",
+ "pages": "Páginas",
+ "previewLinks": "Links de Visualização",
+ "englishVersion": "Versão em Inglês",
+ "germanVersion": "Versão em Alemão",
"editPage": "Editar {{page}}",
- "pageTitle": "Titulo da Pagina",
- "pageContent": "Conteudo da Pagina",
- "pageTitlePlaceholder": "Digite o titulo da pagina...",
- "saveChanges": "Salvar Alteracoes",
- "lastUpdated": "Ultima atualizacao:",
+ "pageTitle": "Título da Página",
+ "pageContent": "Conteúdo da Página",
+ "pageTitlePlaceholder": "Digite o título da página...",
+ "saveChanges": "Salvar Alterações",
+ "lastUpdated": "Última atualização:",
"impressum": "Aviso Legal",
- "datenschutz": "Politica de Privacidade",
- "pageUpdated": "Pagina atualizada com sucesso"
+ "datenschutz": "Política de Privacidade",
+ "pageUpdated": "Página atualizada com sucesso"
},
"eventTypes": {
"title": "Tipos de Evento",
- "subtitle": "Personalize tipos de evento e seus temas padrao",
+ "subtitle": "Personalize os tipos de evento e seus temas padrão",
"loading": "Carregando tipos de evento...",
"loadError": "Falha ao carregar tipos de evento",
"createNew": "Novo Tipo de Evento",
"edit": "Editar Tipo de Evento",
"created": "Tipo de evento criado com sucesso",
"updated": "Tipo de evento atualizado com sucesso",
- "deleted": "Tipo de evento excluido com sucesso",
+ "deleted": "Tipo de evento excluído com sucesso",
"createError": "Falha ao criar tipo de evento",
"updateError": "Falha ao atualizar tipo de evento",
"deleteError": "Falha ao excluir tipo de evento",
- "searchPlaceholder": "Buscar tipos de evento...",
+ "searchPlaceholder": "Pesquisar tipos de evento...",
"showInactive": "Mostrar inativos",
"noResults": "Nenhum tipo de evento encontrado",
"empty": "Nenhum tipo de evento ainda",
"system": "Sistema",
"table": {
"type": "Tipo",
- "slugPrefix": "Prefixo da URL",
- "theme": "Tema Padrao",
+ "slugPrefix": "Prefixo de URL",
+ "theme": "Tema Padrão",
"status": "Status",
- "actions": "Acoes"
+ "actions": "Ações"
},
"form": {
- "name": "Nome de Exibicao",
- "namePlaceholder": "ex., Ensaio Familiar",
- "slugPrefix": "Prefixo da URL",
- "slugPrefixPlaceholder": "ex., familia",
+ "name": "Nome de Exibição",
+ "namePlaceholder": "ex.: Ensaio de Família",
+ "slugPrefix": "Prefixo de URL",
+ "slugPrefixPlaceholder": "ex.: familia",
"slugPreview": "URL de exemplo:",
- "emoji": "Icone",
- "themePreset": "Tema Padrao",
- "isActive": "Ativo (visivel na criacao de eventos)"
+ "emoji": "Ícone",
+ "themePreset": "Tema Padrão",
+ "isActive": "Ativo (visível na criação de eventos)"
},
"validation": {
- "slugFormat": "Apenas letras, numeros e hifens sao permitidos"
+ "slugFormat": "Apenas letras, números e hifens são permitidos"
},
"slugInfo": {
- "title": "Info do Prefixo da URL:",
- "description": "O prefixo da URL e usado para gerar URLs de galeria. Por exemplo, um tipo de evento com prefixo \"familia\" criara URLs como: familia-silva-familia-2025-01-22"
+ "title": "Informações sobre o Prefixo de URL:",
+ "description": "O prefixo de URL é usado para gerar as URLs das galerias. Por exemplo, um tipo de evento com o prefixo \"familia\" criará URLs como: familia-silva-familia-2025-01-22"
},
"deleteConfirm": {
"title": "Excluir Tipo de Evento",
"message": "Tem certeza que deseja excluir",
- "warning": "Esta acao nao pode ser desfeita. Certifique-se de que nenhum evento esta usando este tipo."
+ "warning": "Esta ação não pode ser desfeita. Certifique-se de que nenhum evento está usando este tipo."
}
},
"backup": {
"external": {
"warning": {
- "title": "Midia externa excluida",
- "body": "Esta instalacao referencia fotos de /external-media. Estes originais sao excluidos dos backups. Miniaturas e banco de dados ainda sao salvos."
+ "title": "Mídia externa excluída",
+ "body": "Esta instalação referencia fotos de /external-media. Esses originais estão excluídos dos backups. Miniaturas e banco de dados ainda são incluídos no backup."
}
},
"title": "Gerenciamento de Backup",
"subtitle": "Gerencie backups do sistema, configure backups automatizados e restaure a partir de backups anteriores.",
"tabs": {
"dashboard": "Painel",
- "configuration": "Configuracao",
- "history": "Historico de Backup",
+ "configuration": "Configuração",
+ "history": "Histórico de Backups",
"restore": "Restaurar"
},
"status": {
"inProgress": "Backup em andamento...",
- "lastBackup": "Ultimo backup",
+ "lastBackup": "Último backup",
"noBackups": "Nenhum backup encontrado",
- "nextBackup": "Proximo backup",
- "notScheduled": "Nao agendado",
+ "nextBackup": "Próximo backup",
+ "notScheduled": "Não agendado",
"enabled": "Ativado",
"disabled": "Desativado"
},
@@ -1759,38 +1766,38 @@
"runBackupNow": "Executar Backup Agora",
"starting": "Iniciando...",
"running": "Executando...",
- "testConnection": "Testar Conexao",
- "save": "Salvar Configuracao",
+ "testConnection": "Testar Conexão",
+ "save": "Salvar Configuração",
"delete": "Excluir",
"view": "Ver Detalhes",
"download": "Baixar",
"refresh": "Atualizar"
},
"dashboard": {
- "backupHealth": "Saude do Backup",
+ "backupHealth": "Integridade do Backup",
"healthStatus": {
"excellent": "Excelente",
"good": "Bom",
- "warning": "Alerta",
- "critical": "Critico"
+ "warning": "Atenção",
+ "critical": "Crítico"
},
"health": {
- "title": "Saude do Backup"
+ "title": "Integridade do Backup"
},
"healthMessages": {
"noBackups": "Nenhum backup encontrado",
- "lastBackupFailed": "Ultimo backup falhou",
- "upToDate": "Backup esta atualizado",
- "recent": "Backup e recente",
- "gettingOld": "Backup esta ficando antigo",
- "outdated": "Backup esta desatualizado"
+ "lastBackupFailed": "Último backup falhou",
+ "upToDate": "Backup está atualizado",
+ "recent": "Backup é recente",
+ "gettingOld": "Backup está ficando antigo",
+ "outdated": "Backup está desatualizado"
},
"stats": {
"totalBackups": "Total de Backups",
"backupSize": "Tamanho do Backup",
- "lastDuration": "Ultima Duracao",
+ "lastDuration": "Duração do Último",
"backupStatus": "Status do Backup",
- "last": "Ultimo",
+ "last": "Último",
"files": "arquivos",
"minutes": "{{count}}m",
"active": "Ativo",
@@ -1801,8 +1808,8 @@
"title": "Atividade Recente de Backup"
},
"notConfigured": {
- "title": "Backup Nao Configurado",
- "message": "Por favor, configure as configuracoes de backup na aba Configuracao antes de executar backups."
+ "title": "Backup Não Configurado",
+ "message": "Por favor, configure as definições de backup na aba Configuração antes de executar backups."
},
"actions": {
"runBackupNow": "Executar Backup Agora",
@@ -1814,12 +1821,12 @@
"photos": "Fotos",
"archives": "Arquivos",
"systemFiles": "Arquivos do Sistema",
- "included": "Incluido",
- "excluded": "Excluido",
+ "included": "Incluído",
+ "excluded": "Excluído",
"optional": "Opcional"
},
"storageDestination": "Destino de Armazenamento",
- "nextScheduledBackup": "Proximo Backup Agendado",
+ "nextScheduledBackup": "Próximo Backup Agendado",
"backupType": "Backup {{type}}",
"noDestinationSet": "Nenhum destino definido"
},
@@ -1837,40 +1844,40 @@
"description": "Sincronizar backups para um servidor remoto via SSH/Rsync"
},
"s3": {
- "name": "Armazenamento Compativel com S3",
- "description": "Armazenar backups no Amazon S3 ou armazenamento de objetos compativel"
+ "name": "Armazenamento S3 Compatível",
+ "description": "Armazenar backups no Amazon S3 ou armazenamento de objetos compatível"
}
},
"fields": {
"destinationPath": "Caminho de Destino",
- "destinationPathHelp": "Caminho do diretorio local para armazenar backups",
+ "destinationPathHelp": "Caminho do diretório local para armazenar backups",
"destinationPathPlaceholder": "/caminho/para/diretorio/backup",
"rsyncHost": "Host Remoto",
- "rsyncHostHelp": "Nome do host ou endereco IP SSH",
+ "rsyncHostHelp": "Nome do host SSH ou endereço IP",
"rsyncHostPlaceholder": "backup.exemplo.com",
- "rsyncUser": "Usuario SSH",
- "rsyncUserHelp": "Nome de usuario para conexao SSH",
+ "rsyncUser": "Usuário SSH",
+ "rsyncUserHelp": "Nome de usuário para conexão SSH",
"rsyncUserPlaceholder": "usuario-backup",
"rsyncPath": "Caminho Remoto",
- "rsyncPathHelp": "Caminho do diretorio no servidor remoto",
+ "rsyncPathHelp": "Caminho do diretório no servidor remoto",
"rsyncPathPlaceholder": "/home/backup/compartilhamento-fotos",
"rsyncSshKey": "Chave Privada SSH",
- "rsyncSshKeyHelp": "Chave privada SSH para autenticacao (opcional)",
+ "rsyncSshKeyHelp": "Chave privada SSH para autenticação (opcional)",
"rsyncSshKeyPlaceholder": "-----BEGIN RSA PRIVATE KEY-----",
"s3Endpoint": "Endpoint S3",
- "s3EndpointHelp": "Endpoint da API S3 (ex., s3.amazonaws.com)",
+ "s3EndpointHelp": "Endpoint da API S3 (ex.: s3.amazonaws.com)",
"s3EndpointPlaceholder": "https://s3.amazonaws.com",
"s3Bucket": "Nome do Bucket",
"s3BucketHelp": "Bucket S3 para armazenar backups",
- "s3BucketPlaceholder": "meu-bucket-backup",
+ "s3BucketPlaceholder": "meu-bucket-de-backup",
"s3AccessKey": "ID da Chave de Acesso",
"s3AccessKeyHelp": "ID da chave de acesso AWS/S3",
- "s3AccessKeyPlaceholder": "AKIAIOSFODNN7EXEMPLO",
+ "s3AccessKeyPlaceholder": "AKIAIOSFODNN7EXAMPLE",
"s3SecretKey": "Chave de Acesso Secreta",
"s3SecretKeyHelp": "Chave de acesso secreta AWS/S3",
- "s3SecretKeyPlaceholder": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYCHAVEEXEMPLO",
- "s3Region": "Regiao",
- "s3RegionHelp": "Regiao S3 (ex., us-east-1)",
+ "s3SecretKeyPlaceholder": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+ "s3Region": "Região",
+ "s3RegionHelp": "Região S3 (ex.: us-east-1)",
"s3RegionPlaceholder": "us-east-1"
},
"schedule": {
@@ -1878,66 +1885,66 @@
"scheduleType": "Tipo de Agendamento",
"scheduleOptions": {
"hourly": "A cada hora",
- "daily": "Diario",
- "weekly": "Semanal",
- "custom": "Expressao cron personalizada"
+ "daily": "Diariamente",
+ "weekly": "Semanalmente",
+ "custom": "Expressão cron personalizada"
},
"options": {
"hourly": "A cada hora",
- "daily": "Diario",
- "weekly": "Semanal",
- "custom": "Expressao cron personalizada"
+ "daily": "Diariamente",
+ "weekly": "Semanalmente",
+ "custom": "Expressão cron personalizada"
},
- "customCron": "Expressao Cron",
- "customCronHelp": "Digite uma expressao cron valida (ex., 0 3 * * *)",
- "retention": "Periodo de Retencao",
+ "customCron": "Expressão Cron",
+ "customCronHelp": "Digite uma expressão cron válida (ex.: 0 3 * * *)",
+ "retention": "Período de Retenção",
"retentionDays": "Manter backups por",
- "retentionHelp": "dias (backups mais antigos serao excluidos automaticamente)"
+ "retentionHelp": "dias (backups mais antigos serão excluídos automaticamente)"
},
"whatToBackup": {
- "title": "O que Fazer Backup",
+ "title": "O Que Incluir no Backup",
"database": "Banco de Dados",
- "databaseHelp": "Todos os dados de eventos, configuracoes e configuracoes",
+ "databaseHelp": "Todos os dados de eventos, configurações e definições",
"photos": "Fotos",
"photosHelp": "Todas as fotos enviadas em galerias ativas",
"archives": "Arquivos",
"archivesHelp": "Arquivos ZIP de eventos arquivados",
"thumbnails": "Miniaturas",
"thumbnailsHelp": "Imagens de miniatura geradas (podem ser recriadas)",
- "tempFiles": "Arquivos Temporarios",
- "tempFilesHelp": "Arquivos temporarios de upload e processamento"
+ "tempFiles": "Arquivos Temporários",
+ "tempFilesHelp": "Arquivos temporários de upload e processamento"
},
"advancedOptions": {
- "title": "Opcoes Avancadas",
- "compression": "Ativar Compressao",
- "compressionHelp": "Comprimir arquivos de backup para economizar espaco",
+ "title": "Opções Avançadas",
+ "compression": "Ativar Compressão",
+ "compressionHelp": "Comprimir arquivos de backup para economizar espaço de armazenamento",
"encryption": "Ativar Criptografia",
- "encryptionHelp": "Criptografar backups para seguranca adicional",
- "encryptionPassphrase": "Frase de Criptografia",
- "encryptionPassphraseHelp": "Frase forte para criptografia do backup",
- "confirmPassphrase": "Confirmar Frase",
- "passphrasesDontMatch": "As frases nao conferem"
+ "encryptionHelp": "Criptografar backups para segurança adicional",
+ "encryptionPassphrase": "Senha de Criptografia",
+ "encryptionPassphraseHelp": "Senha forte para criptografia de backup",
+ "confirmPassphrase": "Confirmar Senha",
+ "passphrasesDontMatch": "As senhas não coincidem"
},
"validation": {
- "requiredFields": "Por favor, preencha todos os campos obrigatorios",
- "invalidCron": "Expressao cron invalida",
- "connectionTestFailed": "Teste de conexao falhou",
- "connectionTestSuccess": "Teste de conexao bem-sucedido!"
+ "requiredFields": "Por favor, preencha todos os campos obrigatórios",
+ "invalidCron": "Expressão cron inválida",
+ "connectionTestFailed": "Teste de conexão falhou",
+ "connectionTestSuccess": "Teste de conexão bem-sucedido!"
},
"messages": {
- "requiredFields": "Por favor, preencha todos os campos obrigatorios",
- "connectionSuccess": "Teste de conexao bem-sucedido!",
- "connectionFailed": "Teste de conexao falhou"
+ "requiredFields": "Por favor, preencha todos os campos obrigatórios",
+ "connectionSuccess": "Teste de conexão bem-sucedido!",
+ "connectionFailed": "Teste de conexão falhou"
},
- "testingConnection": "Testando conexao...",
- "saveSettings": "Salvar Configuracao",
+ "testingConnection": "Testando conexão...",
+ "saveSettings": "Salvar Configuração",
"savingSettings": "Salvando..."
},
"history": {
- "searchPlaceholder": "Buscar backups...",
+ "searchPlaceholder": "Pesquisar backups...",
"allStatus": "Todos os Status",
"status": {
- "completed": "Concluido",
+ "completed": "Concluído",
"failed": "Falhou",
"running": "Executando",
"partial": "Parcial"
@@ -1949,75 +1956,75 @@
"type": "Tipo",
"status": "Status",
"size": "Tamanho",
- "duration": "Duracao",
- "actions": "Acoes"
+ "duration": "Duração",
+ "actions": "Ações"
},
"columns": {
"status": "Status",
"dateTime": "Data e Hora",
"type": "Tipo",
"size": "Tamanho",
- "duration": "Duracao",
- "actions": "Acoes"
+ "duration": "Duração",
+ "actions": "Ações"
},
"details": {
"backupDetails": "Detalhes do Backup",
"destination": "Destino",
"started": "Iniciado",
- "completed": "Concluido",
- "contentBackedUp": "Conteudo Salvo",
+ "completed": "Concluído",
+ "contentBackedUp": "Conteúdo no Backup",
"errorDetails": "Detalhes do Erro",
"manifest": "Manifesto"
},
- "statistics": "Estatisticas",
+ "statistics": "Estatísticas",
"errors": "Erros",
"backupDetails": {
"backupId": "ID do Backup",
- "startTime": "Hora de Inicio",
- "endTime": "Hora de Termino",
+ "startTime": "Hora de Início",
+ "endTime": "Hora de Término",
"destination": "Destino",
"filesProcessed": "Arquivos Processados",
"totalSize": "Tamanho Total",
- "compressionRatio": "Taxa de Compressao",
+ "compressionRatio": "Taxa de Compressão",
"errorLog": "Log de Erros",
"noErrors": "Nenhum erro ocorreu"
},
"pagination": {
- "showing": "Mostrando {{from}}-{{to}} de {{total}} backups",
+ "showing": "Exibindo {{from}}-{{to}} de {{total}} backups",
"previous": "Anterior",
- "next": "Proximo"
+ "next": "Próximo"
},
"filter": {
"allStatus": "Todos os Status",
- "completed": "Concluido",
+ "completed": "Concluído",
"failed": "Falhou",
"running": "Executando",
"partial": "Parcial"
},
"noBackupsFound": "Nenhum backup encontrado",
- "backupsWillAppear": "Backups aparecerao aqui depois de criados",
+ "backupsWillAppear": "Os backups aparecerão aqui quando criados",
"messages": {
- "deleteSuccess": "Backup excluido com sucesso"
+ "deleteSuccess": "Backup excluído com sucesso"
}
},
"restore": {
"steps": {
"selectSource": "Selecionar Origem",
"chooseBackup": "Escolher Backup",
- "restoreOptions": "Opcoes de Restauracao",
+ "restoreOptions": "Opções de Restauração",
"reviewConfirm": "Revisar e Confirmar",
- "progress": "Progresso da Restauracao"
+ "progress": "Progresso da Restauração"
},
"source": {
"title": "Selecionar Origem do Backup",
"subtitle": "Escolha de onde restaurar o backup",
"local": {
"name": "Backup Local",
- "description": "Restaurar do sistema de arquivos local"
+ "description": "Restaurar a partir do sistema de arquivos local"
},
"s3": {
"name": "Armazenamento S3",
- "description": "Restaurar do bucket S3"
+ "description": "Restaurar a partir do bucket S3"
},
"upload": {
"name": "Enviar Backup",
@@ -2025,7 +2032,7 @@
"comingSoon": "Funcionalidade de upload em breve"
},
"configuration": {
- "s3": "Configuracao S3",
+ "s3": "Configuração S3",
"endpoint": "URL do Endpoint S3",
"bucket": "Nome do Bucket",
"accessKey": "ID da Chave de Acesso",
@@ -2034,143 +2041,143 @@
},
"backup": {
"title": "Escolher Backup para Restaurar",
- "subtitle": "Selecione entre os backups disponiveis",
+ "subtitle": "Selecione entre os backups disponíveis",
"noBackupsFound": "Nenhum backup encontrado na origem selecionada",
"encrypted": "Backup Criptografado",
- "encryptedMessage": "Voce precisara fornecer a frase de criptografia para restaurar este backup.",
- "enterPassphrase": "Digite a frase de criptografia",
- "at": "as"
+ "encryptedMessage": "Você precisará fornecer a senha de criptografia para restaurar este backup.",
+ "enterPassphrase": "Digite a senha de criptografia",
+ "at": "às"
},
"restoreTypes": {
"full": {
- "name": "Restauracao Completa",
- "description": "Restaurar tudo incluindo banco de dados, fotos e arquivos",
- "warning": "Isto substituira todos os dados atuais"
+ "name": "Restauração Completa",
+ "description": "Restaurar tudo, incluindo banco de dados, fotos e arquivos",
+ "warning": "Isso substituirá todos os dados atuais"
},
"database": {
- "name": "Apenas Banco de Dados",
- "description": "Restaurar apenas o banco de dados (configuracoes, eventos, usuarios)",
- "warning": "O banco de dados atual sera substituido"
+ "name": "Somente Banco de Dados",
+ "description": "Restaurar apenas o banco de dados (configurações, eventos, usuários)",
+ "warning": "O banco de dados atual será substituído"
},
"files": {
- "name": "Apenas Arquivos",
+ "name": "Somente Arquivos",
"description": "Restaurar apenas fotos e arquivos",
"warning": "Arquivos existentes podem ser sobrescritos"
},
"selective": {
- "name": "Restauracao Seletiva",
- "description": "Escolha itens especificos para restaurar",
- "warning": "Apenas itens selecionados serao restaurados"
+ "name": "Restauração Seletiva",
+ "description": "Escolher itens específicos para restaurar",
+ "warning": "Apenas os itens selecionados serão restaurados"
}
},
"options": {
- "title": "Opcoes de Restauracao",
+ "title": "Opções de Restauração",
"subtitle": "Escolha o que restaurar",
"additionalOptions": {
- "title": "Opcoes Adicionais",
- "skipPreBackup": "Pular Backup Pre-Restauracao",
- "skipPreBackupHelp": "Por padrao, um backup e criado antes da restauracao. Marque para pular.",
- "force": "Forcar Restauracao",
- "forceHelp": "Ignorar verificacoes de seguranca e avisos (use com cuidado)"
+ "title": "Opções Adicionais",
+ "skipPreBackup": "Ignorar Backup Pré-Restauração",
+ "skipPreBackupHelp": "Por padrão, um backup é criado antes da restauração. Marque esta opção para ignorar.",
+ "force": "Forçar Restauração",
+ "forceHelp": "Ignorar verificações e avisos de segurança (use com cuidado)"
}
},
"confirmation": {
"title": "Revisar e Confirmar",
- "subtitle": "Por favor, revise sua configuracao de restauracao",
+ "subtitle": "Por favor, revise sua configuração de restauração",
"validation": {
- "passed": "Validacao Aprovada",
- "failed": "Validacao Falhou",
- "checking": "Validando configuracao de restauracao..."
+ "passed": "Validação Aprovada",
+ "failed": "Validação Falhou",
+ "checking": "Validando configuração de restauração..."
},
"spaceCheck": {
- "title": "Espaco de Armazenamento",
- "required": "Necessario",
- "available": "Disponivel",
- "insufficient": "Espaco de armazenamento insuficiente"
+ "title": "Espaço de Armazenamento",
+ "required": "Necessário",
+ "available": "Disponível",
+ "insufficient": "Espaço de armazenamento insuficiente"
},
"summary": {
- "title": "Resumo da Restauracao",
+ "title": "Resumo da Restauração",
"source": "Origem",
"backupDate": "Data do Backup",
- "restoreType": "Tipo de Restauracao",
- "preBackup": "Pre-backup",
+ "restoreType": "Tipo de Restauração",
+ "preBackup": "Pré-backup",
"enabled": "Ativado",
"skipped": "Ignorado"
},
"warning": {
"title": "Aviso Importante",
- "message": "Esta operacao de restauracao substituira dados existentes. Certifique-se de ter um backup atual antes de prosseguir. Esta acao nao pode ser desfeita."
+ "message": "Esta operação de restauração substituirá os dados existentes. Certifique-se de ter um backup atual antes de continuar. Esta ação não pode ser desfeita."
}
},
"progress": {
- "title": "Progresso da Restauracao",
- "inProgress": "Restauracao em andamento...",
- "completed": "Restauracao concluida",
+ "title": "Progresso da Restauração",
+ "inProgress": "Restauração em andamento...",
+ "completed": "Restauração concluída",
"overallProgress": "Progresso Geral",
"current": "Atual",
"statusDetails": "Detalhes do Status",
- "restoreLogs": "Logs de Restauracao",
+ "restoreLogs": "Logs de Restauração",
"steps": {
- "completed": "Concluido",
+ "completed": "Concluído",
"running": "Executando",
"failed": "Falhou",
"pending": "Pendente"
},
"success": {
- "title": "Restauracao Concluida com Sucesso",
- "message": "Seus dados foram restaurados. Por favor, verifique se tudo esta funcionando corretamente."
+ "title": "Restauração Concluída com Sucesso",
+ "message": "Seus dados foram restaurados. Por favor, verifique se tudo está funcionando corretamente."
}
},
"actions": {
"back": "Voltar",
- "next": "Proximo",
- "startRestore": "Iniciar Restauracao",
+ "next": "Próximo",
+ "startRestore": "Iniciar Restauração",
"starting": "Iniciando...",
"validating": "Validando...",
- "startNewRestore": "Iniciar Nova Restauracao"
+ "startNewRestore": "Iniciar Nova Restauração"
},
"messages": {
- "restoreStarted": "Restauracao iniciada com sucesso"
+ "restoreStarted": "Restauração iniciada com sucesso"
}
},
"messages": {
"backupStarted": "Backup iniciado com sucesso",
"backupFailed": "Falha ao iniciar backup",
- "configUpdated": "Configuracao de backup atualizada",
- "configUpdateFailed": "Falha ao atualizar configuracao",
- "backupDeleted": "Backup excluido com sucesso",
+ "configUpdated": "Configuração de backup atualizada",
+ "configUpdateFailed": "Falha ao atualizar configuração",
+ "backupDeleted": "Backup excluído com sucesso",
"deleteFailed": "Falha ao excluir backup",
- "testEmailSent": "Teste de conexao bem-sucedido!",
- "testEmailFailed": "Teste de conexao falhou"
+ "testEmailSent": "Teste de conexão bem-sucedido!",
+ "testEmailFailed": "Teste de conexão falhou"
}
},
"cssTemplates": {
- "title": "Templates CSS Personalizados",
- "template": "Template",
- "templateName": "Nome do Template",
- "enableTemplate": "Ativar este template",
- "enableHint": "Templates ativados podem ser selecionados ao criar eventos",
- "cssContent": "Conteudo CSS",
- "cssHint": "Use .gallery-page para limitar estilos a galeria. Variaveis disponiveis: --gallery-bg, --gallery-text, --gallery-accent",
- "securityNotice": "Aviso de Seguranca",
- "securityText": "O CSS e sanitizado para prevenir codigo malicioso. URLs externas, @import e expressoes JavaScript sao bloqueadas.",
- "resetToDefault": "Restaurar Padrao",
- "resetConfirm": "Restaurar este template para o padrao? Suas alteracoes serao perdidas.",
- "unsavedChanges": "Alteracoes nao salvas",
- "saveTemplate": "Salvar Template",
- "lastUpdated": "Ultima atualizacao",
- "saved": "Template salvo com sucesso",
- "saveFailed": "Falha ao salvar template",
- "sanitizationWarning": "Alguns padroes CSS foram bloqueados por seguranca",
- "reset": "Template restaurado para o padrao",
- "resetFailed": "Falha ao restaurar template"
+ "title": "Modelos de CSS Personalizado",
+ "template": "Modelo",
+ "templateName": "Nome do Modelo",
+ "enableTemplate": "Ativar este modelo",
+ "enableHint": "Modelos ativados podem ser selecionados ao criar eventos",
+ "cssContent": "Conteúdo CSS",
+ "cssHint": "Use .gallery-page para aplicar estilos à galeria. Variáveis disponíveis: --gallery-bg, --gallery-text, --gallery-accent",
+ "securityNotice": "Aviso de Segurança",
+ "securityText": "O CSS é sanitizado para evitar código malicioso. URLs externas, @import e expressões JavaScript são bloqueados.",
+ "resetToDefault": "Redefinir para Padrão",
+ "resetConfirm": "Redefinir este modelo para o padrão? Suas alterações serão perdidas.",
+ "unsavedChanges": "Alterações não salvas",
+ "saveTemplate": "Salvar Modelo",
+ "lastUpdated": "Última atualização",
+ "saved": "Modelo salvo com sucesso",
+ "saveFailed": "Falha ao salvar modelo",
+ "sanitizationWarning": "Alguns padrões CSS foram bloqueados por segurança",
+ "reset": "Modelo redefinido para o padrão",
+ "resetFailed": "Falha ao redefinir modelo"
},
"maintenance": {
- "title": "Manutencao do Sistema",
- "message": "Estamos realizando manutencao programada para melhorar nosso servico. Voltaremos em breve.",
- "expectedCompletion": "Previsao de conclusao:",
+ "title": "Manutenção do Sistema",
+ "message": "Estamos realizando manutenção programada para melhorar nosso serviço. Voltaremos em breve.",
+ "expectedCompletion": "Previsão de conclusão:",
"checkBackLater": "Por favor, volte mais tarde",
- "urgentMatters": "Para assuntos urgentes, entre em contato"
+ "urgentMatters": "Para assuntos urgentes, entre em contato com"
},
"passwordChange": {
"title": "Alterar Senha",
@@ -2180,96 +2187,96 @@
"currentPasswordPlaceholder": "Digite a senha atual",
"newPasswordPlaceholder": "Digite a nova senha",
"confirmPasswordPlaceholder": "Confirme a nova senha",
- "requirements": "Requisitos da Senha:",
+ "requirements": "Requisitos de Senha:",
"minLength": "Pelo menos 6 caracteres",
"mustDiffer": "Deve ser diferente da senha atual",
"success": "Senha alterada com sucesso",
"failed": "Falha ao alterar senha",
- "currentRequired": "Senha atual e obrigatoria",
- "newRequired": "Nova senha e obrigatoria",
- "minLengthError": "Senha deve ter pelo menos 6 caracteres",
+ "currentRequired": "A senha atual é obrigatória",
+ "newRequired": "A nova senha é obrigatória",
+ "minLengthError": "A senha deve ter pelo menos 6 caracteres",
"confirmRequired": "Por favor, confirme sua nova senha",
- "noMatch": "Senhas nao conferem",
- "mustBeDifferent": "Nova senha deve ser diferente da senha atual",
+ "noMatch": "As senhas não coincidem",
+ "mustBeDifferent": "A nova senha deve ser diferente da senha atual",
"cancel": "Cancelar"
},
"mandatoryPasswordChange": {
- "title": "Alteracao de Senha Obrigatoria",
- "description": "Por razoes de seguranca, voce deve alterar sua senha antes de acessar o painel admin.",
- "success": "Senha alterada com sucesso! Voce ja pode acessar o painel admin.",
+ "title": "Alteração de Senha Obrigatória",
+ "description": "Por razões de segurança, você deve alterar sua senha antes de acessar o painel de administração.",
+ "success": "Senha alterada com sucesso! Você já pode acessar o painel de administração.",
"minLength": "Pelo menos 12 caracteres",
- "mustContainUpperLower": "Deve conter letras maiusculas e minusculas",
- "mustContainNumbers": "Deve conter numeros",
+ "mustContainUpperLower": "Deve conter letras maiúsculas e minúsculas",
+ "mustContainNumbers": "Deve conter números",
"mustContainSpecial": "Deve conter caracteres especiais (!@#$%^&*)",
- "minLengthError": "Senha deve ter pelo menos 12 caracteres",
- "mustContainLowercase": "Senha deve conter letras minusculas",
- "mustContainUppercase": "Senha deve conter letras maiusculas",
- "mustContainNumbersError": "Senha deve conter numeros",
- "mustContainSpecialError": "Senha deve conter caracteres especiais"
+ "minLengthError": "A senha deve ter pelo menos 12 caracteres",
+ "mustContainLowercase": "A senha deve conter letras minúsculas",
+ "mustContainUppercase": "A senha deve conter letras maiúsculas",
+ "mustContainNumbersError": "A senha deve conter números",
+ "mustContainSpecialError": "A senha deve conter caracteres especiais"
},
"offline": {
- "backOnline": "De volta online",
- "noConnection": "Sem conexao com a internet"
+ "backOnline": "Conexão restabelecida",
+ "noConnection": "Sem conexão com a internet"
},
"download": {
"downloading": "Baixando...",
- "percentComplete": "% concluido"
+ "percentComplete": "% concluído"
},
"passwordGenerator": {
"weak": "Fraca",
- "fair": "Razoavel",
+ "fair": "Razoável",
"good": "Boa",
"strong": "Forte",
"generating": "Gerando...",
"generatePassword": "Gerar Senha",
- "showSuggestions": "Mostrar sugestoes de senha",
- "moreOptions": "Mais Opcoes",
- "suggestions": "Sugestoes de Senha",
+ "showSuggestions": "Mostrar sugestões de senha",
+ "moreOptions": "Mais Opções",
+ "suggestions": "Sugestões de Senha",
"characters": "caracteres",
"copyPassword": "Copiar senha",
"use": "Usar",
- "pattern": "Padrao:",
- "patternDescription": "As senhas sao geradas usando o nome e a data do seu evento. Exemplo: \"Local2024$Agosto\" para melhor seguranca e memorabilidade."
+ "pattern": "Padrão:",
+ "patternDescription": "As senhas são geradas usando o nome e a data do seu evento. Exemplo: \"Local2024$Agosto\" para maior segurança e facilidade de memorização."
},
"feedback": {
- "comments": "Comentarios",
- "addComment": "Adicionar Comentario",
+ "comments": "Comentários",
+ "addComment": "Adicionar Comentário",
"yourName": "Seu nome",
"yourEmail": "Seu email",
- "writeComment": "Escreva um comentario...",
+ "writeComment": "Escreva um comentário...",
"submit": "Enviar",
- "commentSubmitted": "Comentario enviado",
- "commentError": "Falha ao enviar comentario",
+ "commentSubmitted": "Comentário enviado",
+ "commentError": "Falha ao enviar comentário",
"rateLimited": "Por favor, aguarde antes de comentar novamente",
- "commentRequired": "Comentario e obrigatorio",
- "nameRequired": "Nome e obrigatorio",
- "emailRequired": "Email e obrigatorio",
- "anonymous": "Anonimo",
- "pendingApproval": "Aguardando aprovacao",
- "noComments": "Nenhum comentario ainda. Seja o primeiro a comentar!",
- "rating": "Avaliacao",
- "ratePhoto": "Avalie esta foto",
- "yourRating": "Sua avaliacao",
- "averageRating": "Avaliacao media",
- "totalRatings": "avaliacoes",
+ "commentRequired": "O comentário é obrigatório",
+ "nameRequired": "O nome é obrigatório",
+ "emailRequired": "O email é obrigatório",
+ "anonymous": "Anônimo",
+ "pendingApproval": "Aguardando aprovação",
+ "noComments": "Nenhum comentário ainda. Seja o primeiro a comentar!",
+ "rating": "Avaliação",
+ "ratePhoto": "Avaliar esta foto",
+ "yourRating": "Sua avaliação",
+ "averageRating": "Avaliação média",
+ "totalRatings": "avaliações",
"likes": "Curtidas",
"favorites": "Favoritos",
"likePhoto": "Curtir esta foto",
"favoritePhoto": "Adicionar aos favoritos",
"photoFeedback": "Feedback da Foto",
"hasFeedback": "Tem feedback",
- "hasComments": "Tem comentarios",
- "hasRating": "Tem avaliacao",
+ "hasComments": "Tem comentários",
+ "hasRating": "Tem avaliação",
"settings": {
- "title": "Configuracoes de Feedback dos Convidados",
+ "title": "Configurações de Feedback dos Convidados",
"enableFeedback": "Ativar feedback",
"feedbackTypes": "Tipos de Feedback",
- "ratings": "Avaliacoes com Estrelas",
+ "ratings": "Avaliações por Estrelas",
"ratingsDesc": "Permitir que convidados avaliem fotos (1-5 estrelas)",
"likes": "Curtidas",
"likesDesc": "Funcionalidade simples de curtir/descurtir",
- "comments": "Comentarios",
- "commentsDesc": "Comentarios de texto nas fotos",
+ "comments": "Comentários",
+ "commentsDesc": "Comentários de texto nas fotos",
"favorites": "Favoritos",
"favoritesDesc": "Marcar fotos como favoritas"
}
@@ -2277,40 +2284,65 @@
"filter": {
"feedbackFilters": "Filtros de Feedback",
"clear": "Limpar",
- "rating": "Avaliacao",
+ "rating": "Avaliação",
"allPhotos": "Todas as Fotos",
- "anyRating": "Qualquer Avaliacao",
- "oneStarPlus": "1+ Estrelas",
+ "anyRating": "Qualquer Avaliação",
+ "oneStarPlus": "1+ Estrela",
"twoStarsPlus": "2+ Estrelas",
"threeStarsPlus": "3+ Estrelas",
"fourStarsPlus": "4+ Estrelas",
- "fiveStarsOnly": "5 Estrelas Apenas",
+ "fiveStarsOnly": "Apenas 5 Estrelas",
"hasLikes": "Tem curtidas",
"hasFavorites": "Tem favoritos",
- "hasComments": "Tem comentarios"
+ "hasComments": "Tem comentários"
},
"adminLogin": {
- "title": "Login Admin",
+ "title": "Login de Administrador",
"subtitle": "Entre para gerenciar suas galerias de fotos",
- "sessionExpired": "Sua sessao expirou. Por favor, faca login novamente.",
- "emailLabel": "Endereco de Email",
+ "sessionExpired": "Sua sessão expirou. Por favor, faça login novamente.",
+ "emailLabel": "Endereço de email",
"emailPlaceholder": "admin@exemplo.com",
- "emailRequired": "Email e obrigatorio",
- "invalidEmail": "Formato de email invalido",
+ "emailRequired": "O email é obrigatório",
+ "invalidEmail": "Formato de email inválido",
"passwordLabel": "Senha",
"passwordPlaceholder": "Digite sua senha",
- "passwordRequired": "Senha e obrigatoria",
- "passwordMinLength": "Senha deve ter pelo menos 6 caracteres",
+ "passwordRequired": "A senha é obrigatória",
+ "passwordMinLength": "A senha deve ter pelo menos 6 caracteres",
"rememberMe": "Lembrar de mim",
"forgotPassword": "Esqueceu a senha?",
"signIn": "Entrar",
"loginSuccess": "Login realizado com sucesso!",
- "networkError": "Erro de rede. Por favor, verifique sua conexao e tente novamente.",
+ "networkError": "Erro de rede. Por favor, verifique sua conexão e tente novamente.",
"tooManyAttempts": "Muitas tentativas de login. Por favor, tente novamente mais tarde.",
- "invalidCredentials": "Email ou senha invalidos",
+ "invalidCredentials": "email ou senha inválidos",
"generalError": "Ocorreu um erro. Por favor, tente novamente.",
- "needHelp": "Precisa de ajuda? Entre em contato",
- "poweredBy": "Powered by PicPeak",
- "devModeHint": "Modo de Desenvolvimento: Use email: admin@example.com, senha: admin123"
+ "needHelp": "Precisa de ajuda? Entre em contato com",
+ "poweredBy": "Desenvolvido por PicPeak",
+ "devModeHint": "Modo de Desenvolvimento: Use email: admin@exemplo.com, senha: admin123"
+ },
+ "clientAccess": {
+ "title": "Acesso do Cliente",
+ "description": "Revise as fotos e gerencie a visibilidade antes de compartilhar a galeria com os convidados.",
+ "pinLabel": "PIN do Cliente",
+ "pinPlaceholder": "Digite seu PIN de cliente",
+ "enterPin": "Por favor, digite seu PIN de cliente",
+ "invalidPin": "PIN inválido. Por favor, tente novamente.",
+ "loginFailed": "Autenticação falhou. Por favor, tente novamente.",
+ "loginButton": "Acessar Galeria",
+ "guestHint": "Procurando pela galeria de convidados?",
+ "guestLink": "Ir para a visualização de convidados",
+ "banner": "Modo Cliente",
+ "visibleCount": "{{visible}} de {{total}} fotos visíveis para os convidados",
+ "hideSelected": "Ocultar Selecionadas",
+ "showSelected": "Mostrar Selecionadas",
+ "adminTitle": "Acesso do Cliente",
+ "enableToggle": "Ativar Acesso do Cliente",
+ "enableDescription": "Permitir que clientes revisem e ocultem fotos antes de a galeria ser compartilhada com os convidados.",
+ "pinHelperText": "O cliente usará este PIN para acessar a página de revisão.",
+ "pinUpdated": "PIN do cliente atualizado",
+ "setPin": "Definir PIN",
+ "linkLabel": "Link de Acesso do Cliente",
+ "regenerateToken": "Regenerar link",
+ "tokenRegenerated": "Link de acesso do cliente regenerado"
}
}
diff --git a/frontend/src/i18n/locales/ru.json b/frontend/src/i18n/locales/ru.json
index e1eaf341..6218704b 100644
--- a/frontend/src/i18n/locales/ru.json
+++ b/frontend/src/i18n/locales/ru.json
@@ -1449,6 +1449,13 @@
"username": "Выберите имя пользователя",
"password": "Создайте пароль",
"submit": "Создать аккаунт"
+ },
+ "photos": {
+ "hidden": "Скрыто",
+ "hideSelected": "Скрыть",
+ "showSelected": "Показать",
+ "hiddenSuccess": "Фотографии скрыты от гостей",
+ "visibleSuccess": "Фотографии теперь видны гостям"
}
},
"permissions": {
@@ -2312,5 +2319,30 @@
"needHelp": "Нужна помощь? Свяжитесь",
"poweredBy": "Работает на PicPeak",
"devModeHint": "Режим разработки: используйте email: admin@example.com, пароль: admin123"
+ },
+ "clientAccess": {
+ "title": "Доступ клиента",
+ "description": "Введите PIN-код для просмотра и выбора фотографий перед публикацией.",
+ "pinLabel": "PIN-код клиента",
+ "pinPlaceholder": "Введите PIN-код",
+ "enterPin": "Введите PIN-код, который вы получили",
+ "invalidPin": "Неверный PIN-код. Попробуйте ещё раз.",
+ "loginFailed": "Не удалось войти. Попробуйте ещё раз.",
+ "loginButton": "Получить доступ",
+ "guestHint": "Просто хотите посмотреть фотографии?",
+ "guestLink": "Перейти в гостевую галерею",
+ "banner": "Режим клиента",
+ "visibleCount": "{{visible}} из {{total}} фотографий видны гостям",
+ "hideSelected": "Скрыть выбранные",
+ "showSelected": "Показать выбранные",
+ "adminTitle": "Доступ клиента",
+ "enableToggle": "Включить доступ клиента",
+ "enableDescription": "Позволить клиентам просматривать и скрывать фотографии до того, как галерея будет открыта для гостей.",
+ "pinHelperText": "Клиент будет использовать этот PIN-код для доступа к странице проверки.",
+ "pinUpdated": "PIN-код клиента обновлён",
+ "setPin": "Установить PIN",
+ "linkLabel": "Ссылка для клиента",
+ "regenerateToken": "Сгенерировать новую ссылку",
+ "tokenRegenerated": "Ссылка для клиента обновлена"
}
}
\ No newline at end of file
diff --git a/frontend/src/pages/ClientAccessPage.tsx b/frontend/src/pages/ClientAccessPage.tsx
new file mode 100644
index 00000000..180c312b
--- /dev/null
+++ b/frontend/src/pages/ClientAccessPage.tsx
@@ -0,0 +1,207 @@
+import React, { useState } from 'react';
+import { useParams, useSearchParams, useNavigate, Link } from 'react-router-dom';
+import { AlertCircle, Lock } from 'lucide-react';
+import { useTranslation } from 'react-i18next';
+import { useQuery } from '@tanstack/react-query';
+
+import { Card, CardContent, Input, Button, Loading } from '../components/common';
+import { useGalleryAuth } from '../contexts';
+import { useGalleryInfo } from '../hooks/useGallery';
+import { api } from '../config/api';
+import { buildResourceUrl } from '../utils/url';
+
+export const ClientAccessPage: React.FC = () => {
+ const { slug } = useParams<{ slug: string }>();
+ const [searchParams] = useSearchParams();
+ const navigate = useNavigate();
+ const { isAuthenticated, isClient, clientLogin, isLoading: authLoading } = useGalleryAuth();
+ const { t } = useTranslation();
+ const [pin, setPin] = useState('');
+ const [isLoggingIn, setIsLoggingIn] = useState(false);
+ const [loginError, setLoginError] = useState(null);
+
+ const { data: galleryInfo, isLoading: isLoadingInfo, error: infoError } = useGalleryInfo(slug);
+
+ const { data: settingsData } = useQuery({
+ queryKey: ['gallery-settings'],
+ queryFn: async () => {
+ const response = await api.get('/public/settings');
+ return response.data;
+ },
+ staleTime: 5 * 60 * 1000,
+ });
+
+ // If already authenticated as client, redirect to gallery
+ React.useEffect(() => {
+ if (isAuthenticated && isClient && slug) {
+ navigate(`/gallery/${slug}`, { replace: true });
+ }
+ }, [isAuthenticated, isClient, slug, navigate]);
+
+ const handleLogin = async (e: React.FormEvent) => {
+ e.preventDefault();
+
+ if (!pin.trim()) {
+ setLoginError(t('clientAccess.enterPin'));
+ return;
+ }
+
+ if (!slug) {
+ setLoginError(t('errors.galleryNotFound'));
+ return;
+ }
+
+ try {
+ setIsLoggingIn(true);
+ setLoginError(null);
+ await clientLogin(slug, pin);
+ navigate(`/gallery/${slug}`, { replace: true });
+ } catch (error: any) {
+ const statusCode = error.response?.status;
+ if (statusCode === 401) {
+ setLoginError(t('clientAccess.invalidPin'));
+ } else if (statusCode === 423) {
+ setLoginError(t('auth.tooManyAttempts'));
+ } else {
+ setLoginError(t('clientAccess.loginFailed'));
+ }
+ } finally {
+ setIsLoggingIn(false);
+ }
+ };
+
+ if (isLoadingInfo || authLoading) {
+ return (
+