Skip to content

Commit

Permalink
feat: TIL 페이지 구현 1차 (#146)
Browse files Browse the repository at this point in the history
* chore: script 명령어 변경

* chore: @types/react-syntax-highlighter 패키지 추가

* chore: UTC를 년/월/일 형태로 바꿔주는 헬퍼 함수 추가

* chore: 글로벌 컬러 변수명 및 색깔 교체

* chore: h1, h2, h3 스타일 globals.css에 추가

* style: Typograph 컴포넌트 내 h3 font-weight 변경

* feat: TIL 페이지 구현 2차 (#147)

* chore: typegen 기능 on

* chore: SanityPost non-nullable 타입 정의

* chore: 불필요한 타입 삭제

* fix: 타입 에러

* chore: typegen에 의해 생성된 파일 추가

* feat: Sanity 연동하여 TIL 페이지 구현

* fix: gatsby node 관련 이슈 해결
  • Loading branch information
wherehows committed Nov 3, 2023
1 parent 2bc8d68 commit e92d2e9
Show file tree
Hide file tree
Showing 13 changed files with 6,628 additions and 430 deletions.
1 change: 1 addition & 0 deletions gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = {
flags: {
DEV_SSR: true,
},
graphqlTypegen: true,
siteMetadata: {
title: `Gatsby Default Starter`,
description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
Expand Down
27 changes: 27 additions & 0 deletions gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,33 @@ exports.onCreateWebpackConfig = ({ actions }) => {
});
};

exports.createSchemaCustomization = ({ actions }) => {
actions.createTypes(`
type SanityPost {
publishedAt: Date!
title: String!
_updatedAt: Date!
content: String!
tags: [Tag!]!
debts: [Debt!]!
}
type Tag {
_key: String!
_type: String!
label: String!
value: String!
}
type Debt {
_key: String!
_type: String!
label: String!
value: String!
}
`);
};

exports.onCreateBabelConfig = ({ actions }) => {
actions.setBabelPlugin({
name: '@babel/plugin-transform-react-jsx',
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
},
"devDependencies": {
"@types/react-dom": "^18.0.6",
"@types/react-syntax-highlighter": "^15.5.9",
"@types/react-toggle": "^4.0.3",
"env-cmd": "^10.1.0",
"prettier": "^2.7.1",
Expand All @@ -52,7 +53,7 @@
"license": "0BSD",
"scripts": {
"build": "gatsby build",
"develop": "env-cmd -f .env gatsby develop",
"dev": "env-cmd -f .env gatsby develop",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md,css}\"",
"start": "env-cmd -f .env gatsby develop",
"serve": "gatsby serve",
Expand Down
49 changes: 49 additions & 0 deletions patches/gatsby+4.21.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
diff --git a/node_modules/gatsby/dist/utils/webpack.config.js b/node_modules/gatsby/dist/utils/webpack.config.js
index cf4bdd5..dc7013a 100644
--- a/node_modules/gatsby/dist/utils/webpack.config.js
+++ b/node_modules/gatsby/dist/utils/webpack.config.js
@@ -746,15 +746,35 @@ module.exports = async (program, directory, suppliedStage, port, {
if (stage === `build-html`) {
const builtinModulesToTrack = [`fs`, `http`, `http2`, `https`, `child_process`];

- const builtinsExternalsDictionary = _module.builtinModules.reduce((acc, builtinModule) => {
- if (builtinModulesToTrack.includes(builtinModule)) {
- acc[builtinModule] = `commonjs ${path.join(program.directory, `.cache`, `ssr-builtin-trackers`, builtinModule)}`;
- } else {
- acc[builtinModule] = `commonjs ${builtinModule}`;
- }
-
- return acc;
- }, {});
+ const builtinsExternalsDictionary = _module.builtinModules.reduce(
+ (acc, builtinModule) => {
+ if (builtinModulesToTrack.includes(builtinModule)) {
+ const builtinModuleTracked = path.join(
+ program.directory,
+ `.cache`,
+ `ssr-builtin-trackers`,
+ builtinModule
+ )
+ acc[builtinModule] = `commonjs ${builtinModuleTracked}`
+ acc[`node:${builtinModule}`] = `commonjs ${builtinModuleTracked}`
+ } else {
+ acc[builtinModule] = `commonjs ${builtinModule}`
+ acc[`node:${builtinModule}`] = `commonjs ${builtinModule}`
+ }
+ return acc
+ },
+ {}
+ )
+
+ // const builtinsExternalsDictionary = _module.builtinModules.reduce((acc, builtinModule) => {
+ // if (builtinModulesToTrack.includes(builtinModule)) {
+ // acc[builtinModule] = `commonjs ${path.join(program.directory, `.cache`, `ssr-builtin-trackers`, builtinModule)}`;
+ // } else {
+ // acc[builtinModule] = `commonjs ${builtinModule}`;
+ // }
+
+ // return acc;
+ // }, {});

config.externals.unshift(builtinsExternalsDictionary);
}
246 changes: 155 additions & 91 deletions src/components/TILContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,157 @@ import styled from '@emotion/styled';
import { MAIN_LEFT_MARGIN_WIDTH, MAIN_PURE_WIDTH } from '@/utils/const';
import Typography from './Typography';
import useResponsiveWeb from '@/hooks/useResponsiveWeb';
import { TIL } from '@/types/document';
import Markdown from 'react-markdown';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { cb } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { changeUTCToYYYYMMDD } from '@/utils/time';

interface TILContentProps {
tils: TIL[];
}

export const TILContent = ({ tils }: TILContentProps) => {
export const TILContent = ({ nodes }: Queries.TILTemplateQuery['allMemos']) => {
const { isUnder960px } = useResponsiveWeb();

return (
<Wrapper>
{!isUnder960px && (
<Typography variant="h1">
프론트엔드 개발 및 관심사를 기록하는 블로그
</Typography>
<Typography variant="h1">지극히 개인적인 공간이에요 🫠</Typography>
)}
<DocumentList>
{tils?.map(({ title, date, html, hashtags, debts, id }) => (
<DocumentItem key={id}>
<Button
onClick={e => {
const detail = e.currentTarget
.nextElementSibling as HTMLDivElement;

if (detail.style.display === 'none') {
detail.style.display = 'block';
} else {
detail.style.display = 'none';
}
}}
>
{!!hashtags.length && (
<HashtagList>
{hashtags.map((hashtag, index) => (
<Hashtag key={index}>#{hashtag}</Hashtag>
))}
</HashtagList>
)}
<Typography variant="h2">{title}</Typography>
<SubInformation>
<Typography
as="time"
variant="label"
dateTime={date.toString()}
>
{formatDate(date)}
</Typography>
{!!debts.length && (
<DebtCount> | {debts.length}개의 부채가 있어요!</DebtCount>
{nodes.map(({ title, publishedAt, tags, content, id, _updatedAt }) => {
return (
<DocumentItem key={id}>
<Button
onClick={e => {
const detail = e.currentTarget
.nextElementSibling as HTMLDivElement;

if (detail.style.display === 'none') {
detail.style.display = 'block';
} else {
detail.style.display = 'none';
}
}}
>
<Typography variant="h2">{title}</Typography>
{!!tags?.length && (
<Tags>
{tags.map(tag => {
const { label, value } = tag;
if (!label || !value) {
return <></>;
}

return <Tag key={value}>{label}</Tag>;
})}
</Tags>
)}
</SubInformation>
</Button>
<Collapsible>
<MarkdownRenderer dangerouslySetInnerHTML={{ __html: html }} />
{!!debts.length && (
<>
<Typography variant="h2">부채</Typography>
<DebtList>
{debts.map(debt => (
<Debt>{debt}</Debt>
))}
</DebtList>
</>
)}
</Collapsible>
</DocumentItem>
))}
<SubInformation>
<Typography
as="time"
variant="label"
dateTime={changeUTCToYYYYMMDD(publishedAt)}
>
published at {changeUTCToYYYYMMDD(publishedAt)} | updated at{' '}
{changeUTCToYYYYMMDD(_updatedAt)}
</Typography>
</SubInformation>
</Button>
<Collapsible>
<Markdown
children={content}
components={{
code(props) {
// The type of 'ref' is inferred incorrectly.
const { children, className, ref, ...rest } = props;

const match = /language-(\w+)/.exec(className || '');
return match ? (
<SyntaxHighlighter
{...rest}
children={String(children).replace(/\n$/, '')}
style={cb}
language={match[1]}
PreTag="div"
/>
) : (
<code
{...rest}
style={{
fontFamily: 'inherit',
fontWeight: '400',
borderBottom: '2px dashed var(--colors-orange-01)',
}}
>
{children}
</code>
);
},
li(props) {
const { children, ...rest } = props;
return (
<li
{...rest}
style={{
listStyle: 'auto',
}}
>
{children}
</li>
);
},
h3(props) {
const { children, ...rest } = props;

return (
<h3
{...rest}
style={{
borderBottom: '1px dashed var(--colors-grey-01)',
padding: '0 0 4px 0',
margin: 0,
}}
>
📎 {children}
</h3>
);
},
p(props) {
const { children, ...rest } = props;
let style = {};

if (
typeof children === 'object' &&
children &&
'props' in children &&
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
children.props.node.tagName === 'a'
) {
style = { textAlign: 'right' };
}

return (
<p {...rest} style={style}>
{children}
</p>
);
},
a(props) {
return (
<a
{...props}
style={{
color: 'var(--colors-violet-01)',
textDecoration: 'none',
fontWeight: '700',
fontSize: '16px',
}}
/>
);
},
}}
/>
</Collapsible>
</DocumentItem>
);
})}
</DocumentList>
</Wrapper>
);
Expand All @@ -86,7 +171,7 @@ const Wrapper = styled('main')(() => ({

const DocumentItem = styled('li')(() => ({
listStyle: 'none',
marginBottom: '2rem',
marginBottom: '16px',
}));

const Button = styled('button')(() => ({
Expand All @@ -96,50 +181,29 @@ const Button = styled('button')(() => ({
flexDirection: 'column',
}));

const DebtCount = styled('span')(({ theme }) => ({
...theme.typography.label,
color: 'red',
}));

const DocumentList = styled('ul')(() => ({
padding: 0,
margin: 0,
}));

const Collapsible = styled('div')(() => ({
display: 'none',
borderTop: '2px solid var(--colors-violet-02)',
padding: '12px 16px 0',
}));

const SubInformation = styled('div')(() => ({}));

const MarkdownRenderer = styled('div')(() => ({
width: '100%',
fontSize: '1rem',
a: {
color: 'var(--colors-primary)',
textDecoration: 'none',
fontWeight: 'bold',
},

'a:visited': {
color: 'var(--colors-primary)',
fontWieght: 'bold',
},
}));

const HashtagList = styled('ul')(() => ({
const Tags = styled('ul')(() => ({
display: 'flex',
}));

const Hashtag = styled('li')(() => ({
marginRight: '4px',
const Tag = styled('li')(() => ({
borderRadius: '6px',
backgroundColor: 'var(--colors-violet-02)',
padding: '0 6px',
marginRight: '8px',
fontSize: '14px',
fontWeight: 500,
color: 'white',
}));

const DebtList = styled('ul')(() => ({}));

const Debt = styled('li')(() => ({}));

const formatDate = (date: Date) => {
const sArray = date.toString().split('-');
return `${sArray[0].slice(2, 4)}${sArray[1]}${sArray[2]}일`;
};
Loading

1 comment on commit e92d2e9

@vercel
Copy link

@vercel vercel bot commented on e92d2e9 Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

blog-renewal – ./

blog-renewal-wherehows.vercel.app
blog-wherehows.vercel.app
blog-renewal-git-main-wherehows.vercel.app

Please sign in to comment.