Remove EmailBranding component and fix Puck sidebar scroll

- Remove EmailBranding from Puck editor (branding auto-shows for free tier)
- Fix sidebar scroll in email template editor with single scrollbar
- Fix logo data URL format in email_renderer.py

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-15 14:42:22 -05:00
parent cf8fdfccb4
commit acd84dfa30
9 changed files with 203 additions and 120 deletions

View File

@@ -1,85 +0,0 @@
import React from 'react';
import type { ComponentConfig } from '@measured/puck';
export interface EmailBrandingProps {
showBranding: boolean;
}
/**
* EmailBranding - "Powered by SmoothSchedule" footer
*
* Displays SmoothSchedule branding at the bottom of emails.
* This is shown for free plans and can be hidden on paid plans.
*
* Note: The actual visibility is controlled by the backend based on
* the tenant's billing plan. This component is always rendered in the
* editor but the backend will omit it for paid plans.
*/
export const EmailBranding: ComponentConfig<EmailBrandingProps> = {
label: 'Email Branding',
fields: {
showBranding: {
type: 'radio',
label: 'Show Branding',
options: [
{ label: 'Yes', value: true },
{ label: 'No (Paid Plans Only)', value: false },
],
},
},
defaultProps: {
showBranding: true,
},
render: ({ showBranding }) => {
if (!showBranding) {
return (
<div
style={{
padding: '16px',
textAlign: 'center',
color: '#9ca3af',
fontSize: '12px',
fontStyle: 'italic',
}}
>
[Branding hidden - available on paid plans]
</div>
);
}
return (
<div
style={{
padding: '24px 40px',
textAlign: 'center',
borderTop: '1px solid #e5e7eb',
}}
>
<a
href="https://smoothschedule.com"
target="_blank"
rel="noopener noreferrer"
style={{
display: 'inline-flex',
alignItems: 'center',
gap: '8px',
textDecoration: 'none',
color: '#6b7280',
fontSize: '12px',
}}
>
<img
src="/logo-branding.png"
alt="SmoothSchedule"
width="18"
height="18"
style={{ verticalAlign: 'middle' }}
/>
<span>Powered by SmoothSchedule</span>
</a>
</div>
);
},
};
export default EmailBranding;

View File

@@ -9,7 +9,6 @@ import type { EmailFooterProps } from './types';
* Supports template tags for dynamic content.
*/
const EmailFooterRender: React.FC<EmailFooterProps> = ({ address, phone, email, website }) => {
console.log('[RENDER] EmailFooterRender called with:', { address, phone, email, website });
const contactItems: React.ReactNode[] = [];
if (phone) contactItems.push(phone);

View File

@@ -9,7 +9,6 @@ import type { EmailHeaderProps } from './types';
* Supports optional logo image and preheader text.
*/
const EmailHeaderRender: React.FC<EmailHeaderProps> = ({ logoUrl, businessName, preheader }) => {
console.log('[RENDER] EmailHeaderRender called with:', { logoUrl, businessName, preheader });
return (
<div
style={{

View File

@@ -19,4 +19,3 @@ export { EmailImage } from './EmailImage';
export { EmailPanel } from './EmailPanel';
export { EmailTwoColumn } from './EmailTwoColumn';
export { EmailFooter } from './EmailFooter';
export { EmailBranding } from './EmailBranding';

View File

@@ -80,11 +80,6 @@ export interface EmailFooterProps {
website?: string;
}
// Email Branding Props
export interface EmailBrandingProps {
showBranding: boolean;
}
// All email component props
export type EmailComponentProps = {
EmailLayout: EmailLayoutProps;
@@ -98,7 +93,6 @@ export type EmailComponentProps = {
EmailPanel: EmailPanelProps;
EmailTwoColumn: EmailTwoColumnProps;
EmailFooter: EmailFooterProps;
EmailBranding: EmailBrandingProps;
};
// Email-specific Puck data structure

View File

@@ -6,7 +6,7 @@
*/
import type { Config } from '@measured/puck';
// Import ALL email-specific components
// Import email-specific components
import { EmailHeader } from './components/email/EmailHeader';
import { EmailHeading } from './components/email/EmailHeading';
import { EmailText } from './components/email/EmailText';
@@ -17,21 +17,11 @@ import { EmailImage } from './components/email/EmailImage';
import { EmailPanel } from './components/email/EmailPanel';
import { EmailTwoColumn } from './components/email/EmailTwoColumn';
import { EmailFooter } from './components/email/EmailFooter';
import { EmailBranding } from './components/email/EmailBranding';
// Import the combined type
import type { EmailComponentProps } from './components/email/types';
console.log('[emailConfig] Loading ALL email components');
console.log('[emailConfig] Verifying render functions are distinct:');
console.log(' EmailHeader.render:', EmailHeader.render?.toString().substring(0, 50));
console.log(' EmailHeading.render:', EmailHeading.render?.toString().substring(0, 50));
console.log(' EmailText.render:', EmailText.render?.toString().substring(0, 50));
console.log(' EmailButton.render:', EmailButton.render?.toString().substring(0, 50));
console.log(' EmailFooter.render:', EmailFooter.render?.toString().substring(0, 50));
console.log(' Are renders same?', EmailHeader.render === EmailFooter.render);
// Create the email config with ALL components - using direct assignment (not spread)
// Create the email config with ALL components
export const emailPuckConfig: Config<EmailComponentProps> = {
categories: {
structure: {
@@ -46,13 +36,8 @@ export const emailPuckConfig: Config<EmailComponentProps> = {
title: 'Layout',
components: ['EmailSpacer', 'EmailDivider', 'EmailPanel', 'EmailTwoColumn'],
},
other: {
title: 'Other',
components: ['EmailBranding'],
},
},
components: {
// Direct assignment - no spread to rule out reference issues
EmailHeader,
EmailFooter,
EmailHeading,
@@ -63,12 +48,9 @@ export const emailPuckConfig: Config<EmailComponentProps> = {
EmailDivider,
EmailPanel,
EmailTwoColumn,
EmailBranding,
},
};
console.log('[emailConfig] Config ready with components:', Object.keys(emailPuckConfig.components));
/**
* Get email editor config - creates a fresh clone each time.
*/