diff --git a/app/[locale]/[...not found]/page.tsx b/app/[locale]/[...not found]/page.tsx new file mode 100644 index 0000000..983874e --- /dev/null +++ b/app/[locale]/[...not found]/page.tsx @@ -0,0 +1,5 @@ +import { notFound } from 'next/navigation' + +export default function NotFoundCatchAll() { + notFound() +} diff --git a/app/[locale]/about/[...authors]/page.tsx b/app/[locale]/about/[...authors]/page.tsx index 22511a0..08b2c43 100644 --- a/app/[locale]/about/[...authors]/page.tsx +++ b/app/[locale]/about/[...authors]/page.tsx @@ -6,6 +6,7 @@ import { coreContent } from 'pliny/utils/contentlayer' import { genPageMetadata } from 'app/[locale]/seo' import { createTranslation } from 'app/[locale]/i18n/server' import { LocaleTypes } from 'app/[locale]/i18n/settings' +import { notFound } from 'next/navigation' type AboutProps = { params: { authors: string[]; locale: LocaleTypes } @@ -13,9 +14,12 @@ type AboutProps = { export async function generateMetadata({ params: { authors, locale }, -}: AboutProps): Promise { - const authorSlug = authors.join('/') +}: AboutProps): Promise { + const authorSlug = decodeURI(authors.join('/')) const author = allAuthors.find((a) => a.slug === authorSlug && a.language === locale) as Authors + if (!author) { + return + } const { t } = await createTranslation(locale, 'about') return genPageMetadata({ @@ -25,8 +29,12 @@ export async function generateMetadata({ } export default async function Page({ params: { authors, locale } }: AboutProps) { - const authorSlug = authors.join('/') + const authorSlug = decodeURI(authors.join('/')) const author = allAuthors.find((a) => a.slug === authorSlug && a.language === locale) as Authors + const authorIndex = allAuthors.findIndex((p) => p.slug === authorSlug) + if (authorIndex === -1) { + return notFound() + } const mainContent = coreContent(author) return ( diff --git a/app/[locale]/blog/[...slug]/page.tsx b/app/[locale]/blog/[...slug]/page.tsx index 7db4526..08dac1d 100644 --- a/app/[locale]/blog/[...slug]/page.tsx +++ b/app/[locale]/blog/[...slug]/page.tsx @@ -63,7 +63,7 @@ export async function generateMetadata({ } const author = allAuthors .filter((a) => a.language === locale) - .find((a) => a.slug.includes('default')) + .find((a) => a.default === true) const authorList = post.authors || author const authorDetails = authorList.map((author) => { const authorResults = allAuthors @@ -129,7 +129,7 @@ export default async function Page({ params: { slug, locale } }: BlogPageProps) const post = await getPostFromParams({ params: { slug, locale } }) const author = allAuthors .filter((a) => a.language === locale) - .find((a) => a.slug.includes('default')) + .find((a) => a.default === true) const authorList = post.authors || author const authorDetails = authorList.map((author) => { const authorResults = allAuthors diff --git a/app/[locale]/i18n/locales/en/404.json b/app/[locale]/i18n/locales/en/404.json deleted file mode 100644 index d473e4e..0000000 --- a/app/[locale]/i18n/locales/en/404.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "firsttext": "Sorry we couldn't find this page.", - "secondtext": "But dont worry, you can find plenty of other things on our homepage.", - "back": "Back to homepage" -} diff --git a/app/[locale]/i18n/locales/en/notfound.json b/app/[locale]/i18n/locales/en/notfound.json new file mode 100644 index 0000000..1617fd0 --- /dev/null +++ b/app/[locale]/i18n/locales/en/notfound.json @@ -0,0 +1,5 @@ +{ + "title": "Sorry we couldn't find this page.", + "description": "But dont worry, you can find plenty of other things on our homepage.", + "back": "Back to homepage" +} \ No newline at end of file diff --git a/app/[locale]/i18n/locales/fr/404.json b/app/[locale]/i18n/locales/fr/404.json deleted file mode 100644 index 501c938..0000000 --- a/app/[locale]/i18n/locales/fr/404.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "firstext": "Désolé, nous n'avons pas pu trouver cette page.", - "secondtext": "Ne vous inquiétez pas, vous pourrez trouver plein d'autres choses sur notre page d'accueil.", - "back": "Retour à la page d'accueil" -} diff --git a/app/[locale]/i18n/locales/fr/notfound.json b/app/[locale]/i18n/locales/fr/notfound.json new file mode 100644 index 0000000..0300f97 --- /dev/null +++ b/app/[locale]/i18n/locales/fr/notfound.json @@ -0,0 +1,5 @@ +{ + "title": "Désolé, nous n'avons pas pu trouver cette page.", + "description": "Ne vous inquiétez pas, vous pourrez trouver plein d'autres choses sur notre page d'accueil.", + "back": "Retour à la page d'accueil" +} \ No newline at end of file diff --git a/app/[locale]/not-found.tsx b/app/[locale]/not-found.tsx index a099ea2..3bd5087 100644 --- a/app/[locale]/not-found.tsx +++ b/app/[locale]/not-found.tsx @@ -1,25 +1,5 @@ -import Link from '@/components/mdxcomponents/Link' +import NotFoundclient from '@/components/notfound/Client' export default function NotFound() { - return ( -
-
-

- 404 -

-
-
-

- Sorry we couldn't find this page. -

-

But dont worry, you can find plenty of other things on our homepage.

- - Back to homepage - -
-
- ) + return } diff --git a/app/[locale]/tag-data.json b/app/[locale]/tag-data.json index e27a4cd..319ea00 100644 --- a/app/[locale]/tag-data.json +++ b/app/[locale]/tag-data.json @@ -1,43 +1 @@ -{ - "en": { - "markdown": 1, - "code": 1, - "features": 2, - "next-js": 7, - "math": 1, - "ols": 1, - "github": 1, - "guide": 6, - "tailwind": 4, - "i18n": 1, - "hello": 1, - "holiday": 1, - "canada": 1, - "images": 1, - "feature": 2, - "writings": 1, - "book": 1, - "reflection": 1, - "multi-author": 1 - }, - "fr": { - "markdown": 1, - "code": 1, - "fonctionnalites": 4, - "next-js": 7, - "math": 1, - "ols": 1, - "github": 1, - "guide": 6, - "tailwind": 4, - "i18n": 1, - "salut": 1, - "vacance": 1, - "canada": 1, - "images": 1, - "ecriture": 1, - "livre": 1, - "reflexion": 1, - "multi-auteurs": 1 - } -} +{"en":{"markdown":1,"code":1,"features":2,"next-js":7,"math":1,"ols":1,"github":1,"guide":6,"tailwind":4,"i18n":1,"hello":1,"holiday":1,"canada":1,"images":1,"feature":2,"writings":1,"book":1,"reflection":1,"multi-author":1},"fr":{"markdown":1,"code":1,"fonctionnalites":4,"next-js":7,"math":1,"ols":1,"github":1,"guide":6,"tailwind":4,"i18n":1,"salut":1,"vacance":1,"canada":1,"images":1,"ecriture":1,"livre":1,"reflexion":1,"multi-auteurs":1}} \ No newline at end of file diff --git a/components/notfound/Button.tsx b/components/notfound/Button.tsx new file mode 100644 index 0000000..d807396 --- /dev/null +++ b/components/notfound/Button.tsx @@ -0,0 +1,49 @@ +import { motion } from 'framer-motion' + +type ShimmerButtonProps = { + text: string + href: string +} + +const ShimmerButton = ({ text, href }: ShimmerButtonProps) => { + return ( + + + + {text} + + + + ) +} + +export default ShimmerButton diff --git a/components/notfound/Client.tsx b/components/notfound/Client.tsx new file mode 100644 index 0000000..21c8501 --- /dev/null +++ b/components/notfound/Client.tsx @@ -0,0 +1,24 @@ +'use client' + +import ShimmerButton from './Button' +import { useTranslation } from 'app/[locale]/i18n/client' +import { useParams } from 'next/navigation' +import { LocaleTypes } from 'app/[locale]/i18n/settings' +export default function NotFoundclient() { + const locale = useParams()?.locale as LocaleTypes + const { t } = useTranslation(locale, 'notfound') + return ( +
+
+

+ 404 +

+
+
+

{t('title')}

+

{t('description')}

+ +
+
+ ) +} diff --git a/components/search/kbar/KBarModal.tsx b/components/search/kbar/KBarModal.tsx index 162a43a..51af1ff 100644 --- a/components/search/kbar/KBarModal.tsx +++ b/components/search/kbar/KBarModal.tsx @@ -73,13 +73,13 @@ export const KBarModal: React.FC = ({ actions, isLoading }) => { return segments.join('/') } - const handleLinkClick = (newLocale) => { + const handleLinkClick = (newLocale: string) => { setSelectedTag('') const resolvedUrl = handleLocaleChange(newLocale) router.push(resolvedUrl) } - const handleThemeChange = (newTheme) => setTheme(newTheme) + const handleThemeChange = (newTheme: string) => setTheme(newTheme) if (!mounted) return null diff --git a/components/search/kbar/ResultItem.tsx b/components/search/kbar/ResultItem.tsx index 9850543..83a78ec 100644 --- a/components/search/kbar/ResultItem.tsx +++ b/components/search/kbar/ResultItem.tsx @@ -1,11 +1,11 @@ interface ResultItemProps { item: { - name: string; - subtitle?: string; - icon?: React.ReactNode; - shortcut?: string[]; - }; - active: boolean; + name: string + subtitle?: string + icon?: React.ReactNode + shortcut?: string[] + } + active: boolean } const ResultItem: React.FC = ({ item, active }) => ( diff --git a/package.json b/package.json index 01795b6..0418b7f 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "start": "next dev", "dev": "next dev", - "build": " next build && cross-env NODE_OPTIONS='--experimental-json-modules' ", + "build": " next build && cross-env NODE_OPTIONS='--experimental-json-modules' node ./scripts/postbuild.mjs", "serve": "next start", "analyze": "cross-env ANALYZE=true next build", "lint": "next lint --fix --dir pages --dir app --dir components --dir lib --dir layouts --dir scripts", @@ -81,4 +81,4 @@ ] }, "packageManager": "yarn@4.0.2" -} +} \ No newline at end of file diff --git a/scripts/rss.mjs b/scripts/rss.mjs index a495a46..b7f125d 100644 --- a/scripts/rss.mjs +++ b/scripts/rss.mjs @@ -1,25 +1,25 @@ -import { writeFileSync, mkdirSync } from 'fs' -import path from 'path' -import { slug } from 'github-slugger' -import { escape } from 'pliny/utils/htmlEscaper.js' -import siteMetadata from '../data/siteMetadata.js' -import tagData from '../app/[locale]/tag-data.json' assert { type: 'json' } -import { allBlogs } from '../.contentlayer/generated/index.mjs' -import { sortPosts } from 'pliny/utils/contentlayer.js' +import { writeFileSync, mkdirSync } from 'fs'; +import path from 'path'; +import { slug } from 'github-slugger'; +import { escape } from 'pliny/utils/htmlEscaper.js'; +import siteMetadata from '../data/siteMetadata.js'; +import tagData from '../app/[locale]/tag-data.json' assert { type: 'json' }; +import { allBlogs } from '../.contentlayer/generated/index.mjs'; +import { sortPosts } from 'pliny/utils/contentlayer.js'; -const defaultLocale = 'en' +const defaultLocale = 'en'; const generateRssItem = (config, post, locale) => ` ${config.siteUrl}${defaultLocale === locale ? '' : '/' + locale}/blog/${post.slug} ${escape(post.title)} ${config.siteUrl}${defaultLocale === locale ? '' : '/' + locale}/blog/${post.slug} - ${post.summary && `${escape(post.summary)}`} - ${post.date && `${new Date(post.date).toLocaleDateString(locale)}`} + ${post.summary ? `${escape(post.summary)}` : ''} + ${post.date ? `${new Date(post.date).toUTCString()}` : ''} ${config.email} (${config.author}) - ${post.tags && post.tags.map((t) => `${t}`).join('')} + ${post.tags ? post.tags.map((t) => `${t}`).join('') : ''} -` +`; const generateRss = (config, posts, locale, page = 'feed.xml') => ` @@ -30,46 +30,45 @@ const generateRss = (config, posts, locale, page = 'feed.xml') => ` ${locale} ${config.email} (${config.author}) ${config.email} (${config.author}) - ${ - posts.date && - `${new Date(posts[0].date).toLocaleDateString(locale)}` - } - - ${posts.map((post) => generateRssItem(config, post, locale, defaultLocale)).join('')} + ${posts.length > 0 ? `${new Date(posts[0].date).toUTCString()}` : ''} + + ${posts.map((post) => generateRssItem(config, post, locale)).join('')} -` +`; async function generateRSS(config, allBlogs, locale, page = 'feed.xml') { - const filteredPosts = allBlogs.filter((post) => post.language === locale) - const publishPosts = filteredPosts.filter((post) => post.draft !== true) + const filteredPosts = allBlogs.filter((post) => post.language === locale); + const publishPosts = filteredPosts.filter((post) => post.draft !== true); - // RSS for blog post + // RSS for blog posts if (publishPosts.length > 0) { - const rss = generateRss(config, sortPosts(publishPosts)) - const directoryPath = path.join('public', locale) - mkdirSync(directoryPath, { recursive: true }) // Create the directory if it doesn't exist - writeFileSync(path.join(directoryPath, page), rss) + const rss = generateRss(config, sortPosts(publishPosts), locale); + const directoryPath = path.join('public', locale); + mkdirSync(directoryPath, { recursive: true }); // Create the directory if it doesn't exist + writeFileSync(path.join(directoryPath, page), rss); } - if (publishPosts.length > 0) { - for (const tag of Object.keys(tagData)) { - const filteredPosts = publishPosts.filter((post) => - post.tags.map((t) => slug(t)).includes(tag) - ) - const rss = generateRss(config, filteredPosts, `tags/${tag}/${page}`) - const rssPath = path.join('public', locale, 'tags', tag) - mkdirSync(rssPath, { recursive: true }) // Create the directory if it doesn't exist - writeFileSync(path.join(rssPath, page), rss) + // RSS for tag-specific posts + for (const tag of Object.keys(tagData)) { + const filteredTagPosts = publishPosts.filter((post) => + post.tags.map((t) => slug(t)).includes(tag) + ); + if (filteredTagPosts.length > 0) { + const rss = generateRss(config, sortPosts(filteredTagPosts), locale, `tags/${tag}/${page}`); + const rssPath = path.join('public', locale, 'tags', tag); + mkdirSync(rssPath, { recursive: true }); // Create the directory if it doesn't exist + writeFileSync(path.join(rssPath, page), rss); } } } -const rss = () => { - const locales = ['en', 'fr'] +const rss = async () => { + const locales = ['en', 'fr']; for (const locale of locales) { - generateRSS(siteMetadata, allBlogs, locale) + await generateRSS(siteMetadata, allBlogs, locale); } - console.log('RSS feed generated...') -} -export default rss + console.log('RSS feeds generated...'); +}; + +export default rss;