diff --git a/apps/dashboard/src/components/workflow-editor/steps/push/push-editor-preview.tsx b/apps/dashboard/src/components/workflow-editor/steps/push/push-editor-preview.tsx new file mode 100644 index 00000000000..c9031dfc436 --- /dev/null +++ b/apps/dashboard/src/components/workflow-editor/steps/push/push-editor-preview.tsx @@ -0,0 +1,116 @@ +import { CSSProperties, useEffect, useRef, useState } from 'react'; +import { type StepDataDto, type WorkflowResponseDto } from '@novu/shared'; +import { Code2 } from '@/components/icons/code-2'; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/primitives/accordion'; +import { Button } from '@/components/primitives/button'; +import { Editor } from '@/components/primitives/editor'; +import { loadLanguage } from '@uiw/codemirror-extensions-langs'; +import { useEditorPreview } from '../use-editor-preview'; +import { PushPreview } from './push-preview'; +import { RiCellphoneFill } from 'react-icons/ri'; +import { PushTabsSection } from './push-tabs-section'; + +const getInitialAccordionValue = (value: string) => { + try { + return Object.keys(JSON.parse(value)).length > 0 ? 'payload' : undefined; + } catch (e) { + return undefined; + } +}; + +type PushEditorPreviewProps = { + workflow: WorkflowResponseDto; + step: StepDataDto; + formValues: Record; +}; + +const extensions = [loadLanguage('json')?.extension ?? []]; + +export const PushEditorPreview = ({ workflow, step, formValues }: PushEditorPreviewProps) => { + const workflowSlug = workflow.workflowId; + const stepSlug = step.stepId; + const { editorValue, setEditorValue, previewStep, previewData, isPreviewPending } = useEditorPreview({ + workflowSlug, + stepSlug, + controlValues: formValues, + }); + const [accordionValue, setAccordionValue] = useState(getInitialAccordionValue(editorValue)); + const [payloadError, setPayloadError] = useState(''); + const [height, setHeight] = useState(0); + const contentRef = useRef(null); + + useEffect(() => { + setAccordionValue(getInitialAccordionValue(editorValue)); + }, [editorValue]); + + useEffect(() => { + const timeout = setTimeout(() => { + if (contentRef.current) { + const rect = contentRef.current.getBoundingClientRect(); + setHeight(rect.height); + } + }, 0); + + return () => clearTimeout(timeout); + }, [editorValue]); + + return ( + +
+
+ + Push template editor +
+
+ +
+ + + This preview shows how your message will appear on mobile. Actual rendering may vary by device. + +
+
+ + + +
+ + Configure preview +
+
+ + + {payloadError &&

{payloadError}

} + +
+
+
+
+
+ ); +}; diff --git a/apps/dashboard/src/components/workflow-editor/steps/push/push-preview.tsx b/apps/dashboard/src/components/workflow-editor/steps/push/push-preview.tsx index 45bf690dd72..468d0507cb6 100644 --- a/apps/dashboard/src/components/workflow-editor/steps/push/push-preview.tsx +++ b/apps/dashboard/src/components/workflow-editor/steps/push/push-preview.tsx @@ -111,7 +111,7 @@ export const PushContentContainerPreview = ({ children, className, ...rest }: HT export const PushBackgroundWithPhone = ({ children, className, ...rest }: HTMLAttributes) => { return ( -
+
{children}
); diff --git a/apps/dashboard/src/components/workflow-editor/steps/push/push-tabs.tsx b/apps/dashboard/src/components/workflow-editor/steps/push/push-tabs.tsx index 44bde28b18b..ad9fb2a1e39 100644 --- a/apps/dashboard/src/components/workflow-editor/steps/push/push-tabs.tsx +++ b/apps/dashboard/src/components/workflow-editor/steps/push/push-tabs.tsx @@ -4,12 +4,14 @@ import { StepEditorProps } from '@/components/workflow-editor/steps/configure-st import { PushEditor } from '@/components/workflow-editor/steps/push/push-editor'; import { CustomStepControls } from '../controls/custom-step-controls'; import { TemplateTabs } from '../template-tabs'; +import { PushEditorPreview } from './push-editor-preview'; +import { useFormContext } from 'react-hook-form'; export const PushTabs = (props: StepEditorProps) => { const { workflow, step } = props; const { dataSchema, uiSchema } = step.controls; const [tabsValue, setTabsValue] = useState('editor'); - + const form = useFormContext(); const isNovuCloud = workflow.origin === WorkflowOriginEnum.NOVU_CLOUD && uiSchema; const isExternal = workflow.origin === WorkflowOriginEnum.EXTERNAL; @@ -20,7 +22,7 @@ export const PushTabs = (props: StepEditorProps) => { ); - const previewContent = <>TODO; + const previewContent = ; return (