feat: Add card insert buttons toolbar

##  New Feature: Card Insert Buttons!

### What's Added:

**Card Insert Toolbar** above the rich text editor with 6 quick-insert buttons:

1. **Basic Card** - Plain card with default content
2. **Success Card** - Green checkmark, success message
3. **Info Card** - Blue info icon, informational content
4. **Warning Card** - Orange alert icon, warning message
5. **Hero Card** - Large text, background image support
6. **Button** - Call-to-action button with link

### Features:

**Visual Toolbar:**
```
Insert Card: [Basic] [✓ Success] [ℹ Info] [⚠ Warning] [🖼 Hero] | [+ Button]
```

**One-Click Insert:**
- Click button → Card inserted at end of content
- Pre-filled with sample content
- Proper [card] syntax
- Toast notification confirms insertion

**Smart Behavior:**
- Only shows in Visual Editor mode (hidden in Code Mode)
- Styled toolbar with icons and colors
- Responsive layout (wraps on mobile)
- Separator between cards and button

### Card Types:

**Basic:**
```html
[card]
<h2>Card Title</h2>
<p>Card content goes here...</p>
[/card]
```

**Success:**
```html
[card type="success"]
<h2> Success!</h2>
<p>Your action was successful.</p>
[/card]
```

**Info, Warning, Hero** - Similar structure with different types

**Button:**
```html
<p style="text-align: center;">
  <a href="{order_url}" class="button">Button Text</a>
</p>
```

### Benefits:

-  **No manual typing** of [card] tags
-  **Consistent formatting** every time
-  **Visual feedback** with toast notifications
-  **Beginner-friendly** - just click and edit
-  **Professional templates** with pre-filled content

### Next: Email Appearance Settings 🎨
This commit is contained in:
dwindown
2025-11-13 05:33:28 +07:00
parent efd6fa36c9
commit f8538c4cf7

View File

@@ -9,7 +9,7 @@ import { Input } from '@/components/ui/input';
import { RichTextEditor } from '@/components/ui/rich-text-editor';
import { Label } from '@/components/ui/label';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { ArrowLeft, Eye, Edit, RotateCcw } from 'lucide-react';
import { ArrowLeft, Eye, Edit, RotateCcw, Plus, CheckCircle, Info, AlertCircle, Image } from 'lucide-react';
import { toast } from 'sonner';
import { __ } from '@/lib/i18n';
@@ -125,6 +125,30 @@ export default function EditTemplate() {
}
};
// Insert card helpers
const insertCard = (type?: string, content?: string) => {
let cardText = '';
if (type) {
cardText = `[card type="${type}"]
${content || '<h2>Card Title</h2>\n<p>Card content goes here...</p>'}
[/card]\n\n`;
} else {
cardText = `[card]
${content || '<h2>Card Title</h2>\n<p>Card content goes here...</p>'}
[/card]\n\n`;
}
setBody(body + cardText);
toast.success(__('Card inserted'));
};
const insertButton = () => {
const buttonHtml = `<p style="text-align: center;"><a href="{order_url}" class="button">Button Text</a></p>`;
setBody(body + buttonHtml + '\n');
toast.success(__('Button inserted'));
};
// Get variable keys for the rich text editor
const variableKeys = Object.keys(variables);
@@ -343,6 +367,76 @@ export default function EditTemplate() {
</Button>
</div>
{/* Card Insert Buttons */}
{!codeMode && (
<div className="flex flex-wrap gap-2 p-3 bg-muted/50 rounded-md border">
<span className="text-xs font-medium text-muted-foreground flex items-center">
{__('Insert Card:')}
</span>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => insertCard()}
className="h-7 text-xs gap-1"
>
<Plus className="h-3 w-3" />
{__('Basic')}
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => insertCard('success', '<h2>✅ Success!</h2>\n<p>Your action was successful.</p>')}
className="h-7 text-xs gap-1"
>
<CheckCircle className="h-3 w-3 text-green-600" />
{__('Success')}
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => insertCard('info', '<h2> Information</h2>\n<p>Important information here.</p>')}
className="h-7 text-xs gap-1"
>
<Info className="h-3 w-3 text-blue-600" />
{__('Info')}
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => insertCard('warning', '<h2>⚠️ Warning</h2>\n<p>Please pay attention to this.</p>')}
className="h-7 text-xs gap-1"
>
<AlertCircle className="h-3 w-3 text-orange-600" />
{__('Warning')}
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => insertCard('hero', '<h1>Big Announcement</h1>\n<p>Hero card with large text.</p>', 'https://example.com/bg.jpg')}
className="h-7 text-xs gap-1"
>
<Image className="h-3 w-3 text-purple-600" />
{__('Hero')}
</Button>
<div className="border-l mx-1"></div>
<Button
type="button"
variant="outline"
size="sm"
onClick={insertButton}
className="h-7 text-xs gap-1"
>
<Plus className="h-3 w-3" />
{__('Button')}
</Button>
</div>
)}
{codeMode ? (
<textarea
value={body}