diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json new file mode 100644 index 0000000..d5e749b --- /dev/null +++ b/apps/web/messages/en.json @@ -0,0 +1,530 @@ +{ + "meta": { + "title": "Discord Webhook Manager - Supercharge Your Discord Communication", + "description": "Effortlessly manage, automate, and send rich messages to your Discord channels. Streamline announcements, updates, and interactions with our intuitive Webhook Manager." + }, + "home": { + "hero": { + "heading": "Supercharge Your Discord Communication", + "subtext": "Eliminate manual work, costly bots, and complex custom solutions. Effortlessly manage, automate, and send rich messages to your Discord channels, streamlining announcements and interactions with our intuitive Webhook Manager.", + "button_logged_in": "Go to Dashboard", + "button_logged_out": "Get Started for Free" + }, + "whatWeDo": { + "title": "What We Do", + "features": { + "centralized": { + "title": "Centralized Webhook Management", + "desc": "Keep all your Discord webhooks organized in one place. Easily add, edit, and delete webhooks, eliminating the hassle of juggling multiple Discord servers or manual configurations." + }, + "richMessages": { + "title": "Rich Message Composition", + "desc": "Craft stunning Discord messages with full support for embeds, custom avatars, and usernames. Make your announcements stand out without the need for custom bots or tedious manual work." + }, + "customAvatars": { + "title": "Custom Avatars & Identities", + "desc": "Define and reuse custom avatars and usernames for your webhook messages, allowing for dynamic and engaging announcements tailored to different requirements." + }, + "ui": { + "title": "Intuitive User Interface", + "desc": "Our clean and user-friendly dashboard makes managing your Discord webhooks a breeze, even for beginners." + }, + "secure": { + "title": "Secure & Reliable", + "desc": "Built with security in mind, ensuring your webhook data and Discord interactions are safe and dependable." + } + } + }, + "contact": { + "title": "Get in Touch", + "desc": "Have questions, feedback, or just want to say hello? Feel free to reach out!", + "email": "coderck@proton.me", + "github": "ctrixcode", + "portfolio": "My Portfolio" + }, + "footer": { + "copyright": "Discord Webhook Manager. All rights reserved." + } + }, + "login": { + "loading": { + "sessionCheck": "Checking your session..." + }, + "header": { + "title": "Welcome Back", + "subtitle": "Sign in to your account using email, Google, or Discord." + }, + "oauth": { + "discord": "Continue with Discord", + "google": "Continue with Google", + "loading": "Signing in...", + "discordAlt": "Sign in with Discord", + "googleAlt": "Sign in with Google", + "loadingAlt": "Signing in..." + }, + "divider": { + "or": "OR" + }, + "form": { + "emailLabel": "Email Address", + "emailPlaceholder": "Enter your email", + "passwordLabel": "Password", + "passwordPlaceholder": "Enter your password", + "passwordShow": "Show password", + "passwordHide": "Hide password", + "buttonContinue": "Continue", + "buttonSignIn": "Sign In", + "buttonSigningIn": "Signing In...", + "errorInvalidEmail": "Please enter a valid email address.", + "errorShortPassword": "Password must be at least 8 characters long.", + "errorSignInFailed": "Sign-in failed. Please check your credentials and try again." + }, + "footer": { + "noAccount": "Don't have an account?", + "signUp": "Sign up" + } + }, + "dashboard": { + "welcome": "Welcome back!", + "manage": "Manage your Discord webhooks and messages", + "quickActions": "Quick Actions", + "webhook": "Webhook", + "sendMessage": "Send Message", + "template": "Template", + "gettingStarted": "Getting Started", + "gettingStartedDesc": "New to webhook management? Here's how to get started quickly.", + "steps": { + "oneTitle": "Connect your first webhook", + "oneDesc": "Add a Discord webhook URL to start sending messages.", + "twoTitle": "Send your first message", + "twoDesc": "Test your webhook by sending a message to your Discord channel.", + "threeTitle": "Create templates and schedule", + "threeDesc": "Build reusable templates and schedule messages for later." + }, + "title": "Webhooks", + "subtitle": "Manage your Discord webhooks", + "stats": { + "total": "Total Webhooks", + "active": "active", + "activeTitle": "Active Webhooks", + "ready": "Ready to send messages" + }, + "search": { + "placeholder": "Search webhooks..." + }, + "filters": { + "all": "All", + "active": "Active", + "inactive": "Inactive" + }, + "empty": { + "noResults": { + "title": "No webhooks found", + "desc": "Try adjusting your search query or filters" + }, + "noWebhooks": { + "title": "No webhooks yet", + "desc": "Get started by adding your first Discord webhook" + } + }, + "templates": { + "title": "Message Templates", + "subtitle": "Create and manage reusable message templates", + "createButton": "Create Template", + "searchPlaceholder": "Search templates...", + "badgeUses": "TODO uses", + "edit": "Edit", + "delete": "Delete", + "contentPreview": "Content Preview:", + "noContent": "No content", + "embedCount": "{count, plural, one {# embed} other {# embeds}}", + "noTemplatesTitle": "No templates yet", + "noTemplatesSubtitle": "Create your first message template to get started", + "noResultsTitle": "No templates found", + "noResultsSubtitle": "Try adjusting your search query", + "deleteDialogTitle": "Delete template?", + "deleteDialogDescription": "This action cannot be undone. This will permanently delete the template \"{name}\" from your account.", + "cancel": "Cancel", + "confirmDelete": "Delete", + "toast": { + "deletedTitle": "Template deleted", + "deletedDescription": "Template has been removed" + } + }, + "createTemplate": { + "back": "Back", + "createTitle": "Create Template", + "editTitle": "Edit Template", + "subtitle": "Design your Discord message with live preview", + "save": "Save", + "update": "Update", + "saving": "Saving...", + "toast": { + "savedTitle": "Template saved", + "savedDesc": "Template saved successfully!", + "errorTitle": "Error saving template" + } + }, + "settingsPage": { + "title": "Account Settings", + "subtitle": "Manage your profile, authentication, and usage limits.", + "accountType": { + "title": "Account Type", + "desc": "Check your current plan and features.", + "error": "Could not load account type." + }, + "accountQuotes": { + "free": "The perfect starting point for managing your webhooks.", + "paid": "More power and higher limits for growing needs.", + "premium": "Maximum power for the most demanding users and projects." + }, + "usage": { + "title": "Usage", + "desc": "Track your current usage and limits", + "webhookMessages": "Webhook Messages Sent (Daily)", + "mediaStorage": "Media Storage Used", + "error": "Could not load usage data." + }, + "plans": { + "title": "Manage Plans", + "desc": "Upgrade, downgrade, or cancel your current subscription.", + "button": "View Plans" + }, + "support": { + "title": "Support", + "desc": "Share your love for the app or get in touch for support.", + "message": "We love hearing feedback! If you find the app helpful, consider sharing your positive experience on Twitter.", + "dm": "For support or bug reports, please DM @ctrix on Twitter.", + "button": "Share on X (Twitter)" + }, + "clearData": { + "title": "Clear Local Data", + "desc": "This will clear all local storage data, including your preferences and cached data. This is useful for troubleshooting. You will be logged out.", + "confirm": "Clear Data and Reload" + }, + "auth": { + "password": { + "title": "Password", + "descCreate": "Create a password to enable email login", + "descChange": "Change your account password", + "buttonCreate": "Create Password", + "buttonChange": "Change Password" + }, + "discord": { + "title": "Discord Account", + "descLinked": "Your Discord account is linked", + "descLink": "Link your Discord account for OAuth login", + "statusConnected": "Connected", + "idLabel": "Discord ID", + "usernameLabel": "Discord Username", + "buttonLink": "Link Discord Account" + } + } + }, + "sendMessagePage": { + "title": "Send Message", + "subtitle": "Send messages immediately to one or multiple webhooks", + "sendTo": "Send to {count, plural, one {# webhook} other {# webhooks}}", + "sending": "Sending...", + "tabs": { + "content": "Content", + "settings": "Settings", + "embeds": "Embeds", + "webhooks": "Webhooks" + }, + "composeMessage": "Compose Message", + "characters": "characters", + "clear": "Clear", + "loadTemplate": "Load Template", + "messageText": "Message Text", + "messagePlaceholder": "Enter your message content...", + "appearance": "Message Appearance", + "chooseAvatar": "Choose from your saved avatar profiles", + "tts": "Text-to-Speech", + "enableTts": "Enable TTS for this message", + "threadName": "Thread Name (Optional)", + "threadHint": "If specified, the message will be sent to a new thread", + "messageUrl": "Discord Message URL (Optional)", + "urlHint": "If provided, the message will replace the existing Discord message at this URL.", + "selectWebhooks": "Select Webhooks ({selected}/{total})", + "noWebhooks": "No webhooks available. Add some webhooks first.", + "loadingWebhooks": "Loading webhooks...", + "success": "Message sent successfully to {count, plural, one {# webhook} other {# webhooks}}", + "errorSelect": "Please select at least one webhook", + "errorContent": "Please enter a message or add an embed", + "errorGeneral": "An unexpected error occurred" + }, + "plansPage": { + "title": "Subscription Plans", + "subtitle": "Choose the plan that best fits your needs.", + "plans": { + "free": { + "name": "Free", + "description": "Perfect for getting started", + "features": { + "messages_day": "{count} Webhook Messages/Day", + "media_storage": "{count} MB Media Storage", + "unlimited_messages": "Unlimited Webhook Messages/Day", + "large_storage": "{count} GB Media Storage", + "custom_avatars": "Custom Avatars", + "priority_support": "Priority Support", + "dedicated_support": "24/7 Dedicated Support" + }, + "cta_current": "Current Plan" + }, + "paid": { + "name": "Paid", + "description": "For growing communities", + "cta_upgrade": "Upgrade" + }, + "premium": { + "name": "Premium", + "description": "Unleash full power", + "cta_upgrade": "Upgrade" + } + } + }, + "avatarsPage": { + "title": "Predefined Avatars", + "subtitle": "Create and manage reusable avatar profiles for your webhooks", + "createButton": "Create Avatar", + "searchPlaceholder": "Search avatars...", + "loading": "Loading avatars...", + "emptyState": { + "noAvatarsTitle": "No avatars yet", + "noAvatarsMessage": "Create your first predefined avatar to get started", + "noResultsTitle": "No avatars found", + "noResultsMessage": "Try adjusting your search terms" + } + } + }, + "avatarCard": { + "actions": { + "edit": "Edit", + "copyUrl": "Copy Avatar URL", + "delete": "Delete", + "select": "Select Avatar" + }, + "info": { + "created": "Created: {date}" + }, + "toast": { + "deleteSuccessTitle": "Avatar deleted", + "deleteSuccessDescription": "Avatar deleted successfully", + "deleteErrorTitle": "Error deleting avatar", + "copySuccessTitle": "Avatar URL copied", + "copySuccessDescription": "Avatar URL copied to clipboard" + }, + "deleteDialog": { + "title": "Delete Avatar", + "description": "Are you sure you want to delete \"{username}\"? This action cannot be undone.", + "cancel": "Cancel", + "confirm": "Delete" + } + }, + "avatarSelector": { + "title": "Select Predefined Avatar", + "searchPlaceholder": "Search avatars...", + "addButton": "Add", + "emptyState": { + "noAvatars": "No predefined avatars yet", + "noResults": "No avatars found" + } + }, + "createAvatarDialog": { + "title": { + "create": "Create New Avatar", + "edit": "Edit Avatar" + }, + "form": { + "usernameLabel": "Username", + "usernamePlaceholder": "e.g., BotHelper, Announcer", + "avatarIconLabel": "Avatar Icon", + "urlPlaceholder": "https://example.com/avatar.png", + "browse": "Browse" + }, + "actions": { + "cancel": "Cancel", + "create": "Create Avatar", + "update": "Update Avatar", + "creating": "Creating...", + "updating": "Updating..." + }, + "toast": { + "createSuccessTitle": "Avatar created", + "createSuccessDescription": "Avatar created successfully", + "updateSuccessTitle": "Avatar updated", + "updateSuccessDescription": "Avatar updated successfully", + "errorTitle": "Error", + "unexpectedError": "An unexpected error occurred", + "limitReachedTitle": "Limit Reached", + "mediaLimitLink": "Check your usage in settings." + } + }, + "themeSelector": { + "title": "Theme", + "description": "Choose your preferred theme or let the system decide", + "themes": { + "light": "Light", + "dark": "Dark", + "system": "System" + } + }, + "addWebhookDialog": { + "triggerButton": "Add Webhook", + "title": "Add New Webhook", + "description": "Add a Discord webhook to start sending messages. You can find webhook URLs in your Discord server settings.", + "form": { + "nameLabel": "Webhook Name", + "namePlaceholder": "My Discord Webhook", + "urlLabel": "Webhook URL", + "urlPlaceholder": "https://discord.com/api/webhooks/...", + "descriptionLabel": "Description (Optional)", + "descriptionPlaceholder": "What is this webhook used for?" + }, + "actions": { + "cancel": "Cancel", + "add": "Add Webhook", + "adding": "Adding..." + } + }, + "dashboardHeader": { + "title": "Webhook Manager", + "subtitle": "Discord Integration", + "languageSelector": "Lang", + "accountType": { + "free": "Free", + "paid": "Paid", + "premium": "Premium" + }, + "accountTypeTooltip": { + "free": "Explore the basics, unlock your potential.", + "paid": "Elevate your experience, achieve more.", + "premium": "Unleash the ultimate power, no limits." + }, + "menu": { + "settings": "Settings", + "logout": "Log out" + } + }, + "embedBuilder": { + "header": { + "title": "Discord Embeds", + "subtitle": "Add rich embeds to your message (max {max})", + "addButton": "Add Embed" + }, + "emptyState": { + "noEmbeds": "No embeds added yet", + "callToAction": "Click \"Add Embed\" to create rich message content" + }, + "embedItem": { + "titleLabel": "Embed {index}", + "removeButton": "Remove", + "fields": { + "title": "Title", + "titlePlaceholder": "Embed title", + "url": "URL", + "urlPlaceholder": "Embed URL", + "description": "Description", + "descriptionPlaceholder": "Embed description", + "color": "Color", + "image": "Image", + "imagePlaceholder": "Image URL", + "thumbnail": "Thumbnail", + "thumbnailPlaceholder": "Thumbnail URL", + "timestamp": "Timestamp" + }, + "author": { + "title": "Author", + "selectButton": "Select Avatar", + "clearButton": "Clear Author", + "manualName": "Name", + "manualNamePlaceholder": "Author name", + "manualIconUrl": "Icon URL", + "manualIconUrlPlaceholder": "Author icon URL", + "manualUrl": "URL", + "manualUrlPlaceholder": "Author URL" + }, + "fieldBuilder": { + "title": "Fields", + "addButton": "Add Field", + "fieldLabel": "Field {index}", + "removeButton": "Remove", + "name": "Name", + "namePlaceholder": "Field name", + "value": "Value", + "valuePlaceholder": "Field value", + "inline": "Inline" + }, + "footer": { + "title": "Footer", + "text": "Text", + "textPlaceholder": "Footer text", + "iconUrl": "Icon URL", + "iconUrlPlaceholder": "Footer icon URL" + } + } + }, + "templateForm": { + "tabs": { + "info": "Template Info", + "message": "Message", + "embeds": "Embeds" + }, + "infoTab": { + "header": "Template Information", + "nameLabel": "Template Name", + "namePlaceholder": "My Awesome Template", + "descriptionLabel": "Description (Optional)", + "descriptionPlaceholder": "What is this template for? Describe its purpose..." + }, + "messageTab": { + "contentHeader": "Message Content", + "contentLabel": "Message Text", + "contentPlaceholder": "Enter your message content here... (Max 2000 characters)", + "characterCount": "{current}/2000 characters", + "avatarHeader": "Message Avatar", + "avatarSelectButton": "Select Avatar" + } + }, + "common": { + "delete": "Eliminar", + "areYouSure": "¿Estás seguro?" + }, + "webhookCard": { + "status": { + "active": "Activo", + "inactive": "Inactivo" + }, + "details": { + "description": "Descripción:", + "messagesSent": "Mensajes enviados:", + "created": "Creado:", + "lastUsed": "Último uso:", + "todoPlaceholder": "PENDIENTE" + }, + "actions": { + "testWebhook": "Probar Webhook", + "testing": "Probando...", + "deactivate": "Desactivar", + "activate": "Activar", + "delete": "Eliminar" + }, + "dialog": { + "title": "¿Estás seguro?", + "description": "Esta acción no se puede deshacer. Esto eliminará permanentemente el webhook \"{webhookName}\" de tu cuenta." + }, + "toasts": { + "updateSuccessTitle": "Webhook actualizado", + "updateSuccessDesc": "Webhook actualizado correctamente", + "updateErrorTitle": "Error al actualizar el webhook", + "deleteSuccessTitle": "Webhook eliminado", + "deleteSuccessDesc": "El webhook ha sido eliminado de tu cuenta", + "testSuccessTitle": "¡Prueba exitosa!", + "testSuccessDesc": "Mensaje de prueba enviado a Discord", + "testFailTitle": "Prueba fallida", + "testFailGenericDesc": "Ocurrió un error al probar el webhook" + } + } +} + diff --git a/apps/web/messages/es.json b/apps/web/messages/es.json new file mode 100644 index 0000000..0bbd5d3 --- /dev/null +++ b/apps/web/messages/es.json @@ -0,0 +1,531 @@ +{ + "meta": { + "title": "Discord Webhook Manager - Potencia tu comunicación en Discord", + "description": "Administra, automatiza y envía mensajes enriquecidos a tus canales de Discord sin esfuerzo. Optimiza los anuncios, actualizaciones e interacciones con nuestro intuitivo Administrador de Webhooks." + }, + "home": { + "hero": { + "heading": "Potencia tu comunicación en Discord", + "subtext": "Elimina el trabajo manual, los bots costosos y las soluciones personalizadas complejas. Administra, automatiza y envía mensajes enriquecidos a tus canales de Discord, optimizando los anuncios e interacciones con nuestro intuitivo Administrador de Webhooks.", + "button_logged_in": "Ir al Panel", + "button_logged_out": "Comienza gratis" + }, + "whatWeDo": { + "title": "Lo que hacemos", + "features": { + "centralized": { + "title": "Gestión centralizada de Webhooks", + "desc": "Mantén todos tus webhooks de Discord organizados en un solo lugar. Agrega, edita y elimina webhooks fácilmente, eliminando la molestia de manejar múltiples servidores o configuraciones manuales." + }, + "richMessages": { + "title": "Composición de mensajes enriquecidos", + "desc": "Crea impresionantes mensajes de Discord con soporte completo para embeds, avatares personalizados y nombres de usuario. Haz que tus anuncios destaquen sin necesidad de bots personalizados o trabajo tedioso." + }, + "customAvatars": { + "title": "Avatares e identidades personalizadas", + "desc": "Define y reutiliza avatares y nombres de usuario personalizados para tus mensajes de webhook, permitiendo anuncios dinámicos y atractivos adaptados a diferentes necesidades." + }, + "ui": { + "title": "Interfaz de usuario intuitiva", + "desc": "Nuestro panel limpio y fácil de usar hace que la gestión de tus webhooks de Discord sea muy sencilla, incluso para principiantes." + }, + "secure": { + "title": "Seguro y confiable", + "desc": "Construido con la seguridad en mente, garantizando que tus datos de webhook y las interacciones con Discord sean seguras y confiables." + } + } + }, + "contact": { + "title": "Ponte en contacto", + "desc": "¿Tienes preguntas, comentarios o simplemente quieres saludar? ¡No dudes en comunicarte!", + "email": "coderck@proton.me", + "github": "ctrixcode", + "portfolio": "Mi Portafolio" + }, + "footer": { + "copyright": "Discord Webhook Manager. Todos los derechos reservados." + } + }, + "login": { + "loading": { + "sessionCheck": "Verificando tu sesión..." + }, + "header": { + "title": "Bienvenido de nuevo", + "subtitle": "Inicia sesión en tu cuenta usando correo electrónico, Google o Discord." + }, + "oauth": { + "discord": "Continuar con Discord", + "google": "Continuar con Google", + "loading": "Iniciando sesión...", + "discordAlt": "Iniciar sesión con Discord", + "googleAlt": "Iniciar sesión con Google", + "loadingAlt": "Iniciando sesión..." + }, + "divider": { + "or": "O" + }, + "form": { + "emailLabel": "Correo electrónico", + "emailPlaceholder": "Introduce tu correo electrónico", + "passwordLabel": "Contraseña", + "passwordPlaceholder": "Introduce tu contraseña", + "passwordShow": "Mostrar contraseña", + "passwordHide": "Ocultar contraseña", + "buttonContinue": "Continuar", + "buttonSignIn": "Iniciar sesión", + "buttonSigningIn": "Iniciando sesión...", + "errorInvalidEmail": "Por favor, introduce un correo electrónico válido.", + "errorShortPassword": "La contraseña debe tener al menos 8 caracteres.", + "errorSignInFailed": "Error al iniciar sesión. Verifica tus credenciales e inténtalo de nuevo." + }, + "footer": { + "noAccount": "¿No tienes una cuenta?", + "signUp": "Regístrate" + } + }, + "dashboard": { + "welcome": "¡Bienvenido de nuevo!", + "manage": "Administra tus webhooks y mensajes de Discord", + "quickActions": "Acciones rápidas", + "webhook": "Webhook", + "sendMessage": "Enviar mensaje", + "template": "Plantilla", + "gettingStarted": "Empezando", + "gettingStartedDesc": "¿Nuevo en la gestión de webhooks? Aquí te mostramos cómo empezar rápidamente.", + "steps": { + "oneTitle": "Conecta tu primer webhook", + "oneDesc": "Agrega una URL de webhook de Discord para comenzar a enviar mensajes.", + "twoTitle": "Envía tu primer mensaje", + "twoDesc": "Prueba tu webhook enviando un mensaje a tu canal de Discord.", + "threeTitle": "Crea plantillas y programa mensajes", + "threeDesc": "Crea plantillas reutilizables y programa mensajes para más tarde." + }, + "title": "Webhooks", + "subtitle": "Administra tus webhooks de Discord", + "stats": { + "total": "Webhooks Totales", + "active": "Webhooks Activos", + "activeTitle": "Listos para enviar mensajes", + "ready": "activos" + }, + "filters": { + "all": "Todos", + "active": "Activos", + "inactive": "Inactivos", + "searchPlaceholder": "Buscar webhooks..." + }, + "empty": { + "noResultsTitle": "No se encontraron webhooks", + "noResultsSubtitle": "Prueba ajustando tu búsqueda o filtros", + "noWebhooks": { + "title": "Aún no hay webhooks", + "desc": "Comienza agregando tu primer webhook de Discord" + }, + "noWebhooksSubtitle": "Comienza agregando tu primer webhook de Discord" + }, + "search": { + "placeholder": "Buscar webhooks..." + }, + "templates": { + "title": "Plantillas de Mensajes", + "subtitle": "Crea y administra plantillas de mensajes reutilizables", + "createButton": "Crear Plantilla", + "searchPlaceholder": "Buscar plantillas...", + "badgeUses": "TODO usos", + "edit": "Editar", + "delete": "Eliminar", + "contentPreview": "Vista previa del contenido:", + "noContent": "Sin contenido", + "embedCount": "{count, plural, one {# incrustación} other {# incrustaciones}}", + "noTemplatesTitle": "Aún no hay plantillas", + "noTemplatesSubtitle": "Crea tu primera plantilla de mensaje para comenzar", + "noResultsTitle": "No se encontraron plantillas", + "noResultsSubtitle": "Prueba ajustando tu búsqueda", + "deleteDialogTitle": "¿Eliminar plantilla?", + "deleteDialogDescription": "Esta acción no se puede deshacer. Esto eliminará permanentemente la plantilla \"{name}\" de tu cuenta.", + "cancel": "Cancelar", + "confirmDelete": "Eliminar", + "toast": { + "deletedTitle": "Plantilla eliminada", + "deletedDescription": "La plantilla ha sido eliminada" + } + }, + "createTemplate": { + "back": "Atrás", + "createTitle": "Crear plantilla", + "editTitle": "Editar plantilla", + "subtitle": "Diseña tu mensaje de Discord con vista previa en vivo", + "save": "Guardar", + "update": "Actualizar", + "saving": "Guardando...", + "toast": { + "savedTitle": "Plantilla guardada", + "savedDesc": "¡Plantilla guardada con éxito!", + "errorTitle": "Error al guardar la plantilla" + } + }, + "settingsPage": { + "title": "Configuración de la Cuenta", + "subtitle": "Administra tu perfil, autenticación y límites de uso.", + "accountType": { + "title": "Tipo de Cuenta", + "desc": "Consulta tu plan actual y las funciones disponibles.", + "error": "No se pudo cargar el tipo de cuenta." + }, + "accountQuotes": { + "free": "El punto de partida perfecto para gestionar tus webhooks.", + "paid": "Más potencia y límites superiores para necesidades crecientes.", + "premium": "Máxima potencia para los usuarios y proyectos más exigentes." + }, + "usage": { + "title": "Uso", + "desc": "Realiza un seguimiento de tu uso actual y límites", + "webhookMessages": "Mensajes de Webhook Enviados (Diarios)", + "mediaStorage": "Almacenamiento de Medios Utilizado", + "error": "No se pudieron cargar los datos de uso." + }, + "plans": { + "title": "Gestionar Planes", + "desc": "Actualiza, degrada o cancela tu suscripción actual.", + "button": "Ver Planes" + }, + "support": { + "title": "Soporte", + "desc": "Comparte tu aprecio por la aplicación o ponte en contacto para recibir soporte.", + "message": "¡Nos encanta recibir comentarios! Si la aplicación te resulta útil, considera compartir tu experiencia positiva en Twitter.", + "dm": "Para soporte o informes de errores, por favor envía un MD a @ctrix en Twitter.", + "button": "Compartir en X (Twitter)" + }, + "clearData": { + "title": "Borrar Datos Locales", + "desc": "Esto eliminará todos los datos de almacenamiento local, incluyendo tus preferencias y datos en caché. Es útil para la resolución de problemas. Se cerrará tu sesión.", + "confirm": "Borrar Datos y Recargar" + }, + "auth": { + "password": { + "title": "Contraseña", + "descCreate": "Crea una contraseña para habilitar el inicio de sesión por correo electrónico", + "descChange": "Cambia la contraseña de tu cuenta", + "buttonCreate": "Crear Contraseña", + "buttonChange": "Cambiar Contraseña" + }, + "discord": { + "title": "Cuenta de Discord", + "descLinked": "Tu cuenta de Discord está vinculada", + "descLink": "Vincula tu cuenta de Discord para iniciar sesión con OAuth", + "statusConnected": "Conectada", + "idLabel": "ID de Discord", + "usernameLabel": "Nombre de Usuario de Discord", + "buttonLink": "Vincular Cuenta de Discord" + } + } + }, + "sendMessagePage": { + "title": "Enviar Mensaje", + "subtitle": "Envía mensajes inmediatamente a uno o varios webhooks", + "sendTo": "Enviar a {count, plural, one {# webhook} other {# webhooks}}", + "sending": "Enviando...", + "tabs": { + "content": "Contenido", + "settings": "Configuración", + "embeds": "Embeds", + "webhooks": "Webhooks" + }, + "composeMessage": "Componer Mensaje", + "characters": "caracteres", + "clear": "Limpiar", + "loadTemplate": "Cargar Plantilla", + "messageText": "Texto del Mensaje", + "messagePlaceholder": "Introduce el contenido de tu mensaje...", + "appearance": "Apariencia del Mensaje", + "chooseAvatar": "Elige entre tus perfiles de avatar guardados", + "tts": "Texto a Voz", + "enableTts": "Habilitar TTS para este mensaje", + "threadName": "Nombre del Hilo (Opcional)", + "threadHint": "Si se especifica, el mensaje se enviará a un nuevo hilo", + "messageUrl": "URL del Mensaje de Discord (Opcional)", + "urlHint": "Si se proporciona, el mensaje reemplazará al mensaje de Discord existente en esta URL.", + "selectWebhooks": "Seleccionar Webhooks ({selected}/{total})", + "noWebhooks": "No hay webhooks disponibles. Añade algunos webhooks primero.", + "loadingWebhooks": "Cargando webhooks...", + "success": "Mensaje enviado con éxito a {count, plural, one {# webhook} other {# webhooks}}", + "errorSelect": "Selecciona al menos un webhook", + "errorContent": "Introduce un mensaje o añade un embed", + "errorGeneral": "Ocurrió un error inesperado" + }, + "plansPage": { + "title": "Planes de Suscripción", + "subtitle": "Elige el plan que mejor se adapte a tus necesidades.", + "plans": { + "free": { + "name": "Gratis", + "description": "Perfecto para empezar", + "features": { + "messages_day": "{count} Mensajes de Webhook/Día", + "media_storage": "{count} MB de Almacenamiento Multimedia", + "unlimited_messages": "Mensajes de Webhook Ilimitados/Día", + "large_storage": "{count} GB de Almacenamiento Multimedia", + "custom_avatars": "Avatares Personalizados", + "priority_support": "Soporte Prioritario", + "dedicated_support": "Soporte Dedicado 24/7" + }, + "cta_current": "Plan Actual" + }, + "paid": { + "name": "Pago", + "description": "Para comunidades en crecimiento", + "cta_upgrade": "Actualizar" + }, + "premium": { + "name": "Premium", + "description": "Libera todo el poder", + "cta_upgrade": "Actualizar" + } + } + }, + "avatarsPage": { + "title": "Avatares Predefinidos", + "subtitle": "Crea y gestiona perfiles de avatar reutilizables para tus webhooks", + "createButton": "Crear Avatar", + "searchPlaceholder": "Buscar avatares...", + "loading": "Cargando avatares...", + "emptyState": { + "noAvatarsTitle": "Aún no hay avatares", + "noAvatarsMessage": "Crea tu primer avatar predefinido para empezar", + "noResultsTitle": "No se encontraron avatares", + "noResultsMessage": "Intenta ajustar tus términos de búsqueda" + } + } + }, + "avatarCard": { + "actions": { + "edit": "Editar", + "copyUrl": "Copiar URL del Avatar", + "delete": "Eliminar", + "select": "Seleccionar Avatar" + }, + "info": { + "created": "Creado: {date}" + }, + "toast": { + "deleteSuccessTitle": "Avatar eliminado", + "deleteSuccessDescription": "Avatar eliminado con éxito", + "deleteErrorTitle": "Error al eliminar el avatar", + "copySuccessTitle": "URL del Avatar copiada", + "copySuccessDescription": "URL del Avatar copiada al portapapeles" + }, + "deleteDialog": { + "title": "Eliminar Avatar", + "description": "¿Estás seguro de que quieres eliminar \"{username}\"? Esta acción no se puede deshacer.", + "cancel": "Cancelar", + "confirm": "Eliminar" + } + }, + "avatarSelector": { + "title": "Seleccionar Avatar Predefinido", + "searchPlaceholder": "Buscar avatares...", + "addButton": "Añadir", + "emptyState": { + "noAvatars": "Aún no hay avatares predefinidos", + "noResults": "No se encontraron avatares" + } + }, + "createAvatarDialog": { + "title": { + "create": "Crear Nuevo Avatar", + "edit": "Editar Avatar" + }, + "form": { + "usernameLabel": "Nombre de Usuario", + "usernamePlaceholder": "Ejemplo: BotHelper, Anunciador", + "avatarIconLabel": "Icono de Avatar", + "urlPlaceholder": "https://ejemplo.com/avatar.png", + "browse": "Examinar" + }, + "actions": { + "cancel": "Cancelar", + "create": "Crear Avatar", + "update": "Actualizar Avatar", + "creating": "Creando...", + "updating": "Actualizando..." + }, + "toast": { + "createSuccessTitle": "Avatar creado", + "createSuccessDescription": "El avatar se creó con éxito", + "updateSuccessTitle": "Avatar actualizado", + "updateSuccessDescription": "El avatar se actualizó con éxito", + "errorTitle": "Error", + "unexpectedError": "Ocurrió un error inesperado", + "limitReachedTitle": "Límite Alcanzado", + "mediaLimitLink": "Verifica tu uso en la configuración." + } + }, + "themeSelector": { + "title": "Tema", + "description": "Elige tu tema preferido o deja que el sistema decida", + "themes": { + "light": "Claro", + "dark": "Oscuro", + "system": "Sistema" + } + }, + "addWebhookDialog": { + "triggerButton": "Añadir Webhook", + "title": "Añadir Nuevo Webhook", + "description": "Añade un webhook de Discord para empezar a enviar mensajes. Puedes encontrar las URL de los webhooks en la configuración de tu servidor de Discord.", + "form": { + "nameLabel": "Nombre del Webhook", + "namePlaceholder": "Mi Webhook de Discord", + "urlLabel": "URL del Webhook", + "urlPlaceholder": "https://discord.com/api/webhooks/...", + "descriptionLabel": "Descripción (Opcional)", + "descriptionPlaceholder": "¿Para qué se utiliza este webhook?" + }, + "actions": { + "cancel": "Cancelar", + "add": "Añadir Webhook", + "adding": "Añadiendo..." + } + }, + "dashboardHeader": { + "title": "Gestor de Webhooks", + "subtitle": "Integración con Discord", + "languageSelector": "Idioma", + "accountType": { + "free": "Gratuito", + "paid": "Pago", + "premium": "Premium" + }, + "accountTypeTooltip": { + "free": "Explora lo básico, desbloquea tu potencial.", + "paid": "Mejora tu experiencia, logra más.", + "premium": "Desata el poder definitivo, sin límites." + }, + "menu": { + "settings": "Configuración", + "logout": "Cerrar sesión" + } + }, + "embedBuilder": { + "header": { + "title": "Embeds de Discord", + "subtitle": "Añade embeds enriquecidos a tu mensaje (máx. {max})", + "addButton": "Añadir Embed" + }, + "emptyState": { + "noEmbeds": "Aún no se han añadido embeds", + "callToAction": "Haz clic en \"Añadir Embed\" para crear contenido de mensaje enriquecido" + }, + "embedItem": { + "titleLabel": "Embed {index}", + "removeButton": "Eliminar", + "fields": { + "title": "Título", + "titlePlaceholder": "Título del embed", + "url": "URL", + "urlPlaceholder": "URL del embed", + "description": "Descripción", + "descriptionPlaceholder": "Descripción del embed", + "color": "Color", + "image": "Imagen", + "imagePlaceholder": "URL de la imagen", + "thumbnail": "Miniatura", + "thumbnailPlaceholder": "URL de la miniatura", + "timestamp": "Marca de tiempo" + }, + "author": { + "title": "Autor", + "selectButton": "Seleccionar Avatar", + "clearButton": "Borrar Autor", + "manualName": "Nombre", + "manualNamePlaceholder": "Nombre del autor", + "manualIconUrl": "URL del Icono", + "manualIconUrlPlaceholder": "URL del icono del autor", + "manualUrl": "URL", + "manualUrlPlaceholder": "URL del autor" + }, + "fieldBuilder": { + "title": "Campos", + "addButton": "Añadir Campo", + "fieldLabel": "Campo {index}", + "removeButton": "Eliminar", + "name": "Nombre", + "namePlaceholder": "Nombre del campo", + "value": "Valor", + "valuePlaceholder": "Valor del campo", + "inline": "En línea" + }, + "footer": { + "title": "Pie de página", + "text": "Texto", + "textPlaceholder": "Texto del pie de página", + "iconUrl": "URL del Icono", + "iconUrlPlaceholder": "URL del icono del pie de página" + } + } + }, + "templateForm": { + "tabs": { + "info": "Información de la Plantilla", + "message": "Mensaje", + "embeds": "Embeds" + }, + "infoTab": { + "header": "Información de la Plantilla", + "nameLabel": "Nombre de la Plantilla", + "namePlaceholder": "Mi Plantilla Genial", + "descriptionLabel": "Descripción (Opcional)", + "descriptionPlaceholder": "¿Para qué sirve esta plantilla? Describe su propósito...", + "livePreviewHeader": "Vista Previa en Vivo" + }, + "messageTab": { + "contentHeader": "Contenido del Mensaje", + "contentLabel": "Texto del Mensaje", + "contentPlaceholder": "Introduce el contenido de tu mensaje aquí... (Máx. 2000 caracteres)", + "characterCount": "{current}/2000 caracteres", + "avatarHeader": "Avatar del Mensaje", + "avatarSelectButton": "Seleccionar Avatar" + } + }, + "common": { + "delete": "Eliminar", + "areYouSure": "¿Estás seguro?" + }, + "webhookCard": { + "status": { + "active": "Activo", + "inactive": "Inactivo" + }, + "details": { + "description": "Descripción:", + "messagesSent": "Mensajes enviados:", + "created": "Creado:", + "lastUsed": "Último uso:", + "todoPlaceholder": "PENDIENTE" + }, + "actions": { + "testWebhook": "Probar Webhook", + "testing": "Probando...", + "deactivate": "Desactivar", + "activate": "Activar", + "delete": "Eliminar" + }, + "dialog": { + "title": "¿Estás seguro?", + "description": "Esta acción no se puede deshacer. Esto eliminará permanentemente el webhook \"{webhookName}\" de tu cuenta." + }, + "toasts": { + "updateSuccessTitle": "Webhook actualizado", + "updateSuccessDesc": "Webhook actualizado correctamente", + "updateErrorTitle": "Error al actualizar el webhook", + "deleteSuccessTitle": "Webhook eliminado", + "deleteSuccessDesc": "El webhook ha sido eliminado de tu cuenta", + "testSuccessTitle": "¡Prueba exitosa!", + "testSuccessDesc": "Mensaje de prueba enviado a Discord", + "testFailTitle": "Prueba fallida", + "testFailGenericDesc": "Ocurrió un error al probar el webhook" + } + } +} + diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts index 15d0653..bb67621 100644 --- a/apps/web/next.config.ts +++ b/apps/web/next.config.ts @@ -1,4 +1,7 @@ import type { NextConfig } from 'next'; +import createNextIntlPlugin from 'next-intl/plugin'; + +const withNextIntl = createNextIntlPlugin(); const nextConfig: NextConfig = { images: { @@ -7,4 +10,4 @@ const nextConfig: NextConfig = { }, }; -export default nextConfig; +export default withNextIntl(nextConfig); diff --git a/apps/web/package.json b/apps/web/package.json index 455e4a6..c45807c 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -53,6 +53,7 @@ "input-otp": "^1.4.2", "lucide-react": "^0.539.0", "next": "^15.4.6", + "next-intl": "^4.3.11", "next-themes": "^0.4.6", "react": "^19.1.0", "react-day-picker": "^9.8.1", @@ -66,9 +67,9 @@ "zod": "^4.0.17" }, "devDependencies": { + "@eslint/eslintrc": "^3", "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", - "@eslint/eslintrc": "^3", "@tailwindcss/postcss": "^4.1.12", "@types/node": "^20.19.11", "@types/react": "^19.1.10", diff --git a/apps/web/src/app/api/auth/logout/route.ts b/apps/web/src/app/[locale]/api/auth/logout/route.ts similarity index 100% rename from apps/web/src/app/api/auth/logout/route.ts rename to apps/web/src/app/[locale]/api/auth/logout/route.ts diff --git a/apps/web/src/app/api/auth/refresh-token/route.ts b/apps/web/src/app/[locale]/api/auth/refresh-token/route.ts similarity index 100% rename from apps/web/src/app/api/auth/refresh-token/route.ts rename to apps/web/src/app/[locale]/api/auth/refresh-token/route.ts diff --git a/apps/web/src/app/api/auth/set-refresh-token/route.ts b/apps/web/src/app/[locale]/api/auth/set-refresh-token/route.ts similarity index 100% rename from apps/web/src/app/api/auth/set-refresh-token/route.ts rename to apps/web/src/app/[locale]/api/auth/set-refresh-token/route.ts diff --git a/apps/web/src/app/auth/callback/AuthCallbackClient.tsx b/apps/web/src/app/[locale]/auth/callback/AuthCallbackClient.tsx similarity index 100% rename from apps/web/src/app/auth/callback/AuthCallbackClient.tsx rename to apps/web/src/app/[locale]/auth/callback/AuthCallbackClient.tsx diff --git a/apps/web/src/app/auth/callback/page.tsx b/apps/web/src/app/[locale]/auth/callback/page.tsx similarity index 100% rename from apps/web/src/app/auth/callback/page.tsx rename to apps/web/src/app/[locale]/auth/callback/page.tsx diff --git a/apps/web/src/app/auth/layout.tsx b/apps/web/src/app/[locale]/auth/layout.tsx similarity index 100% rename from apps/web/src/app/auth/layout.tsx rename to apps/web/src/app/[locale]/auth/layout.tsx diff --git a/apps/web/src/app/dashboard/avatars/loading.tsx b/apps/web/src/app/[locale]/dashboard/avatars/loading.tsx similarity index 100% rename from apps/web/src/app/dashboard/avatars/loading.tsx rename to apps/web/src/app/[locale]/dashboard/avatars/loading.tsx diff --git a/apps/web/src/app/dashboard/avatars/page.tsx b/apps/web/src/app/[locale]/dashboard/avatars/page.tsx similarity index 79% rename from apps/web/src/app/dashboard/avatars/page.tsx rename to apps/web/src/app/[locale]/dashboard/avatars/page.tsx index e43777d..ce98be0 100644 --- a/apps/web/src/app/dashboard/avatars/page.tsx +++ b/apps/web/src/app/[locale]/dashboard/avatars/page.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { useState, useMemo } from 'react'; import { useRouter } from 'next/navigation'; import { useQuery, useQueryClient } from '@tanstack/react-query'; +import { useTranslations } from 'next-intl'; // 1. Import useTranslations import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Plus, Search, Users } from 'lucide-react'; @@ -16,6 +17,7 @@ import { CreateAvatarDialog } from '@/components/avatars/create-avatar-dialog'; import { Spinner } from '@/components/ui/spinner'; export default function AvatarsPage() { + const t = useTranslations('dashboard.avatarsPage'); // 2. Initialize translations const { user } = useAuth(); const router = useRouter(); const queryClient = useQueryClient(); @@ -67,10 +69,12 @@ export default function AvatarsPage() {
- Create and manage reusable avatar profiles for your webhooks + {/* 4. Translate Subtitle */} + {t('subtitle')}
{t('loading')}
*/}+ {/* 9. Translate No Avatars/No Results Message */} {searchQuery - ? 'Try adjusting your search terms' - : 'Create your first predefined avatar to get started'} + ? t('emptyState.noResultsMessage') + : t('emptyState.noAvatarsMessage')}
{!searchQuery && ( )}- Manage your Discord webhooks and messages -
+{t('manage')}
- New to webhook management? Here's how to get started quickly. -
+{t('gettingStartedDesc')}
- Add a Discord webhook URL to start sending messages -
-- Test your webhook by sending a message to your Discord - channel -
-- Build reusable templates and schedule messages for later -
-{description}
+- Choose the plan that best fits your needs. -
+ {/* Translate Subtitle */} +{t('subtitle')}
- Send messages immediately to one or multiple webhooks -
+ {/* 8. Translate title */} +{t('subtitle')}
+ {/* Note: This line 'Choose how the webhook message will appear in Discord' is not in the JSON, so it remains hardcoded or requires a new key */} Choose how the webhook message will appear in Discord
+ {/* Note: This line 'Select Predefined Avatar' is not in the JSON, so it remains hardcoded or requires a new key */} Select Predefined Avatar
- Choose from your saved avatar profiles + {/* 23. Translate chooseAvatar hint */} + {t('chooseAvatar')}
- Enable TTS for this message + {/* 25. Translate enableTts hint */} + {t('enableTts')}
- If specified, the message will be sent to a new thread + {/* 27. Translate threadHint */} + {t('threadHint')}
- If provided, the message will replace the existing - Discord message at this URL. + {/* 29. Translate urlHint */} + {t('urlHint')}
- Manage your account and application preferences -
+{t('subtitle')}
{getAccountTypeQuote(user.accountType || 'free')}
Could not load account type.
+{t('accountType.error')}
)}Could not load usage data.
+{t('usage.error')}
)}- If you enjoy using Discord Webhook Manager and want to support its - development, consider sharing it on X (formerly Twitter)! -
+{t('support.message')}
-- DM me on X, if you want to get paid subscriptions. -
+{t('support.dm')}
- Design your Discord message with live preview -
+{t('subtitle')}
- Create and manage reusable message templates -
+{t('subtitle')}
- Create your first message template to get started + {t('noTemplatesSubtitle')}
- Try adjusting your search query + {t('noResultsSubtitle')}
Manage your Discord webhooks
+{t('subtitle')}
{activeWebhooks} active
++ {t('stats.active', { count: activeWebhooks })} +
Ready to send messages
+{t('stats.ready')}
- Try adjusting your search query or filters + {t('empty.noResultsSubtitle')}
> ) : ( <>- Get started by adding your first Discord webhook + {t('empty.noWebhooks.desc')}