tags and other changes
This commit is contained in:
@@ -42,7 +42,7 @@ export default function LoadingBlog(props: any) {
|
||||
{Array.from({ length: numComponents }, (_, index) => (
|
||||
<ContentLoader
|
||||
speed={2}
|
||||
viewBox="0 0 340 50"
|
||||
viewBox="0 0 290 50"
|
||||
backgroundColor="#3b3b3b"
|
||||
foregroundColor="#f5304c"
|
||||
key={index}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import React from 'react';
|
||||
import Markdown from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkBreaks from 'remark-breaks';
|
||||
import remarkMath from 'remark-math';
|
||||
import rehypeRaw from 'rehype-raw';
|
||||
import rehypeKatex from 'rehype-katex';
|
||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import { gruvboxDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
|
||||
import 'katex/dist/katex.min.css';
|
||||
|
||||
type MarkdownRendererProps = {
|
||||
children: string;
|
||||
@@ -12,12 +16,11 @@ type MarkdownRendererProps = {
|
||||
export default function MarkdownRenderer({ children: markdown }: MarkdownRendererProps) {
|
||||
return (
|
||||
<Markdown
|
||||
remarkPlugins={[remarkGfm]}
|
||||
rehypePlugins={[rehypeRaw]}
|
||||
remarkPlugins={[remarkGfm, remarkMath, remarkBreaks]}
|
||||
rehypePlugins={[rehypeRaw, rehypeKatex]}
|
||||
components={{
|
||||
code({ node, inline, className, children, ...props }: any) {
|
||||
const match = /language-(\w+)/.exec(className || '');
|
||||
|
||||
return !inline && match ? (
|
||||
<SyntaxHighlighter style={gruvboxDark} PreTag="div" language={match[1]} {...props}>
|
||||
{String(children).replace(/\n$/, '')}
|
||||
@@ -28,9 +31,30 @@ export default function MarkdownRenderer({ children: markdown }: MarkdownRendere
|
||||
</code>
|
||||
);
|
||||
},
|
||||
ul({ children, ...props }) {
|
||||
return (
|
||||
<ul style={{ listStyleType: 'disc', listStylePosition: 'inside' }} {...props}>
|
||||
{children}
|
||||
</ul>
|
||||
);
|
||||
},
|
||||
ol({ children, ...props }) {
|
||||
return (
|
||||
<ol style={{ listStyleType: 'decimal', listStylePosition: 'inside' }} {...props}>
|
||||
{children}
|
||||
</ol>
|
||||
);
|
||||
},
|
||||
li({ children, ...props }) {
|
||||
return (
|
||||
<li style={{ marginBottom: '4px' }} {...props}>
|
||||
{children}
|
||||
</li>
|
||||
);
|
||||
},
|
||||
}}
|
||||
>
|
||||
{markdown}
|
||||
</Markdown>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import '../../Blog.css';
|
||||
import MarkdownRenderer from './MarkdownRenderer';
|
||||
import LoadingBlog, { LoadingBlogRead } from '../Loading';
|
||||
import { LoadingBlogRead } from '../Loading';
|
||||
|
||||
export default function Blog({ params }: { params: Promise<{ id: string }> }) {
|
||||
const [blog, setBlog] = useState({ title: '', date: '', markdown: '' });
|
||||
@@ -44,7 +44,12 @@ export default function Blog({ params }: { params: Promise<{ id: string }> }) {
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <div className="error">Error loading blog: {error}</div>; // Show error if there is one
|
||||
return (
|
||||
<main>
|
||||
<a href="/blog"><h1 className='name'>Leo's blog</h1></a>
|
||||
<div>Error: {error}</div>;
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -53,7 +58,7 @@ export default function Blog({ params }: { params: Promise<{ id: string }> }) {
|
||||
<div className='blog_container'>
|
||||
<h2 className='blog_title'>{blog.title}</h2>
|
||||
<p className='date'>{date}</p>
|
||||
<div className='markdown'><MarkdownRenderer>{blog.markdown}</MarkdownRenderer></div>
|
||||
<div className='markdown'><MarkdownRenderer>{blog.markdown.replaceAll('\n-\n', '\n<br/>\n')}</MarkdownRenderer></div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
|
||||
+85
-4
@@ -4,9 +4,58 @@ import React, { useEffect, useState } from 'react';
|
||||
import '../Blog.css';
|
||||
import LoadingBlog from './Loading';
|
||||
|
||||
type Blog = { title: string, description: string, id: string, date: string, tags: { name: string, color: string }[] };
|
||||
|
||||
const notionColors: { [index: string]: {
|
||||
background: string,
|
||||
color: string,
|
||||
} } = {
|
||||
default: {
|
||||
background: "#191919",
|
||||
color: "#D4D4D4"
|
||||
},
|
||||
gray: {
|
||||
background: "#252525",
|
||||
color: "#9B9B9B"
|
||||
},
|
||||
brown: {
|
||||
background: "#2E2724",
|
||||
color: "#A27763"
|
||||
},
|
||||
orange: {
|
||||
background: "#36291F",
|
||||
color: "#CB7B37"
|
||||
},
|
||||
yellow: {
|
||||
background: "#372E20",
|
||||
color: "#C19138"
|
||||
},
|
||||
green: {
|
||||
background: "#242B26",
|
||||
color: "#4F9768"
|
||||
},
|
||||
blue: {
|
||||
background: "#1F282D",
|
||||
color: "#447ACB"
|
||||
},
|
||||
purple: {
|
||||
background: "#2A2430",
|
||||
color: "#865DBB"
|
||||
},
|
||||
pink: {
|
||||
background: "#2E2328",
|
||||
color: "#BA4A78"
|
||||
},
|
||||
red: {
|
||||
background: "#332523",
|
||||
color: "#BE524B"
|
||||
}
|
||||
};
|
||||
|
||||
export default function Blog() {
|
||||
const [data, setData] = useState([{ title: '', description: '', id: '', date: '' }]);
|
||||
const [data, setData] = useState<Blog[]>([]);
|
||||
const [error, setError] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
@@ -16,6 +65,7 @@ export default function Blog() {
|
||||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
setData(result);
|
||||
setLoading(false);
|
||||
} else {
|
||||
const errorData = await response.text();
|
||||
setError(errorData);
|
||||
@@ -30,12 +80,19 @@ export default function Blog() {
|
||||
|
||||
|
||||
if (error) {
|
||||
return <div>Error: {JSON.stringify(error)}</div>; // Display any errors
|
||||
} if (data.length === 1 && data[0].id === '') {
|
||||
if (error) {
|
||||
return (
|
||||
<main>
|
||||
<a href="/blog"><h1 className='name'>Leo's blog</h1></a>
|
||||
<div>Error: {error}</div>;
|
||||
</main>
|
||||
)
|
||||
}
|
||||
} if (loading) {
|
||||
return (
|
||||
<main>
|
||||
<a href="/blog"><h1 className='name'>Leo's blog</h1></a>
|
||||
<LoadingBlog/>
|
||||
<LoadingBlog/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -53,6 +110,30 @@ export default function Blog() {
|
||||
<h2 className='title'>{blog.title}</h2>
|
||||
<p className='date'>{new Date(blog.date).toLocaleString('default', { month: 'long', day: 'numeric', year: 'numeric' })}</p>
|
||||
<p className='description'>{blog.description}</p>
|
||||
{blog.tags.map((tag, i) => (
|
||||
notionColors[tag.color] !== undefined ?
|
||||
<span key={i} style={{
|
||||
background: notionColors[tag.color].background,
|
||||
color: notionColors[tag.color].color,
|
||||
fontSize: '12px',
|
||||
border: '5px solid ' + notionColors[tag.color].background,
|
||||
fontFamily: 'sans-serif',
|
||||
borderRadius: '5px',
|
||||
display: 'inline-block',
|
||||
marginTop: '8px'
|
||||
}}>{tag.name}</span>
|
||||
:
|
||||
<span key={i} style={{
|
||||
background: tag.color,
|
||||
color: tag.color,
|
||||
fontSize: '12px',
|
||||
border: '5px solid ' + tag.color,
|
||||
fontFamily: 'sans-serif',
|
||||
borderRadius: '5px',
|
||||
display: 'inline-block',
|
||||
marginTop: '8px'
|
||||
}}>{tag.name}</span>
|
||||
))}
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user