This commit is contained in:
Your Name committed 2026-10-05 06:09:46 +07:00
1 parent af6047fb4d
commit d9901fd9a6
3 files changed
+817 -9

No files matched your search

+56 -6
View File
@@ -6,6 +6,7 @@ import {
ArrowLeft,
ArrowUp,
CheckCircle2,
Download,
Edit3,
Eye,
EyeOff,
@@ -25,6 +26,7 @@ import {
Sparkles,
Star,
Trash2,
Upload,
UploadCloud,
Image as ImageIcon,
} from 'lucide-react'
@@ -36,6 +38,7 @@ import ProductHeroCarouselBlockForm from '../components/products/ProductHeroCaro
import ProductDividerBlockForm from '../components/products/ProductDividerBlockForm'
import { validateProductHeroCarouselPayload } from '../components/products/productHeroCarouselValidation'
import { getAdminDisplayString } from '../utils/localization'
import BlockTranslationModal, { isTranslatableBlock } from '../components/page-builder/BlockTranslationModal'
interface Brand {
id: number
@@ -246,6 +249,8 @@ export default function ProductCmsPage() {
const [isMediaModalOpen, setIsMediaModalOpen] = useState(false)
const [onSelectMedia, setOnSelectMedia] = useState<((url: string) => void) | null>(null)
const [isProductPickerOpen, setIsProductPickerOpen] = useState(false)
const [isTranslationModalOpen, setIsTranslationModalOpen] = useState(false)
const [translationModalTab, setTranslationModalTab] = useState<'export' | 'import'>('export')
const languages = ['th', 'en', 'ja', 'zh', 'vi', 'ko', 'lo', 'it']
const selectedSection = selectedSectionId === 'new'
? null
@@ -757,12 +762,42 @@ export default function ProductCmsPage() {
{SECTION_HELP[sectionType] || 'Configure the section payload for this product detail page.'}
</p>
</div>
{selectedSection?.isLocked && (
<div className="inline-flex items-center gap-2 rounded-xl border border-white/10 bg-night-950 px-3 py-2 text-xs font-bold uppercase tracking-widest text-slate-400">
<Lock className="h-3.5 w-3.5" />
Locked
</div>
)}
<div className="flex flex-wrap items-center gap-2">
{isTranslatableBlock(sectionType) && (
<>
<button
type="button"
onClick={() => {
setTranslationModalTab('export')
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"
>
<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 เพื่ออัปเดตทุกภาษาพร้อมกัน"
>
<Upload className="w-3.5 h-3.5" />
<span>Import ภาษา</span>
</button>
</>
)}
{selectedSection?.isLocked && (
<div className="inline-flex items-center gap-2 rounded-xl border border-white/10 bg-night-950 px-3 py-2 text-xs font-bold uppercase tracking-widest text-slate-400">
<Lock className="h-3.5 w-3.5" />
Locked
</div>
)}
</div>
</div>
<div className="mt-6 grid grid-cols-1 gap-4 md:grid-cols-[1fr_auto]">
@@ -1369,6 +1404,21 @@ export default function ProductCmsPage() {
onClose={() => setIsProductPickerOpen(false)}
/>
)}
<BlockTranslationModal
isOpen={isTranslationModalOpen}
onClose={() => setIsTranslationModalOpen(false)}
section={{
id: typeof selectedSectionId === 'number' ? selectedSectionId : undefined,
type: sectionType,
payload: sectionPayload,
}}
initialTab={translationModalTab}
onApplyTranslations={(updatedPayload) => {
setSectionPayload(updatedPayload)
setSectionJson(JSON.stringify(updatedPayload, null, 2))
}}
/>
</div>
)
}