Files
Momento/memento-note/scripts/localize-agent-slide-themes-and-translate.mjs
Antigravity bd495be965
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 12s
feat: design system overhaul — sidebar, AI chats, settings, brainstorm, color cleanup
- Sidebar: dynamic brand-accent colors, brainstorm section restyled
- AI chat general: popup panel with expand/collapse, hides when contextual AI open
- AI chat contextual: tabs reordered (Actions first), X close button, height fix
- Settings: all tabs restyled, 6 new color presets (sage, terracotta, iron, etc.)
- Global color cleanup: emerald/orange hardcoded → brand-accent dynamic
- Brainstorm page: orange → brand-accent throughout
- PageEntry animation component added to key pages
- Floating AI button: bg-brand-accent instead of hardcoded black
- i18n: all 15 locales updated with new AI/billing keys
- Billing: freemium quota tracking, BYOK, stripe subscription scaffolding
- Admin: integrated into new design
- AGENTS.md + CLAUDE.md project rules added
2026-05-16 12:59:30 +00:00

594 lines
16 KiB
JavaScript

/**
* Met à jour agents.form.slideThemes + richTextEditor (aiReformulateFailed, translateTargets)
* dans memento-note/locales/*.json (seul en.json est laissé hors de ce script).
*/
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const localesDir = path.join(__dirname, '..', 'locales')
const slideKeys = [
'modern_wellness',
'business_authority',
'nature_outdoors',
'vintage_academic',
'soft_creative',
'bohemian',
'vibrant_tech',
'craft_artisan',
'tech_night',
'education_charts',
'forest_eco',
'elegant_fashion',
'art_food',
'luxury_mystery',
'pure_tech_blue',
'coastal_coral',
'vibrant_orange_mint',
'platinum_white_gold',
]
const TT_KEYS = [
'Francais',
'English',
'Espanol',
'Deutsch',
'Persan',
'Portugais',
'Italiano',
'Chinois',
'Japonais',
]
/** @returns {Record<string,string>} slideThemes avec toutes les clés présentes */
function st(...values) {
const out = {}
slideKeys.forEach((k, i) => {
out[k] = values[i]
})
return out
}
/** @returns {Record<string,string>} translateTargets avec clés fixes */
function tt(vf, ven, ves, vd, vp, vp2, vit, vch, vja) {
return {
Francais: vf,
English: ven,
Espanol: ves,
Deutsch: vd,
Persan: vp,
Portugais: vp2,
Italiano: vit,
Chinois: vch,
Japonais: vja,
}
}
/** @type {Record<string, { slideThemes: Record<string,string>, translateTargets: Record<string,string>, aiReformulateFailed: string }>} */
const LOCALE = {
de: {
slideThemes: st(
'Modern & Wohlbefinden',
'Business & Autorität',
'Natur & Outdoor',
'Vintage & Akademisch',
'Sanft & Kreativ',
'Bohemian',
'Lebhaft & Tech',
'Handwerk & Artisan',
'Tech & Nacht (dunkel)',
'Bildung & Diagramme',
'Wald & Öko',
'Elegant & Mode',
'Kunst & Kulinarik',
'Luxus & Mystik',
'Reines Tech-Blau',
'Küsten-Koralle',
'Lebhaft Orange & Minze',
'Platin Weißgold',
),
translateTargets: tt(
'Französisch',
'Englisch',
'Spanisch',
'Deutsch',
'Persisch',
'Portugiesisch',
'Italienisch',
'Chinesisch',
'Japanisch',
),
aiReformulateFailed:
'Der KI-Assistent konnte diesen Text nicht verarbeiten. Bitte erneut versuchen.',
},
es: {
slideThemes: st(
'Moderno y bienestar',
'Negocios y autoridad',
'Naturaleza y aire libre',
'Vintage y académico',
'Suave y creativo',
'Bohemio',
'Vibrante y tech',
'Artesanía',
'Tech y noche (oscuro)',
'Educación y gráficos',
'Bosque y eco',
'Elegancia y moda',
'Arte y gastronomía',
'Lujo y misterio',
'Tech azul puro',
'Coral costero',
'Naranja vibrante y menta',
'Platino blanco y oro',
),
translateTargets: tt(
'Francés',
'Inglés',
'Español',
'Alemán',
'Persa',
'Portugués',
'Italiano',
'Chino',
'Japonés',
),
aiReformulateFailed:
'La IA no pudo procesar este texto. Inténtalo de nuevo.',
},
fr: {
slideThemes: st(
'Moderne & bien-être',
'Affaires & autorité',
'Nature & plein air',
'Vintage & académique',
'Doux & créatif',
'Bohème',
'Éclat & tech',
'Artisan & fait main',
'Tech & nuit (sombre)',
'Éducation & graphiques',
'Forêt & éco',
'Élégance & mode',
'Art & gastronomie',
'Luxe & mystère',
'Bleu tech pur',
'Corail côtier',
'Orange vif & menthe',
'Platine blanc & or',
),
translateTargets: tt(
'Français',
'Anglais',
'Espagnol',
'Allemand',
'Persan',
'Portugais',
'Italien',
'Chinois',
'Japonais',
),
aiReformulateFailed:
"L'assistant IA n'a pas pu traiter ce texte. Réessayez.",
},
it: {
slideThemes: st(
'Moderno e benessere',
'Business e autorevolezza',
'Natura e outdoor',
'Vintage e accademico',
'Morbido e creativo',
'Bohemien',
'Vivace e tech',
'Artigianato',
'Tech e notte (scuro)',
'Formazione e grafici',
'Foresta ed eco',
'Eleganza e moda',
'Arte e cucina',
'Lusso e mistero',
'Tech blu puro',
'Corallo costiero',
'Arancio vivace e menta',
'Platino bianco e oro',
),
translateTargets: tt(
'Francese',
'Inglese',
'Spagnolo',
'Tedesco',
'Persiano',
'Portoghese',
'Italiano',
'Cinese',
'Giapponese',
),
aiReformulateFailed:
"L'assistente IA non ha potuto elaborare questo testo. Riprova.",
},
pt: {
slideThemes: st(
'Moderno e bem-estar',
'Negócios e autoridade',
'Natureza e ar livre',
'Vintage e académico',
'Suave e criativo',
'Boémio',
'Vibrante e tech',
'Artesanato',
'Tech e noite (escuro)',
'Educação e gráficos',
'Floresta e eco',
'Elegância e moda',
'Arte e gastronomia',
'Luxo e mistério',
'Tech azul puro',
'Coral costeiro',
'Laranja vibrante e hortelã',
'Platina branca e ouro',
),
translateTargets: tt(
'Francês',
'Inglês',
'Espanhol',
'Alemão',
'Persa',
'Português',
'Italiano',
'Chinês',
'Japonês',
),
aiReformulateFailed:
'A IA não conseguiu processar este texto. Tenta novamente.',
},
nl: {
slideThemes: st(
'Modern & welzijn',
'Zaken & autoriteit',
'Natuur & buiten',
'Vintage & academisch',
'Zacht & creatief',
'Bohemian',
'Levendig & tech',
'Ambacht',
'Tech & nacht (donker)',
'Onderwijs & grafieken',
'Bos & eco',
'Elegant & mode',
'Kunst & gastronomie',
'Luxe & mysterie',
'Strak techblauw',
'Kustkoraal',
'Levend oranje & munt',
'Platina witgoud',
),
translateTargets: tt(
'Frans',
'Engels',
'Spaans',
'Duits',
'Perzisch',
'Portugees',
'Italiaans',
'Chinees',
'Japans',
),
aiReformulateFailed:
'De AI-assistent kon deze tekst niet verwerken. Probeer het opnieuw.',
},
pl: {
slideThemes: st(
'Nowoczesny wellness',
'Biznes i autorytet',
'Natura i outdoor',
'Vintage i akademicki',
'Miękki i kreatywny',
'Boho',
'Żywy tech',
'Rzemiosło',
'Tech i noc (ciemny)',
'Edukacja i wykresy',
'Las i eco',
'Elegancja i moda',
'Sztuka i kuchnia',
'Luksus i tajemnica',
'Czysty tech niebieski',
'Koral przybrzeżny',
'Żywa pomarańcz i mięta',
'Platyna i białe złoto',
),
translateTargets: tt(
'Francuski',
'Angielski',
'Hiszpański',
'Niemiecki',
'Perski',
'Portugalski',
'Włoski',
'Chiński',
'Japoński',
),
aiReformulateFailed:
'Asystent IA nie mógł przetworzyć tego tekstu. Spróbuj ponownie.',
},
ru: {
slideThemes: st(
'Современность и велнес',
'Бизнес и авторитет',
'Природа и активный отдых',
'Винтаж и академизм',
'Мягкость и креатив',
'Богемный',
'Яркость и техно',
'Ремесло',
'Техно и ночь (тёмный)',
'Образование и графики',
'Лес и эко',
'Элегантность и мода',
'Искусство и гастрономия',
'Роскошь и тайна',
'Чистый техно-синий',
'Прибрежный коралл',
'Яркий оранжевый и мята',
'Платина и белое золото',
),
translateTargets: tt(
'Французский',
'Английский',
'Испанский',
'Немецкий',
'Персидский',
'Португальский',
'Итальянский',
'Китайский',
'Японский',
),
aiReformulateFailed:
'ИИ-помощник не смог обработать этот текст. Попробуйте снова.',
},
zh: {
slideThemes: st(
'现代与活力',
'商务权威',
'自然户外',
'复古学院',
'柔和创意',
'波希米亚',
'活力科技',
'手工艺匠心',
'科技暗夜(深色)',
'教育与图表',
'森林生态',
'优雅时尚',
'艺术与美食',
'奢华神秘',
'纯正科技蓝',
'海岸珊瑚',
'活力橙与薄荷',
'铂金与白金色',
),
translateTargets: tt(
'法语',
'英语',
'西班牙语',
'德语',
'波斯语',
'葡萄牙语',
'意大利语',
'中文',
'日语',
),
aiReformulateFailed: 'AI 助手无法处理此文本,请重试。',
},
ja: {
slideThemes: st(
'モダン&ウェルネス',
'ビジネス&オーソリティ',
'ネイチャー&アウトドア',
'ヴィンテージ&アカデミック',
'ソフト&クリエイティブ',
'ボヘミアン',
'ビブラント&テック',
'クラフト&職人',
'テック&ナイト(ダーク)',
'教育&チャート',
'フォレスト&エコ',
'エレガント&ファッション',
'アート&フード',
'ラグジュアリー&ミステリー',
'ピュアテックブルー',
'コースタルコーラル',
'ビビッドオレンジ&ミント',
'プラチナホワイトゴールド',
),
translateTargets: tt(
'フランス語',
'英語',
'スペイン語',
'ドイツ語',
'ペルシア語',
'ポルトガル語',
'イタリア語',
'中国語',
'日本語',
),
aiReformulateFailed:
'AI アシスタントがこのテキストを処理できませんでした。もう一度お試しください。',
},
ko: {
slideThemes: st(
'모던 앤 웰니스',
'비즈니스 앤 오서리티',
'네이처 앤 아웃도어',
'빈티지 앤 아카데믹',
'소프트 앤 크리에이티브',
'보헤미안',
'비브런트 앤 테크',
'크래프트 앤 아티즌',
'테크 앤 나イト(다크)',
'교육 앤 차트',
'포레스트 앤 에코',
'엘리건트 앤 패션',
'아트 앤 푸드',
'럭셔리 앤 미스터리',
'퓨어 테크 블루',
'코스트럴 코럴',
'비브런트 오렌지 앤 민트',
'플래티넘 화이트 골드',
),
translateTargets: tt(
'프랑스어',
'영어',
'스페인어',
'독일어',
'페르시아어',
'포르투갈어',
'이탈리아어',
'중국어',
'일본어',
),
aiReformulateFailed:
'AI 어시스턴트가 이 텍스트를 처리하지 못했습니다. 다시 시도해 주세요.',
},
ar: {
slideThemes: st(
'عصري وصحة وعافية',
'عمل وسلطة مهنية',
'طبيعة وهواء طلق',
'عتيق وأكاديمي',
'ناعم وإبداعي',
'بوهيمي',
'زاهٍ وتقني',
'حرفة وصناعة يدوية',
'تقني وليلة (داكن)',
'تعليم ورسوم بيانية',
'غابة وبيئة',
'أنيق وأزياء',
'فن وطعام',
'فخامة وغموض',
'أزرق تقني نقي',
'مرجان ساحلي',
'برتقالي زاهٍ ونعناع',
'بلاتيني ذهب أبيض',
),
translateTargets: tt(
'الفرنسية',
'الإنجليزية',
'الإسبانية',
'الألمانية',
'الفارسية',
'البرتغالية',
'الإيطالية',
'الصينية',
'اليابانية',
),
aiReformulateFailed:
'تعذّر على المساعد الذكي معالجة هذا النص. حاول مجدداً.',
},
fa: {
slideThemes: st(
'مدرن و تندرستی',
'کسب‌وکار و اعتبار',
'طبیعت و فضای باز',
'کلاسیک دانشگاهی',
'نرم و خلاقانه',
'بوهمیایی',
'پرجنب‌وجوش و تکنولوژی',
'صنعت دستی و هنرمند',
'فناوری و شب (تیره)',
'آموزش و نمودار',
'جنگل و اکولوژی',
'شیک و مد',
'هنر و غذا',
'لوکس و مرموز',
'آبی تکنولوژی خالص',
'مرجان ساحلی',
'نارنجی شاد و نعناع',
'پلاتین و سفید طلایی',
),
translateTargets: tt(
'فرانسوی',
'انگلیسی',
'اسپانیایی',
'آلمانی',
'فارسی',
'پرتغالی',
'ایتالیایی',
'چینی',
'ژاپنی',
),
aiReformulateFailed:
'دستیار هوش مصنوعی نتوانست این متن را پردازش کند. دوباره تلاش کنید.',
},
hi: {
slideThemes: st(
'आधुनिक और वेलनेस',
'व्यवसाय और प्राधिकरण',
'प्रकृति और बाहर',
'विंटेज और शैक्षणिक',
'मुलायम और रचनात्मक',
'बोहो',
'जीवंत और टेक',
'शिल्प और कारीगर',
'टेक और रात (डार्क)',
'शिक्षा और चार्ट',
'वन और इको',
'सुरुचिपूर्ण और फैशन',
'कला और भोजन',
'लक्ज़री और रहस्य',
'शुद्ध टेक नीला',
'तटीय कोरल',
'जीवंत संतरा और पुदीना',
'प्लैटिनम सफ़ेद सोना',
),
translateTargets: tt(
'फ़्रेंच',
'अंग्रेज़ी',
'स्पेनिश',
'जर्मन',
'फ़ारसी',
'पुर्तगाली',
'इतालवी',
'चीनी',
'जापानी',
),
aiReformulateFailed:
'AI सहायक इस पाठ को प्रोसेस नहीं कर सका। दोबारा कोशिश करें।',
},
}
function applyLocale(code, bundle) {
const file = path.join(localesDir, `${code}.json`)
if (!fs.existsSync(file)) {
console.warn('Fichier manquant:', file)
return
}
const raw = fs.readFileSync(file, 'utf8')
const j = JSON.parse(raw)
if (!j.agents?.form) {
console.warn(`${code}: agents.form absent, ignoré`)
return
}
if (!j.agents.form.slideThemes) j.agents.form.slideThemes = {}
slideKeys.forEach((k) => {
j.agents.form.slideThemes[k] = bundle.slideThemes[k]
})
if (!j.richTextEditor) j.richTextEditor = {}
TT_KEYS.forEach((k) => {
j.richTextEditor.translateTargets =
j.richTextEditor.translateTargets ?? {}
j.richTextEditor.translateTargets[k] = bundle.translateTargets[k]
})
j.richTextEditor.aiReformulateFailed = bundle.aiReformulateFailed
fs.writeFileSync(file, JSON.stringify(j, null, 2) + '\n', 'utf8')
console.log('OK', code)
}
for (const code of Object.keys(LOCALE)) {
applyLocale(code, LOCALE[code])
}