Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions components/Git/Issue/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Avatar, Card, CardContent, CardProps, Chip } from '@mui/material';
import { marked } from 'marked';
import { Issue } from 'mobx-github';
import { FC } from 'react';
import { FC, useEffect, useState } from 'react';

import { SymbolIcon } from '../../Icon';

Expand All @@ -19,7 +19,20 @@ export const IssueCard: FC<IssueCardProps> = ({
comments,
created_at,
...props
}) => (
}) => {
const [parsedBody, setParsedBody] = useState<string>('');

useEffect(() => {
if (body) {
const parseMarkdown = async () => {
const html = await marked.parse(body);
setParsedBody(html);
};
parseMarkdown();
}
}, [body]);

return (
<Card {...props}>
<CardContent className="flex h-full flex-col justify-between gap-2">
<h2 className="text-2xl font-semibold">
Expand Down Expand Up @@ -48,7 +61,7 @@ export const IssueCard: FC<IssueCardProps> = ({
)}
</div>

<article dangerouslySetInnerHTML={{ __html: marked(body || '') }} />
<article dangerouslySetInnerHTML={{ __html: parsedBody }} />

<footer className="flex items-center justify-between">
{user && (
Expand All @@ -66,3 +79,4 @@ export const IssueCard: FC<IssueCardProps> = ({
</CardContent>
</Card>
);
};
22 changes: 18 additions & 4 deletions components/Member/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,28 @@ import { Button, CardProps, Chip, IconButton } from '@mui/material';
import { marked } from 'marked';
import { observer } from 'mobx-react';
import Link from 'next/link';
import { FC } from 'react';
import { FC, useEffect, useState } from 'react';

import { Member } from '../../models/Member';
import { GithubIcon } from '../Layout/Svg';

export type MemberCardProps = Member & Omit<CardProps, 'id'>;

export const MemberCard: FC<MemberCardProps> = observer(
({ className = '', nickname, skill, position, summary, github }) => (
({ className = '', nickname, skill, position, summary, github }) => {
const [parsedSummary, setParsedSummary] = useState<string>('');

useEffect(() => {
if (summary) {
const parseMarkdown = async () => {
const html = await marked.parse((summary as string) || '');
setParsedSummary(html);
};
parseMarkdown();
}
}, [summary]);

return (
<li
className={`elevation-1 hover:elevation-4 relative rounded-2xl border border-gray-200 p-4 dark:border-0 ${className} mb-4 flex break-inside-avoid flex-col gap-3`}
>
Expand Down Expand Up @@ -59,9 +72,10 @@ export const MemberCard: FC<MemberCardProps> = observer(
</ul>

<p
dangerouslySetInnerHTML={{ __html: marked((summary as string) || '') }}
dangerouslySetInnerHTML={{ __html: parsedSummary }}
className="text-neutral-500"
/>
</li>
),
);
},
);
72 changes: 72 additions & 0 deletions components/User/SessionBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Drawer, List, ListItem, ListItemButton, ListItemText } from '@mui/material';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import { Component, HTMLAttributes, JSX } from 'react';

import { PageHead } from '../PageHead';
import { SessionForm } from './SessionForm';

export type MenuItem = Pick<JSX.IntrinsicElements['a'], 'href' | 'title'>;

export interface SessionBoxProps extends HTMLAttributes<HTMLDivElement> {
path?: string;
menu?: MenuItem[];
jwtPayload?: any; // TODO: Define proper JWT payload type
}

@observer
export class SessionBox extends Component<SessionBoxProps> {
@observable
accessor modalShown = false;

componentDidMount() {
this.modalShown = !this.props.jwtPayload;
}

render() {
const { className = '', title, children, path, menu = [], jwtPayload, ...props } = this.props;

return (
<div className={`flex ${className}`} {...props}>
<div>
<List
component="nav"
className="flex-col px-3 sticky-top"
style={{ top: '5rem', minWidth: '200px' }}
>
{menu.map(({ href, title }) => (
<ListItem key={href} disablePadding>
<ListItemButton
href={href}
selected={path?.split('?')[0].startsWith(href!)}
className="rounded"
>
<ListItemText primary={title} />
</ListItemButton>
</ListItem>
))}
</List>
</div>
<main className="flex-1 pb-3">
<PageHead title={title} />

<h1 className="text-3xl font-bold mb-4">{title}</h1>

{children}

<Drawer
anchor="right"
open={this.modalShown}
onClose={() => (this.modalShown = false)}
PaperProps={{
className: 'p-4',
style: { width: '400px' },
}}
>
<SessionForm onSignIn={() => window.location.reload()} />
</Drawer>
</main>
</div>
);
}
}
Loading