File size: 4,253 Bytes
5e0532d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
'use client';

import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import type { Components } from 'react-markdown';

interface MarkdownMessageProps {
  content: string;
  variant?: 'user' | 'assistant';
}

export default function MarkdownMessage({ content, variant = 'assistant' }: MarkdownMessageProps) {
  const isUser = variant === 'user';

  const components: Components = {
    // Headings
    h1: ({ children }) => (
      <h1 className="text-lg font-bold mb-2 mt-3 first:mt-0 text-white">{children}</h1>
    ),
    h2: ({ children }) => (
      <h2 className="text-base font-semibold mb-2 mt-3 first:mt-0 text-white">{children}</h2>
    ),
    h3: ({ children }) => (
      <h3 className="text-sm font-semibold mb-1.5 mt-2 first:mt-0 text-white">{children}</h3>
    ),

    // Paragraphs
    p: ({ children }) => (
      <p className="mb-2 last:mb-0 leading-relaxed">{children}</p>
    ),

    // Strong/Bold - for scripture references
    strong: ({ children }) => (
      <strong className={`font-semibold ${isUser ? 'text-amber-200' : 'text-purple-300'}`}>
        {children}
      </strong>
    ),

    // Emphasis/Italic
    em: ({ children }) => (
      <em className="italic text-neutral-300">{children}</em>
    ),

    // Links
    a: ({ href, children }) => (
      <a
        href={href}
        target="_blank"
        rel="noopener noreferrer"
        className={`underline underline-offset-2 hover:no-underline transition-colors ${
          isUser ? 'text-amber-400 hover:text-amber-300' : 'text-purple-400 hover:text-purple-300'
        }`}
      >
        {children}
      </a>
    ),

    // Lists
    ul: ({ children }) => (
      <ul className="list-none space-y-1.5 my-2 ml-1">{children}</ul>
    ),
    ol: ({ children }) => (
      <ol className="list-decimal list-inside space-y-1.5 my-2 ml-1">{children}</ol>
    ),
    li: ({ children }) => (
      <li className="flex items-start gap-2">
        <span className={`mt-2 w-1.5 h-1.5 rounded-full shrink-0 ${isUser ? 'bg-amber-400/60' : 'bg-purple-400/60'}`} />
        <span className="flex-1">{children}</span>
      </li>
    ),

    // Blockquotes - for scripture
    blockquote: ({ children }) => (
      <blockquote className={`my-3 pl-4 border-l-2 ${
        isUser ? 'border-amber-500/40 bg-amber-500/5' : 'border-purple-500/40 bg-purple-500/5'
      } rounded-r-lg py-2 pr-3 italic`}>
        {children}
      </blockquote>
    ),

    // Code blocks
    code: ({ className, children }) => {
      const isInline = !className;
      if (isInline) {
        return (
          <code className={`px-1.5 py-0.5 rounded text-xs font-mono ${
            isUser ? 'bg-amber-500/20 text-amber-200' : 'bg-purple-500/20 text-purple-200'
          }`}>
            {children}
          </code>
        );
      }
      return (
        <code className="block p-3 my-2 rounded-lg bg-black/30 border border-white/10 text-xs font-mono overflow-x-auto text-neutral-200">
          {children}
        </code>
      );
    },

    // Pre for code blocks
    pre: ({ children }) => (
      <pre className="my-2 rounded-lg overflow-hidden">{children}</pre>
    ),

    // Horizontal rule
    hr: () => (
      <hr className={`my-4 border-t ${isUser ? 'border-amber-500/20' : 'border-purple-500/20'}`} />
    ),

    // Tables
    table: ({ children }) => (
      <div className="my-3 overflow-x-auto">
        <table className="w-full text-xs border-collapse">{children}</table>
      </div>
    ),
    thead: ({ children }) => (
      <thead className={`${isUser ? 'bg-amber-500/10' : 'bg-purple-500/10'}`}>{children}</thead>
    ),
    tbody: ({ children }) => <tbody>{children}</tbody>,
    tr: ({ children }) => (
      <tr className="border-b border-white/5">{children}</tr>
    ),
    th: ({ children }) => (
      <th className="px-3 py-2 text-left font-semibold text-white">{children}</th>
    ),
    td: ({ children }) => (
      <td className="px-3 py-2 text-neutral-300">{children}</td>
    ),
  };

  return (
    <div className={`prose prose-sm max-w-none ${isUser ? 'text-amber-50' : 'text-purple-50'}`}>
      <ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>
        {content}
      </ReactMarkdown>
    </div>
  );
}