Skip to content

Commit dc0a6ca

Browse files
committed
Use markdown-it for mentorship portal summaries
1 parent 1dfdcf0 commit dc0a6ca

File tree

7 files changed

+50
-16
lines changed

7 files changed

+50
-16
lines changed

frontend/__tests__/unit/components/MarkdownWrapper.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jest.mock('dompurify', () => ({
66
sanitize: (html: string) => html,
77
}))
88

9-
jest.mock('markdown-it/index.mjs', () => {
9+
jest.mock('markdown-it', () => {
1010
return jest.fn().mockImplementation(() => ({
1111
render: (content: string) => {
1212
// Very simple mock: replace **bold** and [link](url)

frontend/__tests__/unit/components/ProgramCard.test.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,7 @@ describe('ProgramCard', () => {
276276
)
277277

278278
expect(screen.getByText(longDescription)).toBeInTheDocument()
279-
expect(screen.getByText(longDescription)).toBeInTheDocument()
280-
const descriptionElement = screen.getByText(longDescription)
279+
const descriptionElement = screen.getByText(longDescription).closest('.md-wrapper')
281280
expect(descriptionElement).toHaveClass('line-clamp-8')
282281
})
283282

@@ -296,7 +295,7 @@ describe('ProgramCard', () => {
296295

297296
expect(screen.getByText('Short description')).toBeInTheDocument()
298297

299-
const descriptionElement = screen.getByText('Short description')
298+
const descriptionElement = screen.getByText('Short description').closest('.md-wrapper')
300299
expect(descriptionElement).toHaveClass('line-clamp-8')
301300
})
302301

frontend/src/app/globals.css

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,22 @@
131131
color: #1d7bd7;
132132
}
133133

134+
a .md-wrapper {
135+
color: rgb(75 85 99); /* gray-600 */
136+
}
137+
138+
.dark a .md-wrapper {
139+
color: rgb(156 163 175); /* gray-400 */
140+
}
141+
142+
a .md-wrapper a {
143+
color: #1d7bd7;
144+
}
145+
146+
.dark a .md-wrapper a {
147+
color: #1d7bd7;
148+
}
149+
134150
.navlink {
135151
color: inherit;
136152
}
@@ -253,6 +269,24 @@
253269
transition: transform 1s ease;
254270
}
255271

272+
.md-wrapper ul,
273+
.md-wrapper ol {
274+
margin: 0 0 1em 1.5em;
275+
padding-left: 1.5em;
276+
}
277+
278+
.md-wrapper ul {
279+
list-style-type: disc;
280+
}
281+
282+
.md-wrapper ol {
283+
list-style-type: decimal;
284+
}
285+
286+
.md-wrapper li {
287+
margin: 0.25em 0;
288+
}
289+
256290
.flip-container:hover .icon-flip {
257291
transform: rotateY(180deg);
258292
}

frontend/src/components/CardDetailsPage.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import HealthMetrics from 'components/HealthMetrics'
2222
import InfoBlock from 'components/InfoBlock'
2323
import Leaders from 'components/Leaders'
2424
import LeadersList from 'components/LeadersList'
25+
import Markdown from 'components/MarkdownWrapper'
2526
import MenteeContributorsList from 'components/MenteeContributorsList'
2627
import MetricsScoreCircle from 'components/MetricsScoreCircle'
2728
import Milestones from 'components/Milestones'
@@ -77,14 +78,12 @@ const DetailsCard = ({
7778
const { data } = useSession()
7879

7980
// compute styles based on type prop
80-
const secondaryCardStyles = (() => {
81-
if (type === 'program' || type === 'module') {
82-
return 'gap-2 md:col-span-7'
83-
} else if (type === 'chapter') {
84-
return 'gap-2 md:col-span-3'
85-
}
86-
return 'gap-2 md:col-span-5'
87-
})()
81+
const typeStylesMap = new Map([
82+
['program', 'gap-2 md:col-span-7'],
83+
['module', 'gap-2 md:col-span-7'],
84+
['chapter', 'gap-2 md:col-span-3'],
85+
])
86+
const secondaryCardStyles = typeStylesMap.get(type) ?? 'gap-2 md:col-span-5'
8887

8988
return (
9089
<div className="min-h-screen bg-white p-8 text-gray-600 dark:bg-[#212529] dark:text-gray-300">
@@ -121,7 +120,7 @@ const DetailsCard = ({
121120
<p className="mb-6 text-xl">{description}</p>
122121
{summary && (
123122
<SecondaryCard icon={faCircleInfo} title={<AnchorTitle title="Summary" />}>
124-
<p>{summary}</p>
123+
<Markdown content={summary} />
125124
</SecondaryCard>
126125
)}
127126

frontend/src/components/MarkdownWrapper.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import DOMPurify from 'dompurify'
2-
import markdownit from 'markdown-it/index.mjs'
2+
import markdownit from 'markdown-it'
33
import taskLists from 'markdown-it-task-lists'
44

55
export default function Markdown({ content, className }: { content: string; className?: string }) {

frontend/src/components/ProgramCard.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type React from 'react'
55
import { GetProgramAndModulesDocument } from 'types/__generated__/programsQueries.generated'
66
import { Program } from 'types/mentorship'
77
import EntityActions from 'components/EntityActions'
8+
import Markdown from 'components/MarkdownWrapper'
89

910
interface ProgramCardProps {
1011
program: Program
@@ -96,7 +97,7 @@ const ProgramCard: React.FC<ProgramCardProps> = ({ program, href, accessLevel, i
9697
</span>
9798
)}
9899
</div>
99-
<p className="line-clamp-8 text-sm text-gray-700 dark:text-gray-300">{description}</p>
100+
<Markdown content={description} className="line-clamp-8" />
100101
</div>
101102
</div>
102103
</Link>

frontend/src/components/SingleModuleCard.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { ExtendedSession } from 'types/auth'
1111
import type { Module } from 'types/mentorship'
1212
import { formatDate } from 'utils/dateFormatter'
1313
import EntityActions from 'components/EntityActions'
14+
import Markdown from 'components/MarkdownWrapper'
1415
import { getSimpleDuration } from 'components/ModuleCard'
1516
import TopContributorsList from 'components/TopContributorsList'
1617

@@ -67,7 +68,7 @@ const SingleModuleCard: React.FC<SingleModuleCardProps> = ({ module, accessLevel
6768

6869
{/* Description */}
6970
<div>
70-
<p>{module.description}</p>
71+
<Markdown content={module.description} />
7172
</div>
7273

7374
{/* Details */}

0 commit comments

Comments
 (0)