mirror of
https://github.com/Luchexx/wacrm.git
synced 2026-11-02 09:19:51 +00:00
1662 lines
70 KiB
JSON
1662 lines
70 KiB
JSON
{
|
||
"LoginPage": {
|
||
"titleAccept": "Sign in to accept",
|
||
"titleWelcome": "Welcome back",
|
||
"descAccept": "Sign in and we'll take you to the invitation.",
|
||
"descWelcome": "Sign in to your account",
|
||
"emailLabel": "Email",
|
||
"emailPlaceholder": "you@example.com",
|
||
"passwordLabel": "Password",
|
||
"forgotPassword": "Forgot password?",
|
||
"passwordPlaceholder": "Enter your password",
|
||
"signingIn": "Signing in...",
|
||
"signIn": "Sign in",
|
||
"noAccount": "Don't have an account?",
|
||
"createAccount": "Create account"
|
||
},
|
||
"Sidebar": {
|
||
"title": "CRM Template for WhatsApp",
|
||
"dashboard": "Dashboard",
|
||
"inbox": "Inbox",
|
||
"notifications": "Notifications",
|
||
"contacts": "Contacts",
|
||
"pipelines": "Pipelines",
|
||
"broadcasts": "Broadcasts",
|
||
"automations": "Automations",
|
||
"flows": "Flows",
|
||
"aiAgents": "AI Agents",
|
||
"settings": "Settings",
|
||
"beta": "Beta",
|
||
"unreadConversations": "{count} unread {count, plural, =1 {conversation} other {conversations}}",
|
||
"unreadNotifications": "{count} unread {count, plural, =1 {notification} other {notifications}}",
|
||
"roleOwner": "Owner",
|
||
"roleAdmin": "Admin",
|
||
"roleAgent": "Agent",
|
||
"roleViewer": "Viewer",
|
||
"closeMenu": "Close menu",
|
||
"defaultUser": "User",
|
||
"defaultAvatar": "Avatar",
|
||
"menuProfile": "Profile",
|
||
"menuSettings": "Settings",
|
||
"menuSignOut": "Sign out"
|
||
},
|
||
"Header": {
|
||
"dashboard": "Dashboard",
|
||
"inbox": "Inbox",
|
||
"notifications": "Notifications",
|
||
"contacts": "Contacts",
|
||
"pipelines": "Pipelines",
|
||
"broadcasts": "Broadcasts",
|
||
"automations": "Automations",
|
||
"settings": "Settings",
|
||
"openMenu": "Open menu",
|
||
"openAccountMenu": "Open account menu",
|
||
"defaultUser": "User",
|
||
"defaultAvatar": "Avatar",
|
||
"menuProfile": "Profile",
|
||
"menuSettings": "Settings",
|
||
"menuSignOut": "Sign out"
|
||
},
|
||
"ModeToggle": {
|
||
"switchMode": "Switch to {mode} mode"
|
||
},
|
||
"Dashboard": {
|
||
"page": {
|
||
"title": "Dashboard",
|
||
"description": "Live analytics across conversations, contacts, deals, broadcasts, and automations.",
|
||
"activeConversations": "Active Conversations",
|
||
"newContactsToday": "New Contacts Today",
|
||
"openDealsValue": "Open Deals Value",
|
||
"messagesSentToday": "Messages Sent Today",
|
||
"newTodayVsYesterday": "new today vs yesterday",
|
||
"vsYesterday": "vs yesterday",
|
||
"openDeals": "{count} open {count, plural, =1 {deal} other {deals}}",
|
||
"noChange": "No change {suffix}"
|
||
},
|
||
"quickActions": {
|
||
"newContact": "New Contact",
|
||
"newDeal": "New Deal",
|
||
"newBroadcast": "New Broadcast",
|
||
"newAutomation": "New Automation"
|
||
},
|
||
"activityFeed": {
|
||
"title": "Recent Activity",
|
||
"viewAll": "View all →",
|
||
"noActivity": "No activity yet",
|
||
"noActivityHint": "Activity from messages, deals, broadcasts, and automations will appear here.",
|
||
"showingOf": "Showing {visible} of {totalLoaded}{plus}",
|
||
"show": "Show",
|
||
"timeS": "{sec}s ago",
|
||
"timeM": "{min}m ago",
|
||
"timeH": "{hr}h ago",
|
||
"timeD": "{day}d ago"
|
||
},
|
||
"conversationsChart": {
|
||
"title": "Conversations Over Time",
|
||
"description": "Daily message volume by direction",
|
||
"days": "{count} days",
|
||
"noActivity": "No message activity in this range",
|
||
"noActivityHint": "Send or receive messages to start populating this chart.",
|
||
"incoming": "Incoming",
|
||
"outgoing": "Outgoing",
|
||
"tooltipIncoming": "{count} incoming",
|
||
"tooltipOutgoing": "{count} outgoing",
|
||
"ariaLabel": "Conversations per day"
|
||
},
|
||
"pipelineDonut": {
|
||
"title": "Pipeline Value",
|
||
"description": "Open deals by stage",
|
||
"noOpenDeals": "No open deals yet",
|
||
"noOpenDealsHint": "Create deals in Pipelines to see stage breakdowns here.",
|
||
"dealCount": "{count} {count, plural, =1 {deal} other {deals}}",
|
||
"total": "Total",
|
||
"ariaLabel": "Pipeline value by stage"
|
||
},
|
||
"responseTimeChart": {
|
||
"title": "Average First Response Time",
|
||
"description": "Minutes to reply to a customer's first unreplied message, by weekday",
|
||
"target": "target {minutes}m",
|
||
"thisWeek": "This week:",
|
||
"lastWeek": "Last week:",
|
||
"noReplies": "No replies recorded yet",
|
||
"noRepliesHint": "This chart fills in as you reply to customer messages."
|
||
},
|
||
"emptyState": {
|
||
"title": "Not enough data yet"
|
||
}
|
||
},
|
||
"Inbox": {
|
||
"page": {
|
||
"whatsappNotConnected": "WhatsApp® is not connected. Go to Settings to connect your account."
|
||
},
|
||
"conversationList": {
|
||
"searchPlaceholder": "Search conversations...",
|
||
"filterAll": "All",
|
||
"filterUnread": "Unread",
|
||
"filterOpen": "Open",
|
||
"filterPending": "Pending",
|
||
"filterClosed": "Closed",
|
||
"tags": "Tags",
|
||
"company": "Company",
|
||
"allCompanies": "All companies",
|
||
"clearAll": "Clear all",
|
||
"noConversations": "No conversations found",
|
||
"noMessagesYet": "No messages yet",
|
||
"unknown": "Unknown"
|
||
},
|
||
"messageThread": {
|
||
"backToConversations": "Back to conversations",
|
||
"hideContactPanel": "Hide contact panel",
|
||
"showContactPanel": "Show contact panel",
|
||
"hideContact": "Hide contact",
|
||
"showContact": "Show contact",
|
||
"refresh": "Refresh",
|
||
"refreshConversation": "Refresh conversation",
|
||
"status": "Status",
|
||
"statusOpen": "Open",
|
||
"statusPending": "Pending",
|
||
"statusClosed": "Closed",
|
||
"assign": "Assign",
|
||
"assigned": "Assigned",
|
||
"unassign": "Unassign",
|
||
"noTeammates": "No teammates available",
|
||
"me": " (me)",
|
||
"noMessagesYet": "No messages yet",
|
||
"sendTemplateHint": "Send a template to start the conversation",
|
||
"selectConversation": "Select a conversation",
|
||
"selectConversationHint": "Choose a conversation from the left to start messaging",
|
||
"today": "Today",
|
||
"yesterday": "Yesterday"
|
||
},
|
||
"sessionTimer": {
|
||
"expired": "Expired",
|
||
"xhRemaining": "{hours}h remaining",
|
||
"xmRemaining": "{minutes}m remaining",
|
||
"noCustomerMessages": "No customer messages"
|
||
},
|
||
"composer": {
|
||
"draftHint": "Tap the ✨ to draft a reply with AI — you can edit it before sending",
|
||
"sessionExpiredHint": "24-hour session expired. Use a template to re-engage.",
|
||
"templates": "Templates",
|
||
"readOnlyPlaceholder": "Read-only — viewers can browse but not reply",
|
||
"sessionExpiredPlaceholder": "Session expired - use a template",
|
||
"typeMessagePlaceholder": "Type a message... (Shift+Enter for new line)",
|
||
"readOnlyTitle": "Read-only — your role can't send messages",
|
||
"recording": "Recording… {current} / {max}",
|
||
"cancel": "Cancel",
|
||
"stopAndAttach": "Stop and attach",
|
||
"attachMedia": "Attach media",
|
||
"photo": "Photo",
|
||
"video": "Video",
|
||
"document": "Document",
|
||
"voiceNote": "Voice note",
|
||
"sendTemplate": "Send template",
|
||
"draftWithAI": "Draft a reply with AI",
|
||
"addCaption": "Add a caption…",
|
||
"removeAttachment": "Remove attachment"
|
||
},
|
||
"bubble": {
|
||
"photo": "Photo",
|
||
"video": "Video",
|
||
"audio": "Audio",
|
||
"unavailable": "{label} unavailable",
|
||
"document": "Document",
|
||
"locationShared": "Location shared",
|
||
"template": "Template",
|
||
"buttonReply": "Button reply",
|
||
"interactiveReply": "[Interactive reply]",
|
||
"unsupported": "[Unsupported message type]"
|
||
},
|
||
"actions": {
|
||
"reply": "Reply",
|
||
"copyText": "Copy text",
|
||
"delete": "Delete",
|
||
"react": "React",
|
||
"reactWith": "React with {emoji}",
|
||
"nothingToCopy": "Nothing to copy",
|
||
"copied": "Copied",
|
||
"copyFailed": "Copy failed"
|
||
},
|
||
"replyQuote": {
|
||
"photo": "[Photo]",
|
||
"video": "[Video]",
|
||
"document": "[Document]",
|
||
"audio": "[Audio]",
|
||
"voiceMessage": "[Voice message]",
|
||
"location": "[Location]",
|
||
"template": "[Template]",
|
||
"message": "[Message]",
|
||
"cancelReply": "Cancel reply"
|
||
},
|
||
"templatePicker": {
|
||
"sendTemplate": "Send template",
|
||
"fillPlaceholders": "Fill in the placeholders to render this template. Meta requires every variable to be set.",
|
||
"pickTemplate": "Pick an approved WhatsApp template to send to this contact.",
|
||
"noApprovedTemplates": "No approved templates",
|
||
"noApprovedTemplatesHint": "Approve a template in Meta WhatsApp Manager, then sync it from Settings → Templates.",
|
||
"preview": "Preview",
|
||
"headerValuePlaceholder": "Value for the header variable",
|
||
"bodyValuePlaceholder": "Value for {val}",
|
||
"urlSuffixValuePlaceholder": "URL suffix value",
|
||
"finalUrl": "Final URL: {url}",
|
||
"back": "Back",
|
||
"cancel": "Cancel",
|
||
"send": "Send template"
|
||
},
|
||
"sidebar": {
|
||
"contactInfo": "Contact info",
|
||
"tags": "Tags",
|
||
"notes": "Notes",
|
||
"deals": "Deals",
|
||
"noTags": "No tags",
|
||
"noDeals": "No deals",
|
||
"addNotePlaceholder": "Add a note..."
|
||
}
|
||
},
|
||
"Contacts": {
|
||
"page": {
|
||
"title": "Contacts",
|
||
"subtitle": "Manage your contact list. {count} total contacts.",
|
||
"subtitleZero": "Manage your contact list.",
|
||
"customFieldsBtn": "Custom fields",
|
||
"importBtn": "Import",
|
||
"addContactBtn": "Add Contact",
|
||
"searchPlaceholder": "Search by name, phone, or email...",
|
||
"filterByTags": "Filter by tags",
|
||
"clearAll": "Clear all",
|
||
"noTagsYet": "No tags yet.",
|
||
"selectedCount": "{count} selected",
|
||
"clearSelection": "Clear",
|
||
"deleteSelected": "Delete selected",
|
||
"tableColumns": {
|
||
"name": "Name",
|
||
"phone": "Phone",
|
||
"email": "Email",
|
||
"company": "Company",
|
||
"tags": "Tags",
|
||
"createdAt": "Created"
|
||
},
|
||
"loading": "Loading contacts...",
|
||
"noContactsMatch": "No contacts match your filters.",
|
||
"noContactsYet": "No contacts yet.",
|
||
"addFirstContact": "Add your first contact",
|
||
"unnamed": "Unnamed",
|
||
"editAction": "Edit",
|
||
"deleteAction": "Delete",
|
||
"showingPagination": "Showing {start}-{end} of {total}",
|
||
"pageCount": "Page {page} of {total}",
|
||
"deleteContactTitle": "Delete Contact",
|
||
"deleteContactDesc": "Are you sure you want to delete {name}? This action cannot be undone.",
|
||
"cancel": "Cancel",
|
||
"deleteBtn": "Delete",
|
||
"deleteBulkTitle": "Delete Contacts",
|
||
"deleteBulkDesc": "Are you sure you want to delete {count} selected contacts? This action cannot be undone.",
|
||
"toastFailedLoad": "Failed to load contacts",
|
||
"toastFailedDelete": "Failed to delete contact",
|
||
"toastDeleted": "Contact deleted",
|
||
"toastBulkFailedDelete": "Failed to delete contacts",
|
||
"toastBulkDeleted": "{count} contacts deleted"
|
||
},
|
||
"form": {
|
||
"addTitle": "Add Contact",
|
||
"addDesc": "Create a new contact. Name is required.",
|
||
"editTitle": "Edit Contact",
|
||
"editDesc": "Update contact details and tags.",
|
||
"nameLabel": "Name",
|
||
"namePlaceholder": "Jane Doe",
|
||
"phoneLabel": "Phone Number",
|
||
"phonePlaceholder": "+1234567890",
|
||
"phoneHint": "Include country code, e.g. +1 for US",
|
||
"emailLabel": "Email",
|
||
"emailPlaceholder": "jane@example.com",
|
||
"companyLabel": "Company",
|
||
"companyPlaceholder": "Acme Corp",
|
||
"tagsLabel": "Tags",
|
||
"tagsPlaceholder": "Select tags...",
|
||
"noTagsFound": "No tags found.",
|
||
"createTagAction": "Create tag \"{value}\"",
|
||
"cancel": "Cancel",
|
||
"save": "Save Contact",
|
||
"update": "Update",
|
||
"create": "Create",
|
||
"toastSuccessAdd": "Contact created successfully",
|
||
"toastSuccessEdit": "Contact updated successfully",
|
||
"toastError": "Failed to save contact",
|
||
"toastConflict": "A contact with this phone number already exists",
|
||
"viewExisting": "View {name}",
|
||
"dupExact": "A contact with this phone number already exists.",
|
||
"dupSimilar": "A contact with a very similar number already exists.",
|
||
"loadingTags": "Loading tags...",
|
||
"noTagsAvailable": "No tags available. Create tags in Settings.",
|
||
"phoneRequired": "Phone number is required"
|
||
},
|
||
"detailView": {
|
||
"tabs": {
|
||
"details": "Details",
|
||
"activity": "Activity",
|
||
"notes": "Notes",
|
||
"custom": "Custom Fields",
|
||
"deals": "Deals",
|
||
"noTags": "No tags",
|
||
"noDeals": "No deals",
|
||
"addNotePlaceholder": "Add a note..."
|
||
},
|
||
"actions": {
|
||
"edit": "Edit",
|
||
"message": "Message",
|
||
"delete": "Delete"
|
||
},
|
||
"contactInfo": "Contact Information",
|
||
"unnamed": "Unknown",
|
||
"contactDetailsDesc": "Contact details",
|
||
"phone": "Phone",
|
||
"email": "Email",
|
||
"company": "Company",
|
||
"createdAt": "Created At",
|
||
"customFields": "Custom Fields",
|
||
"noCustomFields": "No custom fields defined. Create them in Settings.",
|
||
"manageFields": "Manage fields",
|
||
"enterCustomField": "Enter {name}...",
|
||
"activityTab": {
|
||
"title": "Activity History",
|
||
"noActivity": "No activity yet."
|
||
},
|
||
"notesTab": {
|
||
"title": "Internal Notes",
|
||
"placeholder": "Write a note...",
|
||
"save": "Add Note",
|
||
"noNotes": "No notes yet."
|
||
},
|
||
"dealsTab": {
|
||
"noDeals": "No deals yet"
|
||
},
|
||
"tagsTab": {
|
||
"clickTagDesc": "Click a tag to add or remove it from this contact.",
|
||
"noTagsAvailable": "No tags available. Create tags in Settings."
|
||
},
|
||
"sendTemplateBtn": "Send template",
|
||
"saveChangesBtn": "Save Changes",
|
||
"saveCustomFieldsBtn": "Save Custom Fields",
|
||
"toastPhoneRequired": "Phone number is required",
|
||
"toastUpdateFailed": "Failed to update contact",
|
||
"toastUpdated": "Contact updated",
|
||
"toastNotAuthenticated": "Not authenticated",
|
||
"toastNoteAddFailed": "Failed to add note",
|
||
"toastNoteAdded": "Note added",
|
||
"toastNoteDeleteFailed": "Failed to delete note",
|
||
"toastNoteDeleted": "Note deleted",
|
||
"toastCustomFieldsSaved": "Custom fields saved",
|
||
"toastCustomFieldsFailed": "Failed to save custom fields",
|
||
"toastTemplateSent": "Template \"{name}\" sent",
|
||
"toastTemplateFailed": "Failed to send template: {reason}"
|
||
},
|
||
"importModal": {
|
||
"title": "Import Contacts",
|
||
"desc": "Upload a CSV with a required <phoneCode>phone</phoneCode> column. Optional: <nameCode>name</nameCode>, <emailCode>email</emailCode>, <companyCode>company</companyCode>, <tagsCode>tags</tagsCode> (comma-separated; quote multi-tag cells).",
|
||
"uploadDropzone": "Click to choose a CSV file",
|
||
"uploadHint": ".csv up to your browser limit",
|
||
"rowsReady": "{count} row ready",
|
||
"rowsReady_plural": "{count} rows ready",
|
||
"preview": "Preview · first {count}",
|
||
"previewTags": "{tags} tag · {contacts} contact",
|
||
"previewTags_plural": "{tags} tags · {contacts} contacts",
|
||
"moreRows": "+ {count} more row not shown",
|
||
"moreRows_plural": "+ {count} more rows not shown",
|
||
"importComplete": "Import complete",
|
||
"resultImported": "{count} imported",
|
||
"resultTags": "{count} tag assigned",
|
||
"resultTags_plural": "{count} tags assigned",
|
||
"resultSkipped": "{count} skipped",
|
||
"resultFailed": "{count} failed",
|
||
"willBeCreated": "{name} (will be created on import)",
|
||
"columns": {
|
||
"phone": "Phone",
|
||
"name": "Name",
|
||
"email": "Email",
|
||
"company": "Company",
|
||
"tags": "Tags"
|
||
},
|
||
"cancel": "Cancel",
|
||
"close": "Close",
|
||
"importBtn": "Import {count} contact",
|
||
"importBtn_plural": "Import {count} contacts",
|
||
"toastNoValidRows": "No valid rows found. Ensure CSV has a \"phone\" column header.",
|
||
"toastTagsWarning": "Contacts imported, but some tag assignments failed.",
|
||
"toastImported": "{count} contact imported",
|
||
"toastImported_plural": "{count} contacts imported",
|
||
"toastTagsAssigned": "{count} tag assignment applied",
|
||
"toastTagsAssigned_plural": "{count} tag assignments applied",
|
||
"toastTagsSkipped": "Unknown tags skipped (create them in Settings first): {sample}{more}",
|
||
"toastSkipped": "{count} duplicate skipped",
|
||
"toastSkipped_plural": "{count} duplicates skipped",
|
||
"toastFailed": "{count} contact failed to import",
|
||
"toastFailed_plural": "{count} contacts failed to import",
|
||
"toastError": "Import failed"
|
||
},
|
||
"customFields": {
|
||
"title": "Custom fields",
|
||
"desc": "Define extra contact fields (e.g. ZIP code, lead source). They appear on every contact and in the “Update Contact Field” automation action.",
|
||
"addField": "Add",
|
||
"fieldName": "New field name…",
|
||
"loading": "Loading…",
|
||
"empty": "No custom fields yet.",
|
||
"renameAria": "Rename {name}",
|
||
"deleteTitle": "Delete field",
|
||
"deleteConfirm": "Delete \"{name}\"? This also removes its stored value on every contact. This cannot be undone.",
|
||
"toastNoAccount": "Your profile is not linked to an account.",
|
||
"toastDuplicate": "A field named \"{name}\" already exists.",
|
||
"toastCreateFailed": "Could not create field. You may not have permission.",
|
||
"toastCreated": "Created \"{name}\".",
|
||
"toastRenameFailed": "Could not rename field.",
|
||
"toastDeleteFailed": "Could not delete field.",
|
||
"toastDeleted": "Deleted \"{name}\"."
|
||
}
|
||
},
|
||
"Pipelines": {
|
||
"page": {
|
||
"selectPipeline": "Select Pipeline",
|
||
"noPipelinesYet": "No pipelines yet",
|
||
"managePipelines": "Manage Pipelines",
|
||
"addPipeline": "Add Pipeline",
|
||
"addDeal": "Add Deal",
|
||
"createToStartTracking": "Create a pipeline to start tracking deals",
|
||
"createPipeline": "Create Pipeline",
|
||
"newPipeline": "New Pipeline",
|
||
"pipelineName": "Pipeline Name",
|
||
"pipelineNamePlaceholder": "e.g., Enterprise Sales",
|
||
"defaultStagesDesc": "Default stages (New Lead → Won) will be created automatically.",
|
||
"cancel": "Cancel",
|
||
"creating": "Creating...",
|
||
"createPipelineBtn": "Create Pipeline",
|
||
"toastFailedLoadPipelines": "Failed to load pipelines",
|
||
"toastFailedMoveDeal": "Failed to move deal",
|
||
"toastFailedCreatePipeline": "Failed to create pipeline",
|
||
"toastPipelineCreated": "Pipeline created",
|
||
"toastNotLinkedToAccount": "Your profile is not linked to an account."
|
||
},
|
||
"board": {
|
||
"dropDealHere": "Drop a deal here",
|
||
"addDeal": "Add Deal"
|
||
},
|
||
"card": {
|
||
"noContact": "No contact",
|
||
"won": "Won",
|
||
"lost": "Lost"
|
||
},
|
||
"form": {
|
||
"editDeal": "Edit Deal",
|
||
"newDeal": "New Deal",
|
||
"title": "Title",
|
||
"titlePlaceholder": "Deal title",
|
||
"contact": "Contact",
|
||
"selectContact": "Select a contact",
|
||
"linkToConversation": "Link to Conversation",
|
||
"value": "Value",
|
||
"currency": "Currency",
|
||
"expectedCloseDate": "Expected Close Date",
|
||
"stage": "Stage",
|
||
"assignedTo": "Assigned To",
|
||
"unassigned": "Unassigned",
|
||
"notes": "Notes",
|
||
"notesPlaceholder": "Add notes...",
|
||
"status": "Status",
|
||
"markAsWon": "Mark as Won",
|
||
"markAsLost": "Mark as Lost",
|
||
"reopenDeal": "Reopen deal",
|
||
"cancel": "Cancel",
|
||
"saving": "Saving...",
|
||
"saveChanges": "Save Changes",
|
||
"createDeal": "Create Deal",
|
||
"deletePrompt": "Delete this deal?",
|
||
"confirm": "Confirm",
|
||
"deleting": "Deleting...",
|
||
"deleteDeal": "Delete Deal",
|
||
"toastRequired": "Title, contact, and stage are required",
|
||
"toastFailedSave": "Failed to save deal",
|
||
"toastNotSignedIn": "Not signed in",
|
||
"toastNotLinked": "Your profile is not linked to an account.",
|
||
"toastFailedCreate": "Failed to create deal",
|
||
"toastUpdated": "Deal updated",
|
||
"toastCreated": "Deal created",
|
||
"toastFailedStatus": "Failed to update deal status",
|
||
"toastMarkedWon": "Marked as won",
|
||
"toastMarkedLost": "Marked as lost",
|
||
"toastReopened": "Deal reopened",
|
||
"toastFailedDelete": "Failed to delete deal",
|
||
"toastDeleted": "Deal deleted"
|
||
},
|
||
"settings": {
|
||
"managePipeline": "Manage Pipeline",
|
||
"deletePipeline": "Delete Pipeline",
|
||
"deletePipelineDesc": "This will archive all deals in this pipeline. This cannot be undone.",
|
||
"cancel": "Cancel",
|
||
"deleting": "Deleting...",
|
||
"deletePipelineBtn": "Delete Pipeline",
|
||
"pipelineName": "Pipeline Name",
|
||
"stages": "Stages",
|
||
"newStageNamePlaceholder": "New stage name",
|
||
"add": "Add",
|
||
"createNewPipeline": "Create a new pipeline",
|
||
"saving": "Saving...",
|
||
"saveChanges": "Save Changes",
|
||
"dragToReorder": "Drag to reorder",
|
||
"changeColor": "Change color",
|
||
"toastFailedSave": "Failed to save pipeline",
|
||
"toastSaved": "Pipeline saved",
|
||
"toastFailedAddStage": "Failed to add stage",
|
||
"toastMoveOrDeleteDeals": "Move or delete deals in this stage first",
|
||
"toastFailedDeleteStage": "Failed to delete stage",
|
||
"toastFailedDeletePipeline": "Failed to delete pipeline",
|
||
"toastDeleted": "Pipeline deleted"
|
||
},
|
||
"analytics": {
|
||
"totalDeals": "Total Deals",
|
||
"totalDealsTooltip": "Count of every deal in this pipeline that isn't marked as Lost. Won deals are still included.",
|
||
"pipelineValue": "Pipeline Value",
|
||
"pipelineValueTooltip": "Sum of the dollar values of all deals in this pipeline, excluding deals marked as Lost.",
|
||
"avgDealSize": "Avg Deal Size",
|
||
"avgDealSizeTooltip": "Pipeline Value divided by Total Deals — the average value of a single non-lost deal.",
|
||
"weightedValue": "Weighted Value",
|
||
"weightedValueTooltip": "Expected revenue: each open deal's value × its stage probability. First stage ≈ 10%, stages progress up to 90%, Won = 100%. Lost deals are excluded.",
|
||
"wonThisMonth": "Won This Month",
|
||
"wonThisMonthTooltip": "Deals marked as Won since the first day of the current month.",
|
||
"lostThisMonth": "Lost This Month",
|
||
"lostThisMonthTooltip": "Deals marked as Lost since the first day of the current month.",
|
||
"howCalculated": "How {label} is calculated"
|
||
}
|
||
},
|
||
"Broadcasts": {
|
||
"page": {
|
||
"title": "Broadcasts",
|
||
"subtitle": "Send bulk messages to your contacts using approved templates.",
|
||
"newBroadcast": "New Broadcast",
|
||
"noBroadcastsYet": "No broadcasts yet",
|
||
"createFirst": "Create your first broadcast to reach your contacts at scale.",
|
||
"table": {
|
||
"name": "Name",
|
||
"template": "Template",
|
||
"recipients": "Recipients",
|
||
"delivery": "Delivery",
|
||
"read": "Read",
|
||
"status": "Status",
|
||
"date": "Date"
|
||
},
|
||
"errorLoad": "Failed to load broadcasts",
|
||
"retry": "Retry"
|
||
},
|
||
"status": {
|
||
"draft": "Draft",
|
||
"scheduled": "Scheduled",
|
||
"sending": "Sending",
|
||
"sent": "Sent",
|
||
"failed": "Failed",
|
||
"pending": "Pending",
|
||
"delivered": "Delivered",
|
||
"read": "Read",
|
||
"replied": "Replied",
|
||
"unknown": "Unknown"
|
||
},
|
||
"detail": {
|
||
"backToBroadcasts": "Back to Broadcasts",
|
||
"notFound": "Broadcast not found",
|
||
"template": "Template: {name}",
|
||
"createdAt": "Created {date}",
|
||
"deletePrompt": "Delete this broadcast?",
|
||
"cancel": "Cancel",
|
||
"confirm": "Confirm",
|
||
"deleting": "Deleting…",
|
||
"delete": "Delete",
|
||
"cannotDeleteSending": "Cannot delete while a broadcast is actively sending",
|
||
"deleteHover": "Delete this broadcast",
|
||
"funnel": "Funnel",
|
||
"recipientsHeader": "Recipients ({filtered} of {total})",
|
||
"recipientsHeaderAll": "Recipients ({total})",
|
||
"allStatuses": "All statuses",
|
||
"exportCsv": "Export CSV",
|
||
"noRecipients": "No recipients found.",
|
||
"noRecipientsFilter": "No recipients match this filter.",
|
||
"table": {
|
||
"contact": "Contact",
|
||
"phone": "Phone",
|
||
"status": "Status",
|
||
"sent": "Sent",
|
||
"delivered": "Delivered",
|
||
"read": "Read",
|
||
"error": "Error"
|
||
},
|
||
"stats": {
|
||
"totalRecipients": "Total Recipients",
|
||
"sent": "Sent",
|
||
"delivered": "Delivered",
|
||
"read": "Read",
|
||
"replied": "Replied",
|
||
"failed": "Failed"
|
||
},
|
||
"toastFailedDelete": "Failed to delete: {error}",
|
||
"toastDeleted": "Broadcast deleted"
|
||
},
|
||
"new": {
|
||
"title": "New Broadcast",
|
||
"subtitle": "Create and send a broadcast message to your contacts.",
|
||
"steps": {
|
||
"template": "Template",
|
||
"audience": "Audience",
|
||
"personalize": "Personalize",
|
||
"send": "Send"
|
||
},
|
||
"toastGiveName": "Give the broadcast a name before saving a draft.",
|
||
"toastNotSignedIn": "Not signed in.",
|
||
"toastNotLinked": "Your profile is not linked to an account.",
|
||
"toastFailedDraft": "Failed to save draft: {error}",
|
||
"toastDraftSaved": "Draft saved"
|
||
},
|
||
"wizard": {
|
||
"next": "Next",
|
||
"back": "Back",
|
||
"cancel": "Cancel",
|
||
"chooseTemplate": {
|
||
"title": "Choose a Template",
|
||
"subtitle": "Select an approved message template for your broadcast.",
|
||
"noTemplates": "No templates available.",
|
||
"createFirst": "Create a template in Settings first.",
|
||
"errorLoad": "Failed to load templates"
|
||
},
|
||
"selectAudience": {
|
||
"title": "Select Audience",
|
||
"subtitle": "Choose who will receive this broadcast.",
|
||
"method": {
|
||
"all": "All Contacts",
|
||
"tags": "Filter by Tags",
|
||
"customField": "Custom Field",
|
||
"csv": "Upload CSV"
|
||
},
|
||
"allDesc": "Send to all {count} contacts in your database.",
|
||
"allDescLoading": "Send to all contacts in your database.",
|
||
"tagDesc": "Send to contacts matching specific tags.",
|
||
"customFieldDesc": "Send to contacts matching a custom field rule.",
|
||
"csvDesc": "Upload a CSV with phone numbers (and optional names).",
|
||
"selectTags": "Select Tags",
|
||
"searchTags": "Search tags...",
|
||
"noTagsFound": "No tags found.",
|
||
"excludeTags": "Exclude Tags (Optional)",
|
||
"searchExcludeTags": "Search tags to exclude...",
|
||
"field": "Field",
|
||
"selectField": "Select a field...",
|
||
"operator": "Operator",
|
||
"operatorIs": "Is",
|
||
"operatorIsNot": "Is not",
|
||
"operatorContains": "Contains",
|
||
"value": "Value",
|
||
"valuePlaceholder": "Value to match",
|
||
"uploadCsv": "Upload CSV File",
|
||
"csvFormatDesc": "Must contain a 'phone' column (E.164 format). 'name' column is optional.",
|
||
"csvContactsFound": "{count} valid contact(s) found in CSV.",
|
||
"errorLoadTags": "Failed to load tags",
|
||
"errorLoadFields": "Failed to load custom fields",
|
||
"errorCsvParse": "Could not parse CSV file.",
|
||
"errorCsvMissingPhone": "CSV must have a 'phone' column."
|
||
},
|
||
"personalize": {
|
||
"title": "Personalize Variables",
|
||
"subtitle": "Map your template variables to contact fields or provide static values.",
|
||
"headerImage": "Header Image",
|
||
"headerImageDesc": "This template requires a header image.",
|
||
"imageUrl": "Image URL",
|
||
"imageUrlPlaceholder": "https://example.com/image.jpg",
|
||
"variables": "Variables",
|
||
"varDesc": "Set values for {{name}}",
|
||
"type": "Type",
|
||
"typeStatic": "Static Value",
|
||
"typeContact": "Contact Field",
|
||
"typeCustom": "Custom Field",
|
||
"staticValue": "Static Value",
|
||
"contactField": "Contact Field",
|
||
"selectContactField": "Select field...",
|
||
"customField": "Custom Field",
|
||
"selectCustomField": "Select custom field...",
|
||
"preview": "Preview",
|
||
"previewSample": "Showing preview with sample data.",
|
||
"noPreview": "Preview not available.",
|
||
"fieldMap": {
|
||
"name": "Name",
|
||
"phone": "Phone",
|
||
"email": "Email"
|
||
}
|
||
},
|
||
"scheduleSend": {
|
||
"title": "Review & Send",
|
||
"subtitle": "Give your broadcast a name and confirm sending.",
|
||
"broadcastName": "Broadcast Name",
|
||
"broadcastNamePlaceholder": "e.g., Summer Promo",
|
||
"summary": "Summary",
|
||
"template": "Template:",
|
||
"audience": "Audience:",
|
||
"audienceAll": "All contacts",
|
||
"audienceTags": "Filtered by tags",
|
||
"audienceField": "Filtered by custom field",
|
||
"audienceCsv": "CSV upload",
|
||
"variables": "Variables:",
|
||
"variablesMapped": "{count} mapped",
|
||
"saveDraft": "Save as Draft",
|
||
"sendNow": "Send Broadcast",
|
||
"sending": "Sending...",
|
||
"preparing": "Preparing...",
|
||
"progressDesc": "Processing {current} of {total} recipients...",
|
||
"toastFailedPreview": "Failed to load preview data"
|
||
}
|
||
}
|
||
},
|
||
"Automations": {
|
||
"list": {
|
||
"title": "Automations",
|
||
"subtitle": "Build workflows that react to WhatsApp® events automatically.",
|
||
"create": "Create Automation",
|
||
"retry": "Retry",
|
||
"templatesTitle": "Quick-start templates",
|
||
"emptyTitle": "No automations yet",
|
||
"emptyDesc": "Pick a template above or create one from scratch.",
|
||
"runs": "{count} run",
|
||
"runsPlural": "{count} runs",
|
||
"lastRun": "last {time}",
|
||
"activate": "Activate",
|
||
"deactivate": "Deactivate",
|
||
"edit": "Edit",
|
||
"duplicate": "Duplicate",
|
||
"viewLogs": "View Logs",
|
||
"delete": "Delete",
|
||
"cancel": "Cancel",
|
||
"deleteTitle": "Delete automation",
|
||
"deleteDesc": "This permanently removes {name} and its execution history. This cannot be undone.",
|
||
"toasts": {
|
||
"activated": "Automation activated",
|
||
"paused": "Automation paused",
|
||
"duplicated": "Automation duplicated",
|
||
"deleted": "Automation deleted",
|
||
"updateError": "Failed to update",
|
||
"duplicateError": "Failed to duplicate",
|
||
"deleteError": "Failed to delete"
|
||
}
|
||
},
|
||
"edit": {
|
||
"loading": "Loading...",
|
||
"loadError": "Failed to load ({status})",
|
||
"back": "Back to Automations"
|
||
},
|
||
"logs": {
|
||
"title": "Execution logs",
|
||
"loadError": "Failed to load logs",
|
||
"emptyTitle": "No executions yet",
|
||
"emptyDesc": "Trigger this automation to see runs here.",
|
||
"unknownContact": "Unknown contact",
|
||
"step": "{count} step",
|
||
"stepPlural": "{count} steps",
|
||
"noSteps": "No steps recorded.",
|
||
"status": {
|
||
"success": "success",
|
||
"partial": "partial",
|
||
"failed": "failed"
|
||
},
|
||
"back": "Back",
|
||
"backAria": "Back"
|
||
},
|
||
"builder": {
|
||
"steps": {
|
||
"send_message": "Send Message",
|
||
"send_template": "Send Template",
|
||
"add_tag": "Add Tag",
|
||
"remove_tag": "Remove Tag",
|
||
"assign_conversation": "Assign Conversation",
|
||
"update_contact_field": "Update Contact Field",
|
||
"create_deal": "Create Deal",
|
||
"wait": "Wait",
|
||
"condition": "Condition (If/Else)",
|
||
"send_webhook": "Send Webhook",
|
||
"close_conversation": "Close Conversation"
|
||
},
|
||
"triggers": {
|
||
"new_message_received": {
|
||
"label": "New Message Received",
|
||
"hint": "Any incoming message"
|
||
},
|
||
"first_inbound_message": {
|
||
"label": "First Message from Contact",
|
||
"hint": "First time this contact ever messages you (works for manually-added contacts too)"
|
||
},
|
||
"keyword_match": {
|
||
"label": "Keyword Match",
|
||
"hint": "Message contains specific keyword(s)"
|
||
},
|
||
"new_contact_created": {
|
||
"label": "New Contact Created",
|
||
"hint": "When a contact is auto-created from an incoming message"
|
||
},
|
||
"conversation_assigned": {
|
||
"label": "Conversation Assigned",
|
||
"hint": "When assigned to an agent"
|
||
},
|
||
"tag_added": {
|
||
"label": "Tag Added",
|
||
"hint": "When a tag is added to a contact"
|
||
},
|
||
"time_based": {
|
||
"label": "Time-Based",
|
||
"hint": "On a recurring schedule"
|
||
}
|
||
},
|
||
"trigger": "Trigger",
|
||
"triggerType": "Trigger type",
|
||
"keywords": "Keywords",
|
||
"keywordsHint": "Comma-separated list (e.g. hello, help, buy)",
|
||
"schedule": "Schedule",
|
||
"scheduleHint": "Cron expression (e.g. 0 9 * * 1-5)",
|
||
"active": "Active",
|
||
"activeAria": "Active",
|
||
"save": "Save",
|
||
"saveDraft": "Save Draft",
|
||
"untitled": "Untitled automation",
|
||
"backToAutomations": "Back to automations",
|
||
"toasts": {
|
||
"saved": "Automation saved",
|
||
"created": "Automation created",
|
||
"saveFailed": "Save failed"
|
||
},
|
||
"tags": {
|
||
"select": "Select a tag…",
|
||
"placeholder": "Tag id",
|
||
"unknown": "{id} (unknown tag)"
|
||
},
|
||
"fields": {
|
||
"name": "Name",
|
||
"email": "Email",
|
||
"company": "Company",
|
||
"customFields": "Custom fields",
|
||
"unknown": "{id} (unknown field)"
|
||
},
|
||
"agents": {
|
||
"select": "Select an agent…",
|
||
"placeholder": "Agent id",
|
||
"unknown": "{id} (unknown agent)"
|
||
},
|
||
"pipelines": {
|
||
"pipelineLabel": "Pipeline",
|
||
"pipelineIdLabel": "Pipeline id",
|
||
"stageLabel": "Stage",
|
||
"stageIdLabel": "Stage id",
|
||
"selectPipeline": "Select a pipeline…",
|
||
"selectStage": "Select a stage…",
|
||
"selectPipelineFirst": "Select a pipeline first…",
|
||
"unknownPipeline": "{id} (unknown pipeline)",
|
||
"unknownStage": "{id} (unknown stage)"
|
||
},
|
||
"templates": {
|
||
"templateLabel": "Template",
|
||
"templateNameLabel": "Template name",
|
||
"languageLabel": "Language",
|
||
"select": "Select a template…",
|
||
"unknown": "{name} ({lang}) — not in approved list",
|
||
"unknownLang": "unknown"
|
||
},
|
||
"branches": {
|
||
"yes": "Yes",
|
||
"no": "No"
|
||
},
|
||
"addStep": "Add step",
|
||
"config": {
|
||
"messageText": "Message text",
|
||
"placeholderMessageText": "Hi! Thanks for reaching out…",
|
||
"tagLabel": "Tag",
|
||
"modeLabel": "Mode",
|
||
"modes": {
|
||
"round_robin": "Round-robin",
|
||
"specific": "Specific agent"
|
||
},
|
||
"agentLabel": "Agent",
|
||
"fieldLabel": "Field",
|
||
"valueLabel": "Value",
|
||
"placeholderValue": "Text or {{ vars.x }} / {{ message.text }}",
|
||
"titleLabel": "Title",
|
||
"amountLabel": "Amount",
|
||
"unitLabel": "Unit",
|
||
"units": {
|
||
"minutes": "Minutes",
|
||
"hours": "Hours",
|
||
"days": "Days"
|
||
},
|
||
"subjectLabel": "Subject",
|
||
"subjects": {
|
||
"tag_presence": "Tag presence",
|
||
"contact_field": "Contact field",
|
||
"message_content": "Message content",
|
||
"time_of_day": "Time of day"
|
||
},
|
||
"operandLabel": "Operand",
|
||
"placeholderTime": "HH:mm-HH:mm",
|
||
"placeholderContact": "name / email / company",
|
||
"placeholderTag": "tag id",
|
||
"urlLabel": "URL",
|
||
"headersLabel": "Headers",
|
||
"placeholderHeaders": "{\"Authorization\": \"Bearer ...\"}",
|
||
"bodyTemplateLabel": "Body template",
|
||
"placeholderBody": "{\"id\": \"{{ contact.id }}\"}",
|
||
"matchType": "Match type",
|
||
"matchContains": "Contains",
|
||
"matchExact": "Exact",
|
||
"closeConversationHint": "Sets the conversation status to \"closed\". No configuration needed."
|
||
}
|
||
}
|
||
},
|
||
"Flows": {
|
||
"list": {
|
||
"title": "Flows",
|
||
"beta": "Beta",
|
||
"description": "Build branching, button-driven WhatsApp conversations. Useful for menus, FAQs, and triage before a human steps in.",
|
||
"newFlow": "New flow",
|
||
"statusDraft": "Draft",
|
||
"statusActive": "Active",
|
||
"statusArchived": "Archived",
|
||
"loadError": "Couldn't load flows.",
|
||
"createError": "Couldn't create flow.",
|
||
"cloneError": "Clone failed",
|
||
"deleteConfirm": "Delete \"{name}\"? Any active runs will end immediately.",
|
||
"deleteSuccess": "Flow deleted.",
|
||
"deleteError": "Couldn't delete flow.",
|
||
"emptyTitle": "No flows yet",
|
||
"emptyDesc": "Build your first conversation — a welcome menu, an order lookup, an FAQ bot. Customers tap buttons; the bot routes them to the right answer (or the right agent).",
|
||
"createFirst": "Create your first flow",
|
||
"createTitle": "Create a new flow",
|
||
"createDesc": "Start from a template or build from scratch.",
|
||
"startTemplate": "Start from a template",
|
||
"nodeCount": "{count} {count, plural, =1 {node} other {nodes}}",
|
||
"startBlank": "Or start blank",
|
||
"placeholderName": "e.g. Welcome menu",
|
||
"cancel": "Cancel",
|
||
"createBlank": "Create blank flow",
|
||
"runCount": "{count} {count, plural, =1 {run} other {runs}}",
|
||
"edit": "Edit",
|
||
"delete": "Delete",
|
||
"triggerKeywordNone": "Triggers on keyword (none set)",
|
||
"triggerKeyword": "Triggers on: {keywords}",
|
||
"triggerFirstInbound": "Triggers on a contact's first-ever inbound message",
|
||
"triggerManual": "Manual trigger"
|
||
},
|
||
"edit": {
|
||
"notFound": "Flow not found.",
|
||
"backToFlows": "← Back to flows",
|
||
"loadError": "Couldn't load flow."
|
||
},
|
||
"logs": {
|
||
"title": "Runs",
|
||
"description": "The 50 most recent times this flow ran. Expand a row to see the engine's per-step log.",
|
||
"emptyState": "No runs yet. Trigger the flow from a personal WhatsApp number to see it appear here.",
|
||
"loadError": "Couldn't load runs.",
|
||
"unknownContact": "Unknown contact",
|
||
"atNode": "at {node}",
|
||
"started": "Started {time}",
|
||
"reprompts": "{count} re-prompts",
|
||
"ranFor": "ran for {duration}",
|
||
"capturedVars": "Captured vars ({count})",
|
||
"noEvents": "No events recorded for this run.",
|
||
"statusActive": "Active",
|
||
"statusCompleted": "Completed",
|
||
"statusHandedOff": "Handed off",
|
||
"statusTimedOut": "Timed out",
|
||
"statusPaused": "Paused by agent",
|
||
"statusFailed": "Failed"
|
||
},
|
||
"builder": {
|
||
"triggerTitle": "Trigger",
|
||
"whenLabel": "When…",
|
||
"triggerKeywordTitle": "A message contains a keyword",
|
||
"triggerFirstInboundTitle": "Customer's first ever inbound message",
|
||
"triggerManualTitle": "Manual only (no auto-trigger)",
|
||
"keywordsLabel": "Keywords (comma-separated)",
|
||
"keywordsPlaceholder": "support, help, hi",
|
||
"entryNodeTitle": "Entry node:",
|
||
"entryNodePlaceholder": "Pick the first node…",
|
||
"nodesTitle": "Nodes ({count})",
|
||
"nodesEmpty": "Add a <strong>Start</strong> node, then a <strong>Send buttons</strong> node, then a <strong>Handoff</strong> — that's the welcome-menu shape from the brief.",
|
||
"addNode": "Add node",
|
||
"setAsEntry": "Set as entry",
|
||
"removeNode": "Remove node",
|
||
"showAdvanced": "Show advanced",
|
||
"hideAdvanced": "Hide advanced",
|
||
"nodeKeyLabel": "Node key (internal identifier — keep stable for analytics)",
|
||
"replyIdsHint": "Reply IDs for each option are shown inline above. They're returned by WhatsApp when a customer taps; you usually don't need to touch them.",
|
||
"badgeEntry": "Entry",
|
||
"noNodesYet": "No nodes yet.",
|
||
"deleteNode": "Delete node",
|
||
"canvasView": "Canvas",
|
||
"listView": "List",
|
||
"noNodeSelected": "No node selected",
|
||
"noNodeDesc": "Select a node on the canvas to edit its configuration.",
|
||
"form": {
|
||
"advancesTo": "Advances to",
|
||
"textToCustomer": "Text sent to the customer",
|
||
"promptToCustomer": "Prompt sent to the customer",
|
||
"varKeyLabel": "Variable key (stored in flow_runs.vars; alphanumeric + underscore)",
|
||
"varKeyPlaceholder": "e.g. name, email, company",
|
||
"varKeyHelp": "Interpolate in downstream prompts and handoff notes with",
|
||
"advanceAfterCapture": "After capturing, advance to",
|
||
"internalNote": "Internal note (for the agent picking up)",
|
||
"endNodeHelp": "Terminal node. When the runner reaches this node the run is marked complete. No config needed.",
|
||
"bodyText": "Body text",
|
||
"footerText": "Footer (optional, 60 chars)",
|
||
"buttonsHelp": "Buttons (1–3) — each one routes to a different next node",
|
||
"optionTitlePlaceholder": "Visible title (≤20 chars)",
|
||
"nextNodePlaceholder": "Next node…",
|
||
"addButton": "Add button",
|
||
"buttonLabel": "Tap-to-expand button label (≤20 chars)",
|
||
"rowsHelp": "Rows (1–10 total across all sections)",
|
||
"sectionTitlePlaceholder": "Section {count} title (optional)",
|
||
"rowTitlePlaceholder": "Row title (≤24)",
|
||
"addRow": "Add row",
|
||
"addSection": "Add section",
|
||
"ifLabel": "If",
|
||
"capturedVariable": "Captured variable",
|
||
"contactHasTag": "Contact has tag",
|
||
"contactField": "Contact field",
|
||
"varName": "var name",
|
||
"tagLabel": "Tag",
|
||
"fieldLabel": "Field",
|
||
"pickTag": "Pick a tag…",
|
||
"pickField": "Pick a field…",
|
||
"operatorLabel": "Operator",
|
||
"isPresent": "is present",
|
||
"isAbsent": "is absent",
|
||
"equals": "equals",
|
||
"contains": "contains",
|
||
"valueLabel": "Value",
|
||
"ifTrueAdvance": "If true → advance to",
|
||
"ifFalseAdvance": "If false → advance to",
|
||
"actionLabel": "Action",
|
||
"addTag": "Add tag",
|
||
"removeTag": "Remove tag",
|
||
"tagUuidPlaceholder": "Tag UUID",
|
||
"thenAdvanceTo": "Then advance to",
|
||
"mediaTypeLabel": "Media type",
|
||
"imageLabel": "Image (PNG, JPEG, WebP)",
|
||
"videoLabel": "Video (MP4, 3GP)",
|
||
"documentLabel": "Document (PDF, Word, Excel, PowerPoint, TXT)",
|
||
"fileLabel": "File",
|
||
"removeFile": "Remove file",
|
||
"uploading": "Uploading…",
|
||
"clickToUpload": "Click to upload (max 16 MB)",
|
||
"captionLabel": "Caption (optional, shown under the media)",
|
||
"filenameLabel": "Filename shown to the customer (documents only)",
|
||
"filenamePlaceholder": "invoice.pdf",
|
||
"advanceAfterSending": "After sending, advance to",
|
||
"pickNextNode": "Pick a next node…",
|
||
"none": "— None —"
|
||
},
|
||
"categories": {
|
||
"messaging": "Messaging",
|
||
"logic": "Logic & data",
|
||
"flow": "Flow control"
|
||
},
|
||
"nodes": {
|
||
"start": {
|
||
"label": "Start",
|
||
"blurb": "Entry point of the flow"
|
||
},
|
||
"send_message": {
|
||
"label": "Send message",
|
||
"blurb": "Sends a WhatsApp text message"
|
||
},
|
||
"send_buttons": {
|
||
"label": "Send buttons",
|
||
"blurb": "Sends quick-reply buttons"
|
||
},
|
||
"send_list": {
|
||
"label": "Send list",
|
||
"blurb": "Sends a tappable list of options"
|
||
},
|
||
"send_media": {
|
||
"label": "Send media",
|
||
"blurb": "Sends an image, video, or document"
|
||
},
|
||
"collect_input": {
|
||
"label": "Collect input",
|
||
"blurb": "Asks a question, saves the reply"
|
||
},
|
||
"condition": {
|
||
"label": "If / else",
|
||
"blurb": "Branches on a rule"
|
||
},
|
||
"set_tag": {
|
||
"label": "Tag contact",
|
||
"blurb": "Adds or removes a contact tag"
|
||
},
|
||
"handoff": {
|
||
"label": "Handoff to agent",
|
||
"blurb": "Hands the conversation to a human"
|
||
},
|
||
"end": {
|
||
"label": "End",
|
||
"blurb": "Ends the flow"
|
||
}
|
||
}
|
||
},
|
||
"validation": {
|
||
"noIssues": "No issues. Ready to activate.",
|
||
"summary": "{errorCount} {errorCount, plural, =1 {error} other {errors}}, {warningCount} {warningCount, plural, =1 {warning} other {warnings}}",
|
||
"jumpToNode": "Jump to node {key}"
|
||
},
|
||
"editorState": {
|
||
"saved": "Saved.",
|
||
"fixIssues": "Fix the issues below before activating.",
|
||
"statusChanged": "Flow is now {status}."
|
||
},
|
||
"summary": {
|
||
"options": "{count} {count, plural, =1 {option} other {options}}",
|
||
"optionsAcrossSections": "{rowCount} {rowCount, plural, =1 {option} other {options}} across {sectionCount} {sectionCount, plural, =1 {section} other {sections}}",
|
||
"noFile": "{label} (no file uploaded)",
|
||
"media": "Media",
|
||
"image": "Image",
|
||
"video": "Video",
|
||
"document": "Document",
|
||
"audio": "Audio",
|
||
"hasTag": "has tag {tag}",
|
||
"opContains": "contains",
|
||
"opExists": "exists",
|
||
"opMissing": "missing",
|
||
"modeAdd": "Add",
|
||
"modeRemove": "Remove",
|
||
"tagPicked": "{mode} tag {tag}…",
|
||
"tagNone": "{mode} tag (none picked)"
|
||
}
|
||
},
|
||
"Settings": {
|
||
"pageTitle": "Settings",
|
||
"pageDesc": "Everything in one place — your account and your workspace. Pick a section to manage it.",
|
||
"overview": {
|
||
"notSetup": "Not set up yet",
|
||
"connected": "Connected",
|
||
"needsReconnecting": "Needs reconnecting",
|
||
"viewTeamMembers": "View team members",
|
||
"membersCount": "{count} {count, plural, =1 {member} other {members}}",
|
||
"pendingInvites": "{count} pending {count, plural, =1 {invite} other {invites}}",
|
||
"manageTemplates": "Manage message templates",
|
||
"templatesCount": "{count} {count, plural, =1 {template} other {templates}}",
|
||
"pendingReview": "{count} pending review",
|
||
"tagsAndFields": "Tags and custom fields",
|
||
"tagsCount": "{count} {count, plural, =1 {tag} other {tags}}",
|
||
"fieldsCount": "{count} custom {count, plural, =1 {field} other {fields}}",
|
||
"appearance": "{mode} mode · {theme} accent",
|
||
"yourAccount": "Your account",
|
||
"loading": "Loading…"
|
||
},
|
||
"members": {
|
||
"title": "Team members",
|
||
"description": "People with access to this account. Roles control what each teammate can do.",
|
||
"inviteMember": "Invite member",
|
||
"online": "online",
|
||
"away": "away",
|
||
"offline": "offline",
|
||
"memberCount": "{count} {count, plural, =1 {member} other {members}}",
|
||
"you": "You",
|
||
"unnamed": "Unnamed",
|
||
"joined": "Joined {date}",
|
||
"remove": "Remove",
|
||
"removedToast": "Removed {name}",
|
||
"updatedToast": "Updated {name} to {role}",
|
||
"pendingInvitations": "Pending invitations",
|
||
"inviteHint": "The plaintext invite URL is only shown once at creation for security — to re-share, revoke the invite below and create a new one.",
|
||
"noPendingTitle": "No pending invitations.",
|
||
"noPendingDesc": "Click <bold>Invite member</bold> above to generate a shareable link.",
|
||
"untitledInvite": "Untitled invite",
|
||
"created": "Created {date}",
|
||
"expiresInDays": "expires in {days} {days, plural, =1 {day} other {days}}",
|
||
"expiresInHours": "expires in {hours} {hours, plural, =1 {hour} other {hours}}",
|
||
"expired": "expired",
|
||
"revoke": "Revoke",
|
||
"revokedToast": "Invitation revoked",
|
||
"removeDialogTitle": "Remove member",
|
||
"removeDialogDesc": "Remove <bold>{name}</bold> from the account? They'll be signed out of this account and given a fresh personal account on their next sign-in. Their login isn't deleted.",
|
||
"cancel": "Cancel",
|
||
"removing": "Removing...",
|
||
"removeBtn": "Remove member"
|
||
},
|
||
"invite": {
|
||
"inviteCreated": "Invite created",
|
||
"inviteCreatedDesc": "Share this link with your new teammate. They'll be able to sign up (or sign in) and join the account as <bold>{role}</bold>. The link is valid for <bold>{days} {days, plural, =1 {day} other {days}}</bold>.",
|
||
"inviteLink": "Invite link",
|
||
"copy": "Copy",
|
||
"saveLinkNow": "Save this link now.",
|
||
"saveLinkHint": "We never store the plaintext — once you close this dialog the URL is gone. To re-share, revoke this invite and create a new one.",
|
||
"sendViaWhatsApp": "Send via WhatsApp",
|
||
"done": "Done",
|
||
"dialogTitle": "Invite a teammate",
|
||
"dialogDesc": "Generate a one-time invite link. Share it via WhatsApp, Slack, or any channel you like — no email service required.",
|
||
"roleLabel": "Role",
|
||
"validForLabel": "Link valid for",
|
||
"days1": "1 day",
|
||
"days7": "7 days",
|
||
"days30": "30 days",
|
||
"labelTitle": "Label",
|
||
"optional": "(optional)",
|
||
"labelPlaceholder": "e.g. Sara — support team",
|
||
"labelHint": "Helps you remember who you sent the link to in the pending list below.",
|
||
"cancel": "Cancel",
|
||
"creating": "Creating...",
|
||
"generateLink": "Generate link",
|
||
"labelTooLong": "Label must be {max} characters or fewer",
|
||
"copied": "Invite link copied",
|
||
"clipboardBlocked": "Clipboard blocked — copy the link manually",
|
||
"whatsappMessage": "Join {accountName} on wacrm using this link (valid for {expiresInDays} days): {url}"
|
||
},
|
||
"tagsAndFields": {
|
||
"title": "Fields & tags",
|
||
"description": "Two ways to organize contacts: colour-coded tags for quick grouping, and custom fields for structured data.",
|
||
"tagsTitle": "Tags",
|
||
"tagsDesc": "Colour-coded labels for grouping and filtering contacts.",
|
||
"fieldsTitle": "Custom fields",
|
||
"fieldsDesc": "Extra contact fields (e.g. ZIP code, lead source). They appear on every contact and in the “Update Contact Field” automation action.",
|
||
"adminRole": "Admin",
|
||
"failedToLoadTags": "Failed to load tags",
|
||
"nameRequired": "Tag name is required",
|
||
"notAuthenticated": "Not authenticated",
|
||
"tagCreated": "Tag created",
|
||
"failedToCreateTag": "Failed to create tag",
|
||
"tagDeleted": "Tag deleted",
|
||
"failedToDeleteTag": "Failed to delete tag",
|
||
"deleteAria": "Delete {name}",
|
||
"noTags": "No tags yet — create your first one below.",
|
||
"placeholder": "e.g. Newsletter",
|
||
"useColor": "Use {color}",
|
||
"addTag": "Add tag",
|
||
"deleteTag": "Delete tag",
|
||
"deleteConfirm": "Delete the tag \"{name}\"? This removes it from all contacts and cannot be undone.",
|
||
"cancel": "Cancel",
|
||
"deleting": "Deleting...",
|
||
"colors": {
|
||
"red": "Red",
|
||
"orange": "Orange",
|
||
"amber": "Amber",
|
||
"emerald": "Emerald",
|
||
"cyan": "Cyan",
|
||
"blue": "Blue",
|
||
"violet": "Violet",
|
||
"pink": "Pink"
|
||
}
|
||
},
|
||
"templates": {
|
||
"title": "Message templates",
|
||
"description": "Create templates and submit them to Meta for approval. Use \"Sync from Meta\" to pull templates approved elsewhere.",
|
||
"syncFromMeta": "Sync from Meta",
|
||
"syncing": "Syncing…",
|
||
"syncTitle": "Pull approved templates from your Meta WhatsApp Business Account",
|
||
"newTemplate": "New Template",
|
||
"noTemplates": "No templates yet.",
|
||
"createFirst": "Create your first message template to get started.",
|
||
"editTitle": "Editing triggers Meta re-review — status flips to PENDING.",
|
||
"editLabel": "Edit template",
|
||
"edit": "Edit",
|
||
"resubmitTitle": "Edit the template and resubmit to Meta for review.",
|
||
"resubmitLabel": "Edit and resubmit template",
|
||
"resubmit": "Resubmit",
|
||
"deleteMetaLocallyAria": "Delete template from Meta and locally",
|
||
"deleteLocallyAria": "Delete template locally",
|
||
"deleteMetaLocallyTitle": "Delete from Meta and locally",
|
||
"deleteLocallyTitle": "Delete locally",
|
||
|
||
"dialogEditTitle": "Edit Message Template",
|
||
"dialogNewTitle": "New Message Template",
|
||
"dialogEditDesc": "Save your changes to re-submit to Meta. Status will flip back to PENDING during review.",
|
||
"dialogNewDesc": "Build a template and submit it to Meta for approval. Once approved, you can use it in broadcasts and the inbox.",
|
||
"authWarning": "AUTHENTICATION templates have a fixed body + OTP button shape that needs a different builder. Create them in Meta WhatsApp Manager for now and use <bold>Sync from Meta</bold> to bring them in.",
|
||
|
||
"templateName": "Template Name",
|
||
"namePlaceholder": "e.g. order_confirmation",
|
||
"nameFixed": "Name is fixed once a template exists on Meta — create a new template to change it.",
|
||
"nameHint": "Lowercase letters, digits, and underscores only.",
|
||
"category": "Category",
|
||
"language": "Language",
|
||
"langFixed": "Language is fixed once a template exists on Meta.",
|
||
"langHint": "Must match the exact code on Meta — <code>en_US</code> and <code>en</code> are distinct.",
|
||
|
||
"header": "Header",
|
||
"headerNone": "None",
|
||
"headerText": "Text",
|
||
"headerImage": "Image",
|
||
"headerVideo": "Video",
|
||
"headerDocument": "Document",
|
||
"headerTextPlaceholder": "Header text (max 60 chars, optional {{1}})",
|
||
"headerSampleAria": "Sample value for header variable",
|
||
"headerSamplePlaceholder": "Sample value for {{1}} (required for Meta review)",
|
||
|
||
"uploadImage": "Upload image",
|
||
"uploadHint": "JPEG or PNG, ≤5 MB",
|
||
"mediaUrlPlaceholder": "https://… (or paste a public {format} link)",
|
||
"imageHint": "Upload a JPEG/PNG (≤5 MB, ≥800×418 px recommended) or paste a public HTTPS link — we upload it to Meta for review automatically.",
|
||
"mediaHint": "Must be a publicly accessible HTTPS link. Meta fetches it once during review, so it needs to stay live for ~24 hrs.",
|
||
"videoHint": " Recommended: MP4 / 3GPP, ≤16 MB, ≤60 seconds.",
|
||
"documentHint": " Recommended: PDF, ≤100 MB.",
|
||
|
||
"bodyText": "Body Text",
|
||
"bodyPlaceholder": "Hello {{1}}, your order {{2}} is confirmed.",
|
||
"bodyHint": "Use {{1}}, {{2}} for variables (must be contiguous starting at {{1}}).",
|
||
"sampleValues": "Sample values (Meta uses these to review your template)",
|
||
"sampleAria": "Sample value for body variable {var}",
|
||
"samplePlaceholder": "Sample for {var}",
|
||
|
||
"footer": "Footer (optional)",
|
||
"footerPlaceholder": "Optional footer text (max 60 chars)",
|
||
|
||
"buttons": "Buttons (optional)",
|
||
"addButton": "Add Button",
|
||
"buttonsLimit": "Up to {max} buttons. QUICK_REPLY buttons must come before URL / phone / copy-code buttons.",
|
||
"btnQuickReply": "Quick Reply",
|
||
"btnUrl": "URL",
|
||
"btnPhone": "Phone",
|
||
"btnCopyCode": "Copy Code",
|
||
"btnLabelPlaceholder": "Button label",
|
||
"urlPlaceholder": "https://example.com/path or with {{1}} suffix",
|
||
"urlSamplePlaceholder": "Example value for {{1}} (required when URL has a variable)",
|
||
"phonePlaceholder": "+15551234567",
|
||
"codePlaceholder": "Example code (e.g. SUMMER20)",
|
||
|
||
"cancel": "Cancel",
|
||
"saving": "Saving…",
|
||
"submitting": "Submitting…",
|
||
"saveResubmit": "Save & Resubmit",
|
||
"submitApproval": "Submit for Approval",
|
||
|
||
"deleteDialogTitle": "Delete template?",
|
||
"deleteMetaDesc": "\"{name}\" will be deleted from Meta and from wacrm. Active broadcasts using this template will start failing on their next send. This can't be undone.",
|
||
"deleteLocalDesc": "\"{name}\" will be deleted from wacrm. It was never submitted to Meta, so no remote cleanup is needed.",
|
||
"deleting": "Deleting…",
|
||
"delete": "Delete",
|
||
|
||
"toastLoadFailed": "Failed to load templates",
|
||
"toastSubmitFailed": "Failed to submit",
|
||
"toastSubmitEditSuccess": "Edit submitted — Meta typically reviews within 24 hours.",
|
||
"toastSubmitNewSuccess": "Submitted to Meta — typical review time is 24 hours. Status updates automatically.",
|
||
"toastSaveEditDry": "Template updated (dry-run — no Meta call)",
|
||
"toastSaveNewDry": "Template saved (dry-run — no Meta call)",
|
||
"toastSyncCount": "Synced {total} {total, plural, =1 {template} other {templates}} from Meta",
|
||
"toastSyncDetails": " ({inserted} new, {updated} updated)",
|
||
"toastSyncFailed": "Failed to sync: {preview}",
|
||
"toastSyncTruncated": "Synced the first 2000 templates only — your account has more. Sync again to continue, or contact support if this persists.",
|
||
"toastSyncError": "Failed to sync templates",
|
||
"toastDeleteSuccess": "Template deleted",
|
||
"toastDeleteError": "Failed to delete template",
|
||
"toastInvalidImage": "Header image must be a JPEG or PNG.",
|
||
"toastImageTooLarge": "Image is {size} MB — Meta's limit is 5 MB.",
|
||
"toastUploadSuccess": "Image uploaded.",
|
||
"toastUploadFailed": "Upload failed."
|
||
},
|
||
"roles": {
|
||
"admin": "Admin",
|
||
"adminHint": "Manage members + everything",
|
||
"agent": "Agent",
|
||
"agentHint": "Use features; no settings",
|
||
"viewer": "Viewer",
|
||
"viewerHint": "Read-only across the app",
|
||
"owner": "Owner",
|
||
"ownerHint": "Full control over account and billing"
|
||
},
|
||
"whatsapp": {
|
||
"title": "WhatsApp connection",
|
||
"description": "Connect your Meta WhatsApp Business API. Credentials, webhook, and setup steps all live here.",
|
||
"tokenCorrupted": "Stored token can't be decrypted",
|
||
"resetting": "Resetting...",
|
||
"resetConfig": "Reset Configuration",
|
||
"credentialsValid": "Credentials valid",
|
||
"notConnected": "Not Connected",
|
||
"connectedDesc": "Your access token authenticates with Meta. See Registration status below for whether webhooks are actually wired.",
|
||
"notConnectedDesc": "Configure your Meta API credentials below to connect your WhatsApp Business account.",
|
||
"registered": "Registered — Meta will deliver events to wacrm",
|
||
"notRegistered": "Not registered — Meta will not deliver events",
|
||
"verifyWithMeta": "Verify with Meta",
|
||
"subscribedSince": "Subscribed since {date}. Click Verify with Meta if events stop arriving.",
|
||
"unknownDate": "unknown",
|
||
"lastAttemptFailed": "Last attempt failed with: ",
|
||
"retryHint": "Enter (or correct) the 2-step PIN below and click Save Configuration to retry.",
|
||
"noRegistrationHint": "This number was saved before registration tracking existed, or registration was skipped. Enter the 2-step PIN below and click Save Configuration to subscribe it.",
|
||
"diagnosticLastRun": "Diagnostic — last run: ",
|
||
"live": "live",
|
||
"notLive": "not live",
|
||
"apiCredentialsTitle": "API Credentials",
|
||
"apiCredentialsDesc": "Enter your Meta WhatsApp Business API credentials.",
|
||
"phoneNumberId": "Phone Number ID",
|
||
"wabaId": "WhatsApp Business Account ID",
|
||
"accessToken": "Permanent Access Token",
|
||
"accessTokenPlaceholder": "Enter your access token",
|
||
"tokenHidden": "Token is hidden for security. Re-enter it to update configuration.",
|
||
"webhookVerifyToken": "Webhook Verify Token",
|
||
"webhookVerifyTokenPlaceholder": "Create a custom verify token",
|
||
"webhookVerifyTokenHint": "A custom string you create. Must match the token you set in Meta webhook settings.",
|
||
"twoStepPin": "Two-step verification PIN",
|
||
"optional": "(optional)",
|
||
"pinPlaceholder": "6-digit PIN from Meta WhatsApp Manager",
|
||
"pinHint": "Needed only to wire inbound messages for a production number. Set it in Meta Business Manager → WhatsApp Accounts → Phone Numbers → Two-step verification, then paste it here so wacrm can subscribe the number — otherwise Meta routes inbound events to whichever app last claimed it (the symptom that hits second numbers under a shared WABA). Meta test numbers have no PIN and are pre-registered — leave this blank for them. Leaving it blank also keeps an existing registration untouched.",
|
||
"webhookTitle": "Webhook Configuration",
|
||
"webhookDesc": "Use this URL as your webhook callback in the Meta App Dashboard.",
|
||
"webhookUrl": "Webhook Callback URL",
|
||
"saving": "Saving...",
|
||
"saveConfig": "Save Configuration",
|
||
"testing": "Testing...",
|
||
"testConnection": "Test API Connection",
|
||
"setupInstructions": "Setup Instructions",
|
||
"setupInstructionsDesc": "Follow these steps to connect your WhatsApp Business API.",
|
||
"step1": "Create a Meta App",
|
||
"step1_1": "Go to developers.facebook.com",
|
||
"step1_2": "Click \"My Apps\" and then \"Create App\"",
|
||
"step1_3": "Select \"Business\" as the app type",
|
||
"step1_4": "Fill in app details and create",
|
||
"step2": "Add WhatsApp Product",
|
||
"step2_1": "In your app dashboard, click \"Add Product\"",
|
||
"step2_2": "Find \"WhatsApp\" and click \"Set Up\"",
|
||
"step2_3": "Follow the setup wizard to link your business",
|
||
"step3": "Get API Credentials",
|
||
"step3_1": "Go to WhatsApp > API Setup",
|
||
"step3_2": "Copy your <strong class=\"text-foreground\">Phone Number ID</strong>",
|
||
"step3_3": "Copy your <strong class=\"text-foreground\">WhatsApp Business Account ID</strong>",
|
||
"step3_4": "Generate a <strong class=\"text-foreground\">Permanent Access Token</strong> from Business Settings > System Users",
|
||
"step4": "Configure Webhooks",
|
||
"step4_1": "Go to WhatsApp > Configuration",
|
||
"step4_2": "Click \"Edit\" on the Webhook section",
|
||
"step4_3": "Paste the <strong class=\"text-foreground\">Webhook Callback URL</strong> from above",
|
||
"step4_4": "Enter the same <strong class=\"text-foreground\">Verify Token</strong> you set here",
|
||
"step4_5": "Subscribe to \"messages\" webhook field",
|
||
"metaDocs": "Meta WhatsApp API Documentation"
|
||
},
|
||
"sections": {
|
||
"overview": "Overview",
|
||
"profile": "Your profile",
|
||
"security": "Login & security",
|
||
"appearance": "Appearance",
|
||
"whatsapp": "WhatsApp",
|
||
"templates": "Templates",
|
||
"fields": "Fields & tags",
|
||
"deals": "Deals & currency",
|
||
"members": "Team members",
|
||
"api": "API keys"
|
||
},
|
||
"groups": {
|
||
"account": "Account",
|
||
"workspace": "Workspace"
|
||
},
|
||
"profile": {
|
||
"title": "Your profile",
|
||
"description": "How you show up across the app. Your avatar and name appear in the header, sidebar, and anywhere your teammates see you.",
|
||
"changePhoto": "Change photo",
|
||
"uploadPhoto": "Upload photo",
|
||
"remove": "Remove",
|
||
"photoHint": "PNG, JPG, WebP, or GIF. Up to 2 MB.",
|
||
"displayName": "Display name",
|
||
"email": "Email",
|
||
"emailChangeHint": "Check the inbox for <bold>{oldEmail}</bold> and <bold>{newEmail}</bold> — both need to confirm before the change takes effect.",
|
||
"accountDetails": "Account details",
|
||
"role": "Role",
|
||
"joined": "Joined",
|
||
"userId": "User ID",
|
||
"loading": "Loading your profile…",
|
||
"saving": "Saving…",
|
||
"saveChanges": "Save changes",
|
||
"unsupportedImage": "Unsupported image type",
|
||
"unsupportedImageDesc": "Use PNG, JPG, WebP, or GIF.",
|
||
"imageTooLarge": "Image is too large",
|
||
"imageTooLargeDesc": "Maximum 2 MB.",
|
||
"nameRequired": "Display name is required",
|
||
"invalidEmail": "Enter a valid email address",
|
||
"uploadFailed": "Upload failed: {message}",
|
||
"saveFailed": "Save failed: {message}",
|
||
"profileSaved": "Profile saved",
|
||
"emailChangeFailed": "Email change failed: {message}",
|
||
"profileSavedEmailCheck": "Profile saved — check your email to confirm the address change",
|
||
|
||
"passwordTitle": "Password",
|
||
"passwordDesc": "Use at least {min} characters. You will stay signed in on this device after changing it.",
|
||
"currentPassword": "Current password",
|
||
"newPassword": "New password",
|
||
"confirmPassword": "Confirm new password",
|
||
"updating": "Updating…",
|
||
"updatePassword": "Update password",
|
||
"cannotChangeNoEmail": "Cannot change password without a current email",
|
||
"passwordTooShort": "Password must be at least {min} characters",
|
||
"passwordMismatch": "New password and confirmation do not match",
|
||
"currentPasswordIncorrect": "Current password is incorrect",
|
||
"passwordUpdateFailed": "Password update failed: {message}",
|
||
"passwordUpdated": "Password updated",
|
||
|
||
"sessionsTitle": "Active sessions",
|
||
"sessionsDesc": "Sign out of every device where you're logged in — including this one. Useful if you lost a laptop or shared your password.",
|
||
"signOutAll": "Sign out of all devices",
|
||
"signOutConfirmTitle": "Sign out everywhere?",
|
||
"signOutConfirmDesc": "Every device logged into this account will be signed out and will need to log in again. You will be redirected to the login page.",
|
||
"cancel": "Cancel",
|
||
"signingOut": "Signing out…",
|
||
"signOutEverywhere": "Sign out everywhere",
|
||
"signOutFailed": "Sign-out failed: {message}"
|
||
},
|
||
"appearance": {
|
||
"title": "Appearance",
|
||
"description": "Set the mode and accent colour used across the app. Saved to this device — try it, it changes live.",
|
||
"mode": "Mode",
|
||
"useMode": "Use {mode} mode",
|
||
"active": "Active",
|
||
"accentColor": "Accent color",
|
||
"useTheme": "Use {name} theme"
|
||
},
|
||
"security": {
|
||
"title": "Login & security",
|
||
"description": "Change your password and sign out of your devices. These keep your account safe."
|
||
},
|
||
"apiKeys": {
|
||
"title": "API keys",
|
||
"description": "Keys authenticate the public REST API (<apiCode>/api/v1</apiCode>) so you can build your own automations. Send them as <headerCode>Authorization: Bearer <key></headerCode>.",
|
||
"newApiKey": "New API key",
|
||
"noApiKeys": "No API keys yet.",
|
||
"createOneHint": "Click <bold>New API key</bold> to create one.",
|
||
"askAdminHint": "Ask an admin to create one.",
|
||
"revoked": "Revoked",
|
||
"expired": "Expired",
|
||
"noScopes": "No scopes",
|
||
"created": "Created {date}",
|
||
"lastUsed": "last used {date}",
|
||
"neverUsed": "never used",
|
||
"expires": "expires {date}",
|
||
"revoke": "Revoke",
|
||
"revokeSuccess": "Revoked \"{name}\"",
|
||
"revokeFailed": "Failed to revoke key",
|
||
"loadFailed": "Failed to load API keys",
|
||
"createError": "Failed to create key",
|
||
"nameRequired": "Give the key a name",
|
||
"nameLabel": "Name",
|
||
"namePlaceholder": "e.g. Zapier automation",
|
||
"scopesLabel": "Scopes",
|
||
"scopesHint": "A key with no scopes can still call <code className=\"text-[11px]\">GET /api/v1/me</code> to verify it works.",
|
||
"cancel": "Cancel",
|
||
"creating": "Creating…",
|
||
"createKey": "Create key",
|
||
"copyTitle": "Copy your API key",
|
||
"copyDesc": "This is the only time the full key is shown. Store it somewhere safe — if you lose it, revoke it and create a new one.",
|
||
"apiKeyLabel": "API key",
|
||
"copy": "Copy",
|
||
"copySuccess": "API key copied",
|
||
"copyFailed": "Copy failed — select and copy manually",
|
||
"newKeyTitle": "New API key",
|
||
"newKeyDesc": "Name it after the integration that will use it, and grant only the scopes it needs.",
|
||
"done": "Done",
|
||
"networkError": "Could not reach the server"
|
||
},
|
||
"deals": {
|
||
"title": "Deals & currency",
|
||
"description": "The currency used for new deals and for pipeline and dashboard totals.",
|
||
"defaultCurrency": "Default currency",
|
||
"defaultCurrencyDesc": "New deals default to this currency, and pipeline and dashboard totals are shown in it. Existing deals keep the currency they were saved with.",
|
||
"currencyLabel": "Currency",
|
||
"adminOnlyHint": "Only account admins can change the default currency.",
|
||
"save": "Save",
|
||
"saving": "Saving...",
|
||
"saveFailed": "Failed to save default currency",
|
||
"saveSuccess": "Default currency updated"
|
||
},
|
||
"aiConfig": {
|
||
"title": "Agent setup",
|
||
"description": "Bring your own OpenAI or Anthropic key. wacrm calls the provider directly with your key — no per-seat AI fees, and your data stays yours. This powers AI-drafted replies in the inbox, the auto-reply bot, and the Playground.",
|
||
"adminOnlyConfig": "Only admins and owners can change the AI configuration.",
|
||
"loadFailed": "Failed to load AI configuration",
|
||
"providerAndKey": "Provider & key",
|
||
"encryptionNotice": "Your key is encrypted at rest (AES-256-GCM) and never shown again after saving.",
|
||
"provider": "Provider",
|
||
"model": "Model",
|
||
"apiKey": "API key",
|
||
"testKey": "Test key",
|
||
"testSuccess": "Key works — the provider responded.",
|
||
"testRejected": "The provider rejected the request.",
|
||
"testNetworkError": "Could not reach the provider.",
|
||
"embeddingsKey": "Embeddings key",
|
||
"optionalSemanticSearch": "(optional — enables semantic knowledge-base search)",
|
||
"embeddingsHint": "An OpenAI key used only to embed your knowledge base (text-embedding-3-small){sameKeyText}. Leave blank to use keyword search instead. Clear it to turn semantic search off.",
|
||
"sameKeyText": " — can be the same key as above",
|
||
"behaviour": "Behaviour",
|
||
"behaviourDesc": "Tell the assistant about your business — products, tone, what it may and may not promise. This context feeds both drafts and auto-replies.",
|
||
"businessContext": "Business context & instructions",
|
||
"promptPlaceholder": "e.g. We are Acme, a coffee-equipment store. Be warm and concise. Never quote prices or delivery dates — hand off to a human for those.",
|
||
"enableAssistant": "Enable AI assistant",
|
||
"enableAssistantDesc": "Master switch. Turns on the “Draft with AI” button in the inbox.",
|
||
"autoReply": "Auto-reply to inbound messages",
|
||
"autoReplyDesc": "The bot answers new inbound messages automatically (only when no flow handles them and no agent is assigned). Hands off to a human when it can’t help.",
|
||
"maxAutoReplies": "Max auto-replies per conversation",
|
||
"maxAutoRepliesDesc": "After this many bot replies in one thread, the bot goes quiet.",
|
||
"remove": "Remove",
|
||
"save": "Save",
|
||
"missingModel": "Enter a model name.",
|
||
"missingApiKey": "Enter your API key.",
|
||
"saveSuccess": "AI assistant saved.",
|
||
"saveFailed": "Failed to save.",
|
||
"removeSuccess": "AI configuration removed.",
|
||
"removeFailed": "Failed to remove."
|
||
},
|
||
"aiKnowledge": {
|
||
"loadFailed": "Failed to load knowledge base",
|
||
"openFailed": "Failed to open document",
|
||
"titleContentRequired": "Title and content are required.",
|
||
"saveSuccessNew": "Document added.",
|
||
"saveSuccessUpdate": "Document updated.",
|
||
"saveFailed": "Failed to save.",
|
||
"removeSuccess": "Document removed.",
|
||
"removeFailed": "Failed to remove.",
|
||
"reindexSuccess": "Reindexed {count} document(s).",
|
||
"reindexFailed": "Reindex failed.",
|
||
"title": "Knowledge base",
|
||
"description": "Add FAQs, policies, or product details. The assistant retrieves the relevant pieces when drafting and auto-replying, so it can answer instead of handing off.{searchType}",
|
||
"semanticSearchOn": " Semantic search is on (embeddings key set).",
|
||
"keywordSearchOn": " Using keyword search — add an embeddings key above for semantic search.",
|
||
"noDocs": "No documents yet.",
|
||
"editDocTitle": "Title",
|
||
"editDocTitlePlaceholder": "e.g. Returns & refunds policy",
|
||
"editDocContent": "Content",
|
||
"editDocContentPlaceholder": "Paste the FAQ answer, policy text, or product details…",
|
||
"cancel": "Cancel",
|
||
"saveDoc": "Save document",
|
||
"addDoc": "Add document",
|
||
"reindex": "Reindex",
|
||
"reindexTooltip": "Re-embed all documents (e.g. after adding an embeddings key)",
|
||
"loading": "Loading…"
|
||
}
|
||
}
|
||
}
|