fix height and padding
This commit is contained in:
@@ -15,10 +15,7 @@ const GenericSection: FC<GenericSectionProps> = ({ sectionKey }) => {
|
|||||||
|
|
||||||
const { activeSection, activeItemIndex, data, setActiveSection, setActiveItemIndex } = usePersonalityStore()
|
const { activeSection, activeItemIndex, data, setActiveSection, setActiveItemIndex } = usePersonalityStore()
|
||||||
|
|
||||||
// Helper function to get numeric height
|
|
||||||
const getNumericHeight = (height?: string) => {
|
|
||||||
return parseInt(height?.replace(/px|em|rem|%/g, '') || "123")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to generate border style object based on selected sides
|
// Helper function to generate border style object based on selected sides
|
||||||
const generateBorderStyle = (border?: { width?: string; color?: string; style?: string; sides?: string[] }) => {
|
const generateBorderStyle = (border?: { width?: string; color?: string; style?: string; sides?: string[] }) => {
|
||||||
@@ -38,7 +35,7 @@ const GenericSection: FC<GenericSectionProps> = ({ sectionKey }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate individual border sides
|
// Generate individual border sides
|
||||||
const borderStyle: any = {}
|
const borderStyle: Record<string, string> = {}
|
||||||
sides.forEach(side => {
|
sides.forEach(side => {
|
||||||
borderStyle[`border${side.charAt(0).toUpperCase() + side.slice(1)}`] = `${width} ${style} ${color}`
|
borderStyle[`border${side.charAt(0).toUpperCase() + side.slice(1)}`] = `${width} ${style} ${color}`
|
||||||
})
|
})
|
||||||
@@ -125,7 +122,6 @@ const GenericSection: FC<GenericSectionProps> = ({ sectionKey }) => {
|
|||||||
{
|
{
|
||||||
sectionData.columnsCount > 0 ?
|
sectionData.columnsCount > 0 ?
|
||||||
<td style={{
|
<td style={{
|
||||||
padding: '10px',
|
|
||||||
...(() => {
|
...(() => {
|
||||||
const borderStyle = generateBorderStyle(sectionData.border)
|
const borderStyle = generateBorderStyle(sectionData.border)
|
||||||
if (activeSection === sectionKey) {
|
if (activeSection === sectionKey) {
|
||||||
@@ -149,7 +145,7 @@ const GenericSection: FC<GenericSectionProps> = ({ sectionKey }) => {
|
|||||||
})(),
|
})(),
|
||||||
borderRadius: '24px',
|
borderRadius: '24px',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
height: sectionData.height || '123px'
|
padding: sectionData.padding || '10px'
|
||||||
}}>
|
}}>
|
||||||
<table width="100%" cellPadding="0" cellSpacing="0" border={0} style={{ tableLayout: 'fixed' }}>
|
<table width="100%" cellPadding="0" cellSpacing="0" border={0} style={{ tableLayout: 'fixed' }}>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -193,7 +189,7 @@ const GenericSection: FC<GenericSectionProps> = ({ sectionKey }) => {
|
|||||||
<tr>
|
<tr>
|
||||||
<td
|
<td
|
||||||
width="100%"
|
width="100%"
|
||||||
height={getNumericHeight(sectionData.height).toString()}
|
height={parseInt(sectionData.height || '123px')}
|
||||||
style={{
|
style={{
|
||||||
padding: '8px',
|
padding: '8px',
|
||||||
cursor: 'pointer'
|
cursor: 'pointer'
|
||||||
@@ -210,7 +206,7 @@ const GenericSection: FC<GenericSectionProps> = ({ sectionKey }) => {
|
|||||||
<tr>
|
<tr>
|
||||||
<td
|
<td
|
||||||
width="100%"
|
width="100%"
|
||||||
height={getNumericHeight(sectionData.height).toString()}
|
height={parseInt(sectionData.height || '123px')}
|
||||||
align={getButtonHorizontalAlign(item.buttons[0])}
|
align={getButtonHorizontalAlign(item.buttons[0])}
|
||||||
valign={getButtonVerticalAlign(item.buttons[0])}
|
valign={getButtonVerticalAlign(item.buttons[0])}
|
||||||
style={{
|
style={{
|
||||||
@@ -231,8 +227,8 @@ const GenericSection: FC<GenericSectionProps> = ({ sectionKey }) => {
|
|||||||
<td
|
<td
|
||||||
width="100%"
|
width="100%"
|
||||||
height={item?.buttons && item.buttons.length > 0 ?
|
height={item?.buttons && item.buttons.length > 0 ?
|
||||||
Math.floor(getNumericHeight(sectionData.height) * 0.6).toString() :
|
Math.max(parseInt(sectionData.height || '123px') - 50, 30) :
|
||||||
Math.floor(getNumericHeight(sectionData.height) * 0.8).toString()}
|
Math.max(parseInt(sectionData.height || '123px') - 25, 30)}
|
||||||
align={item?.texts?.[0]?.alignment || 'center'}
|
align={item?.texts?.[0]?.alignment || 'center'}
|
||||||
valign={item?.texts?.[0]?.verticalAlignment === VerticalAlignment.TOP ? 'top' :
|
valign={item?.texts?.[0]?.verticalAlignment === VerticalAlignment.TOP ? 'top' :
|
||||||
item?.texts?.[0]?.verticalAlignment === VerticalAlignment.BOTTOM ? 'bottom' : 'middle'}
|
item?.texts?.[0]?.verticalAlignment === VerticalAlignment.BOTTOM ? 'bottom' : 'middle'}
|
||||||
@@ -264,7 +260,7 @@ const GenericSection: FC<GenericSectionProps> = ({ sectionKey }) => {
|
|||||||
<tr>
|
<tr>
|
||||||
<td
|
<td
|
||||||
width="100%"
|
width="100%"
|
||||||
height={Math.floor(getNumericHeight(sectionData.height) * 0.2).toString()}
|
height="25"
|
||||||
align={getButtonHorizontalAlign(item.buttons[0])}
|
align={getButtonHorizontalAlign(item.buttons[0])}
|
||||||
valign={getButtonVerticalAlign(item.buttons[0])}
|
valign={getButtonVerticalAlign(item.buttons[0])}
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -14,11 +14,12 @@ import { Trash } from 'iconsax-react';
|
|||||||
|
|
||||||
const SettingSideBar: FC = () => {
|
const SettingSideBar: FC = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { activeSection, setColumnsCount, updateActiveItem, data, activeItemIndex, removeSection, setSectionHeight, setSectionBorder } = usePersonalityStore()
|
const { activeSection, setColumnsCount, updateActiveItem, data, activeItemIndex, removeSection, setSectionPadding, setSectionHeight, setSectionBorder } = usePersonalityStore()
|
||||||
const [color, setColor] = useState("#aabbcc");
|
const [color, setColor] = useState("#aabbcc");
|
||||||
const [backgroundSize, setBackgroundSize] = useState<BackgroundSize>(BackgroundSize.COVER)
|
const [backgroundSize, setBackgroundSize] = useState<BackgroundSize>(BackgroundSize.COVER)
|
||||||
const [backgroundPosition, setBackgroundPosition] = useState<BackgroundPosition>(BackgroundPosition.CENTER)
|
const [backgroundPosition, setBackgroundPosition] = useState<BackgroundPosition>(BackgroundPosition.CENTER)
|
||||||
const [isUploading, setIsUploading] = useState<boolean>(false)
|
const [isUploading, setIsUploading] = useState<boolean>(false)
|
||||||
|
const [sectionPadding, setSectionPaddingState] = useState<string>('0px')
|
||||||
const [sectionHeight, setSectionHeightState] = useState<string>('123px')
|
const [sectionHeight, setSectionHeightState] = useState<string>('123px')
|
||||||
const [borderWidth, setBorderWidth] = useState<string>('0px')
|
const [borderWidth, setBorderWidth] = useState<string>('0px')
|
||||||
const [borderColor, setBorderColor] = useState<string>('#E5E7EB')
|
const [borderColor, setBorderColor] = useState<string>('#E5E7EB')
|
||||||
@@ -62,8 +63,13 @@ const SettingSideBar: FC = () => {
|
|||||||
setBackgroundPosition(currentPosition)
|
setBackgroundPosition(currentPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
// بروزرسانی section height و border
|
// بروزرسانی section padding, height و border
|
||||||
setSectionHeightState(currentSection?.height || '123px')
|
setSectionPaddingState(currentSection?.padding || '0px')
|
||||||
|
|
||||||
|
// مقدار پیشفرض height بر اساس نوع سکشن
|
||||||
|
const defaultHeight = currentSection?.isContent ? '246px' : '123px'
|
||||||
|
setSectionHeightState(currentSection?.height || defaultHeight)
|
||||||
|
|
||||||
setBorderWidth(currentSection?.border?.width || '0px')
|
setBorderWidth(currentSection?.border?.width || '0px')
|
||||||
setBorderColor(currentSection?.border?.color || '#E5E7EB')
|
setBorderColor(currentSection?.border?.color || '#E5E7EB')
|
||||||
setBorderStyle(currentSection?.border?.style || 'solid')
|
setBorderStyle(currentSection?.border?.style || 'solid')
|
||||||
@@ -97,6 +103,13 @@ const SettingSideBar: FC = () => {
|
|||||||
updateActiveItem({ backgroundColor: color })
|
updateActiveItem({ backgroundColor: color })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSectionPaddingChange = (padding: string) => {
|
||||||
|
if (activeSection) {
|
||||||
|
setSectionPaddingState(padding)
|
||||||
|
setSectionPadding(activeSection, padding)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleSectionHeightChange = (height: string) => {
|
const handleSectionHeightChange = (height: string) => {
|
||||||
if (activeSection) {
|
if (activeSection) {
|
||||||
setSectionHeightState(height)
|
setSectionHeightState(height)
|
||||||
@@ -378,6 +391,17 @@ const SettingSideBar: FC = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Section Padding Control */}
|
||||||
|
<div className='mt-5'>
|
||||||
|
<Input
|
||||||
|
label="فاصله داخلی سکشن"
|
||||||
|
value={sectionPadding}
|
||||||
|
onChange={(e) => handleSectionPaddingChange(e.target.value)}
|
||||||
|
placeholder="مثال: 20px"
|
||||||
|
disabled={isUploading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Section Height Control */}
|
{/* Section Height Control */}
|
||||||
<div className='mt-5'>
|
<div className='mt-5'>
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@@ -273,6 +273,17 @@ export const usePersonalityStore = create<PersonalityStore>((set, get) => ({
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
setSectionPadding: (sectionKey: string, padding: string) =>
|
||||||
|
set((state) => ({
|
||||||
|
data: {
|
||||||
|
...state.data,
|
||||||
|
[sectionKey]: {
|
||||||
|
...state.data[sectionKey],
|
||||||
|
padding,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
|
||||||
setSectionHeight: (sectionKey: string, height: string) =>
|
setSectionHeight: (sectionKey: string, height: string) =>
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ export type SectionType = {
|
|||||||
columnsCount: number;
|
columnsCount: number;
|
||||||
sortNumber: number;
|
sortNumber: number;
|
||||||
items: SectionItemType[];
|
items: SectionItemType[];
|
||||||
|
padding?: string;
|
||||||
height?: string;
|
height?: string;
|
||||||
border?: {
|
border?: {
|
||||||
width?: string;
|
width?: string;
|
||||||
@@ -207,6 +208,7 @@ export type PersonalityStore = {
|
|||||||
updateActiveItem: (updates: Partial<SectionItemType>) => void;
|
updateActiveItem: (updates: Partial<SectionItemType>) => void;
|
||||||
removeItem: (sectionKey: string, id: string) => void;
|
removeItem: (sectionKey: string, id: string) => void;
|
||||||
setColumnsCount: (sectionKey: string, columnsCount: number) => void;
|
setColumnsCount: (sectionKey: string, columnsCount: number) => void;
|
||||||
|
setSectionPadding: (sectionKey: string, padding: string) => void;
|
||||||
setSectionHeight: (sectionKey: string, height: string) => void;
|
setSectionHeight: (sectionKey: string, height: string) => void;
|
||||||
setSectionBorder: (
|
setSectionBorder: (
|
||||||
sectionKey: string,
|
sectionKey: string,
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ export const exportPersonalityToHTML = async (
|
|||||||
|
|
||||||
// Render section equivalent (HeaderSection, ContentSection, FooterSection)
|
// Render section equivalent (HeaderSection, ContentSection, FooterSection)
|
||||||
const renderSection = (
|
const renderSection = (
|
||||||
section: SectionType,
|
section: SectionType & { name?: string; isContent?: boolean },
|
||||||
sectionHeight: string,
|
sectionHeight: string,
|
||||||
paddingTop = ""
|
paddingTop = ""
|
||||||
) => {
|
) => {
|
||||||
@@ -453,7 +453,7 @@ export const exportPersonalityToHTML = async (
|
|||||||
${renderImages(item?.images || [])}
|
${renderImages(item?.images || [])}
|
||||||
${renderSocials(item?.socials || [])}
|
${renderSocials(item?.socials || [])}
|
||||||
${
|
${
|
||||||
sectionHeight === "246px"
|
section?.isContent
|
||||||
? '<div style="margin: 0 0 10px 0; text-align: right; color: #888; font-size: 14px;">{{content}}</div>'
|
? '<div style="margin: 0 0 10px 0; text-align: right; color: #888; font-size: 14px;">{{content}}</div>'
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
@@ -461,18 +461,19 @@ export const exportPersonalityToHTML = async (
|
|||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
} else {
|
} else {
|
||||||
// ردیف اصلی برای متن و تصاویر
|
// ردیف اصلی برای متن و تصاویر - محاسبه بر اساس height سکشن
|
||||||
|
const sectionHeightNumber = parseInt(
|
||||||
|
sectionHeight
|
||||||
|
);
|
||||||
const mainHeight = hasButtons
|
const mainHeight = hasButtons
|
||||||
? sectionHeight === "123px"
|
? Math.max(
|
||||||
? "60"
|
sectionHeightNumber - 50,
|
||||||
: sectionHeight === "246px"
|
30
|
||||||
? "203"
|
).toString()
|
||||||
: "40"
|
: Math.max(
|
||||||
: sectionHeight === "123px"
|
sectionHeightNumber - 25,
|
||||||
? "87"
|
30
|
||||||
: sectionHeight === "246px"
|
).toString();
|
||||||
? "230"
|
|
||||||
: "67";
|
|
||||||
|
|
||||||
result += `<tr>
|
result += `<tr>
|
||||||
<td width="100%" height="${mainHeight}" style="padding: 20px; vertical-align: top; font-size: 15px; line-height: 1.8;">
|
<td width="100%" height="${mainHeight}" style="padding: 20px; vertical-align: top; font-size: 15px; line-height: 1.8;">
|
||||||
@@ -480,7 +481,7 @@ export const exportPersonalityToHTML = async (
|
|||||||
${renderImages(item?.images || [])}
|
${renderImages(item?.images || [])}
|
||||||
${renderSocials(item?.socials || [])}
|
${renderSocials(item?.socials || [])}
|
||||||
${
|
${
|
||||||
sectionHeight === "246px" &&
|
section?.isContent &&
|
||||||
!hasTexts &&
|
!hasTexts &&
|
||||||
!hasImages &&
|
!hasImages &&
|
||||||
!hasSocials
|
!hasSocials
|
||||||
@@ -506,15 +507,22 @@ export const exportPersonalityToHTML = async (
|
|||||||
} else {
|
} else {
|
||||||
// اگر هیچ محتوایی نداریم و content section است
|
// اگر هیچ محتوایی نداریم و content section است
|
||||||
console.log(
|
console.log(
|
||||||
"🔥 [ExportHTML] Empty content section detected, sectionHeight:",
|
"🔥 [ExportHTML] Empty section detected, isContent:",
|
||||||
sectionHeight
|
section?.isContent
|
||||||
);
|
);
|
||||||
if (sectionHeight === "246px") {
|
if (section?.isContent) {
|
||||||
console.log(
|
console.log(
|
||||||
"🔥 [ExportHTML] Adding {{content}} placeholder to empty content"
|
"🔥 [ExportHTML] Adding {{content}} placeholder to empty content"
|
||||||
);
|
);
|
||||||
|
const sectionHeightNumber = parseInt(
|
||||||
|
sectionHeight
|
||||||
|
);
|
||||||
|
const emptyHeight = Math.max(
|
||||||
|
sectionHeightNumber - 25,
|
||||||
|
30
|
||||||
|
);
|
||||||
result += `<tr>
|
result += `<tr>
|
||||||
<td width="100%" height="230" style="padding: 20px; vertical-align: top; font-size: 15px; line-height: 1.8;">
|
<td width="100%" height="${emptyHeight}" style="padding: 20px; vertical-align: top; font-size: 15px; line-height: 1.8;">
|
||||||
<div style="margin: 0; text-align: right; color: #888; font-size: 14px;">{{content}}</div>
|
<div style="margin: 0; text-align: right; color: #888; font-size: 14px;">{{content}}</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
@@ -548,22 +556,26 @@ export const exportPersonalityToHTML = async (
|
|||||||
</tr>`;
|
</tr>`;
|
||||||
} else {
|
} else {
|
||||||
// حالت خالی
|
// حالت خالی
|
||||||
const emptyMessages = {
|
const getEmptyMessage = (
|
||||||
"123px": "سربرگ ایمیل",
|
section: SectionType & { name?: string; isContent?: boolean }
|
||||||
"246px": "محتوای ایمیل",
|
) => {
|
||||||
|
if (section?.isContent) return "محتوای ایمیل";
|
||||||
|
if (section?.name) return section.name;
|
||||||
|
return "سکشن خالی";
|
||||||
};
|
};
|
||||||
const emptyMessage =
|
|
||||||
emptyMessages[sectionHeight as keyof typeof emptyMessages] ||
|
const emptyMessage = getEmptyMessage(section);
|
||||||
"فوتر ایمیل";
|
const sectionHeightNumber = parseInt(sectionHeight);
|
||||||
|
const displayHeight = section?.isContent
|
||||||
|
? Math.max(sectionHeightNumber + 40, 286)
|
||||||
|
: sectionHeight;
|
||||||
|
|
||||||
return `<tr>
|
return `<tr>
|
||||||
${paddingTop ? `<td style="padding-top: ${paddingTop};">` : "<td>"}
|
${paddingTop ? `<td style="padding-top: ${paddingTop};">` : "<td>"}
|
||||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="height: ${
|
<td style="height: ${displayHeight}; border-radius: 24px; text-align: right; vertical-align: middle; padding: 0px;">
|
||||||
sectionHeight === "246px" ? "286px" : sectionHeight
|
|
||||||
}; border-radius: 24px; text-align: right; vertical-align: middle; padding: 0px;">
|
|
||||||
<div style="color: #888; font-size: 14px; margin-bottom: 8px;">
|
<div style="color: #888; font-size: 14px; margin-bottom: 8px;">
|
||||||
${emptyMessage}
|
${emptyMessage}
|
||||||
</div>
|
</div>
|
||||||
@@ -583,7 +595,15 @@ export const exportPersonalityToHTML = async (
|
|||||||
) => {
|
) => {
|
||||||
console.log(`🔥 [ExportHTML] Getting height for section: ${sectionKey}`, {
|
console.log(`🔥 [ExportHTML] Getting height for section: ${sectionKey}`, {
|
||||||
isContent: sectionData?.isContent,
|
isContent: sectionData?.isContent,
|
||||||
|
customHeight: sectionData?.height,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// اگر height سفارشی تعریف شده باشد، از آن استفاده کن
|
||||||
|
if (sectionData?.height) {
|
||||||
|
return sectionData.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// مقدار پیشفرض بر اساس نوع سکشن
|
||||||
if (sectionKey === "content" || sectionData?.isContent) {
|
if (sectionKey === "content" || sectionData?.isContent) {
|
||||||
return "246px";
|
return "246px";
|
||||||
}
|
}
|
||||||
@@ -619,14 +639,8 @@ export const exportPersonalityToHTML = async (
|
|||||||
isContent: sectionData.isContent,
|
isContent: sectionData.isContent,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pass only the section structure (without name and isContent)
|
// Pass the complete section data for rendering
|
||||||
const sectionStructure = {
|
const renderedSection = renderSection(sectionData, height, "");
|
||||||
columnsCount: sectionData.columnsCount,
|
|
||||||
items: sectionData.items || [],
|
|
||||||
sortNumber: sectionData.sortNumber,
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderedSection = renderSection(sectionStructure, height, "");
|
|
||||||
console.log(
|
console.log(
|
||||||
`🔥 [ExportHTML] Section ${sectionKey} rendered, HTML length:`,
|
`🔥 [ExportHTML] Section ${sectionKey} rendered, HTML length:`,
|
||||||
renderedSection.length
|
renderedSection.length
|
||||||
|
|||||||
Reference in New Issue
Block a user