Skip to content

Commit 84b1d35

Browse files
committed
feat(announcements): enhance announcement rendering and markdown support
- Implemented a `stripMarkdown` function to convert Markdown content to plain text for better preview handling in the announcement page. - Created an `AnnouncementPreview` component to render announcements with Markdown support, improving content display in the announcements tab. - Updated the announcement editor to utilize a dynamic Markdown editor, enhancing the editing experience for users.
1 parent cfadc84 commit 84b1d35

3 files changed

Lines changed: 79 additions & 430 deletions

File tree

app/(landing)/organizations/[id]/hackathons/[hackathonId]/announcement/page.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ import {
2929
import { Switch } from '@/components/ui/switch';
3030
import { reportError } from '@/lib/error-reporting';
3131

32+
/** Strip Markdown to plain text for list preview (headings, bold, links, etc.). */
33+
function stripMarkdown(md: string): string {
34+
if (!md || typeof md !== 'string') return '';
35+
return md
36+
.replace(/!\[[^\]]*\]\([^)]*\)/g, '')
37+
.replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
38+
.replace(/#{1,6}\s*/g, '')
39+
.replace(/\*\*([^*]+)\*\*/g, '$1')
40+
.replace(/\*([^*]+)\*/g, '$1')
41+
.replace(/__([^_]+)__/g, '$1')
42+
.replace(/_([^_]+)_/g, '$1')
43+
.replace(/`([^`]+)`/g, '$1')
44+
.replace(/<[^>]*>/g, '')
45+
.replace(/\n+/g, ' ')
46+
.trim();
47+
}
48+
3249
export default function AnnouncementPage() {
3350
const params = useParams();
3451
const organizationId = params.id as string;
@@ -298,7 +315,7 @@ export default function AnnouncementPage() {
298315
)}
299316
</div>
300317
<p className='line-clamp-2 text-sm text-zinc-400'>
301-
{item.content.replace(/<[^>]*>/g, '')}
318+
{stripMarkdown(item.content)}
302319
</p>
303320
<div className='flex items-center gap-4 text-xs text-zinc-500'>
304321
<span>

components/hackathons/announcements/AnnouncementsTab.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@ import { Megaphone, Pin, ArrowUpDown, ExternalLink } from 'lucide-react';
55
import { cn } from '@/lib/utils';
66
import type { HackathonAnnouncement } from '@/lib/api/hackathons/index';
77
import Link from 'next/link';
8+
import { useMarkdown } from '@/hooks/use-markdown';
9+
10+
/** Renders announcement body as Markdown (supports both Markdown and legacy HTML). */
11+
function AnnouncementPreview({ content }: { content: string }) {
12+
const raw = content?.trim() || '';
13+
const isLikelyHtml = raw.startsWith('<');
14+
const markdown = isLikelyHtml ? raw.replace(/<[^>]*>/g, ' ') : raw;
15+
const { styledContent, loading } = useMarkdown(markdown, {
16+
loadingDelay: 0,
17+
});
18+
19+
if (!raw) return <span className='text-zinc-500'>No content</span>;
20+
if (loading) return <span className='animate-pulse text-zinc-500'></span>;
21+
22+
return (
23+
<div className='[&_.markdown-content]:line-clamp-2 [&_.markdown-content]:overflow-hidden [&_.markdown-content]:text-sm [&_.markdown-content]:text-zinc-400 [&_.markdown-content_h1]:text-base [&_.markdown-content_h2]:text-base! [&_.markdown-content_h3]:text-base [&_.markdown-content_p]:my-0 [&_.markdown-content_p]:text-zinc-400'>
24+
{styledContent}
25+
</div>
26+
);
27+
}
828

929
interface AnnouncementsTabProps {
1030
announcements: HackathonAnnouncement[];
@@ -90,9 +110,7 @@ export function AnnouncementsTab({
90110
</h3>
91111
</div>
92112

93-
<p className='line-clamp-2 text-sm text-zinc-400'>
94-
{announcement.content.replace(/<[^>]*>/g, '')}
95-
</p>
113+
<AnnouncementPreview content={announcement.content} />
96114

97115
<div className='flex items-center gap-4 text-xs text-zinc-500'>
98116
<span className='flex items-center gap-1.5'>

0 commit comments

Comments
 (0)