This commit is contained in:
Your Name committed 2026-10-05 06:01:05 +07:00
1 parent 8d415ecef7
commit af6047fb4d
2 files changed
+2095 -9

No files matched your search

File diff suppressed because it is too large. Load diff
+55 -9
View File
@@ -19,12 +19,15 @@ import {
Copy, Copy,
Check, Check,
Sparkles, Sparkles,
Globe Globe,
Download,
Upload,
} from 'lucide-react'; } from 'lucide-react';
import { API_BASE, type Page, type PageSection, type Category } from '@homaroma/types'; import { API_BASE, type Page, type PageSection, type Category } from '@homaroma/types';
import { getAdminDisplayString } from '../utils/localization'; import { getAdminDisplayString } from '../utils/localization';
import MediaLibraryModal from '../components/MediaLibraryModal'; import MediaLibraryModal from '../components/MediaLibraryModal';
import PageSeoModal from '../components/page-builder/PageSeoModal'; import PageSeoModal from '../components/page-builder/PageSeoModal';
import BlockTranslationModal, { isTranslatableBlock } from '../components/page-builder/BlockTranslationModal';
import { useStoreSettings } from '../contexts/StoreSettingsContext'; import { useStoreSettings } from '../contexts/StoreSettingsContext';
import { getAuthHeaders } from '../utils/auth'; import { getAuthHeaders } from '../utils/auth';
@@ -189,6 +192,8 @@ export default function PageBuilderPage() {
}; };
const [editingLang, setEditingLang] = useState('th'); const [editingLang, setEditingLang] = useState('th');
const [isTranslationModalOpen, setIsTranslationModalOpen] = useState(false);
const [translationModalTab, setTranslationModalTab] = useState<'export' | 'import'>('export');
// Helper to read localized string safely // Helper to read localized string safely
const getLocalizedValue = (payload: any, field: string) => { const getLocalizedValue = (payload: any, field: string) => {
@@ -1363,14 +1368,44 @@ export default function PageBuilderPage() {
</div> </div>
)} )}
</div> </div>
<button <div className="flex items-center gap-2">
type="button" {isTranslatableBlock(editingSection.type) && (
onClick={() => setEditingSection(null)} <div className="flex items-center gap-2 mr-2">
className="p-2 rounded-xl hover:bg-white/5 text-slate-400 hover:text-white transition-all" <button
> type="button"
<X className="w-6 h-6" /> onClick={() => {
</button> setTranslationModalTab('export');
</div> setIsTranslationModalOpen(true);
}}
className="flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-cyan-glow/10 hover:bg-cyan-glow/20 text-cyan-glow border border-cyan-glow/20 text-xs font-bold transition-all shadow-sm cursor-pointer"
title="ส่งออกข้อความทุกภาษาเพื่อนำไปแปลด้วย LLM (Export & AI Prompt)"
>
<Download className="w-3.5 h-3.5" />
<span>Export ภาษา</span>
</button>
<button
type="button"
onClick={() => {
setTranslationModalTab('import');
setIsTranslationModalOpen(true);
}}
className="flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-pop-pink/10 hover:bg-pop-pink/20 text-pop-pink border border-pop-pink/20 text-xs font-bold transition-all shadow-sm cursor-pointer"
title="วาง JSON ผลลัพธ์จาก LLM เพื่ออัปเดตทุกภาษาพร้อมกัน (Import Translations)"
>
<Upload className="w-3.5 h-3.5" />
<span>Import ภาษา</span>
</button>
</div>
)}
<button
type="button"
onClick={() => setEditingSection(null)}
className="p-2 rounded-xl hover:bg-white/5 text-slate-400 hover:text-white transition-all cursor-pointer"
>
<X className="w-6 h-6" />
</button>
</div>
</div>
{/* Premium Sub-header for Language Tabs */} {/* Premium Sub-header for Language Tabs */}
<div className="px-8 py-4 border-b border-white/5 bg-night-950/50 flex items-center overflow-x-auto hide-scrollbar"> <div className="px-8 py-4 border-b border-white/5 bg-night-950/50 flex items-center overflow-x-auto hide-scrollbar">
@@ -2155,6 +2190,17 @@ export default function PageBuilderPage() {
}} }}
frontendBaseUrl={frontendBase} frontendBaseUrl={frontendBase}
/> />
<BlockTranslationModal
isOpen={isTranslationModalOpen}
onClose={() => setIsTranslationModalOpen(false)}
section={editingSection}
pageSlug={page?.slug}
initialTab={translationModalTab}
onApplyTranslations={(updatedPayload) => {
setEditingSection((prev) => (prev ? { ...prev, payload: updatedPayload } : null));
}}
/>
</div> </div>
); );
} }