Skip to content

Commit 5f49850

Browse files
committed
handle markdown in collaborative summary
1 parent b76a27d commit 5f49850

File tree

5 files changed

+1794
-76
lines changed

5 files changed

+1794
-76
lines changed

app/[locale]/(user)/collaboratives/CollaborativesListingClient.tsx

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,44 @@ import { useState } from 'react';
1515
import { cn } from '@/lib/utils';
1616
import Styles from '../datasets/dataset.module.scss';
1717

18+
// Helper function to strip markdown and HTML tags for card preview
19+
const stripMarkdown = (markdown: string): string => {
20+
if (!markdown) return '';
21+
return markdown
22+
// Remove code blocks first (before other replacements)
23+
.replace(/```[\s\S]*?```/g, '')
24+
// Remove inline code
25+
.replace(/`([^`]+)`/g, '$1')
26+
// Remove images
27+
.replace(/!\[([^\]]*)\]\([^\)]+\)/g, '$1')
28+
// Remove links
29+
.replace(/\[([^\]]+)\]\([^\)]+\)/g, '$1')
30+
// Remove headers
31+
.replace(/^#{1,6}\s+/gm, '')
32+
// Remove bold
33+
.replace(/\*\*([^*]+)\*\*/g, '$1')
34+
.replace(/__([^_]+)__/g, '$1')
35+
// Remove italic
36+
.replace(/\*([^*]+)\*/g, '$1')
37+
.replace(/_([^_]+)_/g, '$1')
38+
// Remove strikethrough
39+
.replace(/~~([^~]+)~~/g, '$1')
40+
// Remove blockquotes
41+
.replace(/^\s*>\s+/gm, '')
42+
// Remove horizontal rules
43+
.replace(/^(-{3,}|_{3,}|\*{3,})$/gm, '')
44+
// Remove list markers
45+
.replace(/^\s*[-*+]\s+/gm, '')
46+
.replace(/^\s*\d+\.\s+/gm, '')
47+
// Remove HTML tags
48+
.replace(/<[^>]*>/g, '')
49+
// Remove extra whitespace and newlines
50+
.replace(/\n\s*\n/g, '\n')
51+
.replace(/\n/g, ' ')
52+
.replace(/\s+/g, ' ')
53+
.trim();
54+
};
55+
1856
const PublishedCollaboratives = graphql(`
1957
query PublishedCollaboratives {
2058
publishedCollaboratives {
@@ -326,7 +364,7 @@ const CollaborativesListingClient = () => {
326364
label: 'Published by',
327365
},
328366
]}
329-
description={collaborative.summary || ''}
367+
description={stripMarkdown(collaborative.summary || '')}
330368
/>
331369
))}
332370
</div>

app/[locale]/(user)/collaboratives/components/Details.tsx

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import React, { useState } from 'react';
44
import Image from 'next/image';
55
import { Button, Icon, Spinner, Tag, Text, Tray } from 'opub-ui';
6+
import ReactMarkdown from 'react-markdown';
7+
import rehypeRaw from 'rehype-raw';
8+
import remarkGfm from 'remark-gfm';
69

