Move email provider settings to Integrasi tab and fix database schema
- Move Mailketing API configuration from NotifikasiTab to IntegrasiTab - Remove email provider settings from NotifikasiTab, add info card - Update IntegrasiTab to save email settings to notification_settings table - Add test email functionality to Integrasi tab - Fix database schema compatibility with new email settings - Remove GitHub remote, keep only Gitea remote - Clean up unused imports and variables 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,24 +2,14 @@ import { useEffect, useState } from 'react';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { Alert, AlertDescription } from '@/components/ui/alert';
|
||||
import { RichTextEditor } from '@/components/RichTextEditor';
|
||||
import { toast } from '@/hooks/use-toast';
|
||||
import { Mail, AlertTriangle, Send, ChevronDown, ChevronUp, Webhook, Key } from 'lucide-react';
|
||||
import { Mail, ChevronDown, ChevronUp, Webhook } from 'lucide-react';
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
|
||||
interface EmailProviderSettings {
|
||||
id?: string;
|
||||
provider: 'mailketing';
|
||||
api_token: string;
|
||||
from_name: string;
|
||||
from_email: string;
|
||||
}
|
||||
|
||||
interface NotificationTemplate {
|
||||
id: string;
|
||||
@@ -84,31 +74,16 @@ const DEFAULT_TEMPLATES: { key: string; name: string; defaultSubject: string; de
|
||||
},
|
||||
];
|
||||
|
||||
const emptyEmailSettings: EmailProviderSettings = {
|
||||
provider: 'mailketing',
|
||||
api_token: '',
|
||||
from_name: '',
|
||||
from_email: '',
|
||||
};
|
||||
|
||||
export function NotifikasiTab() {
|
||||
const [emailSettings, setEmailSettings] = useState<EmailProviderSettings>(emptyEmailSettings);
|
||||
const [templates, setTemplates] = useState<NotificationTemplate[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [testEmail, setTestEmail] = useState('');
|
||||
const [expandedTemplates, setExpandedTemplates] = useState<Set<string>>(new Set());
|
||||
const [sendingTest, setSendingTest] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const fetchData = async () => {
|
||||
// Fetch email provider settings
|
||||
const { data: emailData } = await supabase.from('notification_settings').select('*').single();
|
||||
if (emailData) setEmailSettings(emailData);
|
||||
|
||||
// Fetch templates
|
||||
const { data: templatesData } = await supabase.from('notification_templates').select('*').order('key');
|
||||
if (templatesData && templatesData.length > 0) {
|
||||
@@ -133,62 +108,7 @@ export function NotifikasiTab() {
|
||||
if (!error && data) setTemplates(data);
|
||||
};
|
||||
|
||||
const saveEmailSettings = async () => {
|
||||
setSaving(true);
|
||||
const payload = { ...emailSettings };
|
||||
delete payload.id;
|
||||
|
||||
if (emailSettings.id) {
|
||||
const { error } = await supabase.from('notification_settings').update(payload).eq('id', emailSettings.id);
|
||||
if (error) toast({ title: 'Error', description: error.message, variant: 'destructive' });
|
||||
else toast({ title: 'Berhasil', description: 'Pengaturan email disimpan' });
|
||||
} else {
|
||||
const { data, error } = await supabase.from('notification_settings').insert(payload).select().single();
|
||||
if (error) toast({ title: 'Error', description: error.message, variant: 'destructive' });
|
||||
else { setEmailSettings(data); toast({ title: 'Berhasil', description: 'Pengaturan email disimpan' }); }
|
||||
}
|
||||
setSaving(false);
|
||||
};
|
||||
|
||||
const sendTestEmail = async () => {
|
||||
if (!testEmail) return toast({ title: 'Error', description: 'Masukkan email tujuan', variant: 'destructive' });
|
||||
if (!isEmailConfigured) return toast({ title: 'Error', description: 'Lengkapi konfigurasi email provider terlebih dahulu', variant: 'destructive' });
|
||||
|
||||
setSendingTest(true);
|
||||
try {
|
||||
const { data, error } = await supabase.functions.invoke('send-email-v2', {
|
||||
body: {
|
||||
to: testEmail,
|
||||
api_token: emailSettings.api_token,
|
||||
from_name: emailSettings.from_name,
|
||||
from_email: emailSettings.from_email,
|
||||
subject: 'Test Email dari Access Hub',
|
||||
html_body: `
|
||||
<h2>Test Email</h2>
|
||||
<p>Ini adalah email uji coba dari aplikasi Access Hub Anda.</p>
|
||||
<p>Jika Anda menerima email ini, konfigurasi Mailketing API sudah berfungsi dengan baik!</p>
|
||||
<p>Kirim ke: ${testEmail}</p>
|
||||
<br>
|
||||
<p>Best regards,<br>Access Hub Team</p>
|
||||
`,
|
||||
},
|
||||
});
|
||||
|
||||
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) => {
|
||||
const { id, key, name, ...updates } = template;
|
||||
const { error } = await supabase.from('notification_templates').update(updates).eq('id', id);
|
||||
@@ -205,108 +125,29 @@ export function NotifikasiTab() {
|
||||
});
|
||||
};
|
||||
|
||||
const isEmailConfigured = emailSettings.api_token && emailSettings.from_email;
|
||||
|
||||
if (loading) return <div className="animate-pulse h-64 bg-muted rounded-md" />;
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Email Provider Settings */}
|
||||
{/* Notification Templates Info */}
|
||||
<Card className="border-2 border-border">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Mail className="w-5 h-5" />
|
||||
Pengaturan Email Provider
|
||||
Konfigurasi Email
|
||||
</CardTitle>
|
||||
<CardDescription>Konfigurasi provider email untuk pengiriman notifikasi</CardDescription>
|
||||
<CardDescription>
|
||||
Pengaturan provider email (Mailketing API) ada di tab <strong>Integrasi</strong>
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
{!isEmailConfigured && (
|
||||
<Alert variant="destructive" className="border-2">
|
||||
<AlertTriangle className="w-4 h-4" />
|
||||
<AlertDescription>
|
||||
Konfigurasi email provider belum lengkap. Email tidak akan terkirim.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label>Provider Email</Label>
|
||||
<Select
|
||||
value={emailSettings.provider}
|
||||
onValueChange={(value: 'mailketing') => setEmailSettings({ ...emailSettings, provider: value })}
|
||||
>
|
||||
<SelectTrigger className="border-2">
|
||||
<SelectValue placeholder="Pilih provider email" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="mailketing">Mailketing</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label className="flex items-center gap-2">
|
||||
<Key className="w-4 h-4" />
|
||||
API Token
|
||||
</Label>
|
||||
<Input
|
||||
type="password"
|
||||
value={emailSettings.api_token}
|
||||
onChange={(e) => setEmailSettings({ ...emailSettings, api_token: e.target.value })}
|
||||
placeholder="Masukkan API token dari Mailketing"
|
||||
className="border-2"
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Dapatkan API token dari menu Integration di dashboard Mailketing
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label>Nama Pengirim</Label>
|
||||
<Input
|
||||
value={emailSettings.from_name}
|
||||
onChange={(e) => setEmailSettings({ ...emailSettings, from_name: e.target.value })}
|
||||
placeholder="Nama Bisnis"
|
||||
className="border-2"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>Email Pengirim</Label>
|
||||
<Input
|
||||
type="email"
|
||||
value={emailSettings.from_email}
|
||||
onChange={(e) => setEmailSettings({ ...emailSettings, from_email: e.target.value })}
|
||||
placeholder="info@domain.com"
|
||||
className="border-2"
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Pastikan email sudah terdaftar di Mailketing
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4 pt-4 border-t">
|
||||
<Button onClick={saveEmailSettings} disabled={saving}>
|
||||
{saving ? 'Menyimpan...' : 'Simpan'}
|
||||
</Button>
|
||||
<div className="flex gap-2 flex-1">
|
||||
<Input
|
||||
type="email"
|
||||
value={testEmail}
|
||||
onChange={(e) => setTestEmail(e.target.value)}
|
||||
placeholder="Email uji coba"
|
||||
className="border-2 max-w-xs"
|
||||
/>
|
||||
<Button variant="outline" onClick={sendTestEmail} className="border-2" disabled={sendingTest}>
|
||||
<Send className="w-4 h-4 mr-2" />
|
||||
{sendingTest ? 'Mengirim...' : 'Kirim Email Uji Coba'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<CardContent>
|
||||
<Alert>
|
||||
<Mail className="w-4 h-4" />
|
||||
<AlertDescription>
|
||||
Konfigurasikan provider email di tab <strong>Integrasi → Provider Email</strong> untuk mengirim notifikasi.
|
||||
Gunakan Mailketing API untuk pengiriman email yang andal.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -336,10 +177,10 @@ export function NotifikasiTab() {
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs mt-2 p-2 bg-background rounded border">
|
||||
<strong>Penting:</strong> Email dikirim melalui Mailketing API. Pastikan API token valid
|
||||
dan domain pengirim sudah terdaftar di Mailketing. Toggle "Aktifkan" hanya mengontrol
|
||||
pengiriman email. Jika <code>webhook_url</code> diisi, sistem tetap akan mengirim payload
|
||||
ke URL tersebut meskipun email dinonaktifkan.
|
||||
<strong>Penting:</strong> Email dikirim melalui Mailketing API yang dikonfigurasi di tab Integrasi.
|
||||
Pastikan API token valid dan domain pengirim sudah terdaftar di Mailketing.
|
||||
Toggle "Aktifkan" hanya mengontrol pengiriman email. Jika <code>webhook_url</code> diisi,
|
||||
sistem tetap akan mengirim payload ke URL tersebut meskipun email dinonaktifkan.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user