@@ -2163,7 +2167,7 @@ export function DashboardPage() {
setMessageSubject(subj.startsWith('Re:') ? subj : `Re: ${subj}`);
setMessageBody('');
}}
- className="px-4 py-2 rounded-xl bg-emerald-500 hover:bg-emerald-400 text-slate-950 font-semibold text-xs flex items-center gap-1.5 cursor-pointer"
+ className="px-4 py-2 rounded-xl bg-emerald-500 hover:bg-emerald-400 text-slate-950 font-semibold text-xs flex items-center gap-1.5 cursor-pointer transition shadow-lg shadow-emerald-500/20"
>
Reply
diff --git a/PostFundManagement.PartnerUI/src/components/notifications/MessageViewer.tsx b/PostFundManagement.PartnerUI/src/components/notifications/MessageViewer.tsx
new file mode 100644
index 0000000..9d22279
--- /dev/null
+++ b/PostFundManagement.PartnerUI/src/components/notifications/MessageViewer.tsx
@@ -0,0 +1,186 @@
+import React, { useState, useMemo } from 'react';
+import {
+ Copy,
+ Check,
+ Mail,
+ MessageSquare,
+ Code2,
+ Eye,
+ ShieldCheck,
+} from 'lucide-react';
+import { NotificationPlatform } from '../../types';
+import { parseMarkdownToHtml, isHtmlContent, stripMarkdown } from '../../lib/markdownUtils';
+
+export interface MessageViewerProps {
+ content: string;
+ platform?: NotificationPlatform | number | string;
+ subject?: string;
+ className?: string;
+ showFormatHeader?: boolean;
+}
+
+export const MessageViewer: React.FC
= ({
+ content,
+ platform,
+ subject,
+ className = '',
+ showFormatHeader = true,
+}) => {
+ const [copied, setCopied] = useState(false);
+ const [showRaw, setShowRaw] = useState(false);
+
+ // Determine whether this message represents an Email (HTML) or In-App (Markup)
+ const isEmail = useMemo(() => {
+ if (
+ platform === NotificationPlatform.Email ||
+ platform === 1 ||
+ platform === '1' ||
+ String(platform).toLowerCase() === 'email'
+ ) {
+ return true;
+ }
+ // If platform is not explicitly InApp, detect if content is structured HTML
+ if (
+ platform !== NotificationPlatform.InApp &&
+ platform !== 5 &&
+ platform !== '5' &&
+ String(platform).toLowerCase() !== 'inapp' &&
+ isHtmlContent(content)
+ ) {
+ return true;
+ }
+ return false;
+ }, [platform, content]);
+
+ const isInApp = useMemo(() => {
+ if (
+ platform === NotificationPlatform.InApp ||
+ platform === 5 ||
+ platform === '5' ||
+ String(platform).toLowerCase() === 'inapp'
+ ) {
+ return true;
+ }
+ return !isEmail;
+ }, [platform, isEmail]);
+
+ // Convert the message to its respective format:
+ // - Email: HTML rendered
+ // - In-App: Markup (Markdown) parsed to HTML
+ const renderedHtml = useMemo(() => {
+ if (!content) return 'No message content
';
+
+ // Format 1: Email => HTML
+ if (isEmail) {
+ if (isHtmlContent(content)) {
+ return content.replace(/