Files
marketplaces/src/app/i18n/en.ts

1910 lines
81 KiB
TypeScript
Raw Normal View History

2026-02-26 23:09:20 +04:00
import { Translations } from './translations';
export const en: Translations = {
header: {
home: 'Home',
search: 'Search',
about: 'About',
contacts: 'Contacts',
searchPlaceholder: 'Search...',
catalog: 'Catalog',
wishlist: 'Wishlist',
compare: 'Compare',
openMenu: 'Open menu',
closeMenu: 'Close menu',
2026-02-26 23:09:20 +04:00
},
footer: {
description: 'A modern marketplace for comfortable shopping',
company: 'Company',
aboutUs: 'About us',
contacts: 'Contacts',
requisites: 'Company details',
support: 'Support',
faq: 'FAQ',
delivery: 'Delivery',
guarantee: 'Warranty',
legal: 'Legal information',
offer: 'Public offer',
privacy: 'Privacy policy',
returns: 'Returns',
info: 'Information',
aboutCompany: 'About company',
documents: 'Documents',
paymentRules: 'Payment terms',
returnPolicy: 'Return policy',
publicOffer: 'Public offer',
help: 'Help',
payment: 'Payment',
allRightsReserved: 'All rights reserved.',
},
home: {
welcomeTo: 'Welcome to {{brand}}',
subtitle: 'Find everything you need in one place',
startSearch: 'Start search',
loading: 'Loading categories...',
errorTitle: 'Something went wrong',
retry: 'Try again',
categoriesTitle: 'Product categories',
categoriesSubtitle: 'Choose a category',
categoriesEmpty: 'Categories coming soon',
categoriesEmptyDesc: 'We are working on filling the catalog',
dexarHeroTitle: 'Find everything here',
dexarHeroSubtitle: 'Thousands of products in one place',
dexarHeroTagline: 'simple and convenient',
goToCatalog: 'Go to catalog',
findProduct: 'Find a product',
loadingDexar: 'Loading categories...',
catalogTitle: 'Product catalog',
emptyCategoriesDexar: 'No categories yet',
categoriesSoonDexar: 'Categories will appear here soon',
itemsCount: '{{count}} products',
},
cart: {
title: 'Cart',
clear: 'Clear',
empty: 'Cart is empty',
emptyDesc: 'Add products to start shopping',
goShopping: 'Start shopping',
total: 'Total',
items: 'Products',
deliveryLabel: 'Delivery',
2026-06-21 23:13:01 +04:00
deliveryMethod: 'Delivery option',
selectDelivery: 'Select delivery option',
deliveryPlace: 'Place',
deliveryTime: 'Delivery time',
digitalDelivery: 'Digital delivery',
deliveryRequired: 'Select delivery for every shippable item before checkout.',
2026-02-26 23:09:20 +04:00
toPay: 'To pay',
agreeWith: 'I agree with the',
publicOffer: 'public offer',
returnPolicy: 'return policy',
guaranteeTerms: 'warranty terms',
privacyPolicy: 'privacy policy',
and: 'and',
checkout: 'Place order',
2026-06-29 00:06:18 +04:00
payViaQr: 'Pay via QR',
payViaCard: 'Pay via card',
2026-02-26 23:09:20 +04:00
close: 'Close',
creatingPayment: 'Creating payment...',
waitFewSeconds: 'Please wait a few seconds',
scanQr: 'Scan the QR code to pay',
amountToPay: 'Amount due:',
waitingPayment: 'Waiting for payment...',
copied: '✓ Copied',
copyLink: 'Copy link',
openNewTab: 'Open in new tab',
paymentSuccess: 'Congratulations! Payment successful!',
paymentSuccessDesc: 'Enter your contact details and we will send your purchase within a few minutes',
sending: 'Sending...',
send: 'Send',
2026-06-02 00:57:36 +04:00
paymentError: 'Unable to create payment',
paymentErrorDesc: 'We could not prepare the payment QR code right now. Please try again in a moment.',
retryPayment: 'Try again',
2026-02-26 23:09:20 +04:00
paymentTimeout: 'Payment timed out',
paymentTimeoutDesc: 'We did not receive payment confirmation within 3 minutes.',
autoClose: 'Window will close automatically...',
confirmClear: 'Are you sure you want to clear the cart?',
removeItem: 'Remove item',
paymentQrAlt: 'Payment QR code',
2026-02-26 23:09:20 +04:00
acceptTerms: 'Please accept the offer terms, return policy, and warranty terms to proceed with the order.',
copyError: 'Copy error:',
emailSuccess: 'Email sent successfully! Check your inbox.',
emailError: 'An error occurred while sending the email. Please try again.',
phoneRequired: 'Phone number is required',
phoneMoreDigits: 'Enter {{count}} more digits',
phoneTooMany: 'Too many digits',
emailRequired: 'Email is required',
emailTooShort: 'Email is too short (minimum 5 characters)',
emailTooLong: 'Email is too long (maximum 100 characters)',
emailNeedsAt: 'Email must contain @',
emailNeedsDomain: 'Email must contain a domain (.com, .ru, etc.)',
emailInvalid: 'Invalid email format',
2026-03-24 00:09:11 +04:00
loginRequired: 'Log in to checkout',
loginRequiredDesc: 'Please log in via Telegram to place your order',
loginWithTelegram: 'Log in with Telegram',
orScanQr: 'Or scan the QR code',
2026-02-26 23:09:20 +04:00
},
search: {
title: 'Product search',
placeholder: 'Enter product name...',
searchBarAria: 'Search bar',
2026-02-26 23:09:20 +04:00
resultsCount: 'Products found:',
searching: 'Searching...',
retry: 'Try again',
noResults: 'Nothing found',
noResultsFor: 'No products found for "{{query}}"',
noResultsHint: 'Try changing your query or using different keywords',
emptyResultsAria: 'Empty search results',
popularCategories: 'Popular categories',
recommendedProducts: 'Recommended products',
aiSuggestionHint: 'AI suggestion (future)',
suggestionType: {
product: 'Product',
category: 'Category',
brand: 'Brand',
collection: 'Collection',
seller: 'Seller',
'static-page': 'Page',
ai: 'AI',
},
2026-02-26 23:09:20 +04:00
addToCart: 'Add to cart',
loadingMore: 'Loading...',
allLoaded: 'All results loaded',
emptyState: 'Enter a query to search for products',
2026-07-05 01:10:56 +04:00
minLength: 'Enter at least {{count}} characters to search',
2026-02-26 23:09:20 +04:00
of: 'of',
},
category: {
retry: 'Try again',
addToCart: 'Add to cart',
loadingMore: 'Loading...',
allLoaded: 'All products loaded',
emptyTitle: 'Oops! Nothing here yet',
emptyDesc: 'There are no products in this category yet, but they will appear soon',
goHome: 'Go home',
loading: 'Loading products...',
},
2026-07-05 01:36:21 +04:00
catalog: {
title: 'Catalog',
breadcrumb: 'Catalog breadcrumb',
allCategories: 'All categories',
products: 'Products',
loading: 'Loading catalog...',
loadingProducts: 'Loading products...',
errorTitle: 'Catalog is unavailable',
error: 'Could not load catalog data. Try again later.',
retry: 'Try again',
categoryHint: 'Choose a category to continue',
productHint: 'Browse products in this category',
emptyTitle: 'Nothing here yet',
emptyCategories: 'There are no child categories in this section yet.',
emptyProducts: 'There are no products in this category yet.',
addToCart: 'Add to cart',
categoriesCount: '{{count}} categories',
productsCount: '{{count}} products',
2026-07-09 01:40:22 +04:00
entriesCount: '{{count}} entries',
categoryBannerPlaceholder: 'Category banner placeholder for backend-driven media and description.',
navigationPlaceholder: 'Navigation layout placeholder prepared for backend/bootstrap-driven rendering.',
removeSavedSearch: 'Remove saved search',
resetFilters: 'Reset',
filtersTitle: 'Filters',
from: 'From',
to: 'To',
2026-07-09 01:40:22 +04:00
minValue: 'Min {{value}}',
maxValue: 'Max {{value}}',
enabled: 'Enabled',
searchPlaceholder: 'Search products, brands, categories',
searchSubmit: 'Search',
clearSearch: 'Clear',
2026-07-09 01:40:22 +04:00
suggestionsTitle: 'Suggestions',
popularSearchesTitle: 'Popular searches',
2026-07-09 01:40:22 +04:00
recentSearchesTitle: 'Recent searches',
searchHistoryTitle: 'Search history',
clearHistory: 'Clear',
searchNoResultsHint: 'No results found for this query. Try broader keywords.',
searchProductsFound: '{{total}} products found',
searchResultsSummary: '{{total}} results for "{{query}}"',
2026-07-10 15:55:38 +04:00
loadMore: 'Load more',
2026-07-09 01:40:22 +04:00
sortBy: 'Sort by',
sortRelevance: 'Recommended',
2026-07-09 01:40:22 +04:00
sortLatest: 'Newest',
sortPriceAsc: 'Price Low -> High',
sortPriceDesc: 'Price High -> Low',
sortRating: 'Highest Rated',
sortPopular: 'Most Popular',
sortDiscount: 'Discount',
layoutGrid: 'Grid',
layoutLargeGrid: 'Large grid',
layoutCompactGrid: 'Compact grid',
2026-07-10 15:55:38 +04:00
layoutGrid2: '2 Columns',
layoutGrid3: '3 Columns',
layoutGrid4: '4 Columns',
layoutCompact: 'Compact',
2026-07-09 01:40:22 +04:00
layoutList: 'List',
noResults: 'No results',
itemsCount: '{{count}} items',
emptyResultsTitle: 'No results found',
emptyResultsDescription: 'Try changing filters, sorting, or search keywords.',
previousPage: 'Previous',
nextPage: 'Next',
pageOf: 'Page {{page}} / {{total}}',
emptyCategoryTitle: 'This category has no products yet',
emptyCategoryMessage: 'Try browsing parent categories or return to the full catalog.',
2026-07-10 15:55:38 +04:00
goToParentCategory: 'Go to parent category',
browseCategories: 'Browse Categories',
2026-07-10 15:55:38 +04:00
offlineTitle: 'You are offline',
offlineMessage: 'Reconnect to continue browsing this catalog.',
noFilterMatchTitle: 'No products match your selected filters.',
noFilterMatchMessage: 'Try broadening price, attributes, or brand filters.',
clearFilters: 'Clear Filters',
openFilters: 'Open Filters',
applyFilters: 'Apply',
close: 'Close',
filtersDrawerAria: 'Filters drawer',
sortSheetAria: 'Sort options',
mobileToolbarAria: 'Catalog mobile toolbar',
gridCycle: 'Grid',
filtersPanelAria: 'Catalog filters',
2026-07-09 01:40:22 +04:00
filterPrice: 'Price',
filterAvailability: 'Availability',
filterInStock: 'In stock',
filterLowStock: 'Low stock',
filterOutOfStock: 'Out of stock',
filterRating: 'Rating',
filterStars: '{{count}} stars',
filterBrand: 'Brand',
filterCategory: 'Category',
filterCategoryValue: 'Category {{value}}',
filterSubcategory: 'Subcategory',
filterDiscount: 'Discount',
filterNew: 'New',
filterColor: 'Color',
filterSize: 'Size',
filterAttributes: 'Attributes',
},
productDetails: {
loading: 'Loading product...',
errorTitle: 'Product unavailable',
retry: 'Try again',
missingTitle: 'Product not found',
missingDescription: 'This product does not exist or is no longer available.',
backToCatalog: 'Back to catalog',
tabsAria: 'Product tabs',
mediaAria: 'Product media',
ratingStarsAria: 'Rating stars',
selectRatingAria: 'Select rating',
reviewsEmpty: 'No reviews yet.',
questionsEmpty: 'No questions yet.',
askQuestion: 'Ask question',
hideQuestionForm: 'Hide question form',
questionFormTitle: 'Ask a question',
questionFormPlaceholder: 'Ask about size, delivery, compatibility or usage',
questionFormAnonymous: 'Ask anonymously',
submitQuestion: 'Submit question',
reviewFormTitle: 'Leave a review',
reviewRatingLabel: 'Rating',
reviewTitleLabel: 'Title',
reviewTitlePlaceholder: 'Short headline',
reviewTextLabel: 'Review',
reviewTextPlaceholder: 'Describe your experience',
reviewAnonymous: 'Submit anonymously',
reviewUploadPlaceholder: 'Photo upload is planned for a future sprint.',
reviewRatingRequired: 'Please select a rating.',
reviewTextRequired: 'Please add your review text.',
reviewSuccess: 'Review submitted successfully.',
2026-07-09 01:40:22 +04:00
submitReview: 'Submit review',
submitting: 'Submitting...',
loadMore: 'Load more',
showingOf: 'Showing {{shown}} of {{total}}',
questionsSubmissionFuture: 'Question submission can be enabled later without component changes.',
specificationsGeneral: 'General',
actionsAria: 'Product actions',
buyNow: 'Buy now',
wishlist: 'Wishlist',
compare: 'Compare',
share: 'Share',
notifyMe: 'Notify me',
zoom: 'Zoom',
fullscreen: 'Fullscreen',
pdfDocument: 'Product PDF document',
manualDocument: 'Product manual',
warrantyDocument: 'Warranty document',
openDocument: 'Open document',
2026-07-09 01:40:22 +04:00
specificationsEmpty: 'No specifications provided yet.',
warrantyTitle: 'Warranty and returns',
warrantyItem1: 'Warranty terms are provided by the seller and local law.',
warrantyItem2: 'Return eligibility depends on item condition and category.',
warrantyItem3: 'Detailed return instructions are available after purchase.',
verifiedPurchase: 'Verified purchase',
officialSeller: 'Official seller',
acceptedAnswer: 'Accepted answer',
like: 'Like',
dislike: 'Dislike',
reviewsCountLabel: '{{count}} reviews',
previous: 'Previous',
next: 'Next',
pageOf: 'Page {{page}} / {{total}}',
2026-07-05 01:36:21 +04:00
},
2026-02-26 23:09:20 +04:00
subcategories: {
loading: 'Loading subcategories...',
retry: 'Try again',
emptyTitle: 'Oops! No subcategories yet',
emptyDesc: 'There are no subcategories in this section yet, but they will appear soon',
goHome: 'Go home',
2026-03-24 00:09:11 +04:00
itemsInCategory: 'Items in this category',
2026-07-05 01:09:55 +04:00
childrenCount: '{{count}} categories',
productsCount: '{{count}} products',
includesProducts: 'Includes products',
2026-02-26 23:09:20 +04:00
},
itemDetail: {
loading: 'Loading...',
loadingDexar: 'Loading product...',
back: 'Go back',
backHome: 'Back to home',
noImage: 'No image',
stock: 'Availability:',
inStock: 'In stock',
lowStock: 'Few left',
lastItems: 'Last items',
mediumStock: 'Running low',
addToCart: 'Add to cart',
description: 'Description',
specifications: 'Specifications',
2026-02-26 23:09:20 +04:00
reviews: 'Reviews',
yourReview: 'Your review',
leaveReview: 'Leave a review',
rating: 'Rating:',
reviewPlaceholder: 'Share your experience with this product...',
reviewPlaceholderDexar: 'Share your thoughts on this product...',
anonymous: 'Anonymous',
submitting: 'Submitting...',
submit: 'Submit',
reviewSuccess: 'Thank you for your review!',
reviewError: 'Submission failed. Please try later.',
defaultUser: 'User',
defaultUserDexar: 'Anonymous',
noReviews: 'No reviews yet. Be the first!',
qna: 'Questions & Answers',
photo: 'Photo',
reviewsCount: 'reviews',
today: 'Today',
yesterday: 'Yesterday',
daysAgo: 'd. ago',
weeksAgo: 'w. ago',
2026-03-24 00:09:11 +04:00
colour: 'Colour',
size: 'Size',
2026-07-05 01:07:53 +04:00
relatedProducts: 'Related products',
2026-02-26 23:09:20 +04:00
},
app: {
connecting: 'Connecting to server...',
serverUnavailable: 'Server unavailable',
serverError: 'Could not connect to the server. Please check your internet connection.',
retryConnection: 'Retry',
pageTitle: 'Marketplace of goods and services',
},
platform: {
loadingPage: 'Loading platform page...',
emptyConfig: 'No page configuration found.',
},
backoffice: {
title: 'Backoffice Sandbox',
subtitle: 'Business data management domain (mocked for platform foundation).',
loading: 'Loading backoffice data...',
products: 'Products',
categories: 'Categories',
otherDomains: 'Other Domains',
sku: 'SKU',
titleColumn: 'Title',
price: 'Price',
status: 'Status',
itemsCount: 'items',
orders: 'Orders',
customers: 'Customers',
inventory: 'Inventory',
media: 'Media',
settings: 'Settings',
notAvailable: 'n/a',
},
builder: {
feat(builder): redesign marketplace builder experience and navigation Renamed the experience consistently to Marketplace Builder everywhere visible (page title/subtitle, breadcrumbs, sidebar, dashboard quick action/shortcut copy) - internal ProjectEditor class/selector names kept as-is to avoid regressions. builder.title/subtitle no longer say 'bootstrap-config editing surface' to end users. New business-oriented IA (builder-groups.model.ts): 12 existing ProjectEditorSectionIds regrouped into 8 groups (Marketplace, Branding and Design, Homepage, Content, Languages, Marketplace Features, Navigation and Search, Preview) - every existing section mapped to exactly one group, none dropped, no group points at a page that doesn't exist. New Builder landing page at /edit (was a redirect straight into the General form): readiness percent, recommended next step, one overview card per group (purpose + real complete/in-progress/not-started/unknown status, icon+text never color-alone), a Marketplace Readiness checklist, quick links. All derived from real facade/schema signals (required-field fill state, modifiedSections, staticPages, catalog counts via BackofficeDataService) or explicitly marked unknown (the "preview reviewed" check has no tracking - shown as unknown, never guessed). Section pages (/edit/:section) now share one consistent header: breadcrumb (Builder > Group > Section), draft/published + modified badges, and a contextual help panel (what is this / where visible / what happens if you skip it) sourced per group. Sidebar nav rewritten as grouped, icon-led sections with per-section and per-group status indicators; layout converted from a top pill-tab bar to a responsive sidebar (desktop 280px, tablet 72px icon rail, mobile drawer with Escape-to-close), matching the Sprint 1 admin shell pattern. Section form components themselves untouched. Routes: 'edit' is now its own landing route instead of redirecting to 'edit/general'; /builder and /project-editor redirect to 'edit'. Sprint 1/2 destinations that pointed at edit/general now point at the new edit landing page. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 09:43:03 +04:00
title: 'Marketplace Builder',
subtitle: 'Build your marketplace step by step.',
2026-07-10 13:43:53 +04:00
general: 'General',
branding: 'Branding',
2026-07-10 13:43:53 +04:00
theme: 'Theme',
header: 'Header',
footer: 'Footer',
homepage: 'Homepage',
widgets: 'Widgets',
2026-07-10 13:52:01 +04:00
staticPages: 'Static Pages',
2026-07-10 13:43:53 +04:00
marketplaceFeatures: 'Marketplace Features',
preview: 'Preview',
brandName: 'Brand Name',
2026-07-10 13:43:53 +04:00
marketplaceName: 'Marketplace Name',
domain: 'Domain',
descriptionLabel: 'Description',
defaultLanguage: 'Default Language',
supportedLanguages: 'Supported Languages',
logo: 'Logo',
smallLogo: 'Small Logo',
favicon: 'Favicon',
socialImage: 'Social Share Image',
gallery: 'Gallery',
addGalleryImage: 'Add image',
headerLayout: 'Header Layout',
headerLayoutDefault: 'Default',
headerLayoutCentered: 'Centered',
headerSticky: 'Sticky Header',
2026-07-10 13:43:53 +04:00
marketplaceTitle: 'Marketplace Title',
primaryColor: 'Primary Color',
secondaryColor: 'Secondary Color',
backgroundColor: 'Background',
surfaceColor: 'Surface',
textColor: 'Text',
successColor: 'Success',
warningColor: 'Warning',
dangerColor: 'Danger',
showLogo: 'Logo',
showSearch: 'Search',
showCategories: 'Categories',
showLanguages: 'Languages',
showCart: 'Cart',
showProfile: 'Profile',
showWishlist: 'Wishlist',
showCompare: 'Compare',
showRegion: 'Region',
companyName: 'Company Information',
address: 'Address',
phone: 'Phone',
email: 'Email',
copyright: 'Copyright',
paymentIcons: 'Payment Icons',
socialLinks: 'Social Links',
footerLogo: 'Footer Logo',
addPaymentIcon: 'Add Payment Icon',
removePaymentIcon: 'Remove',
iconAltLabel: 'Icon Label',
addSocialLink: 'Add Social Link',
removeSocialLink: 'Remove',
socialLinkLabel: 'Platform',
socialLinkUrl: 'URL',
invalidUrl: 'Enter a valid URL starting with http:// or https://.',
2026-07-10 13:52:01 +04:00
createPage: 'Create Page',
deletePage: 'Delete Page',
pageId: 'Page ID',
slug: 'Slug',
iconLabel: 'Icon',
showInFooter: 'Show In Footer',
showInHeader: 'Show In Header',
showInSitemap: 'Show In Sitemap',
requiresAuthentication: 'Requires Authentication',
footerGroup: 'Footer Group',
orderLabel: 'Order',
translationTitle: 'Translation Title',
htmlPreview: 'HTML',
seoSection: 'SEO',
seoTitle: 'SEO Title',
seoDescription: 'SEO Description',
seoKeywords: 'Keywords',
seoCanonical: 'Canonical URL',
seoOgTitle: 'OG Title',
seoOgDescription: 'OG Description',
seoOgImage: 'OG Image',
2026-07-10 13:43:53 +04:00
visible: 'Visible',
layoutLabel: 'Layout',
columns: 'Columns',
height: 'Height',
overlay: 'Overlay',
autoplay: 'Autoplay',
cardsPerRow: 'Cards Per Row',
filtersLabel: 'Filters',
showBadges: 'Show Badges',
showRating: 'Show Rating',
showPrice: 'Show Price',
widgetJson: 'Widget JSON',
reviews: 'Reviews',
questions: 'Questions',
comments: 'Comments',
recommendations: 'Recommendations',
recentlyViewed: 'Recently Viewed',
searchSuggestions: 'Search Suggestions',
searchHistory: 'Search History',
livePreview: 'Live Preview',
previewChangesTitle: 'Changes since last publish',
previewNoIssues: 'No validation issues.',
previewNoChanges: 'No changes since the last publish.',
previewChangeField: 'Field',
previewChangeBefore: 'Before',
previewChangeAfter: 'After',
languagesTab: 'Languages',
addLanguage: 'Add Language',
removeLanguage: 'Remove',
setDefaultLanguage: 'Set as Default',
defaultLanguageLabel: 'Default',
navigationTab: 'Navigation',
navigationHeader: 'Header Navigation',
navigationFooter: 'Footer Navigation',
navigationFooterGrouped: 'Footer navigation uses grouped columns and is not editable here yet — edit via the Footer tab.',
addLink: 'Add Link',
insertPageLink: 'Insert page link',
linkedToPage: 'Linked to page',
removeLink: 'Remove',
linkLabel: 'Label',
linkUrl: 'URL',
2026-07-10 13:43:53 +04:00
exportBootstrap: 'Export Bootstrap',
importBootstrap: 'Import Bootstrap',
exportedBootstrap: 'Exported Bootstrap',
importSource: 'Import Source',
importError: 'Import failed. Invalid bootstrap JSON.',
featureFlags: 'Feature Flags',
validationMissingLogo: 'Branding is missing a logo.',
validationNoLanguages: 'No languages are configured.',
validationDefaultLocaleNotSupported: 'The default language is not in the supported languages list.',
validationInvalidUrl: 'The marketplace URL is invalid.',
validationDuplicateSlugs: 'Two or more static pages share the same slug.',
validationEmptyHomepage: 'The homepage has no sections.',
validationMissingWidget: 'A homepage section has a widget with no type.',
validationDuplicateNavLinks: 'Two or more header navigation links are duplicates.',
validationInvalidColors: 'One or more theme colors are not valid hex colors.',
validationMissingTranslations: 'Some content is missing translations for a supported language.',
validationInvalidLayouts: 'One or more layouts reference an unknown layout type.',
validationInvalidJson: 'The configuration is not valid JSON.',
validationInvalidCss: 'A static page contains invalid CSS.',
validationDuplicateRoutes: 'Two or more pages share the same route.',
validationInvalidWidgetConfig: 'A widget is missing a required field (id, type, version, or props).',
validationInvalidContactEmail: 'The company contact email is not a valid email address.',
validationInvalidSocialLinkUrl: 'One or more footer social links have an invalid URL.',
validationIncompletePaymentIcon: 'A footer payment icon is missing its image or alt text.',
undo: 'Undo',
redo: 'Redo',
statusDraft: 'Draft',
statusPublished: 'Published',
unsavedChanges: 'Unsaved changes',
save: 'Save',
publish: 'Publish',
confirmLeaveUnsaved: 'You have unsaved changes. Leave anyway?',
promptLinkUrl: 'URL',
promptImageUrl: 'Image URL',
promptEmbedUrl: 'Embed URL',
htmlEditorInvalidHtml: 'This HTML has an unclosed or mismatched tag. Fix it before switching back to the visual editor.',
htmlEditorCode: 'Code',
htmlEditorPreview: 'Preview',
lastSaved: 'Last saved',
draftRestored: 'A local draft was restored from your last session.',
dismiss: 'Dismiss',
resetDraft: 'Reset draft',
resetSection: 'Reset section',
confirmResetDraft: 'This discards all unpublished changes and restores the last published configuration. Continue?',
confirmResetSection: 'This discards unpublished changes in this section only. Continue?',
marketplaceNameDesc: 'The name shown to shoppers across the storefront and browser tab.',
domainDesc: 'The domain shoppers use to reach this marketplace. Changing it does not move DNS.',
descriptionFieldDesc: 'A short summary used for search engines and social link previews.',
defaultLanguageDesc: 'The language shown when a shopper has no saved language preference.',
supportedLanguagesDesc: 'Comma-separated language codes shoppers can switch to (e.g. en, ru, hy).',
logoDesc: 'Full logo image URL, shown in the header on desktop.',
smallLogoDesc: 'Compact logo image URL, used where space is limited (e.g. mobile header).',
faviconDesc: 'Browser tab icon image URL. Should be a small square image.',
socialImageDesc: 'Default image shown when the marketplace is shared on social media (Open Graph).',
galleryDesc: 'Extra brand images available for future use across the storefront.',
headerLayoutDesc: 'How the header content is arranged: default (logo left, nav spread) or centered.',
headerStickyDesc: 'Keep the header pinned to the top of the viewport while scrolling.',
marketplaceTitleDesc: 'The page title used by search engines and browser tabs.',
primaryColorDesc: 'The main brand color, used on primary buttons and highlights. Must be a valid hex color.',
secondaryColorDesc: 'A supporting brand color used for secondary UI elements. Must be a valid hex color.',
backgroundColorDesc: 'The default page background color. Must be a valid hex color.',
surfaceColorDesc: 'The background color for cards and raised surfaces. Must be a valid hex color.',
textColorDesc: 'The default body text color. Must be a valid hex color.',
successColorDesc: 'Color used for success messages and positive states. Must be a valid hex color.',
warningColorDesc: 'Color used for warning messages and caution states. Must be a valid hex color.',
dangerColorDesc: 'Color used for errors and destructive actions. Must be a valid hex color.',
themeModeLabel: 'Color mode',
themeModeDesc: 'Controls whether the storefront renders in light, dark, or the shopper\'s system preference.',
themeModeLight: 'Light',
themeModeLightDesc: 'Always use the light color scheme.',
themeModeDark: 'Dark',
themeModeDarkDesc: 'Always use the dark color scheme.',
themeModeSystem: 'System',
themeModeSystemDesc: 'Follow the shopper\'s device/browser color scheme preference.',
siteLayoutLabel: 'Site layout',
siteLayoutDesc: 'The overall page chrome mode used across the storefront.',
siteLayoutDefault: 'Default',
siteLayoutDefaultDesc: 'Standard layout with a top navigation bar.',
siteLayoutSidebarLeft: 'Sidebar (left)',
siteLayoutSidebarLeftDesc: 'Adds a left-hand sidebar, typically for category navigation.',
siteLayoutCarouselHome: 'Carousel home',
siteLayoutCarouselHomeDesc: 'Homepage leads with a full-width carousel/hero.',
siteLayoutMinimal: 'Minimal',
siteLayoutMinimalDesc: 'Stripped-down chrome with minimal navigation elements.',
showLogoDesc: 'Show the marketplace logo in the header.',
showSearchDesc: 'Show the search bar in the header.',
showCategoriesDesc: 'Show the categories menu entry point in the header.',
showLanguagesDesc: 'Show the language switcher in the header.',
showCartDesc: 'Show the cart icon/link in the header.',
showProfileDesc: 'Show the account/profile entry point in the header.',
showWishlistDesc: 'Show the wishlist entry point in the header.',
showCompareDesc: 'Show the compare-products entry point in the header.',
showRegionDesc: 'Show the region/country selector in the header.',
companyNameDesc: 'Legal company name shown in the footer and static pages.',
addressDesc: 'Company street address shown in the footer.',
phoneDesc: 'Contact phone number shown in the footer.',
emailDesc: 'Contact email address shown in the footer.',
copyrightDesc: 'Copyright line shown at the bottom of every page.',
paymentIconsDesc: 'One payment icon entry per line (image URL and label) shown in the footer.',
socialLinksDesc: 'One social link entry per line (platform and URL) shown in the footer.',
footerLogoDesc: 'Logo shown in the footer, if different from the header logo.',
iconAltLabelDesc: 'Alt text describing the payment icon for accessibility.',
socialLinkUrlDesc: 'Full URL to the social media profile, must start with http:// or https://.',
staticPagesFieldDesc: 'Static pages (about, terms, privacy, etc.) linked from the footer.',
feat(builder): visual footer builder with drag-and-drop columns Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> P0 user feedback: footer static pages were comma-separated text; no way to add extra phones/emails for different countries. - New FooterColumnConfig/FooterLinkConfig model (footer-config.model.ts): columns of links, each link pointing at an existing static page (resolved by key, so it survives route renames) or a custom URL - Footer Builder UI: add/remove columns and links, per-link toggle between 'existing page' (dropdown of real static pages) and 'custom URL', drag-and-drop reordering of both columns and links via @angular/cdk/drag-drop (same primitive already used by the homepage section builder) - Wired FooterResolverService (the service the real storefront footer actually renders through) to read footer.columns as the primary source when present - without this the builder would have saved data nobody ever displayed. Falls back to the existing legacy static-page auto-grouping when no columns are configured, so existing sites are unaffected - CompanyContactConfig gains additionalPhones/additionalEmails (primary phone/email field unchanged) with add/remove UI for country-specific support lines - Old comma-separated staticPageKeys input removed from the UI; field kept on the model as deprecated/read-compat only - New builder.* i18n keys (en/ru/hy); fixed an accidental duplicate-key collision with pre-existing navigation-section addLink/removeLink keys during the rename pass - Verified in browser: added column, added link, switched link source page->custom, added phone number - all reactive and error-free
2026-07-19 13:58:57 +04:00
additionalPhones: 'Extra phone numbers',
additionalPhonesDesc: 'Add more numbers if you support customers in different countries.',
addPhone: 'Add phone number',
removePhone: 'Remove phone number',
additionalEmails: 'Extra email addresses',
additionalEmailsDesc: 'Add more addresses for different regions or departments.',
addEmail: 'Add email address',
removeEmail: 'Remove email address',
footerColumns: 'Footer columns',
footerColumnsDesc: 'Group links into columns, like a real footer. Drag columns and links to reorder them.',
footerColumnTitlePlaceholder: 'Column title, e.g. Company',
footerLinkLabelPlaceholder: 'Link text',
footerLinkExistingPage: 'Existing page',
footerLinkCustomUrl: 'Custom URL',
addColumn: 'Add column',
removeColumn: 'Remove column',
addColumnLink: 'Add link',
removeColumnLink: 'Remove link',
sectionVisibleDesc: 'Whether this homepage section is shown to shoppers.',
layoutStrategyLabel: 'Layout strategy',
layoutStrategyDesc: 'How widgets inside this section are arranged.',
layoutStrategyStack: 'Stack',
layoutStrategyStackDesc: 'Widgets stack vertically, one after another.',
layoutStrategyGrid: 'Grid',
layoutStrategyGridDesc: 'Widgets arrange in a multi-column grid.',
layoutStrategyHero: 'Hero',
layoutStrategyHeroDesc: 'A single large, full-width promotional layout.',
layoutStrategyCarousel: 'Carousel',
layoutStrategyCarouselDesc: 'Widgets scroll horizontally as a carousel.',
layoutStrategySplit: 'Split',
layoutStrategySplitDesc: 'Content is split into two side-by-side panes.',
sectionColumnsDesc: 'Number of columns to use when the layout strategy supports columns.',
widgetLayoutDesc: 'Free-text layout variant name understood by this widget (e.g. "full-bleed", "boxed").',
widgetHeightDesc: 'Preferred height for this widget (e.g. "480px" or "60vh").',
widgetOverlayDesc: 'Show a dark overlay behind hero text for readability.',
widgetAutoplayDesc: 'Automatically rotate hero slides without shopper interaction.',
widgetColumnsDesc: 'Number of category tiles per row.',
widgetCardsPerRowDesc: 'Number of product cards shown per row.',
widgetFiltersDesc: 'Show filter controls alongside the product collection.',
widgetShowBadgesDesc: 'Show badges such as "New" or "Sale" on product cards.',
widgetShowRatingDesc: 'Show the star rating on product cards.',
widgetShowPriceDesc: 'Show the price on product cards.',
widgetJsonDesc: 'Raw widget properties as JSON. Used when no dedicated editor exists for this widget type.',
widgetJsonInvalid: 'Invalid JSON - the last valid version is still saved.',
wishlistFeatureDesc: 'Let shoppers save products to a wishlist.',
compareFeatureDesc: 'Let shoppers compare multiple products side by side.',
reviewsFeatureDesc: 'Let shoppers leave and read product reviews.',
questionsFeatureDesc: 'Let shoppers ask and read product questions and answers.',
commentsFeatureDesc: 'Enable general comments on marketplace content.',
recommendationsFeatureDesc: 'Show recommended-product blocks across the storefront.',
recentlyViewedFeatureDesc: 'Show a "recently viewed" product list to shoppers.',
searchSuggestionsDesc: 'Show live search suggestions as shoppers type.',
searchHistoryDesc: 'Remember and show a shopper\'s recent searches.',
catalogNavigationModeLabel: 'Catalog navigation mode',
catalogNavigationModeDesc: 'How shoppers navigate categories in the catalog.',
catalogNavDefault: 'Default',
catalogNavDefaultDesc: 'Standard breadcrumb-driven category navigation.',
catalogNavLeftCategory: 'Left category navigation',
catalogNavLeftCategoryDesc: 'Persistent category tree in a left-hand sidebar.',
catalogNavMegaCategory: 'Mega category layout',
catalogNavMegaCategoryDesc: 'Expanded dropdown showing subcategories and featured items.',
catalogNavTopCarousel: 'Top category carousel',
catalogNavTopCarouselDesc: 'Horizontally scrollable category chips above the catalog grid.',
newLanguageDesc: 'ISO language code to add as a supported storefront language (e.g. de, fr).',
languageAlreadyAdded: 'This language is already supported.',
languagesTabDesc: 'Languages available to shoppers. The default language is used as a fallback everywhere.',
linkLabelDesc: 'Text shown for this navigation link.',
linkUrlDesc: 'Path or URL this navigation link points to.',
linkVisibleDesc: 'Whether this navigation link is shown to shoppers.',
feat(builder): redesign marketplace builder experience and navigation Renamed the experience consistently to Marketplace Builder everywhere visible (page title/subtitle, breadcrumbs, sidebar, dashboard quick action/shortcut copy) - internal ProjectEditor class/selector names kept as-is to avoid regressions. builder.title/subtitle no longer say 'bootstrap-config editing surface' to end users. New business-oriented IA (builder-groups.model.ts): 12 existing ProjectEditorSectionIds regrouped into 8 groups (Marketplace, Branding and Design, Homepage, Content, Languages, Marketplace Features, Navigation and Search, Preview) - every existing section mapped to exactly one group, none dropped, no group points at a page that doesn't exist. New Builder landing page at /edit (was a redirect straight into the General form): readiness percent, recommended next step, one overview card per group (purpose + real complete/in-progress/not-started/unknown status, icon+text never color-alone), a Marketplace Readiness checklist, quick links. All derived from real facade/schema signals (required-field fill state, modifiedSections, staticPages, catalog counts via BackofficeDataService) or explicitly marked unknown (the "preview reviewed" check has no tracking - shown as unknown, never guessed). Section pages (/edit/:section) now share one consistent header: breadcrumb (Builder > Group > Section), draft/published + modified badges, and a contextual help panel (what is this / where visible / what happens if you skip it) sourced per group. Sidebar nav rewritten as grouped, icon-led sections with per-section and per-group status indicators; layout converted from a top pill-tab bar to a responsive sidebar (desktop 280px, tablet 72px icon rail, mobile drawer with Escape-to-close), matching the Sprint 1 admin shell pattern. Section form components themselves untouched. Routes: 'edit' is now its own landing route instead of redirecting to 'edit/general'; /builder and /project-editor redirect to 'edit'. Sprint 1/2 destinations that pointed at edit/general now point at the new edit landing page. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 09:43:03 +04:00
appName: 'Marketplace Builder',
backToDashboard: 'Back to dashboard',
languagesSummaryDesc: 'Languages your marketplace is available in. The first one is what customers see by default.',
manageLanguages: 'Manage languages',
htmlToolBold: 'Bold',
htmlToolItalic: 'Italic',
htmlToolUnderline: 'Underline',
htmlToolHeading: 'Heading',
htmlToolSubheading: 'Subheading',
htmlToolBulletList: 'Bulleted list',
htmlToolNumberedList: 'Numbered list',
htmlToolLink: 'Insert link',
htmlToolImage: 'Insert image',
htmlToolTable: 'Insert table',
htmlToolDivider: 'Divider line',
htmlToolCodeBlock: 'Code block',
htmlToolEmbed: 'Embed video',
feat(builder): redesign marketplace builder experience and navigation Renamed the experience consistently to Marketplace Builder everywhere visible (page title/subtitle, breadcrumbs, sidebar, dashboard quick action/shortcut copy) - internal ProjectEditor class/selector names kept as-is to avoid regressions. builder.title/subtitle no longer say 'bootstrap-config editing surface' to end users. New business-oriented IA (builder-groups.model.ts): 12 existing ProjectEditorSectionIds regrouped into 8 groups (Marketplace, Branding and Design, Homepage, Content, Languages, Marketplace Features, Navigation and Search, Preview) - every existing section mapped to exactly one group, none dropped, no group points at a page that doesn't exist. New Builder landing page at /edit (was a redirect straight into the General form): readiness percent, recommended next step, one overview card per group (purpose + real complete/in-progress/not-started/unknown status, icon+text never color-alone), a Marketplace Readiness checklist, quick links. All derived from real facade/schema signals (required-field fill state, modifiedSections, staticPages, catalog counts via BackofficeDataService) or explicitly marked unknown (the "preview reviewed" check has no tracking - shown as unknown, never guessed). Section pages (/edit/:section) now share one consistent header: breadcrumb (Builder > Group > Section), draft/published + modified badges, and a contextual help panel (what is this / where visible / what happens if you skip it) sourced per group. Sidebar nav rewritten as grouped, icon-led sections with per-section and per-group status indicators; layout converted from a top pill-tab bar to a responsive sidebar (desktop 280px, tablet 72px icon rail, mobile drawer with Escape-to-close), matching the Sprint 1 admin shell pattern. Section form components themselves untouched. Routes: 'edit' is now its own landing route instead of redirecting to 'edit/general'; /builder and /project-editor redirect to 'edit'. Sprint 1/2 destinations that pointed at edit/general now point at the new edit landing page. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 09:43:03 +04:00
breadcrumbRoot: 'Marketplace Builder',
statusComplete: 'Complete',
statusInProgress: 'In progress',
statusNotStarted: 'Not started',
statusUnknown: 'Not tracked yet',
draftBadge: 'Draft',
publishedBadge: 'Published',
modifiedBadge: 'Unsaved changes',
helpToggleShow: 'What is this?',
helpToggleHide: 'Hide help',
helpWhatIsThis: 'What is this',
helpWhySkip: 'Why configure it',
helpWhereVisible: 'Where shoppers see it',
helpWhatIfSkip: "What happens if you skip it",
helpWhenReturn: 'When to come back to this',
openSidebar: 'Open sections menu',
closeSidebar: 'Close sections menu',
overviewTitle: 'Marketplace Builder',
overviewSubtitle: 'Build your marketplace step by step',
overviewReadinessLabel: 'Your marketplace is {{percent}}% configured',
overviewReadinessHint: 'Based on the required fields you have filled in so far.',
overviewNextStepLabel: 'Recommended next step',
overviewNextStepFallback: 'All required steps are done - you are ready to publish.',
overviewQuickLinksTitle: 'Quick links',
overviewSectionsTitle: 'Builder sections',
overviewOpenSection: 'Open section',
overviewReadinessTitle: 'Marketplace readiness',
readinessLogoUploaded: 'Logo uploaded',
readinessHomepageConfigured: 'Homepage configured',
readinessThemeConfigured: 'Theme configured',
readinessLanguagesConfigured: 'Languages configured',
readinessContentPagesAdded: 'Info pages added',
readinessPreviewReviewed: 'Preview reviewed',
readinessPublished: 'Marketplace published',
readinessCategoriesExist: 'Categories exist',
readinessProductsExist: 'Products exist',
groupMarketplaceLabel: 'Marketplace',
groupMarketplaceDescription: 'Name, address, and the core details of your marketplace.',
groupMarketplacePurpose: 'The basic information that defines your marketplace: name, domain, and default language.',
groupMarketplaceWhere: 'The name and address show up in the browser tab, search results, and every storefront page.',
groupMarketplaceSkip: "Without a name and address, your marketplace won't feel finished to shoppers.",
groupBrandingLabel: 'Branding & Design',
groupBrandingDescription: 'Logo, colors, header and footer - your store\'s visual identity.',
groupBrandingPurpose: "Set how your marketplace looks: logo, color palette, and the header/footer chrome.",
groupBrandingWhere: 'Changes show up on every page a shopper sees.',
groupBrandingSkip: "Your marketplace will use default styling that doesn't reflect your brand.",
groupHomepageLabel: 'Homepage',
groupHomepageDescription: 'The banners, showcases, and widgets shoppers see first.',
groupHomepagePurpose: 'Build your homepage from blocks: a hero banner, featured categories and products, promotions.',
groupHomepageWhere: "It's the first page a shopper sees when they open your marketplace.",
groupHomepageSkip: 'Your homepage will stay empty or use a default layout.',
groupContentLabel: 'Content',
groupContentDescription: 'About us, contacts, delivery, returns, and other info pages.',
groupContentPurpose: 'Add the pages shoppers trust: about us, contacts, delivery and return terms.',
groupContentWhere: "Links to these pages usually appear in the site footer.",
groupContentSkip: "Shoppers won't find answers about delivery, returns, or how to contact you - that hurts trust.",
groupLanguagesLabel: 'Languages',
groupLanguagesDescription: 'Which languages your marketplace works in.',
groupLanguagesPurpose: 'Pick a default language and add more for shoppers in other regions.',
groupLanguagesWhere: 'The language switcher is visible in the header on every page.',
groupLanguagesSkip: 'Your marketplace will only be available in the default language.',
groupFeaturesLabel: 'Marketplace Features',
groupFeaturesDescription: 'Wishlist, compare, reviews, guest checkout, and more.',
groupFeaturesPurpose: 'Turn shopper-facing features on or off: wishlist, product comparison, guest checkout.',
groupFeaturesWhere: 'Affects the catalog, product, and checkout pages.',
groupFeaturesSkip: 'Your marketplace will use the default feature set.',
groupNavigationLabel: 'Navigation & Search',
groupNavigationDescription: "The site menu and how shoppers find products.",
groupNavigationPurpose: 'Configure the menu items and how catalog navigation is structured.',
groupNavigationWhere: 'Visible in the site header on every page.',
groupNavigationSkip: 'Shoppers will use the default navigation.',
groupPreviewLabel: 'Preview',
groupPreviewDescription: 'See how your marketplace looks on desktop, tablet, and phone.',
groupPreviewPurpose: 'Check your marketplace through a shopper\'s eyes before publishing - across screen sizes.',
groupPreviewWhere: "This is a preview - shoppers never see it.",
groupPreviewSkip: 'You can publish your changes without reviewing them first.',
feat(builder): implement professional brand management experience New BrandOverviewComponent, mounted at the top of the existing Branding section page (no route/schema/business-logic changes): - Completion ring + recommended next step + last-modified timestamp, computed from real facade signals (branding.logoUrl/faviconUrl/ socialImageUrl, theme.palette, theme.typography, lastSavedAt) - nothing fabricated. - Brand Health checklist (6 items: logo, favicon, colors, typography, social image, accessibility) - icon+text, never color alone. - Color palette preview: 10 swatches from the real ThemePaletteConfig (primary/secondary/accent/success/warning/danger/backgrounds/text/ border), each with a readable label. - Real WCAG contrast check (contrast.util.ts, relative-luminance formula) between configured text and background colors - shows an inline warning when below 4.5:1, never blocks publishing. - Typography live preview using the configured heading/body font families and base size. - Social share preview card (Open Graph-style) using the existing socialImageUrl + seo.default.title/description, with an explicit empty state when no image is set yet. Scope cut from the full brief given this session's cost already well over budget entering this sprint - see Known limitations in the final report (no multi-variant logo/favicon management, no live responsive device preview, no new media library/asset picker; all reuse the existing single-logo/single-favicon fields and image-field upload component as-is). Could not verify live in-browser this sprint: port 4200 is held by another chat's dev server. Verified via `tsc --noEmit` (clean) and manual template/binding review only; one binding (`--pct` custom- property style binding) was replaced with a plain computed string to remove an unverifiable risk rather than ship it unverified. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 10:13:35 +04:00
brandOverviewTitle: 'Brand identity',
brandOverviewSubtitle: 'The logo, colors, and fonts shoppers see on every page.',
brandOverviewComplete: 'Your brand is fully set up.',
brandLastModified: 'Last modified',
brandFaviconUploaded: 'Favicon uploaded',
brandColorsSelected: 'Brand colors selected',
brandTypographyConfigured: 'Typography configured',
brandSocialImageUploaded: 'Social share image uploaded',
brandAccessibilityPassed: 'Text contrast looks good',
brandColorsPreviewTitle: 'Marketplace colors',
brandTypographyPreviewTitle: 'Typography',
brandSocialPreviewTitle: 'How this looks when shared',
brandTypeSampleHeading: 'Sample heading',
brandTypeSampleBody: 'Sample body text the way shoppers will see it.',
brandContrastWarning: 'This text is hard to read against the background - consider higher-contrast colors. This will not block publishing.',
brandSocialEmpty: "No social share image yet - shared links will show a blank card until you add one.",
brandAccentColor: 'Accent',
brandBorderColor: 'Borders',
homepageOverviewTitle: 'Homepage',
homepageOverviewSubtitle: "What your marketplace's homepage is made of.",
homepageOverviewComplete: 'Your homepage is fully set up.',
homepageActiveSections: 'Active sections',
homepageDisabledSections: 'Hidden sections',
homepageHealthHero: 'Hero banner added',
homepageHealthCategories: 'Featured categories added',
homepageHealthProducts: 'Featured products added',
homepageHealthPromotion: 'Promotion block added',
homepageHealthNewsletter: 'Newsletter signup added',
homepageHealthAnySections: 'The page has at least one section',
widgetTypeHero: 'Hero banner',
widgetTypeCategories: 'Featured categories',
widgetTypeProducts: 'Featured products',
widgetHidden: 'Hidden',
widgetVisible: 'Show',
widgetMoveUp: 'Move up',
widgetMoveDown: 'Move down',
widgetDuplicate: 'Duplicate',
widgetRemove: 'Remove',
widgetRemoveConfirm: 'Remove this section from the homepage?',
widgetAdvancedSettings: 'Advanced settings',
},
dashboard: {
title: 'Dashboard',
subtitle: 'Overview of your marketplace',
cardMarketplaceStatus: 'Marketplace Status',
cardProjectName: 'Project Name',
cardCurrentTheme: 'Current Theme',
cardLanguages: 'Languages',
cardCategoriesCount: 'Categories',
cardProductsCount: 'Products',
cardOrders: 'Orders',
cardRevenue: 'Revenue',
cardLastPublish: 'Last Publish',
cardLastDraftSave: 'Last Draft Save',
cardBootstrapVersion: 'Bootstrap Version',
cardActiveLayout: 'Active Layout',
cardEnabledWidgets: 'Enabled Widgets',
stateLoading: 'Loading...',
stateEmpty: 'No data yet',
stateError: 'Could not load this card',
statePendingBackend: 'Awaiting backend integration',
never: 'Never',
quickActionsTitle: 'Quick Actions',
feat(builder): redesign marketplace builder experience and navigation Renamed the experience consistently to Marketplace Builder everywhere visible (page title/subtitle, breadcrumbs, sidebar, dashboard quick action/shortcut copy) - internal ProjectEditor class/selector names kept as-is to avoid regressions. builder.title/subtitle no longer say 'bootstrap-config editing surface' to end users. New business-oriented IA (builder-groups.model.ts): 12 existing ProjectEditorSectionIds regrouped into 8 groups (Marketplace, Branding and Design, Homepage, Content, Languages, Marketplace Features, Navigation and Search, Preview) - every existing section mapped to exactly one group, none dropped, no group points at a page that doesn't exist. New Builder landing page at /edit (was a redirect straight into the General form): readiness percent, recommended next step, one overview card per group (purpose + real complete/in-progress/not-started/unknown status, icon+text never color-alone), a Marketplace Readiness checklist, quick links. All derived from real facade/schema signals (required-field fill state, modifiedSections, staticPages, catalog counts via BackofficeDataService) or explicitly marked unknown (the "preview reviewed" check has no tracking - shown as unknown, never guessed). Section pages (/edit/:section) now share one consistent header: breadcrumb (Builder > Group > Section), draft/published + modified badges, and a contextual help panel (what is this / where visible / what happens if you skip it) sourced per group. Sidebar nav rewritten as grouped, icon-led sections with per-section and per-group status indicators; layout converted from a top pill-tab bar to a responsive sidebar (desktop 280px, tablet 72px icon rail, mobile drawer with Escape-to-close), matching the Sprint 1 admin shell pattern. Section form components themselves untouched. Routes: 'edit' is now its own landing route instead of redirecting to 'edit/general'; /builder and /project-editor redirect to 'edit'. Sprint 1/2 destinations that pointed at edit/general now point at the new edit landing page. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 09:43:03 +04:00
actionEditProject: 'Marketplace Builder',
actionCategories: 'Categories',
actionProducts: 'Products',
actionStaticPages: 'Static Pages',
actionTransactions: 'Transactions',
actionOrders: 'Orders',
actionMediaLibrary: 'Media Library',
actionUsers: 'Users & Permissions',
actionMonitoring: 'Monitoring',
actionAnalytics: 'Analytics',
actionPreviewMarketplace: 'Preview Marketplace',
activityTitle: 'Recent Activity',
feat(admin): redesign dashboard into professional SaaS homepage Replaced the placeholder dashboard with a real business homepage built on 6 new reusable widget components (DashboardSection, DashboardCard, DashboardMetric, DashboardStatusRow, DashboardTimeline, DashboardShortcutCard), all wired through shared app-card/app-skeleton/ app-empty-state. Sections: Welcome (tenant, env badge, current user, last publish/save - all real facade signals, never blank), Quick Actions (large cards: add product, create category, open builder, edit homepage, media, orders), Draft Status (real dirty/modifiedFields/publish/discard from ProjectEditorFacade), Marketplace Health (9 checks - config, product/ category counts, missing translations, draft, static-pages-unpublished, homepage/theme configured, all real; images-without-alt shown as 'not tracked yet' rather than fabricated), Recent Activity (existing localStorage-backed history service, loading/empty states), Useful Shortcuts, Documentation (honest coming-soon list, no dead links). 12-column responsive grid: 3-across cards on desktop, 2-column on tablet, single column on mobile, no horizontal scroll. Keyboard/focus/ ARIA per shortcut card and status row; health status never conveyed by color alone (icon + text every time). AdminDashboardHealthCheck (boolean 'healthy' shape) and its facade signal are untouched - AdminMonitoringPageComponent also consumes them. New richer status data lives in a separate homeHealthChecks signal/ AdminDashboardHomeHealthCheck type instead of widening the shared one. Added ~50 new dashboard.* / kept existing i18n strings across ru/en/hy; no raw keys. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 08:59:29 +04:00
activityEmpty: 'No activity yet',
activityDraftSaved: 'Draft saved',
activityPublished: 'Published',
healthTitle: 'System Health',
healthAllClear: 'All checks passed',
healthBootstrapValid: 'Bootstrap valid',
healthConfigurationValid: 'Configuration valid',
healthMissingTranslations: 'Missing translations',
healthInvalidColors: 'Invalid colors',
healthInvalidWidgetReferences: 'Invalid widget references',
healthInvalidLayouts: 'Invalid layouts',
comingSoonTitle: 'Coming soon',
comingSoonDescription: 'This section is not built yet. Check back in a future update.',
backToDashboard: 'Back to dashboard',
feat(admin): redesign dashboard into professional SaaS homepage Replaced the placeholder dashboard with a real business homepage built on 6 new reusable widget components (DashboardSection, DashboardCard, DashboardMetric, DashboardStatusRow, DashboardTimeline, DashboardShortcutCard), all wired through shared app-card/app-skeleton/ app-empty-state. Sections: Welcome (tenant, env badge, current user, last publish/save - all real facade signals, never blank), Quick Actions (large cards: add product, create category, open builder, edit homepage, media, orders), Draft Status (real dirty/modifiedFields/publish/discard from ProjectEditorFacade), Marketplace Health (9 checks - config, product/ category counts, missing translations, draft, static-pages-unpublished, homepage/theme configured, all real; images-without-alt shown as 'not tracked yet' rather than fabricated), Recent Activity (existing localStorage-backed history service, loading/empty states), Useful Shortcuts, Documentation (honest coming-soon list, no dead links). 12-column responsive grid: 3-across cards on desktop, 2-column on tablet, single column on mobile, no horizontal scroll. Keyboard/focus/ ARIA per shortcut card and status row; health status never conveyed by color alone (icon + text every time). AdminDashboardHealthCheck (boolean 'healthy' shape) and its facade signal are untouched - AdminMonitoringPageComponent also consumes them. New richer status data lives in a separate homeHealthChecks signal/ AdminDashboardHomeHealthCheck type instead of widening the shared one. Added ~50 new dashboard.* / kept existing i18n strings across ru/en/hy; no raw keys. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 08:59:29 +04:00
welcomeEyebrow: 'Welcome back',
welcomeFallbackTenant: 'Your marketplace',
envProduction: 'Production',
envDevelopment: 'Development',
factCurrentUser: 'Current user',
factTenant: 'Store',
quickActionsDescription: 'Your most common tasks - start here',
actionAddProduct: 'Add product',
actionAddProductDescription: 'Create a new product listing',
actionCreateCategory: 'Create category',
actionCreateCategoryDescription: 'Add a category to the catalog',
actionEditProjectDescription: 'Open the marketplace builder',
actionEditHomepage: 'Edit homepage',
actionEditHomepageDescription: 'Configure the homepage widgets',
actionMediaLibraryDescription: 'Upload and organize files',
actionOrdersDescription: 'Review recent orders',
draftStatusTitle: 'Draft status',
draftStatusHasChanges: 'There are unpublished changes waiting to go live.',
draftStatusAllPublished: 'Everything published. No draft in progress.',
draftStatusMoreFields: '+{{count}} more',
draftOpenBuilder: 'Open builder',
draftPublish: 'Publish',
draftDiscard: 'Discard draft',
healthProductsCount: 'Products',
healthCategoriesCount: 'Categories',
healthDraftExists: 'Draft',
healthImagesWithoutAlt: 'Images missing alt text',
healthStaticPagesUnpublished: 'Unpublished static pages',
healthHomepageConfigured: 'Homepage configured',
healthThemeConfigured: 'Theme configured',
statusHealthy: 'Healthy',
statusAttention: 'Needs attention',
statusUnhealthy: 'Issue',
statusUnknown: 'Not tracked yet',
activityEmptyHint: 'Save or publish a change to see it appear here.',
activityUnavailable: 'Activity history unavailable',
activityUnavailableHint: "Couldn't reach the activity data source. Try refreshing later.",
activityErrorHint: "Couldn't load recent activity.",
shortcutsTitle: 'Useful shortcuts',
shortcutsDescription: 'Frequently used destinations across the admin panel',
shortcutMarketplaceBuilder: 'Marketplace Builder',
shortcutSettings: 'Settings',
shortcutContent: 'Content',
docTitle: 'Documentation',
docDocumentation: 'Documentation',
docKeyboardShortcuts: 'Keyboard shortcuts',
docReportIssue: 'Report an issue',
docReleaseNotes: 'Release notes',
},
2026-07-10 13:52:01 +04:00
staticPages: {
notFound: 'Page not found',
backHome: 'Back to home',
duplicateSlug: 'Duplicate slugs are not allowed.',
emptyTitle: 'Each page must have at least one title.',
feat(static-pages): CRUD completion + search/filter/bulk actions Milestone 2 of the Static Pages Module sprint. - StaticPagesEditorComponent: duplicate page, confirm-before-delete/bulk- delete (matches the resetDraft confirm pattern), route/enabled/customTemplate/ media(hero/thumbnail/gallery) fields wired into the card, per-page publish/ unpublish action, status + duplicate-route/invalid-html/invalid-seo badges. - Search (id/slug/route/title across all locales), filter by status (draft/published) and by locale (hides pages missing a translation for the selected locale) - all local computed() filters, no new service. - Bulk selection (per-row + select-all-visible checkboxes) with bulk delete/ enable/disable/publish/unpublish, one updateBootstrap() call each. - Correctness note: introduced `allPages` (unfiltered) vs `pages` (filtered view) computeds. Every mutation (create/duplicate/delete/move/bulk) reads from allPages(), never the filtered pages() - reading from the filtered view would have silently deleted whatever an active search/filter hid on the next persist(). Documented inline on persist() as a guardrail for future edits. - Fixed a template compile error found by the build gate: Angular templates don't support inline arrow functions in binding expressions ((ngModelChange)="...map(v => v.trim())..." failed to parse) - moved the gallery CSV-parsing into a component method (updateGallery). - SEO robots field added to the page card (validated against a known-token set from M1). - i18n: staticPages.* extended (search/filter/bulk/route/enabled/status/ media/robots/disabled labels) across the interface + en/ru/hy. Gate: tsc --noEmit, npm test (57/57), arch:check, build all green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 09:55:21 +04:00
duplicateRoute: 'Two or more pages share the same route.',
invalidHtml: 'This page has malformed HTML content.',
invalidSeo: 'This page has an invalid SEO field (canonical/OG image URL or robots value).',
searchPlaceholder: 'Search pages…',
filterAll: 'All statuses',
filterAllLocales: 'All languages',
confirmDeletePage: 'Delete this page? This cannot be undone.',
confirmBulkDelete: 'Delete the selected pages? This cannot be undone.',
duplicatePage: 'Duplicate',
selectAll: 'Select all',
selectedCount: 'selected',
bulkDelete: 'Delete selected',
bulkEnable: 'Enable selected',
bulkDisable: 'Disable selected',
bulkPublishAction: 'Publish selected',
bulkUnpublish: 'Unpublish selected',
routeLabel: 'Route',
enabledLabel: 'Enabled',
statusLabel: 'Status',
publishPageAction: 'Publish page',
unpublishPageAction: 'Unpublish page',
heroImageLabel: 'Hero image',
thumbnailLabel: 'Thumbnail',
galleryLabel: 'Gallery',
customTemplateLabel: 'Custom template',
seoRobotsLabel: 'Robots',
disabledBadge: 'Disabled',
previewDesktop: 'Desktop',
previewTablet: 'Tablet',
previewMobile: 'Mobile',
previewToggle: 'Preview',
2026-07-10 13:52:01 +04:00
},
contentManagement: {
publishedPages: 'Published pages',
draftPages: 'Draft pages',
missingLegalPages: 'Missing legal pages',
seoHealth: 'SEO health',
lastEdited: 'Last edited',
lastEditedNever: 'Never',
completionLabel: 'Completion',
recommendedNext: 'Recommended next step',
recommendAddTitles: 'Some pages are missing a title in at least one language.',
recommendFixSeo: 'A page has an SEO field that needs fixing (canonical/OG image URL or robots value).',
recommendPublish: 'A required legal page is still a draft — publish it so customers can see it.',
recommendNone: 'Nice work — your content is in good shape.',
openAction: 'Open',
backToPages: 'Back to pages',
groupContent: 'Content',
groupSeo: 'SEO',
groupSharing: 'Sharing',
groupAdvanced: 'Advanced',
groupAdvancedHtml: 'Raw HTML (advanced)',
seoExplainDesc: 'This is what shows up in search results — a clear title and description help customers find this page.',
seoTitleHelp: 'The headline shown in search results. Keep it short and descriptive.',
seoDescriptionHelp: 'A short summary shown under the title in search results.',
seoCanonicalHelp: 'The official web address for this page, used to avoid duplicate-content issues.',
seoRobotsHelp: 'Controls whether search engines are allowed to list this page.',
sharingExplain: 'This is how the page looks when shared on social media (Facebook, Twitter/X, and others).',
mediaSelect: 'Choose image',
mediaReplace: 'Replace',
mediaRemove: 'Remove',
mediaAlt: 'Alt text',
mediaCaption: 'Caption',
emptyStateGuideTitle: 'Start building your storefront pages',
emptyStateGuideBody: 'Legal pages like About, Privacy, and Terms build trust with customers. We recommend publishing About, Contacts, Privacy, and Terms first, then adding Cookies, Delivery, Returns, and FAQ.',
seoStatusGood: 'SEO good',
seoStatusPartial: 'SEO partial',
seoStatusWarning: 'SEO issue',
seoStatusMissing: 'SEO missing',
needsAttention: 'Needs attention',
legal: {
about: { label: 'About', why: 'Tells customers who you are and builds trust before they buy.' },
contacts: { label: 'Contacts', why: 'Gives customers a way to reach you with questions or issues.' },
privacy: { label: 'Privacy', why: 'Explains how customer data is handled — often legally required.' },
terms: { label: 'Terms', why: 'Sets the rules for using your store — protects you and your customers.' },
cookies: { label: 'Cookies', why: 'Discloses cookie usage, required in many regions.' },
delivery: { label: 'Delivery', why: 'Sets clear shipping expectations and reduces support requests.' },
returns: { label: 'Returns', why: 'Explains your refund policy and builds purchase confidence.' },
faq: { label: 'FAQ', why: 'Answers common questions before customers have to ask.' },
},
},
widgets: {
unavailable: 'Widget unavailable',
},
2026-02-26 23:09:20 +04:00
carousel: {
loading: 'Loading products...',
addToCart: 'Add to cart',
},
common: {
retry: 'Try again',
loading: 'Loading...',
remove: 'Remove',
2026-02-26 23:09:20 +04:00
},
2026-02-28 17:18:24 +04:00
location: {
allRegions: 'All regions',
chooseRegion: 'Choose region',
detectAuto: 'Detect automatically',
},
auth: {
loginRequired: 'Login required',
loginDescription: 'Please log in via Telegram to proceed with your order',
checking: 'Checking...',
loginWithTelegram: 'Log in with Telegram',
orScanQr: 'Or scan the QR code',
loginNote: 'You will be redirected back after login',
2026-03-25 15:32:50 +04:00
qrExpired: 'QR code expired. Click to refresh',
2026-06-01 00:47:26 +04:00
qrError: 'Could not create login session. Click to retry',
2026-02-28 17:18:24 +04:00
},
ux: {
items: 'items',
wishlistTitle: 'Wishlist',
wishlistEmptyTitle: 'Your wishlist is empty',
wishlistEmptyDescription: 'Save products to revisit them anytime.',
clearWishlist: 'Clear wishlist',
wishlistCleared: 'Wishlist cleared',
compareTitle: 'Compare Products',
compareEmptyTitle: 'No products to compare',
compareEmptyDescription: 'Add products from catalog cards to compare specs and prices.',
clearCompare: 'Clear compare',
hideIdentical: 'Hide identical values',
highlightDifferences: 'Highlight differences',
clearRecentlyViewed: 'Clear recently viewed',
recentlyViewedEmpty: 'No recently viewed products yet.',
saveSearch: 'Save search',
goToCatalog: 'Go to catalog',
2026-07-09 01:40:22 +04:00
wishlistAdded: 'Added to wishlist',
wishlistRemoved: 'Removed from wishlist',
compareAdded: 'Added to compare',
compareRemoved: 'Removed from compare',
compareLimitReached: 'Compare limit reached ({{maxItems}})',
productShared: 'Product shared',
productLinkCopied: 'Product link copied',
sharingUnsupported: 'Sharing is not supported on this device',
addedToCart: 'Added to cart',
2026-07-09 01:40:22 +04:00
enterQueryBeforeSave: 'Enter a search query before saving',
savedSearchNamed: 'Saved search: {{name}}',
recentlyViewedTitle: 'Recently Viewed',
compareAttribute: 'Attribute',
comparePrice: 'Price',
compareRating: 'Rating',
compareStock: 'Stock',
compareDiscount: 'Discount',
compareColor: 'Color',
compareSize: 'Size',
compareUnknown: 'unknown',
},
2026-07-10 13:34:25 +04:00
diagnostics: {
title: 'Marketplace Diagnostics',
disabledTitle: 'Diagnostics unavailable',
disabledDescription: 'Diagnostics page is available only in development mode.',
generatedAt: 'Generated at {{value}}',
healthScore: 'Health score',
summary: 'Summary',
passedChecks: '{{count}} passed checks',
warnings: '{{count}} warnings',
errors: '{{count}} errors',
critical: '{{count}} critical',
healthChecks: 'Health checks',
results: 'Detailed results',
noIssues: 'No diagnostics issues found.',
ok: 'OK',
failed: 'Failed',
affectedComponent: 'Affected component',
suggestedResolution: 'Suggested resolution',
severity: {
info: 'Info',
warning: 'Warning',
error: 'Error',
critical: 'Critical',
},
checks: {
bootstrapLoaded: 'Bootstrap loaded',
tenantResolved: 'Tenant resolved',
runtimeInitialized: 'Runtime initialized',
themeLoaded: 'Theme loaded',
widgetManifestLoaded: 'Widget manifest loaded',
sectionEngineInitialized: 'Section engine reachable',
configurationEngineInitialized: 'Configuration engine initialized',
translationResourcesAvailable: 'Translations available',
requiredAssetsAvailable: 'Required assets healthy',
},
bootstrapMissingTitle: 'Bootstrap missing',
bootstrapMissingDescription: 'Bootstrap configuration could not be loaded.',
bootstrapMissingResolution: 'Verify bootstrap provider response and local mock availability.',
requiredPropertyMissingTitle: 'Required property missing',
requiredPropertyMissingDescription: 'Required bootstrap property is missing.',
requiredPropertyMissingResolution: 'Add missing property to bootstrap payload.',
unknownWidgetTypeTitle: 'Unknown widget type',
unknownWidgetTypeDescription: 'Widget type is not present in widget manifest.',
unknownWidgetTypeResolution: 'Register widget in manifest or remove invalid widget config.',
duplicateIdTitle: 'Duplicate identifier',
duplicatePageIdDescription: 'Duplicate page id detected.',
duplicateSectionIdDescription: 'Duplicate section id detected.',
duplicateWidgetIdDescription: 'Duplicate widget id detected.',
duplicateIdResolution: 'Ensure ids are unique within bootstrap config.',
unknownLayoutTitle: 'Unknown layout',
unknownLayoutDescription: 'Page layout value is not recognized.',
unknownLayoutResolution: 'Use supported layout or extend diagnostics allow-list.',
invalidFeatureFlagTitle: 'Invalid feature flag',
invalidFeatureFlagDescription: 'Feature flag value must be boolean.',
invalidFeatureFlagResolution: 'Normalize feature flag values to true or false.',
brokenPageDefinitionTitle: 'Broken page definition',
brokenPageDefinitionDescription: 'Page definition is incomplete.',
brokenPageDefinitionResolution: 'Add missing route, title, key, or sections.',
invalidNavigationTargetTitle: 'Invalid navigation target',
invalidNavigationTargetDescription: 'Navigation route does not match known routes.',
invalidNavigationTargetResolution: 'Update route target or add matching route surface.',
missingTranslationTitle: 'Missing translation',
missingTranslationDescription: 'Translation key resolves to itself.',
missingTranslationResolution: 'Add missing key to translation resources.',
missingMediaTitle: 'Missing media',
missingMediaDescription: 'Expected branding media is missing.',
missingMediaResolution: 'Provide valid media URLs in bootstrap branding config.',
runtimeNotInitializedTitle: 'Runtime not initialized',
runtimeNotInitializedDescription: 'Platform runtime state has not been marked initialized.',
runtimeNotInitializedResolution: 'Verify PlatformRuntimeService initialize sequence.',
configFallbackUsageTitle: 'Configuration fallback in use',
configFallbackUsageDescription: 'Development runtime is using fallback or mock configuration.',
configFallbackUsageResolution: 'Switch provider mode if real bootstrap validation is needed.',
missingDatasourceTitle: 'Missing datasource',
missingDatasourceDescription: 'Widget supports datasource selection but none was declared.',
missingDatasourceResolution: 'Define source in widget props or manifest default settings.',
widgetRenderFailureTitle: 'Widget render failure',
widgetRenderFailureDescription: 'Widget fell back to unknown widget renderer.',
widgetRenderFailureResolution: 'Register widget component or fix manifest component key.',
brokenRouteTitle: 'Broken route expectation',
brokenRouteDescription: 'Expected route surface is missing.',
brokenRouteResolution: 'Restore route registration or update diagnostics expectation.',
imageLoadFailedTitle: 'Image load failed',
imageLoadFailedDescription: 'Rendered image failed to load.',
imageLoadFailedResolution: 'Verify asset path, CORS, and media availability.',
optionalDataMissingTitle: 'Optional data missing',
optionalDataMissingDescription: 'Optional configuration data is absent.',
optionalDataMissingResolution: 'Add optional value if UX depends on it.',
},
adminModeration: {
search: 'Search by customer, product, or review text…',
allStatuses: 'All statuses',
allRatings: 'All ratings',
rating: 'Rating',
customer: 'Customer',
product: 'Product',
reviewText: 'Review',
photos: 'Photos',
workflow: 'Actions',
approve: 'Approve',
reject: 'Reject',
markSpam: 'Mark as spam',
hide: 'Hide',
restore: 'Restore',
pin: 'Pin',
unpin: 'Unpin',
feature: 'Feature',
unfeature: 'Unfeature',
featureDisabledHint: 'Only approved reviews can be featured.',
moderatorNotes: 'Moderator notes',
notAvailable: 'Not available yet',
changeStatus: 'Change status',
hideSelected: 'Hide',
archiveSelected: 'Archive',
reportsQueue: 'Reports queue',
reportsColumn: 'Reports',
reportTarget: 'Reported item',
reportType: 'Type',
reportReason: 'Reason',
resolve: 'Resolve',
dismiss: 'Dismiss',
reportsEmptyTitle: 'No reports',
reportsEmptyDescription: 'Customer reports about products, reviews, or accounts will show up here.',
reportedCount: 'Reported',
averageRating: 'Average rating',
moderationHealth: 'Moderation health',
emptyTitle: 'No reviews yet',
emptyDescription: 'Reviews will appear here once customers start leaving feedback.',
emptyGuide: 'Customers leave a star rating and text after purchase. New reviews start as Pending until a moderator approves, rejects, or marks them as spam — approved reviews become visible on the storefront. Aim to clear the pending queue regularly.',
healthRating: 'Rating',
healthText: 'Text',
healthMedia: 'Media',
healthModeration: 'Moderated',
healthReportStatus: 'No open reports',
healthVisibility: 'Visible',
health: 'Health',
column_product: 'Product',
column_rating: 'Rating',
column_status: 'Status',
column_reports: 'Reports',
column_created: 'Submitted',
status: {
pending: 'Pending',
approved: 'Approved',
rejected: 'Rejected',
spam: 'Spam',
},
targetType: {
product: 'Product',
review: 'Review',
customer: 'Customer',
category: 'Category',
unknown: 'Unknown',
},
reportStatus: {
open: 'Open',
resolved: 'Resolved',
dismissed: 'Dismissed',
},
},
adminOrders: {
back: 'Back to orders',
search: 'Search by order number, name, email, or phone…',
export: 'Export',
view: 'View',
orderNumber: 'Order',
customer: 'Customer',
payment: 'Payment',
delivery: 'Delivery',
trackingNumber: 'Tracking number',
createdAt: 'Placed',
items: 'Items',
timeline: 'Timeline',
notes: 'Notes to customer',
internalNotes: 'Internal notes',
addNote: 'Add note',
changeStatus: 'Change status',
applyStatus: 'Apply',
archiveSelected: 'Archive',
printSelected: 'Print',
printInvoice: 'Print invoice',
requestRefund: 'Request refund',
cancelOrder: 'Cancel order',
confirmCancel: 'Cancel this order?',
confirmRefund: 'Request a refund for this order?',
emptyTitle: 'No orders yet',
emptyDescription: 'Orders will show up here as customers check out.',
column_customer: 'Customer',
column_status: 'Status',
column_payment: 'Payment',
column_total: 'Total',
column_created: 'Placed',
status: {
pending: 'Pending',
processing: 'Packing',
shipped: 'Shipping',
delivered: 'Completed',
cancelled: 'Cancelled',
refunded: 'Refunded',
},
paymentStatus: {
unpaid: 'Unpaid',
paid: 'Paid',
refund_requested: 'Refund requested',
refunded: 'Refunded',
},
ordersToday: 'Orders today',
paidCount: 'Paid',
customersCount: 'Customers',
returningCustomers: 'Returning customers',
averageOrder: 'Average order',
recentActivity: 'Recent activity',
noRecentActivity: 'No activity yet.',
alertStuckPending: 'orders have been pending for over 48 hours',
alertRefundRequested: 'orders have a refund request waiting',
},
adminCustomers: {
search: 'Search by name, email, or phone…',
name: 'Name',
email: 'Email',
phone: 'Phone',
orderCount: 'Orders',
lifetimeValue: 'Lifetime value',
returning: 'Returning',
profile: 'Profile',
statistics: 'Statistics',
firstOrder: 'First order',
lastOrder: 'Last order',
addresses: 'Addresses',
notes: 'Notes',
notesUnavailable: 'No customer-level notes yet — add a note on one of their orders instead.',
orders: 'Orders',
activity: 'Activity',
emptyTitle: 'No customers yet',
emptyDescription: 'Customers appear here once they place their first order.',
},
mediaLibrary: {
title: 'Media Library',
upload: 'Upload',
uploading: 'Uploading...',
searchPlaceholder: 'Search files...',
delete: 'Delete',
deleteConfirmTitle: 'Delete file?',
deleteConfirmBody: 'This cannot be undone.',
cancel: 'Cancel',
confirm: 'Delete',
emptyTitle: 'No files yet',
emptyDescription: 'Upload an image or document to get started.',
allFolders: 'All folders',
newFolder: 'New folder',
editTags: 'Edit tags',
totalAssets: 'Total assets',
logos: 'Logos',
unused: 'Unused',
storageUsed: 'Storage used',
altCoverage: 'Alt text coverage',
allTypes: 'All types',
typeImage: 'Images',
typeSvg: 'SVG',
typePdf: 'PDF',
sortRecent: 'Recent',
sortName: 'Name',
sortSize: 'Size',
viewMode: 'View',
viewGrid: 'Grid',
viewList: 'List',
dropHint: 'Drag and drop images here, or use Upload above.',
cancelUpload: 'Cancel',
retry: 'Retry',
errorTooLarge: 'That file is too large. Try a smaller file.',
errorUnsupportedType: 'That file type is not supported. Use JPG, PNG, WebP, GIF, SVG, or PDF.',
errorGeneric: 'Upload failed. Please try again.',
selectedCount: 'selected',
download: 'Download',
exportMetadata: 'Export metadata',
bulkDelete: 'Delete selected',
bulkDeleteConfirm: 'Delete the selected files? This cannot be undone.',
clearSelection: 'Clear selection',
guideCopy: 'Reusing an existing asset avoids duplicate uploads and keeps your storage tidy. For best results upload images around 1200×1200px for hero/banner use and compress large photos before uploading.',
missingAlt: 'Missing alt text',
usageCount: 'uses',
detailsTitle: 'Asset details',
filename: 'Filename',
format: 'Format',
fileSize: 'File size',
dimensions: 'Dimensions',
uploadDate: 'Uploaded',
lastUsed: 'Last used',
usageCountLabel: 'Usage count',
usedIn: 'Used in',
notUsed: 'Not currently used anywhere.',
unknownValue: 'Unknown',
altText: 'Alt text',
altTextHelp: 'Describes the image for screen readers and search engines.',
decorative: 'Decorative (no alt text needed)',
missingAltWarning: 'This image has no alt text and is not marked decorative — screen reader users wont know what it shows.',
caption: 'Caption',
description: 'Description',
usage: {
brand: 'Logo',
theme: 'Theme',
header: 'Header',
footer: 'Footer',
staticPage: 'Static page',
homepage: 'Homepage',
catalog: 'Catalog',
productPage: 'Product page',
widget: 'Widget',
company: 'Company info',
seo: 'SEO',
navigation: 'Navigation',
other: 'Other',
},
},
fix(static-pages): backfill enabled/status in export, fix missing i18n key Independent review pass over the Static Pages Module sprint (M1-M7), including live browser E2E per the task's own verification checklist. - ProjectEditorFacade.normalize() now backfills enabled/status on record-format static pages (defaulting missing values to enabled+published, same rule ContentPageService.normalizePage applies for display - mirrored rather than imported, to avoid a project-editor <-> content-management circular dependency since ContentManagementFacade already depends on this facade). Found live: exporting a page that predates this sprint and was never touched/re-saved in the current session produced JSON missing enabled/status entirely - the editor UI and storefront resolver both normalize-on-read so nothing was actually broken live, but Export/Import fidelity should match what the editor shows. Verified fixed live (export now includes "enabled":true,"status":"published" for an untouched legacy page) and via the full gate. - Added the missing adminCategories.chooseImage i18n key (interface + en/ru/hy). Found live: the media-picker "choose image" button rendered as the literal string "adminCategories.chooseImage" - a pre-existing, repo-wide bug (5 templates reference this key; none of the locale files ever defined it) that I propagated into a 3rd/4th/5th... well, 2 new occurrences by copying the existing branding-section/footer-section pattern into static-pages-editor. Fixed the actual defect (missing translation) rather than renaming the key, which would have required touching 2 unrelated admin components outside this sprint's scope. Live-verified this pass: Static Pages editor renders with all new fields; create page works (page count 4->confirmed); device preview toggles desktop/tablet/mobile widths correctly; navigation "Insert page link" creates a real type:'staticPage' nav item end-to-end (confirmed in the exported JSON); export includes all Sprint X+2 fields after the fix; no console errors throughout. Gate: tsc --noEmit, npm test (57/57), arch:check, build all green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 11:27:29 +04:00
adminCategories: {
chooseImage: 'Choose image',
replaceImage: 'Replace image',
feat(categories): implement professional category management experience Categories dashboard (real total/visible/hidden/empty/root/subcategory/missing-image/missing-SEO/last-modified/completion% stats, recommended next action); tree view is now a real expand/collapse hierarchy (state persisted via LocalStorageService) with keyboard navigation (arrow keys, jump-to-parent), search that force-expands and keeps only matching branches + their ancestors/descendants instead of silently dropping deep matches; added Table/Cards views alongside the tree with density and saved column visibility; real bulk actions (show/hide/delete/assign parent/assign image via the Media Library picker/duplicate via the existing createCategory call/CSV export) plus the pre-existing single-item actions; reusable CategoryHealthWidget (image/SEO/description/valid-parent/visibility/products-assigned + completion%); editor reorganized into General/Media/SEO/Visibility/Navigation/Attributes/Advanced tabs, media now uses the shared ImageFieldComponent, SEO explains fields in plain language with a live preview, Navigation tab shows real breadcrumb/children/visibility-based nav status, Attributes uses the shared KeyValueEditorComponent. Filled in the adminCategories i18n namespace (previously only 2 of ~90 referenced keys existed) across en/ru/hy. Also fixed the pre-existing bug where a filtered/searched category list could silently drop a matched descendant whose ancestor's title didn't match, by loading the full catalog once and filtering client-side.
2026-07-18 17:04:11 +04:00
search: 'Search categories…',
showDeleted: 'Show deleted',
create: 'Create category',
edit: 'Edit category',
title: 'Title',
slug: 'URL slug',
slugTaken: 'This slug is already used by another category.',
parent: 'Parent category',
noParent: 'No parent (top level)',
icon: 'Icon',
image: 'Image',
imageHint: 'Shown in category listings and navigation.',
description: 'Description',
items: 'products',
status: { draft: 'Draft', published: 'Published' },
restore: 'Restore',
saveDraft: 'Save draft',
publish: 'Publish',
confirmDelete: 'Delete this category? This cannot be undone.',
confirmLeaveUnsaved: 'You have unsaved changes. Leave without saving?',
deleteBlocked: 'This category can\'t be deleted while it has subcategories or assigned products.',
emptyTitle: 'No categories yet',
emptyDescription: 'Create your first category to start organizing products.',
emptyGuide: 'Categories help customers browse and find products. Start with a few broad top-level categories (e.g. Clothing, Electronics), then add subcategories as your catalog grows — avoid nesting more than 2-3 levels deep.',
viewTree: 'Tree',
viewCards: 'Cards',
expandAll: 'Expand all',
collapseAll: 'Collapse all',
expandNode: 'Expand',
collapseNode: 'Collapse',
jumpToParent: 'Jump to parent',
deletedBadge: 'Deleted',
column_slug: 'Slug',
column_items: 'Products',
column_status: 'Status',
column_visibility: 'Visibility',
column_updated: 'Last updated',
bulkAssignParent: 'Assign parent',
bulkAssignImage: 'Assign image',
groupGeneral: 'General',
groupMedia: 'Media',
groupSeo: 'SEO',
groupVisibility: 'Visibility',
groupNavigation: 'Navigation',
groupAttributes: 'Attributes',
groupAdvanced: 'Advanced',
visibilityExplain: 'A hidden category and its products stay out of the storefront navigation and search until you make it visible again.',
navBreadcrumb: 'Breadcrumb',
navBreadcrumbHint: 'This is the path customers see above this category, e.g. Home Electronics Phones. It comes from the parent category you choose.',
iconHint: 'A small emoji or symbol shown next to the category name in menus, e.g. 📱. Leave empty for none.',
feat(categories): implement professional category management experience Categories dashboard (real total/visible/hidden/empty/root/subcategory/missing-image/missing-SEO/last-modified/completion% stats, recommended next action); tree view is now a real expand/collapse hierarchy (state persisted via LocalStorageService) with keyboard navigation (arrow keys, jump-to-parent), search that force-expands and keeps only matching branches + their ancestors/descendants instead of silently dropping deep matches; added Table/Cards views alongside the tree with density and saved column visibility; real bulk actions (show/hide/delete/assign parent/assign image via the Media Library picker/duplicate via the existing createCategory call/CSV export) plus the pre-existing single-item actions; reusable CategoryHealthWidget (image/SEO/description/valid-parent/visibility/products-assigned + completion%); editor reorganized into General/Media/SEO/Visibility/Navigation/Attributes/Advanced tabs, media now uses the shared ImageFieldComponent, SEO explains fields in plain language with a live preview, Navigation tab shows real breadcrumb/children/visibility-based nav status, Attributes uses the shared KeyValueEditorComponent. Filled in the adminCategories i18n namespace (previously only 2 of ~90 referenced keys existed) across en/ru/hy. Also fixed the pre-existing bug where a filtered/searched category list could silently drop a matched descendant whose ancestor's title didn't match, by loading the full catalog once and filtering client-side.
2026-07-18 17:04:11 +04:00
navRoot: 'This is a top-level category.',
navChildren: 'Subcategories',
navNoChildren: 'No subcategories yet.',
navAppearsIn: 'Where this appears',
navAppearsVisible: 'Visible in catalog navigation and search.',
navAppearsHidden: 'Hidden — not shown in catalog navigation while hidden.',
itemsCountLabel: 'Assigned products',
createdAtLabel: 'Created',
healthImage: 'Image',
healthSeo: 'SEO',
healthDescription: 'Description',
healthParent: 'Parent',
healthVisibility: 'Visibility',
healthProducts: 'Products assigned',
totalCategories: 'Total categories',
visibleCount: 'Visible',
hiddenCount: 'Hidden',
emptyCount: 'Empty',
rootCount: 'Root categories',
subCount: 'Subcategories',
missingImagesCount: 'Missing images',
missingSeoCount: 'Missing SEO',
lastModified: 'Last modified',
lastModifiedNever: 'Never',
completionLabel: 'Completion',
recommendedNext: 'Recommended next step',
recommendAddImage: 'A category has no image — add one so it looks trustworthy in listings.',
recommendAddSeo: 'A category is missing a search title or description — add one so it can be found.',
recommendFillEmpty: 'A category has no products assigned — add products or consider hiding it.',
recommendNone: 'Nice work — your category structure is in good shape.',
fix(static-pages): backfill enabled/status in export, fix missing i18n key Independent review pass over the Static Pages Module sprint (M1-M7), including live browser E2E per the task's own verification checklist. - ProjectEditorFacade.normalize() now backfills enabled/status on record-format static pages (defaulting missing values to enabled+published, same rule ContentPageService.normalizePage applies for display - mirrored rather than imported, to avoid a project-editor <-> content-management circular dependency since ContentManagementFacade already depends on this facade). Found live: exporting a page that predates this sprint and was never touched/re-saved in the current session produced JSON missing enabled/status entirely - the editor UI and storefront resolver both normalize-on-read so nothing was actually broken live, but Export/Import fidelity should match what the editor shows. Verified fixed live (export now includes "enabled":true,"status":"published" for an untouched legacy page) and via the full gate. - Added the missing adminCategories.chooseImage i18n key (interface + en/ru/hy). Found live: the media-picker "choose image" button rendered as the literal string "adminCategories.chooseImage" - a pre-existing, repo-wide bug (5 templates reference this key; none of the locale files ever defined it) that I propagated into a 3rd/4th/5th... well, 2 new occurrences by copying the existing branding-section/footer-section pattern into static-pages-editor. Fixed the actual defect (missing translation) rather than renaming the key, which would have required touching 2 unrelated admin components outside this sprint's scope. Live-verified this pass: Static Pages editor renders with all new fields; create page works (page count 4->confirmed); device preview toggles desktop/tablet/mobile widths correctly; navigation "Insert page link" creates a real type:'staticPage' nav item end-to-end (confirmed in the exported JSON); export includes all Sprint X+2 fields after the fix; no console errors throughout. Gate: tsc --noEmit, npm test (57/57), arch:check, build all green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 11:27:29 +04:00
},
adminProducts: {
emptyTitle: 'No products found',
emptyDescription: 'Try adjusting your filters, or create a new product.',
emptyGuide: 'Good products have a clear title, at least one photo, a price, and a short description — that\'s enough to publish. You can always add more detail later.',
search: 'Search products…',
category: 'Category',
allCategories: 'All categories',
visibility: 'Visibility',
allVisibility: 'All visibility',
visible: 'Visible',
hidden: 'Hidden',
stockStatus: 'Stock status',
allStock: 'All stock levels',
inStock: 'In stock',
lowStock: 'Low stock',
outOfStock: 'Out of stock',
sortTitle: 'Name',
sortPrice: 'Price',
sortPriority: 'Priority',
sortStock: 'Stock',
sortUpdated: 'Last updated',
showArchived: 'Show archived',
infiniteScroll: 'Infinite scroll',
viewMode: 'View',
viewTable: 'Table',
viewGrid: 'Grid',
density: 'Density',
densityComfortable: 'Comfortable',
densityCompact: 'Compact',
columns: 'Columns',
column_sku: 'SKU',
column_brand: 'Brand',
column_price: 'Price',
column_stock: 'Stock',
column_visibility: 'Visibility',
column_updated: 'Last updated',
create: 'Create product',
edit: 'Edit product',
duplicate: 'Duplicate',
selectedCount: 'selected',
bulkShow: 'Publish',
bulkHide: 'Hide',
bulkAssignCategory: 'Assign category',
bulkAssignTags: 'Assign tags',
bulkDuplicateAction: 'Duplicate',
bulkExportAction: 'Export',
bulkDelete: 'Delete',
tagsPlaceholder: 'e.g. summer, sale',
name: 'Name',
brand: 'Brand',
healthColumn: 'Health',
actions: 'Actions',
archive: 'Archive',
delete: 'Delete',
items: 'products',
loadMore: 'Load more',
noImage: 'No image',
slug: 'URL slug',
barcode: 'Barcode',
priority: 'Priority',
shortDescription: 'Short description',
translations: 'Translations',
primaryImage: 'Primary image',
primaryImageHint: 'The main photo shown in listings and search results.',
gallery: 'Gallery',
galleryHint: 'Additional photos shown on the product page. Drag order with the arrows.',
moveLeft: 'Move earlier',
moveRight: 'Move later',
videos: 'Videos (one URL per line)',
discount: 'Discount %',
currency: 'Currency',
stockQuantity: 'Stock quantity',
stockQuantityHint: 'How many units are available to sell right now.',
availabilityStatus: 'Availability',
availabilityStatusHint: 'What customers see: in stock, running low, or out of stock.',
availabilityNote: 'Availability note',
availabilityNoteHint: 'Optional extra detail shown to customers, e.g. "Ships in 3 days".',
reservedNote: 'Reserved stock isn\'t tracked separately yet — quantity shown here is total available stock.',
relatedProducts: 'Related products',
specifications: 'Specifications',
attributes: 'Attributes',
addRow: 'Add row',
removeRow: 'Remove',
rowKey: 'Name',
rowValue: 'Value',
addVariant: 'Add variant',
variantName: 'Variant name',
variantsHint: 'Each variant is a purchasable option of this product, e.g. a size or color, with its own price and stock.',
variants: 'Variants',
feat(admin): Shopify-style variant attributes matching production data shape Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> P0 user feedback: variants were just free-text name+price, and the user shared the real production payload - a flat array of {color, size, price, currency, remaining} rows, colors as '0x8B4513' hex. - New model: AdminProductVariantAttributeDef (key/label/isColor/values) + AdminProductVariant (attributes: Record<string,string>, sku, image, remaining, prices: {currency,price}[]) - this IS the production shape, grouped by combo with one row per currency instead of flattened, so admins edit one variant card instead of 4 duplicate rows - Attribute manager: add custom attributes (Color, Size, or anything), color attributes get a native color picker + live swatch preview instead of typing hex; other attributes get plain value chips - 'Generate variants' computes the cartesian product of attribute values (Color x Size = 4 combos for 1 color x 4 sizes) and preserves existing sku/price/stock data for combos that still exist after regeneration - Multi-currency pricing per variant (matches prod: same combo priced in RUB/USD/EUR/AMD) with per-currency add/remove - Color hex kept in the exact '0x8B4513' production format (toBackendColor/toCssColor conversion helpers) - Fixed an Angular v21 control-flow parser bug hit while building this: an @if/@else block whose only content is a bare {{ interpolation }} touching the block's closing brace fails to parse (NG5002 'Unclosed block for' cascading from a completely unrelated line) - worked around by keeping interpolation in its own element - Verified end-to-end in browser: added Color (color picker) + Size (S/M/L/XL) attributes, generated 4 variant combos, added all 4 currencies to a variant - matches the shared production JSON exactly
2026-07-19 13:40:51 +04:00
variantAttributes: 'Options',
variantAttributesHint: 'Add options like Color or Size, then list the values customers can choose from. Combinations below are generated automatically.',
colorAttribute: 'Color',
removeAttribute: 'Remove option',
removeValue: 'Remove value',
pickColor: 'Pick a color',
newValuePlaceholder: 'e.g. Small',
addValue: 'Add',
newAttributePlaceholder: 'e.g. Size',
addAttribute: 'Add option',
generateVariants: 'Generate variants',
variantsList: 'Variants',
remaining: 'Stock',
variantImage: 'Image',
archived: 'Archived',
slugHint: 'The web address of this product. Filled in automatically from the name - edit only if you need a custom URL.',
skuHint: 'SKU (stock keeping unit) is your internal product code, used for inventory and order lookups. Any unique text works.',
generate: 'Generate',
seoGenerate: 'Fill from product details',
seoGenerateHint: 'Fills empty fields from the product name and short description. Your existing text is kept.',
translationsHint: 'The main fields above are shown in your default store language. Add translations here for other languages - if a translation is empty, customers see the default text instead.',
badgesHint: 'Badges are the small colored labels customers see on the product photo. Pick from the standard set or add your own.',
addBadge: 'Add',
removeBadge: 'Remove badge',
customBadgePlaceholder: 'Your own badge text…',
seoExplain: 'This is what shows up in search results — a clear title and description help customers find this product.',
searchTitle: 'Search title',
searchTitleHint: 'The headline shown in search results. Keep it short and descriptive.',
searchDescription: 'Search description',
searchDescriptionHint: 'A short summary shown under the title in search results.',
seoMissingTitle: 'Add a search title so this product can be found.',
seoMissingDescription: 'Add a search description to improve how this product appears in results.',
keywords: 'Keywords',
featured: 'Featured',
recommended: 'Recommended',
new: 'New',
bestseller: 'Bestseller',
badges: 'Badges (comma-separated)',
htmlDescription: 'Detailed description',
customer: 'Customer feedback',
reviewsReadonly: 'Reviews',
noReviews: 'No reviews yet.',
questionsReadonly: 'Questions',
noQuestions: 'No questions yet.',
save: 'Save product',
groupGeneral: 'General',
groupMedia: 'Media',
groupPricing: 'Pricing',
groupInventory: 'Inventory',
groupCategories: 'Categories',
groupAttributes: 'Attributes',
groupSeo: 'SEO',
groupVisibility: 'Visibility',
groupAdvanced: 'Advanced',
healthImages: 'Images',
healthSeo: 'SEO',
healthPrice: 'Price',
healthCategory: 'Category',
healthDescription: 'Description',
healthInventory: 'Inventory',
totalProducts: 'Total products',
publishedCount: 'Published',
draftsCount: 'Drafts',
outOfStockCount: 'Out of stock',
hiddenCount: 'Hidden',
missingImagesCount: 'Missing images',
missingSeoCount: 'Missing SEO',
lowQualityCount: 'Low-quality',
recentlyEdited: 'Recently edited',
recommendedNext: 'Recommended next step',
openAction: 'Open',
recommendAddImages: 'A product has no photos — add at least one image so it looks trustworthy.',
recommendAddSeo: 'A product is missing a search title or description — add one so it can be found.',
recommendRestock: 'A product is out of stock — restock it or mark it unavailable.',
recommendNone: 'Nice work — your catalog is in good shape.',
},
adminUsers: {
emptyTitle: 'No users found',
emptyDescription: 'Invite a teammate to get started.',
invitationsEmptyTitle: 'No pending invitations',
title: 'Team members',
name: 'Name',
email: 'Email',
scope: 'Workspace',
role: 'Role',
roles: 'Roles',
lastLogin: 'Last sign-in',
sessions: 'Active sessions',
currentSession: 'This session',
invite: 'Invite member',
sendInvite: 'Send invitation',
revoke: 'Revoke',
passwordlessHint: 'Team members sign in with Telegram - no passwords to manage.',
confirmSuspend: 'Suspend this team member? They will lose access immediately.',
scopeValue: {
marketplace: 'Storefront',
office: 'Back office',
},
statusValue: {
active: 'Active',
invited: 'Invited',
suspended: 'Suspended',
},
invitationStatus: {
pending: 'Pending',
accepted: 'Accepted',
expired: 'Expired',
revoked: 'Revoked',
},
},
adminTransactions: {
search: 'Search transactions',
type: 'Type',
method: 'Payment method',
fraud: 'Fraud check',
flagged: 'Flagged',
flag: 'Flag as suspicious',
clearFlag: 'Clear flag',
retry: 'Retry',
audit: 'History',
emptyTitle: 'No transactions found',
emptyDescription: 'Try a different filter or search term.',
status: {
all: 'All statuses',
pending: 'Pending',
success: 'Successful',
failed: 'Failed',
retried: 'Retried',
},
typeValue: {
all: 'All types',
payment: 'Payment',
refund: 'Refund',
qr_payment: 'QR payment',
},
},
adminMonitoring: {
eventsEmptyTitle: 'No events found',
eventsEmptyDescription: 'Try a different category filter or search term.',
health: 'Health checks',
queues: 'Background queues',
depth: 'Waiting',
webhooks: 'Webhook deliveries',
endpoint: 'Destination',
event: 'Event',
events: 'Activity log',
category: 'Category',
level: 'Severity',
message: 'Description',
categoryValue: {
all: 'All categories',
audit: 'Admin activity',
security: 'Security',
login: 'Sign-in',
failed_login: 'Failed sign-in',
api: 'API',
error: 'Error',
warning: 'Warning',
},
queueStatus: {
healthy: 'Running smoothly',
degraded: 'Slowed down',
down: 'Stopped',
},
webhookStatus: {
delivered: 'Delivered',
failed: 'Failed',
pending: 'Pending',
},
levelValue: {
info: 'Info',
warning: 'Warning',
error: 'Error',
},
systemState: 'System state',
backendConnectivity: 'Backend',
connected: 'Connected',
loading: 'Loading',
draftState: 'Draft',
unsavedChanges: 'Unsaved changes',
noDraft: 'No draft',
lastSaved: 'Last saved',
lastPublished: 'Last published',
syncStatus: 'Sync',
},
adminAnalytics: {
topProductsEmptyTitle: 'No product sales in this period',
topProductsEmptyDescription: 'Try a wider date range.',
topProducts: 'Top products',
print: 'Print',
tabsLabel: 'Analytics sections',
tab: {
overview: 'Overview',
health: 'Health',
products: 'Products',
customers: 'Customers',
search: 'Search',
traffic: 'Traffic',
recommendations: 'Recommendations',
},
revenue: 'Revenue',
orders: 'Orders',
customers: 'Customers',
avgOrderValue: 'Avg. Order Value',
conversion: 'Conversion',
completionPercent: 'Completion',
unknown: 'Unknown',
salesChart: 'Sales',
quantitySold: 'Qty sold',
lowStock: 'Low stock',
lowStockEmptyTitle: 'No low-stock products',
quantity: 'Quantity',
status: 'Status',
recentActivity: 'Recent activity',
recentActivityEmptyTitle: 'No recent activity',
activityDraftSaved: 'Draft saved',
activityPublished: 'Published',
warnings: 'Warnings',
topViewed: 'Top viewed',
hiddenProducts: 'Hidden products',
archivedProducts: 'Archived products',
mostReviewed: 'Most reviewed',
worstRated: 'Worst rated',
noReviewedProducts: 'No reviewed products yet',
reviewCount: 'Reviews',
avgRating: 'Avg. rating',
newCustomers: 'New customers',
returningCustomers: 'Returning customers',
averageSpend: 'Average spend',
retention: 'Retention',
searchAnalytics: 'Search analytics',
trafficAnalytics: 'Traffic',
availableAfterBackend: 'Available after backend integration.',
pendingBackend: 'Pending backend',
pendingBackendHint: 'No search-query tracking exists yet.',
funnelsHeatmaps: 'Funnels & heatmaps',
visitors: 'Visitors',
products: 'Products',
categories: 'Categories',
},
adminMarketplaceHealth: {
title: 'Marketplace health',
complete: 'complete',
recommendationsTitle: 'Recommendations',
recommendNone: 'Everything looks good.',
checkImages: 'Products have images',
checkSeo: 'Products have SEO metadata',
checkCategories: 'Categories have products',
checkReviews: 'Reviews are moderated',
checkOrders: 'Orders are processed',
checkTranslations: 'Translations are complete',
checkHomepage: 'Homepage is configured',
checkBackend: 'Backend connectivity',
checkPerformance: 'Performance',
recommendImages: 'Add images to products missing them',
recommendImagesCount: 'Products without images hurt conversion.',
recommendSeo: 'Add SEO metadata to products missing it',
recommendSeoCount: 'Missing SEO titles/descriptions hurt search visibility.',
recommendCategory: 'Assign a category to uncategorized products',
recommendCategoryCount: 'Products without a category are harder to discover.',
recommendEmptyCategories: 'Categories without products',
recommendEmptyCategoriesCount: 'Consider merging or removing empty categories.',
recommendHomepage: 'Homepage is incomplete',
recommendStaticPages: 'Static pages are unpublished',
severity: {
info: 'Info',
warning: 'Warning',
critical: 'Critical',
},
},
adminShell: {
skipToContent: 'Skip to content',
openSidebar: 'Open menu',
closeSidebar: 'Close menu',
collapseSidebar: 'Collapse menu',
expandSidebar: 'Expand menu',
nav: {
dashboard: 'Dashboard',
catalogGroup: 'Catalog',
products: 'Products',
categories: 'Categories',
orders: 'Orders',
customers: 'Customers',
transactions: 'Transactions',
moderation: 'Reviews & Moderation',
reviews: 'Reviews',
reports: 'Reports',
content: 'Content',
mediaLibrary: 'Media Library',
marketplaceBuilder: 'Marketplace Builder',
users: 'Users',
settings: 'Settings',
monitoring: 'Monitoring',
analytics: 'Analytics',
documentation: 'Documentation',
help: 'Help',
logout: 'Log out',
comingSoonBadge: 'Soon',
},
topbar: {
searchLabel: 'Search the admin panel',
searchPlaceholder: 'Search products, orders, pages...',
notifications: 'Notifications',
notificationsEmpty: 'No new notifications',
account: 'Admin account',
tenantSelector: 'Store',
tenantSelectorComingSoon: 'Switching between stores is coming soon',
quickPublish: 'Publish',
quickPublishComingSoon: 'Quick publish is coming soon',
},
breadcrumbHome: 'Admin',
pages: {
dashboard: { title: 'Dashboard', description: 'An overview of your marketplace' },
products: { title: 'Products', description: 'Manage product listings and their visibility' },
productCreate: { title: 'New product', description: 'Fill in the details to add a product to the catalog' },
productEdit: { title: 'Edit product', description: 'Change this product\'s details' },
productDuplicate: { title: 'Duplicate product', description: 'Create a new product based on an existing one' },
categories: { title: 'Categories', description: 'Build your catalog\'s category tree' },
categoryCreate: { title: 'New category', description: 'Add a category to the catalog tree' },
categoryEdit: { title: 'Edit category', description: 'Change this category\'s details' },
orders: { title: 'Orders', description: 'View and process customer orders' },
orderDetail: { title: 'Order', description: 'Order details and status' },
customers: { title: 'Customers', description: 'Everyone who has placed an order' },
customerDetail: { title: 'Customer', description: 'Customer profile, orders, and activity' },
moderation: { title: 'Reviews & Moderation', description: 'Review and moderate customer feedback' },
reviewDetail: { title: 'Review', description: 'Review details and moderation actions' },
reportsQueue: { title: 'Reports queue', description: 'Content reported by customers' },
transactions: { title: 'Transactions', description: 'Payments, refunds, and fraud review' },
media: { title: 'Media Library', description: 'Images and files for products and pages' },
users: { title: 'Users', description: 'Admin team members and permissions' },
monitoring: { title: 'Monitoring', description: 'Queue, webhook, and system event status' },
analytics: { title: 'Analytics', description: 'Sales, products, and shopper behavior' },
},
},
2026-02-26 23:09:20 +04:00
};