Skip to content

Commit c4a3c1d

Browse files
committed
feat: use local mdx implementation instead of notion for experiences
1 parent b65e315 commit c4a3c1d

File tree

18 files changed

+254
-112
lines changed

18 files changed

+254
-112
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ Source code of my personal website & blog ✨
44

55
Check the live version [here](https://shellbear.me/) ⚡️
66

7-
[![home](./.github/img/home.png)](https://shellbear.me/)
8-
[![blog](./.github/img/blog.png)](https://shellbear.me/)
7+
[![home](./.github/img/home.webp)](https://shellbear.me/)
8+
[![blog](./.github/img/blog.webp)](https://shellbear.me/)
99

1010
## ✨ Features
1111

components/Layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const Layout: React.FC<LayoutProps> = ({
3636
<meta name="twitter:card" content="summary_large_image" />
3737
<meta
3838
property="og:image"
39-
content="https://shellbear.me/img/preview.png"
39+
content="https://shellbear.me/img/preview.webp"
4040
/>
4141
{process.env.NODE_ENV === 'production' && (
4242
<>

components/MDXContent.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { MDXRemote, MDXRemoteProps } from 'next-mdx-remote';
2+
import { memo } from 'react';
3+
import styled from 'styled-components';
4+
import Text from './Text';
5+
6+
interface MDXContentProps extends MDXRemoteProps {}
7+
8+
const List = styled.ul`
9+
padding-left: 2rem;
10+
`;
11+
12+
const ListItem = styled.li`
13+
margin: 0.5rem 0;
14+
font-size: medium;
15+
margin: 0.75rem 0;
16+
color: rgba(0, 0, 0, 0.7);
17+
white-space: pre-wrap;
18+
line-height: 160%;
19+
letter-spacing: 0.02em;
20+
`;
21+
22+
const MDXContent = ({ components, ...props }: MDXContentProps) => (
23+
<MDXRemote
24+
{...props}
25+
components={{
26+
p: Text,
27+
ul: List,
28+
li: ListItem,
29+
...components,
30+
}}
31+
/>
32+
);
33+
34+
export default memo(MDXContent);

components/Text.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
fontWeight,
77
display,
88
typography,
9+
color,
910
layout,
1011
compose,
1112
TextAlignProps,
@@ -34,6 +35,7 @@ const Text = styled.p<
3435
letter-spacing: 0.02em;
3536
3637
${compose(
38+
color,
3739
textAlign,
3840
margin,
3941
fontSize,

components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ export { default as List } from './List';
1010
export { default as Card } from './Card';
1111
export { default as Image } from './Image';
1212
export { default as TransparentLink } from './TransparentLink';
13+
export { default as MDXContent } from './MDXContent';

notion/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { Client } from '@notionhq/client';
2-
32
const notion = new Client({
43
auth: process.env.NOTION_TOKEN,
54
});
65

7-
export const getBookmarks = async () =>
8-
await notion.databases.query({
6+
export const getBookmarks = async () => {
7+
return await notion.databases.query({
98
database_id: process.env.NOTION_BOOKMARKS_ID!,
109
page_size: 10000,
1110
sorts: [
@@ -15,3 +14,4 @@ export const getBookmarks = async () =>
1514
},
1615
],
1716
});
17+
};

pages/about.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,7 @@ const About = ({ experiences }: AboutProps): JSX.Element => {
166166
<Title fontSize="1.5rem" margin={0} as="h3">
167167
{data.title}
168168
</Title>
169-
<Text
170-
fontSize="smaller"
171-
margin={0}
172-
color="rgba(0, 0, 0, 0.1)"
173-
>
169+
<Text fontSize="smaller" margin={0}>
174170
{data.date}
175171
</Text>
176172
</Grid>

pages/about/[slug].tsx

Lines changed: 78 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,85 @@
1-
import { GetStaticPaths, GetStaticPropsResult, NextPage } from 'next';
2-
import dynamic from 'next/dynamic';
3-
import { NotionRenderer } from 'react-notion-x';
4-
import { NotionAPI } from 'notion-client';
1+
import {
2+
GetStaticPaths,
3+
GetStaticProps,
4+
InferGetStaticPropsType,
5+
NextPage,
6+
} from 'next';
57
import Head from 'next/head';
6-
import { getPageInfo, Page, EXPERIENCES } from '@posts/notion';
7-
import { Container } from '@components';
8-
import { ComponentProps } from 'react';
8+
import { Container, Title, Text, MDXContent } from '@components';
9+
import { getPosts, Post } from '@posts';
10+
import Image from 'next/image';
911

10-
const Code = dynamic(
11-
async () => (await import('react-notion-x/build/third-party/code')).Code,
12-
);
13-
14-
interface BlogProps {
15-
page: Page;
16-
recordMap: ComponentProps<typeof NotionRenderer>['recordMap'];
17-
}
18-
19-
const About: NextPage<BlogProps> = ({ page, recordMap }) => (
12+
const About: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = ({
13+
experience,
14+
}) => (
2015
<Container
2116
width={['100%', 1200]}
2217
maxWidth="100vw"
2318
marginBottom={['1rem', '4rem']}
2419
>
2520
<Head>
26-
<title>{page.title}</title>
27-
<meta property="og:title" content={page.title} />
21+
<title>{experience.data.title}</title>
22+
<meta property="og:title" content={experience.data.title} />
23+
<meta property="og:description" content={experience.data.description} />
2824
</Head>
29-
<NotionRenderer
30-
fullPage
31-
className="notion-container"
32-
recordMap={recordMap}
33-
components={{
34-
Code,
25+
<Container alignItems="flex-start" mb="2rem">
26+
<Container flexDirection="row" gridColumnGap="1rem" gridRowGap=".2rem">
27+
{experience.data.tags.map((tag: string) => (
28+
<Text fontSize="small" color="plum" key={tag} m="0">
29+
#{tag}
30+
</Text>
31+
))}
32+
</Container>
33+
<Title fontSize={['2.5rem', '4rem']} textAlign="justify">
34+
{experience.data.title} - {experience.data.post}
35+
</Title>
36+
<Container
37+
flexDirection="row"
38+
gridGap="1.5rem"
39+
alignItems="center"
40+
mb="2rem"
41+
>
42+
<Text>📅 {experience.data.date}</Text>
43+
<a href={experience.data.link}>🔗 Website</a>
44+
</Container>
45+
<Container position="relative" width="100%" height="300px">
46+
<Image
47+
src={experience.data.image}
48+
alt={experience.data.title}
49+
layout="fill"
50+
objectFit="cover"
51+
/>
52+
</Container>
53+
<Container mt="1rem" gridGap="1rem">
54+
<Container
55+
pl="2rem"
56+
backgroundColor="rgb(241, 241, 239)"
57+
borderRadius="3px"
58+
>
59+
<Text as="h3" fontWeight="normal">
60+
{experience.data.description}
61+
</Text>
62+
</Container>
63+
<Text m="0" fontSize="smaller">
64+
{experience.data.stack.join(', ')}
65+
</Text>
66+
</Container>
67+
</Container>
68+
<hr
69+
style={{
70+
width: '100%',
71+
border: '1px solid rgba(0,0,0,0.1)',
3572
}}
3673
/>
74+
<MDXContent {...experience.source} />
3775
</Container>
3876
);
3977

4078
export const getStaticPaths: GetStaticPaths = async () => {
79+
const experiences = await getPosts('experiences');
80+
4181
return {
42-
paths: Object.keys(EXPERIENCES).map((slug) => ({
82+
paths: experiences.map(({ data: { slug } }) => ({
4383
params: {
4484
slug,
4585
},
@@ -48,30 +88,22 @@ export const getStaticPaths: GetStaticPaths = async () => {
4888
};
4989
};
5090

51-
type Params = {
52-
params: {
53-
slug: keyof typeof EXPERIENCES;
54-
};
55-
};
91+
export const getStaticProps: GetStaticProps<
92+
{ experience: Post },
93+
{ slug: string }
94+
> = async ({ params }) => {
95+
const experiences = await getPosts('experiences');
96+
const experience = experiences.find(({ data }) => data.slug === params?.slug);
5697

57-
const notion = new NotionAPI();
58-
59-
export const getStaticProps = async ({
60-
params: { slug },
61-
}: Params): Promise<GetStaticPropsResult<BlogProps>> => {
62-
const { uri, date } = EXPERIENCES[slug];
63-
const recordMap = await notion.getPage(uri);
64-
const pageInfo = getPageInfo(recordMap);
65-
const page: Page = {
66-
...pageInfo,
67-
uri,
68-
date,
69-
};
98+
if (!experience) {
99+
return {
100+
notFound: true,
101+
};
102+
}
70103

71104
return {
72105
props: {
73-
page,
74-
recordMap,
106+
experience,
75107
},
76108
};
77109
};

pages/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const Home = (): JSX.Element => (
1818
>
1919
<Container alignItems="center" alignContent="center">
2020
<Image
21-
src="/me.jpg"
21+
src="/me.webp"
2222
alt="Antoine Ordonez"
2323
width="120px"
2424
height="120px"

posts/experiences/bilberry.mdx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,34 @@
22
title: Bilberry
33
post: DevOps + FullStack Developer
44
date: 2018 - 2020
5+
link: https://bilberry.io
6+
image: /img/bilberry.webp
57
caption: My first developer experience. Full-Stack and DevOps.
8+
description: 🌿 Intelligent Spot Spraying System that reduces the usage of herbicide by more than 80% while protecting the environment and lowering the costs for farmers dramatically.
9+
tags:
10+
[
11+
'Artificial intelligence',
12+
'Hardware devices',
13+
'Plants recognition',
14+
'AI Labelling web platform',
15+
]
16+
stack:
17+
[
18+
'Python',
19+
'Django',
20+
'React',
21+
'Rancher',
22+
'Kubernetes',
23+
'OVH',
24+
'GCP',
25+
'Docker',
26+
'PostgreSQL',
27+
'MongoDB',
28+
]
629
---
30+
31+
- I migrated the old infrastructure from single server Docker deployment to **Kubernetes** on **Google Cloud**.
32+
- I had to migrate stored objects and databases data and automate the deployment with a **CI/CD**.
33+
- This led to a better scalability of the infrastructure and more safety for the storage of the data.
34+
- I worked on multiple services based on a **Django** / **React** / **PostgreSQL** / **MongoDB**.
35+
- I made a 6-month internship and continued to work for them.

0 commit comments

Comments
 (0)