710
import { Icons } from '@/components/icons';
811
import Metadata from './Metadata';
@@ -13,7 +16,9 @@ const PrimaryDetails = ({ data, isLoading }: { data: any; isLoading: any }) => {
1316
return (
1417
<div>
1518
<div>
16-
<Text variant="heading2xl" color="onBgDefault">{data.collaborativeBySlug.title}</Text>
19+
<Text variant="heading2xl" color="onBgDefault">
20+
{data.collaborativeBySlug.title}
21+
</Text>
1722
</div>
1823
<div className="mt-4 flex flex-wrap gap-2">
1924
{data.collaborativeBySlug.tags.map((item: any, index: number) => (
@@ -72,7 +77,7 @@ const PrimaryDetails = ({ data, isLoading }: { data: any; isLoading: any }) => {
7277
/>
7378
</div>
7479
)}
75-
80+
7681
{/* Stats Section */}
7782
<div className="mt-10 flex flex-wrap items-center gap-8 lg:mt-12 lg:gap-0">
7883
<div className="flex flex-col border-x-[1px] border-solid border-tertiaryAccent px-8">
@@ -83,7 +88,7 @@ const PrimaryDetails = ({ data, isLoading }: { data: any; isLoading: any }) => {
8388
Use Cases
8489
</Text>
8590
</div>
86-
91+
8792
<div className="flex flex-col border-x-[1px] border-solid border-tertiaryAccent px-8">
8893
<Text variant="heading3xl" className="text-secondaryOrange">
8994
{data.collaborativeBySlug.datasets?.length || 0}
@@ -92,17 +97,17 @@ const PrimaryDetails = ({ data, isLoading }: { data: any; isLoading: any }) => {
9297
Datasets
9398
</Text>
9499
</div>
95-
100+
96101
<div className="flex flex-col border-x-[1px] border-solid border-tertiaryAccent px-8">
97102
<Text variant="heading3xl" className="text-secondaryOrange">
98-
{(data.collaborativeBySlug.supportingOrganizations?.length || 0) +
99-
(data.collaborativeBySlug.partnerOrganizations?.length || 0)}
103+
{(data.collaborativeBySlug.supportingOrganizations?.length || 0) +
104+
(data.collaborativeBySlug.partnerOrganizations?.length || 0)}
100105
</Text>
101106
<Text variant="bodyLg" color="onBgDefault" className="w-24">
102107
Organizations
103108
</Text>
104109
</div>
105-
110+
106111
<div className="flex flex-col border-x-[1px] border-solid border-tertiaryAccent px-8">
107112
<Text variant="heading3xl" className="text-secondaryOrange">
108113
{data.collaborativeBySlug.contributors?.length || 0}
@@ -112,31 +117,41 @@ const PrimaryDetails = ({ data, isLoading }: { data: any; isLoading: any }) => {
112117
</Text>
113118
</div>
114119
</div>
115-
120+
116121
<div className=" lg:pr-4">
117-
{data.collaborativeBySlug.geographies && data.collaborativeBySlug.geographies.length > 0 && (
118-
<div className="mt-6 lg:mt-10">
119-
<Text variant="headingXl" color="onBgDefault">Geographies</Text>
120-
<div className="mt-4 flex flex-wrap gap-2">
121-
{data.collaborativeBySlug.geographies.map((geo: any, index: number) => (
122-
<Tag
123-
key={index}
124-
fillColor="var(--orange-secondary-color)"
125-
borderColor="var(--orange-secondary-text)"
126-
textColor="black"
127-
>
128-
{geo.name}
129-
</Tag>
130-
))}
122+
{data.collaborativeBySlug.geographies &&
123+
data.collaborativeBySlug.geographies.length > 0 && (
124+
<div className="mt-6 lg:mt-10">
125+
<Text variant="headingXl" color="onBgDefault">
126+
Geographies
127+
</Text>
128+
<div className="mt-4 flex flex-wrap gap-2">
129+
{data.collaborativeBySlug.geographies.map(
130+
(geo: any, index: number) => (
131+
<Tag
132+
key={index}
133+
fillColor="var(--orange-secondary-color)"
134+
borderColor="var(--orange-secondary-text)"
135+
textColor="black"
136+
>
137+
{geo.name}
138+
</Tag>
139+
)
140+
)}
141+
</div>
131142
</div>
132-
</div>
133-
)}
143+
)}
134144
<div className="mt-6 lg:mt-10">
135-
<Text variant="headingXl" color="onBgDefault">Summary</Text>
136-
<div className="mt-4">
137-
<Text variant="bodyLg" fontWeight="regular" className="leading-5" color="onBgDefault">
145+
<Text variant="headingXl" color="onBgDefault">
146+
Summary
147+
</Text>
148+
<div className="prose-h1:text-3xl prose-h2:text-2xl prose-h3:text-xl prose-p:leading-relaxed prose-a:text-blue-400 hover:prose-a:text-blue-300 prose-code:bg-gray-800 prose-code:rounded prose-pre:bg-gray-900 prose-pre:border prose-pre:border-gray-700 prose-blockquote:border-l-blue-500 prose-th:bg-gray-800 prose-img:rounded-lg prose prose-lg prose-invert mt-4 max-w-none prose-headings:text-white prose-p:text-white prose-a:underline prose-blockquote:text-white prose-strong:text-white prose-em:text-white prose-code:px-1 prose-code:py-0.5 prose-code:text-white prose-code:before:content-none prose-code:after:content-none prose-pre:text-white prose-ol:text-white prose-ul:text-white prose-li:text-white prose-li:marker:text-white prose-table:text-white prose-thead:border-white prose-tr:border-white prose-th:border-white prose-th:text-white prose-td:border-white prose-td:text-white prose-hr:border-white">
149+
<ReactMarkdown
150+
remarkPlugins={[remarkGfm]}
151+
rehypePlugins={[rehypeRaw]}
152+
>
138153
{data.collaborativeBySlug.summary}
139-
</Text>
154+
</ReactMarkdown>
140155
</div>
141156
</div>
142157
</div>

0 commit comments

Comments
 (0)