This commit is contained in:
gpt-engineer-app[bot]
2025-12-19 14:43:28 +00:00
parent 04a140b305
commit b63da103cd
8 changed files with 265 additions and 35 deletions

View File

@@ -20,6 +20,7 @@ import {
Home,
MoreHorizontal,
X,
Video,
} from 'lucide-react';
interface NavItem {
@@ -40,6 +41,7 @@ const adminNavItems: NavItem[] = [
{ label: 'Dashboard', href: '/admin', icon: LayoutDashboard },
{ label: 'Produk', href: '/admin/products', icon: Package },
{ label: 'Bootcamp', href: '/admin/bootcamp', icon: BookOpen },
{ label: 'Konsultasi', href: '/admin/consulting', icon: Video },
{ label: 'Order', href: '/admin/orders', icon: Receipt },
{ label: 'Member', href: '/admin/members', icon: Users },
{ label: 'Kalender', href: '/admin/events', icon: Calendar },
@@ -152,15 +154,17 @@ export function AppLayout({ children }: AppLayoutProps) {
</nav>
<div className="p-4 border-t-2 border-border space-y-2">
<Link to="/checkout" className="flex items-center gap-3 px-3 py-2 hover:bg-muted text-sm font-medium">
<ShoppingCart className="w-5 h-5" />
Keranjang
{items.length > 0 && (
<span className="ml-auto bg-primary text-primary-foreground text-xs px-2 py-0.5">
{items.length}
</span>
)}
</Link>
{!isAdmin && (
<Link to="/checkout" className="flex items-center gap-3 px-3 py-2 hover:bg-muted text-sm font-medium">
<ShoppingCart className="w-5 h-5" />
Keranjang
{items.length > 0 && (
<span className="ml-auto bg-primary text-primary-foreground text-xs px-2 py-0.5">
{items.length}
</span>
)}
</Link>
)}
<button
onClick={handleSignOut}
className="flex items-center gap-3 px-3 py-2 hover:bg-muted text-sm font-medium w-full text-left"

View File

@@ -9,7 +9,7 @@ import {
Image as ImageIcon, Heading1, Heading2, Undo, Redo
} from 'lucide-react';
import { cn } from '@/lib/utils';
import { useCallback } from 'react';
import { useCallback, useEffect } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { toast } from '@/hooks/use-toast';
@@ -45,6 +45,13 @@ export function RichTextEditor({ content, onChange, placeholder = 'Tulis konten.
},
});
// Sync content when it changes externally (e.g., when editing different items)
useEffect(() => {
if (editor && content !== editor.getHTML()) {
editor.commands.setContent(content || '');
}
}, [content, editor]);
const addLink = useCallback(() => {
if (!editor) return;
const url = window.prompt('Masukkan URL:');

View File

@@ -103,6 +103,7 @@ export function NotifikasiTab() {
const [saving, setSaving] = useState(false);
const [testEmail, setTestEmail] = useState('');
const [expandedTemplates, setExpandedTemplates] = useState<Set<string>>(new Set());
const [sendingTest, setSendingTest] = useState(false);
useEffect(() => {
fetchData();
@@ -156,8 +157,36 @@ export function NotifikasiTab() {
const sendTestEmail = async () => {
if (!testEmail) return toast({ title: 'Error', description: 'Masukkan email tujuan', variant: 'destructive' });
console.log('Test email would be sent to:', testEmail, 'with SMTP config:', smtp);
toast({ title: 'Info', description: `Email uji coba akan dikirim ke ${testEmail} (fitur sedang dikembangkan)` });
if (!isSmtpConfigured) return toast({ title: 'Error', description: 'Lengkapi konfigurasi SMTP terlebih dahulu', variant: 'destructive' });
setSendingTest(true);
try {
const { data, error } = await supabase.functions.invoke('send-test-email', {
body: {
to: testEmail,
smtp_host: smtp.smtp_host,
smtp_port: smtp.smtp_port,
smtp_username: smtp.smtp_username,
smtp_password: smtp.smtp_password,
smtp_from_name: smtp.smtp_from_name,
smtp_from_email: smtp.smtp_from_email,
smtp_use_tls: smtp.smtp_use_tls,
},
});
if (error) throw error;
if (data?.success) {
toast({ title: 'Berhasil', description: data.message });
} else {
throw new Error(data?.message || 'Failed to send test email');
}
} catch (error: any) {
console.error('Test email error:', error);
toast({ title: 'Error', description: error.message || 'Gagal mengirim email uji coba', variant: 'destructive' });
} finally {
setSendingTest(false);
}
};
const updateTemplate = async (template: NotificationTemplate) => {
@@ -278,9 +307,9 @@ export function NotifikasiTab() {
placeholder="Email uji coba"
className="border-2 max-w-xs"
/>
<Button variant="outline" onClick={sendTestEmail} className="border-2">
<Button variant="outline" onClick={sendTestEmail} className="border-2" disabled={sendingTest}>
<Send className="w-4 h-4 mr-2" />
Kirim Email Uji Coba
{sendingTest ? 'Mengirim...' : 'Kirim Email Uji Coba'}
</Button>
</div>
</div>