From bcbf2cc112adba472fdefe9ce77a0db149ea94c2 Mon Sep 17 00:00:00 2001 From: Inamul-hasan-tec Date: Wed, 12 Aug 2026 15:02:23 +0530 Subject: [PATCH] feat(channels): implement PayloadPreviewModal side-by-side JSON inspector and Preview Transformed Payload button --- src/features/channels/api/channels.api.ts | 5 ++ .../channels/components/ChannelMappingTab.tsx | 26 +++++- .../components/PayloadPreviewModal.tsx | 84 +++++++++++++++++++ 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/features/channels/components/PayloadPreviewModal.tsx diff --git a/src/features/channels/api/channels.api.ts b/src/features/channels/api/channels.api.ts index ec8f291..b523b96 100644 --- a/src/features/channels/api/channels.api.ts +++ b/src/features/channels/api/channels.api.ts @@ -54,6 +54,11 @@ export const channelsApi = { const res = await apiClient.get>(`${BASE_URL}/${channelId}/jobs`); return res.data || []; }, + + previewPayload: async (channelId: string): Promise => { + const res = await apiClient.post>(`${BASE_URL}/${channelId}/preview`); + return res.data; + }, }; export default channelsApi; diff --git a/src/features/channels/components/ChannelMappingTab.tsx b/src/features/channels/components/ChannelMappingTab.tsx index f6273b3..9bcae75 100644 --- a/src/features/channels/components/ChannelMappingTab.tsx +++ b/src/features/channels/components/ChannelMappingTab.tsx @@ -1,8 +1,9 @@ import { useState, useEffect } from "react"; -import { Save, Plus, Trash2, ArrowRight } from "lucide-react"; +import { Save, Plus, Trash2, ArrowRight, Eye } from "lucide-react"; import { Button } from "../../../components/customs/Button"; import { channelsApi } from "../api/channels.api"; import { notify } from "../../../services/toast"; +import { PayloadPreviewModal } from "./PayloadPreviewModal"; const COMMON_PIM_ATTRIBUTES = [ { code: "name", label: "Product Title / Name (name)" }, @@ -34,6 +35,8 @@ export function ChannelMappingTab({ channelId }: { channelId: string }) { const [mappings, setMappings] = useState([]); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); + const [previewing, setPreviewing] = useState(false); + const [previewData, setPreviewData] = useState(null); useEffect(() => { loadMappings(); @@ -93,6 +96,18 @@ export function ChannelMappingTab({ channelId }: { channelId: string }) { } }; + const handlePreview = async () => { + setPreviewing(true); + try { + const data = await channelsApi.previewPayload(channelId); + setPreviewData(data); + } catch { + notify.error("Failed to generate transformation preview"); + } finally { + setPreviewing(false); + } + }; + if (loading) { return (
@@ -109,6 +124,9 @@ export function ChannelMappingTab({ channelId }: { channelId: string }) {

Map central PIM attributes to target storefront fields and apply transformation pipelines.

+ @@ -118,6 +136,12 @@ export function ChannelMappingTab({ channelId }: { channelId: string }) {
+ setPreviewData(null)} + previewData={previewData} + /> +
diff --git a/src/features/channels/components/PayloadPreviewModal.tsx b/src/features/channels/components/PayloadPreviewModal.tsx new file mode 100644 index 0000000..9b0fa94 --- /dev/null +++ b/src/features/channels/components/PayloadPreviewModal.tsx @@ -0,0 +1,84 @@ +import { Button } from "../../../components/customs/Button"; +import { Code, Check, Copy } from "lucide-react"; +import { useState } from "react"; + +interface PayloadPreviewModalProps { + isOpen: boolean; + onClose: () => void; + previewData: any; +} + +export function PayloadPreviewModal({ isOpen, onClose, previewData }: PayloadPreviewModalProps) { + const [copied, setCopied] = useState(false); + + if (!isOpen || !previewData) return null; + + const handleCopy = () => { + navigator.clipboard.writeText(JSON.stringify(previewData.adapterOutput, null, 2)); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }; + + return ( +
+
+ {/* Header */} +
+
+
+ +
+
+

Transformed Payload Preview

+

Real-time adapter transformation preview for channel: {previewData.channel?.name}

+
+
+ +
+ + {/* Content */} +
+ {/* Left Column: PIM Raw Data */} +
+
+ PIM Central Product (Raw JSON) +
+
+              {JSON.stringify(previewData.pimProductRaw, null, 2)}
+            
+
+ + {/* Right Column: Adapter Storefront Output */} +
+
+ Adapter Storefront Payload ({previewData.channel?.code}) + +
+
+              {JSON.stringify(previewData.adapterOutput, null, 2)}
+            
+
+
+ + {/* Footer */} +
+ +
+
+
+ ); +}