feat(project-editor): reusable image-field (thumbnail+replace+remove), branding OG image+gallery

- shared app-image-field component: thumbnail preview, replace, remove, opens media-picker
- branding: add socialImageUrl + galleryUrls fields, wire to new image-field
- footer: logo + payment icon fields use image-field (drop manual media-picker plumbing)
- i18n: common.remove, adminCategories.replaceImage, builder.socialImage/gallery keys (en/ru/hy)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sdarbinyan
2026-07-17 15:22:45 +04:00
parent feda0f685f
commit b183410888
12 changed files with 175 additions and 71 deletions

View File

@@ -427,6 +427,9 @@ export const en: Translations = {
logo: 'Logo',
smallLogo: 'Small Logo',
favicon: 'Favicon',
socialImage: 'Social Share Image',
gallery: 'Gallery',
addGalleryImage: 'Add image',
marketplaceTitle: 'Marketplace Title',
primaryColor: 'Primary Color',
secondaryColor: 'Secondary Color',
@@ -572,6 +575,8 @@ export const en: Translations = {
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.',
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.',
@@ -765,6 +770,7 @@ export const en: Translations = {
common: {
retry: 'Try again',
loading: 'Loading...',
remove: 'Remove',
},
location: {
allRegions: 'All regions',
@@ -923,6 +929,7 @@ export const en: Translations = {
},
adminCategories: {
chooseImage: 'Choose image',
replaceImage: 'Replace image',
},
adminProducts: {
emptyTitle: 'No products found',

View File

@@ -427,6 +427,9 @@ export const hy: Translations = {
logo: 'Լոգո',
smallLogo: 'Փոքր լոգո',
favicon: 'Favicon',
socialImage: 'Սոցիալական պատկեր',
gallery: 'Պատկերասրահ',
addGalleryImage: 'Ավելացնել պատկեր',
marketplaceTitle: 'Մարքեթփլեյսի վերնագիր',
primaryColor: 'Հիմնական գույն',
secondaryColor: 'Երկրորդական գույն',
@@ -572,6 +575,8 @@ export const hy: Translations = {
logoDesc: 'Ամբողջական լոգոյի պատկերի URL, ցուցադրվում է header-ում դեսքթոփի վրա։',
smallLogoDesc: 'Կոմպակտ լոգոյի URL՝ սահմանափակ տարածքի համար (օր․՝ mobile header)։',
faviconDesc: 'Բրաուզերի ներդիրի պատկերակի URL։ Պետք է լինի փոքր քառակուսի պատկեր։',
socialImageDesc: 'Կանխադրված պատկեր, երբ մարքեթփլեյսը կիսվում է սոցիալական ցանցերում (Open Graph)։',
galleryDesc: 'Լրացուցիչ բրենդային պատկերներ ապագա օգտագործման համար։',
marketplaceTitleDesc: 'Էջի վերնագիրը որոնողական համակարգերի և բրաուզերի ներդիրների համար։',
primaryColorDesc: 'Բրենդի հիմնական գույնը՝ հիմնական կոճակների և ընդգծումների համար։ Պետք է վավեր hex գույն լինի։',
secondaryColorDesc: 'Բրենդի երկրորդական գույնը՝ երկրորդական տարրերի համար։ Պետք է վավեր hex գույն լինի։',
@@ -765,6 +770,7 @@ export const hy: Translations = {
common: {
retry: 'Փորձել կրկին',
loading: 'Բեռնում...',
remove: 'Հեռացնել',
},
location: {
allRegions: 'Բոլոր տարածաշրջանները',
@@ -918,6 +924,7 @@ export const hy: Translations = {
},
adminCategories: {
chooseImage: 'Ընտրել պատկեր',
replaceImage: 'Փոխարինել պատկերը',
},
adminProducts: {
emptyTitle: 'Ապրանքներ չեն գտնվել',

View File

@@ -427,6 +427,9 @@ export const ru: Translations = {
logo: 'Логотип',
smallLogo: 'Малый логотип',
favicon: 'Favicon',
socialImage: 'Изображение для соцсетей',
gallery: 'Галерея',
addGalleryImage: 'Добавить изображение',
marketplaceTitle: 'Заголовок маркетплейса',
primaryColor: 'Основной цвет',
secondaryColor: 'Вторичный цвет',
@@ -572,6 +575,8 @@ export const ru: Translations = {
logoDesc: 'URL полного логотипа, отображается в шапке на десктопе.',
smallLogoDesc: 'URL компактного логотипа для ограниченного пространства (например, мобильная шапка).',
faviconDesc: 'URL иконки вкладки браузера. Должен быть небольшим квадратным изображением.',
socialImageDesc: 'Изображение по умолчанию при публикации маркетплейса в соцсетях (Open Graph).',
galleryDesc: 'Дополнительные брендовые изображения для будущего использования в витрине.',
marketplaceTitleDesc: 'Заголовок страницы для поисковых систем и вкладок браузера.',
primaryColorDesc: 'Основной цвет бренда для главных кнопок и акцентов. Должен быть корректным hex-цветом.',
secondaryColorDesc: 'Дополнительный цвет бренда для второстепенных элементов. Должен быть корректным hex-цветом.',
@@ -765,6 +770,7 @@ export const ru: Translations = {
common: {
retry: 'Попробовать снова',
loading: 'Загрузка...',
remove: 'Удалить',
},
location: {
allRegions: 'Все регионы',
@@ -918,6 +924,7 @@ export const ru: Translations = {
},
adminCategories: {
chooseImage: 'Выбрать изображение',
replaceImage: 'Заменить изображение',
},
adminProducts: {
emptyTitle: 'Товары не найдены',

View File

@@ -425,6 +425,9 @@ export interface Translations {
logo: string;
smallLogo: string;
favicon: string;
socialImage: string;
gallery: string;
addGalleryImage: string;
marketplaceTitle: string;
primaryColor: string;
secondaryColor: string;
@@ -570,6 +573,8 @@ export interface Translations {
logoDesc: string;
smallLogoDesc: string;
faviconDesc: string;
socialImageDesc: string;
galleryDesc: string;
marketplaceTitleDesc: string;
primaryColorDesc: string;
secondaryColorDesc: string;
@@ -763,6 +768,7 @@ export interface Translations {
common: {
retry: string;
loading: string;
remove: string;
};
location: {
allRegions: string;
@@ -930,6 +936,7 @@ export interface Translations {
// anywhere, so it rendered as the literal string "adminCategories.chooseImage".
adminCategories: {
chooseImage: string;
replaceImage: string;
};
adminProducts: {
emptyTitle: string;