diff --git a/components/Layout/Dashboard/API-Integrations/WebhookManager.tsx b/components/Layout/Dashboard/API-Integrations/WebhookManager.tsx index b854922..6f606d7 100644 --- a/components/Layout/Dashboard/API-Integrations/WebhookManager.tsx +++ b/components/Layout/Dashboard/API-Integrations/WebhookManager.tsx @@ -22,6 +22,9 @@ import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import { ScrollArea } from '@/components/ui/scroll-area'; +import { saveWebhookCredentials } from '@/lib/db/content'; +import { toast } from 'sonner'; +import { useContent } from '@/context/GenerationContext'; // Mock Encryption/Decryption Utility (Simulating secure storage/retrieval) const mockEncrypt = (data) => `ENC:${btoa(data)}`; @@ -71,7 +74,9 @@ const WebhookFormDialog = ({ isOpen, onClose, initialData, onSave, status, messa }, [initialData]); useEffect(() => { - setMessageBox({ message, status }) + const timer = setTimeout(() => setMessageBox({ message, status }), 300); + + return () => clearTimeout(timer); }, [status, message]); @@ -81,7 +86,6 @@ const WebhookFormDialog = ({ isOpen, onClose, initialData, onSave, status, messa try { const url = new URL(formData.url.trim()); if (url.protocol !== 'https:') { - // Using console.error instead of alert as per instructions console.error("Validation Error: Only HTTPS URLs are permitted for security."); // setMessageBox('Validation Error: Only HTTPS URLs are permitted for security.', 'error'); return; @@ -221,17 +225,17 @@ const WebhookFormDialog = ({ isOpen, onClose, initialData, onSave, status, messa // --- Main Webhook Manager Component --- export const WebhookManager = () => { - // Initialize state with mock data. We decrypt for display purposes. - const [webhooks, setWebhooks] = useState(initialMockWebhooks.map(h => ({ - ...h, - secret_key: mockDecrypt(h.secret_key), - }))); + const { + webhookCredentials: webhooks, + setWebhookCredentials: setWebhooks, + isWebhookCredentialsLoading + } = useContent(); const [isDialogOpen, setIsDialogOpen] = useState(false); const [editingWebhook, setEditingWebhook] = useState(null); // UI Status State (used for global actions like delete or toggle) - const [status, setStatus] = useState('idle'); // 'idle', 'loading', 'success', 'error' + const [status, setStatus] = useState<'idle'| 'loading'| 'success'| 'error'>('idle'); const [message, setMessage] = useState(''); // --- CRUD Handlers (Local State Management) --- @@ -247,12 +251,11 @@ export const WebhookManager = () => { setIsDialogOpen(true); }; - const handleSave = (data) => { + const handleSave = async (data) => { setStatus('loading'); setMessage(data.id ? 'Updating webhook...' : 'Creating new webhook...'); - // Simulate async operation delay - setTimeout(() => { + try { const dataToSave = { ...data, // Re-encrypt the key before saving to mock persistent storage @@ -260,6 +263,8 @@ export const WebhookManager = () => { updated_at: Date.now(), }; + await saveWebhookCredentials(dataToSave); + setWebhooks(prevHooks => { if (data.id) { // Update existing hook @@ -286,7 +291,12 @@ export const WebhookManager = () => { setIsDialogOpen(false); }, 1000); - }, 500); // Mock network delay + }catch (e) { + toast.error(e.message || "Error saving webhook..."); + setMessage("Error saving webhook...") + }finally { + + } }; const handleDelete = (id) => { @@ -353,9 +363,9 @@ export const WebhookManager = () => {
{message}
) : ( -No webhooks configured.
diff --git a/context/GenerationContext.tsx b/context/GenerationContext.tsx
index 6299514..113f5c6 100644
--- a/context/GenerationContext.tsx
+++ b/context/GenerationContext.tsx
@@ -6,7 +6,12 @@ import { toast } from 'sonner';
import { ReadonlyURLSearchParams, useParams, useRouter, useSearchParams } from 'next/navigation';
import { createClient } from '@/utils/supabase/client';
import { useAuth } from '@/context/AuthContext';
-import { getGeneratedContents, getScheduledJobs } from '@/lib/db/content';
+import {
+ getGeneratedContents,
+ getScheduledJobs,
+ getWebhookCredentials,
+ WebhookCredentials,
+} from '@/lib/db/content';
import { SystemPromptOption } from '@/components/Layout/Dashboard/Generate/AISystemConfig';
import { predefinedPrompts } from '@/lib/AI/ai.system.prompt';
import { refinePrompt } from '@/lib/AI/ai.actions';
@@ -118,6 +123,11 @@ interface GenerationContextType {
onRefinePrompt: () => Promise