This commit is contained in:
Your Name committed 2026-10-06 16:58:21 +07:00
1 parent 641cc4e42b
commit 46968782b6
17 files changed
+265 -30

No files matched your search

@@ -0,0 +1,130 @@
import { MoveVertical, Sparkles } from 'lucide-react';
interface SectionSpacingControlsProps {
payload: Record<string, any>;
updatePayloadValue: (field: string, value: any) => void;
}
export default function SectionSpacingControls({
payload,
updatePayloadValue,
}: SectionSpacingControlsProps) {
const currentTop = payload?.paddingTop || payload?.sectionPadding || 'normal';
const currentBottom = payload?.paddingBottom || payload?.sectionPadding || 'normal';
const applyPreset = (top: string, bottom: string) => {
updatePayloadValue('paddingTop', top);
updatePayloadValue('paddingBottom', bottom);
updatePayloadValue('sectionPadding', top === bottom ? top : 'normal');
};
return (
<div className="bg-gradient-to-r from-night-950/70 via-night-900/50 to-night-950/70 p-4 rounded-2xl border border-white/10 space-y-3">
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-2 border-b border-white/5 pb-2.5">
<div className="flex items-center gap-2">
<MoveVertical className="w-4 h-4 text-cyan-glow" />
<span className="text-xs font-bold uppercase tracking-widest text-slate-200">
ระยะห่างแนวตั้งของบล็อก (Vertical Spacing)
</span>
</div>
<div className="flex items-center gap-1.5 text-[11px] font-mono text-cyan-glow/80 bg-cyan-glow/10 px-2 py-0.5 rounded-lg border border-cyan-glow/20">
<span>Top: {currentTop}</span>
<span className="text-white/30">•</span>
<span>Bottom: {currentBottom}</span>
</div>
</div>
{/* Quick Spacing Presets */}
<div className="flex items-center gap-2 overflow-x-auto hide-scrollbar pb-0.5">
<span className="text-[10px] uppercase font-bold tracking-wider text-slate-400 shrink-0 flex items-center gap-1">
<Sparkles className="w-3 h-3 text-cyan-glow" /> Preset:
</span>
<button
type="button"
onClick={() => applyPreset('compact', 'compact')}
className={`px-2.5 py-1 rounded-lg text-[11px] font-medium transition-all cursor-pointer whitespace-nowrap border ${
currentTop === 'compact' && currentBottom === 'compact'
? 'bg-cyan-glow/20 border-cyan-glow text-cyan-300'
: 'bg-white/5 border-white/5 text-slate-300 hover:bg-white/10'
}`}
>
กะทัดรัด (Compact 24-40px)
</button>
<button
type="button"
onClick={() => applyPreset('normal', 'normal')}
className={`px-2.5 py-1 rounded-lg text-[11px] font-medium transition-all cursor-pointer whitespace-nowrap border ${
currentTop === 'normal' && currentBottom === 'normal'
? 'bg-cyan-glow/20 border-cyan-glow text-cyan-300'
: 'bg-white/5 border-white/5 text-slate-300 hover:bg-white/10'
}`}
>
มาตรฐาน (Normal 40-56px)
</button>
<button
type="button"
onClick={() => applyPreset('spacious', 'spacious')}
className={`px-2.5 py-1 rounded-lg text-[11px] font-medium transition-all cursor-pointer whitespace-nowrap border ${
currentTop === 'spacious' && currentBottom === 'spacious'
? 'bg-cyan-glow/20 border-cyan-glow text-cyan-300'
: 'bg-white/5 border-white/5 text-slate-300 hover:bg-white/10'
}`}
>
กว้างโปร่ง (Spacious 80-96px)
</button>
<button
type="button"
onClick={() => applyPreset('none', 'none')}
className={`px-2.5 py-1 rounded-lg text-[11px] font-medium transition-all cursor-pointer whitespace-nowrap border ${
currentTop === 'none' && currentBottom === 'none'
? 'bg-cyan-glow/20 border-cyan-glow text-cyan-300'
: 'bg-white/5 border-white/5 text-slate-300 hover:bg-white/10'
}`}
>
ชิดติดกัน (Flush 0px)
</button>
</div>
{/* Manual Fine-grained Controls */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 pt-1">
<div className="space-y-1.5">
<label className="text-[10px] uppercase font-bold tracking-widest text-slate-400">
ระยะห่างด้านบน (Top Padding)
</label>
<select
value={currentTop}
onChange={(e) => {
updatePayloadValue('paddingTop', e.target.value);
updatePayloadValue('sectionPadding', e.target.value === currentBottom ? e.target.value : 'normal');
}}
className="admin-input w-full text-xs bg-slate-900 border-white/10"
>
<option value="none">ไม่มีระยะห่างด้านบน (None - 0px)</option>
<option value="compact">กะทัดรัด (Compact - 24-40px)</option>
<option value="normal">มาตรฐาน (Normal - 40-56px)</option>
<option value="spacious">กว้างโปร่ง (Spacious - 80-96px)</option>
</select>
</div>
<div className="space-y-1.5">
<label className="text-[10px] uppercase font-bold tracking-widest text-slate-400">
ระยะห่างด้านล่าง (Bottom Padding)
</label>
<select
value={currentBottom}
onChange={(e) => {
updatePayloadValue('paddingBottom', e.target.value);
updatePayloadValue('sectionPadding', currentTop === e.target.value ? e.target.value : 'normal');
}}
className="admin-input w-full text-xs bg-slate-900 border-white/10"
>
<option value="none">ไม่มีระยะห่างด้านล่าง (None - 0px)</option>
<option value="compact">กะทัดรัด (Compact - 24-40px)</option>
<option value="normal">มาตรฐาน (Normal - 40-56px)</option>
<option value="spacious">กว้างโปร่ง (Spacious - 80-96px)</option>
</select>
</div>
</div>
</div>
);
}
+9
View File
@@ -68,6 +68,7 @@ import DividerForm from '../components/page-builder/DividerForm';
import AddSectionModal from '../components/page-builder/AddSectionModal';
import FeaturedTilesForm from '../components/page-builder/FeaturedTilesForm';
import HeroVideoForm from '../components/page-builder/HeroVideoForm';
import SectionSpacingControls from '../components/page-builder/SectionSpacingControls';
import {
HeroMinimalForm,
HeroSplitMinimalForm,
@@ -1496,6 +1497,14 @@ export default function PageBuilderPage() {
</div>
)}
{/* ── Universal Section Spacing Controls (Full Control for all block types) ── */}
{editingSection.type?.toUpperCase() !== 'DIVIDER' && (
<SectionSpacingControls
payload={editingSection.payload || {}}
updatePayloadValue={updatePayloadValue}
/>
)}
{/* Dynamic Forms based on Type */}
{editingSection.type?.toUpperCase() === 'HERO_MINIMAL' && (
<HeroMinimalForm