My personal site. theclashfruit.me
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: get started on the post page

+169 -7
+46
app/(main)/post/[slug]/page.tsx
··· 1 + import { db } from '@/lib/db/drizzle'; 2 + import { postsTable, usersTable } from '@/lib/db/schema'; 3 + 4 + import rehypeStarryNight from 'rehype-starry-night'; 5 + 6 + import { eq } from 'drizzle-orm'; 7 + 8 + import { MDXRemote, type MDXRemoteOptions } from 'next-mdx-remote-client/rsc'; 9 + 10 + import { components } from '@/mdx-components'; 11 + 12 + const options: MDXRemoteOptions = { 13 + mdxOptions: { 14 + rehypePlugins: [rehypeStarryNight] 15 + } 16 + }; 17 + 18 + export default async function Post({ 19 + params 20 + }: { 21 + params: Promise<{ slug: string }>; 22 + }) { 23 + const { slug } = await params; 24 + const { posts: post } = await fetchPostData(slug); 25 + 26 + return ( 27 + <> 28 + <h1>{post.title}</h1> 29 + 30 + <article> 31 + <MDXRemote source={post.content} components={components} options={options} /> 32 + </article> 33 + </> 34 + ); 35 + } 36 + 37 + const fetchPostData = async (slug: string) => { 38 + const post = await db 39 + .select() 40 + .from(postsTable) 41 + .leftJoin(usersTable, eq(postsTable.author, usersTable.id)) 42 + .where(eq(postsTable.slug, slug)) 43 + .limit(1); 44 + 45 + return post[0]; 46 + };
+1 -1
lib/db/drizzle.ts
··· 4 4 connection: process.env.DATABASE_URL!, 5 5 casing: 'snake_case', 6 6 logger: true 7 - }); 7 + });
+1 -1
mdx-components.tsx
··· 1 1 import type { MDXComponents } from 'mdx/types'; 2 2 3 - const components: MDXComponents = {}; 3 + export const components: MDXComponents = {}; 4 4 5 5 export function useMDXComponents(): MDXComponents { 6 6 return components;
+13
next.config.ts
··· 20 20 rehypePlugins: ['rehype-starry-night'] 21 21 } 22 22 })(nextConfig); 23 + 24 + // :3 25 + // Override default toString()s to return stuff in a 'better' way. 26 + 27 + // eslint-disable-next-line @typescript-eslint/no-explicit-any 28 + (Date.prototype as any).toJSON = function () { 29 + return this.getTime(); 30 + }; 31 + 32 + // eslint-disable-next-line @typescript-eslint/no-explicit-any 33 + (BigInt.prototype as any).toJSON = function () { 34 + return this.toString(); 35 + };
+1
package.json
··· 22 22 "drizzle-orm": "^0.45.1", 23 23 "lucide-react": "^0.577.0", 24 24 "next": "16.1.6", 25 + "next-mdx-remote-client": "^2.1.9", 25 26 "pg": "^8.20.0", 26 27 "react": "19.2.3", 27 28 "react-dom": "19.2.3",
+93
pnpm-lock.yaml
··· 47 47 next: 48 48 specifier: 16.1.6 49 49 version: 16.1.6(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.98.0) 50 + next-mdx-remote-client: 51 + specifier: ^2.1.9 52 + version: 2.1.9(@types/react@19.2.14)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(unified@11.0.5) 50 53 pg: 51 54 specifier: ^8.20.0 52 55 version: 8.20.0 ··· 3046 3049 natural-compare@1.4.0: 3047 3050 resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 3048 3051 3052 + next-mdx-remote-client@2.1.9: 3053 + resolution: {integrity: sha512-2NuWJO2GykxOecI7xbS3AfjOn8qXnfTZ7rN2cUCWiDFC1w2hsm3mssiUFRCk3sBcI7AvDnyTZfUvDDhgZSzoCg==} 3054 + engines: {node: '>=20.9.0'} 3055 + peerDependencies: 3056 + react: '>= 19.1.0' 3057 + react-dom: '>= 19.1.0' 3058 + 3049 3059 next@16.1.6: 3050 3060 resolution: {integrity: sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==} 3051 3061 engines: {node: '>=20.9.0'} ··· 3087 3097 3088 3098 node-releases@2.0.36: 3089 3099 resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} 3100 + 3101 + non-error@0.1.0: 3102 + resolution: {integrity: sha512-TMB1uHiGsHRGv1uYclfhivcnf0/PdFp2pNqRxXjncaAsjYMoisaQJI+SSZCqRq+VliwRTC8tsMQfmrWjDMhkPQ==} 3103 + engines: {node: '>=20'} 3090 3104 3091 3105 nth-check@2.1.1: 3092 3106 resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} ··· 3318 3332 rehype-starry-night@2.2.0: 3319 3333 resolution: {integrity: sha512-hAdJb/14aNHPEAsP37Rt1X8HbkTsQb/2pAyL0inJn+VnXqdM714MBAL/9zC5CObCM3/zIjpwOsXMETTayx2iaw==} 3320 3334 3335 + remark-mdx-remove-esm@1.2.3: 3336 + resolution: {integrity: sha512-n6r36SaE+7cno7pmshWbGzYolDVLxJm5EKuw67+q4SPQT6kelNJHyZAiFYYtOB0axh+/1xF4BC57Ec3jncAGXQ==} 3337 + peerDependencies: 3338 + unified: ^11 3339 + 3321 3340 remark-mdx@3.1.1: 3322 3341 resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} 3323 3342 ··· 3383 3402 resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} 3384 3403 engines: {node: '>=10'} 3385 3404 hasBin: true 3405 + 3406 + serialize-error@13.0.1: 3407 + resolution: {integrity: sha512-bBZaRwLH9PN5HbLCjPId4dP5bNGEtumcErgOX952IsvOhVPrm3/AeK1y0UHA/QaPG701eg0yEnOKsCOC6X/kaA==} 3408 + engines: {node: '>=20'} 3386 3409 3387 3410 set-function-length@1.2.2: 3388 3411 resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} ··· 3525 3548 engines: {node: '>=14.0.0'} 3526 3549 hasBin: true 3527 3550 3551 + tagged-tag@1.0.0: 3552 + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} 3553 + engines: {node: '>=20'} 3554 + 3528 3555 tinyglobby@0.2.15: 3529 3556 resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} 3530 3557 engines: {node: '>=12.0.0'} ··· 3559 3586 type-check@0.4.0: 3560 3587 resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 3561 3588 engines: {node: '>= 0.8.0'} 3589 + 3590 + type-fest@5.4.4: 3591 + resolution: {integrity: sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==} 3592 + engines: {node: '>=20'} 3562 3593 3563 3594 typed-array-buffer@1.0.3: 3564 3595 resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} ··· 3623 3654 unist-util-position@5.0.0: 3624 3655 resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} 3625 3656 3657 + unist-util-remove@4.0.0: 3658 + resolution: {integrity: sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==} 3659 + 3626 3660 unist-util-stringify-position@4.0.0: 3627 3661 resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} 3628 3662 ··· 3643 3677 3644 3678 uri-js@4.4.1: 3645 3679 resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 3680 + 3681 + vfile-matter@5.0.1: 3682 + resolution: {integrity: sha512-o6roP82AiX0XfkyTHyRCMXgHfltUNlXSEqCIS80f+mbAyiQBE2fxtDVMtseyytGx75sihiJFo/zR6r/4LTs2Cw==} 3646 3683 3647 3684 vfile-message@4.0.3: 3648 3685 resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} ··· 3687 3724 3688 3725 yallist@3.1.1: 3689 3726 resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} 3727 + 3728 + yaml@2.8.2: 3729 + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} 3730 + engines: {node: '>= 14.6'} 3731 + hasBin: true 3690 3732 3691 3733 yocto-queue@0.1.0: 3692 3734 resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} ··· 6924 6966 6925 6967 natural-compare@1.4.0: {} 6926 6968 6969 + next-mdx-remote-client@2.1.9(@types/react@19.2.14)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(unified@11.0.5): 6970 + dependencies: 6971 + '@babel/code-frame': 7.29.0 6972 + '@mdx-js/mdx': 3.1.1 6973 + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.3) 6974 + react: 19.2.3 6975 + react-dom: 19.2.3(react@19.2.3) 6976 + remark-mdx-remove-esm: 1.2.3(unified@11.0.5) 6977 + serialize-error: 13.0.1 6978 + vfile: 6.0.3 6979 + vfile-matter: 5.0.1 6980 + transitivePeerDependencies: 6981 + - '@types/react' 6982 + - supports-color 6983 + - unified 6984 + 6927 6985 next@16.1.6(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.98.0): 6928 6986 dependencies: 6929 6987 '@next/env': 16.1.6 ··· 6969 7027 node-gyp-build@4.8.4: {} 6970 7028 6971 7029 node-releases@2.0.36: {} 7030 + 7031 + non-error@0.1.0: {} 6972 7032 6973 7033 nth-check@2.1.1: 6974 7034 dependencies: ··· 7241 7301 unist-util-visit-parents: 6.0.2 7242 7302 vfile: 6.0.3 7243 7303 7304 + remark-mdx-remove-esm@1.2.3(unified@11.0.5): 7305 + dependencies: 7306 + '@types/mdast': 4.0.4 7307 + mdast-util-mdxjs-esm: 2.0.1 7308 + unified: 11.0.5 7309 + unist-util-remove: 4.0.0 7310 + transitivePeerDependencies: 7311 + - supports-color 7312 + 7244 7313 remark-mdx@3.1.1: 7245 7314 dependencies: 7246 7315 mdast-util-mdx: 3.0.0 ··· 7325 7394 7326 7395 semver@7.7.4: {} 7327 7396 7397 + serialize-error@13.0.1: 7398 + dependencies: 7399 + non-error: 0.1.0 7400 + type-fest: 5.4.4 7401 + 7328 7402 set-function-length@1.2.2: 7329 7403 dependencies: 7330 7404 define-data-property: 1.1.4 ··· 7532 7606 picocolors: 1.1.1 7533 7607 sax: 1.5.0 7534 7608 7609 + tagged-tag@1.0.0: {} 7610 + 7535 7611 tinyglobby@0.2.15: 7536 7612 dependencies: 7537 7613 fdir: 6.5.0(picomatch@4.0.3) ··· 7568 7644 type-check@0.4.0: 7569 7645 dependencies: 7570 7646 prelude-ls: 1.2.1 7647 + 7648 + type-fest@5.4.4: 7649 + dependencies: 7650 + tagged-tag: 1.0.0 7571 7651 7572 7652 typed-array-buffer@1.0.3: 7573 7653 dependencies: ··· 7657 7737 dependencies: 7658 7738 '@types/unist': 3.0.3 7659 7739 7740 + unist-util-remove@4.0.0: 7741 + dependencies: 7742 + '@types/unist': 3.0.3 7743 + unist-util-is: 6.0.1 7744 + unist-util-visit-parents: 6.0.2 7745 + 7660 7746 unist-util-stringify-position@4.0.0: 7661 7747 dependencies: 7662 7748 '@types/unist': 3.0.3 ··· 7705 7791 uri-js@4.4.1: 7706 7792 dependencies: 7707 7793 punycode: 2.3.1 7794 + 7795 + vfile-matter@5.0.1: 7796 + dependencies: 7797 + vfile: 6.0.3 7798 + yaml: 2.8.2 7708 7799 7709 7800 vfile-message@4.0.3: 7710 7801 dependencies: ··· 7770 7861 xtend@4.0.2: {} 7771 7862 7772 7863 yallist@3.1.1: {} 7864 + 7865 + yaml@2.8.2: {} 7773 7866 7774 7867 yocto-queue@0.1.0: {} 7775 7868
+1 -1
styles/components/NavBar.module.scss
··· 1 1 .navBar { 2 - width: 215px; 2 + min-width: 215px; 3 3 // max-height: 550px; 4 4 5 5 display: flex;
+10 -4
styles/layout/Main.module.scss
··· 1 1 .main { 2 2 display: flex; 3 - 3 + 4 4 align-items: flex-start; 5 - 5 + 6 6 gap: 16px; 7 - 7 + 8 8 padding: 0 16px; 9 - 9 + 10 10 > div { 11 11 flex: 1; 12 + 13 + max-width: calc(100% - (16px + 215px)); 14 + 15 + @media (max-width: 769px) { 16 + max-width: 100%; 17 + } 12 18 } 13 19 }
+3
styles/typography.module.scss
··· 66 66 67 67 pre { 68 68 margin-bottom: 8px; 69 + 70 + width: 100%; 71 + overflow: scroll; 69 72 70 73 &:last-child { 71 74 margin-bottom: 0;