Skip to content

Commit

Permalink
refactor: all (#74)
Browse files Browse the repository at this point in the history
_
  • Loading branch information
ashgw authored Feb 13, 2024
2 parents 9e1defe + 72e5548 commit 51d6fd2
Show file tree
Hide file tree
Showing 17 changed files with 1,972 additions and 5,671 deletions.
7,347 changes: 1,811 additions & 5,536 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

27 changes: 0 additions & 27 deletions src/app/(pages)/blog/[post]/_seo.tsx

This file was deleted.

64 changes: 57 additions & 7 deletions src/app/(pages)/blog/[post]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,67 @@
import { Suspense } from 'react';
import { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { getPost } from '@/app/actions/blog';
import LoadingScreen from '../loading';
import SEO from './_seo';
import BlogSection from './_blog-section';
import { getBlogPosts, getBlogPost } from '../content';
import { pub } from '@/lib/env';
import LoadingScreen from '@/app/components/reusables/loading-screen';
import BlogSection from '@/app/components/blog/blog-section';

export default async function Blog({ params }: { params: { post: string } }) {
const post = await getPost(params.post);
type RouteParams = {
params: { post: string };
};

export const generateStaticParams = async () => {
const posts = await getBlogPosts();
return posts.map((post) => ({ post: post.filename }));
};

export async function generateMetadata({
params,
}: RouteParams): Promise<Metadata> {
const post = await getBlogPost(params.post);
if (!post) {
return {};
}
const postAttrs = post.parsedContent.attributes;
const title = postAttrs.seoTitle;
const description = postAttrs.summary;
const url = pub.SITE_URL_PROD + '/' + post.filename;

const postImageWidth = 1200;
const postImageHeight = 630;
const postImageUrl = `https://via.placeholder.com/${postImageWidth}x${postImageHeight}.png/000000/ffffff/?text=${title}`;
return {
title,
description,
openGraph: {
title,
description,
type: 'article',
url,
images: [
{
url: postImageUrl,
width: postImageWidth,
height: postImageHeight,
alt: title,
},
],
},
twitter: {
card: 'summary_large_image',
title,
description,
images: [postImageUrl],
},
};
}

export default async function Blog({ params }: RouteParams) {
const post = await getBlogPost(params.post);
if (post) {
return (
<Suspense fallback={<LoadingScreen />}>
<main className="pt-5">
<SEO post={post} />
<BlogSection post={post} />
</main>
</Suspense>
Expand Down
16 changes: 12 additions & 4 deletions src/app/api/blogs/content.ts → src/app/(pages)/blog/content.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'use server';
import { promises as fsPromises } from 'fs';

import { promises as fsPromises } from 'fs';
import path from 'path';
import fm from 'front-matter';
import type { MDXData, BlogData } from '@/lib/types/mdx';
import { BLOG_CONTENT_PATH } from '@/lib/constants';
import type { Maybe } from '@/lib/types/global';

function parseMDX(content: string): MDXData {
return fm(content) as MDXData;
Expand All @@ -29,18 +30,18 @@ async function readMDXFile(filePath: string): Promise<MDXData> {
} catch (error) {
// TODO: hadnle err
console.error('Error reading MDX file:', error);
throw error;
throw new Error();
}
}
async function getMDXData(dir: string): Promise<BlogData[]> {
const mdxFiles = await getMDXFiles(dir);

const blogDataPromises = mdxFiles.map(async (file) => {
const parsedContent = await readMDXFile(path.join(dir, file));
const filenameSlug: string = path.basename(file, path.extname(file));
const filename: string = path.basename(file, path.extname(file));
return {
parsedContent,
filenameSlug,
filename,
};
});

Expand All @@ -50,3 +51,10 @@ async function getMDXData(dir: string): Promise<BlogData[]> {
export async function getBlogPosts(): Promise<BlogData[]> {
return getMDXData(path.join(process.cwd(), BLOG_CONTENT_PATH));
}

export async function getBlogPost(slug: string): Promise<Maybe<BlogData>> {
// TODO: optimize
const blogs = await getBlogPosts();
const blogPost = blogs.find((p) => p?.filename === slug);
return blogPost;
}
2 changes: 1 addition & 1 deletion src/app/(pages)/blog/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
import LoadingScreen from '@/app/loading';
import LoadingScreen from '@/app/components/reusables/loading-screen';
export default LoadingScreen;
3 changes: 1 addition & 2 deletions src/app/(pages)/blog/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Suspense } from 'react';
import LoadingScreen from '@/app/components/reusables/loading-screen';
import BlogPosts from '@/app/components/blog/blog-posts';
import { getBlogPosts } from '@/app/actions/blog';
import { getBlogPosts } from './content';
import { notFound } from 'next/navigation';

export default async function BlogPage() {
const blogPosts = await getBlogPosts();

Expand Down
49 changes: 0 additions & 49 deletions src/app/actions/blog.ts

This file was deleted.

31 changes: 0 additions & 31 deletions src/app/api/blogs/route.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/app/components/blog/blog-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default function BlogPostCard({ blogData }: { blogData: BlogData }) {
<li className="list-disc ml-5 dimmed-0">
{formatDate(blogData.parsedContent.attributes.firstModDate)}
</li>
<Link href={`${BLOG_URI}/${blogData.filenameSlug}`}>
<Link href={`${BLOG_URI}/${blogData.filename}`}>
<h2 className="text-2xl font-bold dimmed-4 lg:text-[2.5rem]">
{blogData.parsedContent.attributes.title}
</h2>
Expand All @@ -39,7 +39,7 @@ export default function BlogPostCard({ blogData }: { blogData: BlogData }) {
</div>
</div>
<Link
href={`${BLOG_URI}/${blogData.filenameSlug}`}
href={`${BLOG_URI}/${blogData.filename}`}
className="relative h-full overflow-hidden rounded-[2rem]"
></Link>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/blog/blog-posts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function BlogPosts({ blogPosts }: { blogPosts: BlogData[] }) {
.slice(0, visibleNum)
.map((post, index) => (
<motion.div
key={post.filenameSlug}
key={post.filename}
initial={{
opacity: 0,
y: -200, // y: index % 2 == 0 ? -200 : 200 , push for 5 wehn blogs are 20+
Expand Down
File renamed without changes.
18 changes: 10 additions & 8 deletions src/app/components/nav/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@ import { Button } from '@/app/components/ui/button';
import Link from 'next/link';
import Image from 'next/image';
import HamburgerButton from '@/app/components/nav/hamburger';
import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import useToggleDropDownMenu from '@/lib/hooks/useToggleDropDownMenue';

export default function NavBar() {
const [isOpened, setIsOpened] = useState(false);
const [isOpened, toggleMenu] = useToggleDropDownMenu({
menuId: 'nav-menue',
});

const toggleMenu = () => {
setIsOpened(!isOpened);
};
return (
<nav className="pt-3">
<nav id="nav-menue" className="pt-3">
<div className="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8 ">
<div className="relative flex h-16 items-center justify-between">
<div className="absolute inset-y-0 left-2 flex items-center sm:hidden">
<div
id="hamburger"
className="absolute inset-y-0 left-2 flex items-center sm:hidden"
>
<HamburgerButton isOpened={isOpened} onClick={toggleMenu} />
</div>
<div className="flex flex-1 items-center justify-center sm:items-stretch sm:justify-start">
Expand All @@ -45,7 +47,7 @@ export function Logo() {
height={25}
src="https://avatars.githubusercontent.com/u/126174609?v=4"
className="h-8 w-auto rounded-full invisible"
alt="..."
alt="The logo"
/>
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/styles/hamburger.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
stroke: white;
stroke-width: 6;
transition:
stroke-dasharray 200ms cubic-bezier(0.4, 0, 0.2, 1),
stroke-dashoffset 200ms cubic-bezier(0.4, 0, 0.2, 1);
stroke-dasharray 300ms cubic-bezier(0.4, 0, 0.2, 1),
stroke-dashoffset 300ms cubic-bezier(0.4, 0, 0.2, 1);
}
.ham-line1 {
stroke-dasharray: 60 207;
Expand Down
Empty file added src/lib/declarations/aze.ts
Empty file.
39 changes: 39 additions & 0 deletions src/lib/declarations/err.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import pkg from '../../../package.json';
import { nextJS } from '../env';

abstract class BaseErr extends Error {
private readonly version = pkg.version;
readonly caughtError?: Error;

constructor(
readonly message: string,
readonly error?: Error
) {
super(message, error);
this.caughtError = error;
}

toJSON(): _SerializedErr {
return {
version: 'v' + this.version,
caughtError: this.caughtError?.name,
message: this.caughtError?.message || this.message,
stack:
nextJS.NEXT_NODE_ENV === 'production'
? 'HIDDEN'
: this.caughtError?.stack || this.stack,
cause:
JSON.stringify(this.caughtError?.cause) || JSON.stringify(this.cause),
};
}
}

type _SerializedErr = {
version: string;
caughtError?: string;
message: string;
stack?: string;
cause: string;
};

declare class Err extends BaseErr {}
35 changes: 35 additions & 0 deletions src/lib/hooks/useToggleDropDownMenue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use client';

import { useState, useEffect } from 'react';
import type { MouseEvent, TouchEvent } from 'react';

const useToggleDropDownMenu = ({
menuId,
}: {
menuId: string;
}): [boolean, () => void] => {
const initialState = false;
const [isOpened, setIsOpened] = useState(initialState);

const toggleMenu: () => void = () => {
setIsOpened(!isOpened);
};

useEffect(() => {
const handleClickOutside = (e: MouseEvent | TouchEvent) => {
if (!document.getElementById(menuId)?.contains(e.target as Node)) {
setIsOpened(initialState);
}
};
// @ts-expect-error it just works, no time to set types
window.addEventListener('click', handleClickOutside);

return () => {
// @ts-expect-error it just works, no time to set types
window.removeEventListener('click', handleClickOutside);
};
}, [menuId]);

Check warning on line 31 in src/lib/hooks/useToggleDropDownMenue.ts

View workflow job for this annotation

GitHub Actions / lint

React Hook useEffect has a missing dependency: 'initialState'. Either include it or remove the dependency array

return [isOpened, toggleMenu];
};
export default useToggleDropDownMenu;
Loading

0 comments on commit 51d6fd2

Please sign in to comment.