Skip to content

Commit

Permalink
chore: refactor homepage details into components
Browse files Browse the repository at this point in the history
  • Loading branch information
y3owk1n committed Jul 19, 2023
1 parent c1524f8 commit 6e9e747
Show file tree
Hide file tree
Showing 6 changed files with 275 additions and 228 deletions.
197 changes: 9 additions & 188 deletions src/app/(main)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,200 +1,21 @@
import Link from "next/link";
import config from "../../../keystatic.config";
import CoverImage from "@/components/CoverImage";
import { Badge } from "@/components/ui/Badge";
import { LinkTag } from "@/components/ui/typography/LinkTag";
import { linkedInProfile } from "@/lib/constants";
import { formatDateRange } from "@/lib/dates";
import { createReader } from "@keystatic/core/reader";
import { DocumentRenderer } from "@keystatic/core/renderer";
import dayjs from "dayjs";
import { TbExternalLink } from "react-icons/tb";

const reader = createReader(process.cwd(), config);
import About from "@/components/homepage/About";
import Experiences from "@/components/homepage/Experiences";
import Posts from "@/components/homepage/Posts";
import Projects from "@/components/homepage/Projects";

export const metadata = {
alternates: {
canonical: "/",
},
};

const Page = async () => {
const aboutData = await reader.singletons.about.read({
resolveLinkedFiles: true,
});
const experiencesData = await reader.collections.experiences.all();

const sortedExperiencesDataByDate = experiencesData.sort((a, b) =>
dayjs(b.entry.startDate).diff(dayjs(a.entry.startDate))
);

const projectsData = await reader.collections.projects.all();

const postsData = await reader.collections.posts.all();

const sortedPostsData = postsData.sort((a, b) =>
dayjs(b.entry.date).diff(dayjs(a.entry.date))
);

const firstThreePosts = sortedPostsData.slice(0, 3);

const Page = () => {
return (
<>
<section className="space-y-4">
<h2
id="about"
className="scroll-m-20 text-2xl font-bold tracking-tight text-foreground sm:text-3xl">
About
</h2>

{aboutData && aboutData.description && (
<div className="prose text-justify">
<DocumentRenderer document={aboutData.description} />
</div>
)}
</section>

<section className="space-y-4">
<h2
id="experiences"
className="mb-10 scroll-m-20 text-2xl font-bold tracking-tight text-foreground sm:text-3xl">
Experiences
</h2>
<ol className="group/container">
{sortedExperiencesDataByDate.map((experience) => (
<li
key={experience.slug}
className="mb-12 transition-all duration-100 lg:hover:!opacity-100 lg:group-hover/container:opacity-50 ">
<a
target="_blank"
rel="noreferrer noopener"
href={experience.entry.link ?? undefined}
className="group/list relative grid rounded sm:grid-cols-12 md:gap-4 ">
<span className="absolute -inset-x-4 -inset-y-2.5 hidden rounded-md transition-all md:-inset-x-6 md:-inset-y-4 lg:block lg:group-hover/list:bg-foreground/5 lg:group-hover/list:backdrop-blur-md"></span>
<header
className="z-10 mb-2 mt-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground sm:col-span-4"
aria-label={formatDateRange(
experience.entry.startDate,
experience.entry.endDate.value
)}>
{formatDateRange(
experience.entry.startDate,
experience.entry.endDate.value
)}
</header>
<div className="z-10 space-y-4 sm:col-span-8">
<div className="space-y-2">
<p className="font-medium leading-snug text-foreground">
{experience.entry.title}
</p>
<p className="text-justify">
{experience.entry.description}
</p>
</div>
<div className="flex flex-wrap gap-2">
{experience.entry.tags.map((tag) => (
<Badge
key={tag}
variant="secondary">
{tag}
</Badge>
))}
</div>
</div>
</a>
</li>
))}
</ol>

<LinkTag
className="flex items-center gap-2"
href={linkedInProfile}
target="_blank"
rel="noreferrer noopener">
View More at LinkedIn
<TbExternalLink className="h-4 w-4 transition-all duration-100 group-hover:translate-x-4" />
</LinkTag>
</section>
<section className="space-y-4">
<h2
id="projects"
className="mb-10 scroll-m-20 text-2xl font-bold tracking-tight text-foreground sm:text-3xl">
Projects
</h2>
<ol className="group/container">
{projectsData.map((project) => (
<li
key={project.slug}
className="mb-12 transition-all duration-100 lg:hover:!opacity-100 lg:group-hover/container:opacity-50 ">
<a
target="_blank"
rel="noreferrer noopener"
href={project.entry.link ?? undefined}
className="group/list relative grid rounded sm:grid-cols-12 md:gap-4 ">
<span className="absolute -inset-x-4 -inset-y-2.5 hidden rounded-md transition-all md:-inset-x-6 md:-inset-y-4 lg:block lg:group-hover/list:bg-foreground/5 lg:group-hover/list:backdrop-blur-md"></span>
<header
className="z-10 mb-2 mt-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground sm:col-span-4"
aria-label={project.entry.name}>
{project.entry.image && (
<CoverImage
title={project.entry.name}
src={project.entry.image}
/>
)}
</header>
<div className="z-10 space-y-4 sm:col-span-8">
<div className="space-y-2">
<p className="font-medium leading-snug text-foreground">
{project.entry.name}
</p>
<p className="text-justify">
{project.entry.description}
</p>
</div>
</div>
</a>
</li>
))}
</ol>
</section>
<section className="space-y-4">
<h2
id="posts"
className="mb-10 scroll-m-20 text-2xl font-bold tracking-tight text-foreground sm:text-3xl">
Posts
</h2>
<ol className="group/container">
{firstThreePosts.map((post) => (
<li
key={post.slug}
className="mb-12 transition-all duration-100 lg:hover:!opacity-100 lg:group-hover/container:opacity-50 ">
<Link
href={`/posts/${post.slug}`}
className="group/list relative grid rounded ">
<span className="absolute -inset-x-4 -inset-y-2.5 hidden rounded-md transition-all md:-inset-x-6 md:-inset-y-4 lg:block lg:group-hover/list:bg-foreground/5 lg:group-hover/list:backdrop-blur-md"></span>
<div className="z-10 space-y-4 ">
<div className="space-y-2">
<p className="font-medium leading-snug text-foreground">
{post.entry.title}
</p>
<p className="text-justify">
{post.entry.description}
</p>
</div>
</div>
</Link>
</li>
))}
</ol>

<Link
className="group font-medium text-foreground transition-all duration-300 ease-in-out "
href="/posts">
<span className="bg-gradient-to-r from-foreground to-foreground bg-[length:0%_2px] bg-left-bottom bg-no-repeat pb-1 transition-all duration-500 ease-out group-hover:bg-[length:100%_2px]">
More Posts
</span>
</Link>
</section>
<About />
<Experiences />
<Projects />
<Posts />
</>
);
};
Expand Down
78 changes: 38 additions & 40 deletions src/app/(main)/posts/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,48 +43,46 @@ const Page = async () => {
dayjs(b.entry.date).diff(dayjs(a.entry.date))
);
return (
<>
<section
id="posts"
className="space-y-4">
<Link
className="group mb-10 flex items-center gap-2 font-medium text-foreground"
href="/">
<ChevronLeftIcon className="h-4 w-4" />
<span
className={twMerge(
"transition-all group-hover:underline group-hover:underline-offset-4 "
)}>
Back
</span>
</Link>
<section
id="posts"
className="space-y-4">
<Link
className="group mb-10 flex items-center gap-2 font-medium text-foreground"
href="/">
<ChevronLeftIcon className="h-4 w-4" />
<span
className={twMerge(
"transition-all group-hover:underline group-hover:underline-offset-4 "
)}>
Back
</span>
</Link>

<h2 className="sr-only">Posts</h2>
<ol className="group/container">
{sortedPostsData.map((post) => (
<li
key={post.slug}
className="mb-12 transition-all duration-100 lg:hover:!opacity-100 lg:group-hover/container:opacity-50 ">
<Link
href={`/posts/${post.slug}`}
className="group/list relative grid rounded ">
<span className="absolute -inset-x-4 -inset-y-2.5 hidden rounded-md transition-all md:-inset-x-6 md:-inset-y-4 lg:block lg:group-hover/list:bg-foreground/5 lg:group-hover/list:backdrop-blur-md"></span>
<div className="z-10 space-y-4 ">
<div className="space-y-2">
<p className="font-medium leading-snug text-foreground">
{post.entry.title}
</p>
<p className="text-justify">
{post.entry.description}
</p>
</div>
<h2 className="sr-only">Posts</h2>
<ol className="group/container">
{sortedPostsData.map((post) => (
<li
key={post.slug}
className="mb-12 transition-all duration-100 lg:hover:!opacity-100 lg:group-hover/container:opacity-50 ">
<Link
href={`/posts/${post.slug}`}
className="group/list relative grid rounded ">
<span className="absolute -inset-x-4 -inset-y-2.5 hidden rounded-md transition-all md:-inset-x-6 md:-inset-y-4 lg:block lg:group-hover/list:bg-foreground/5 lg:group-hover/list:backdrop-blur-md"></span>
<div className="z-10 space-y-4 ">
<div className="space-y-2">
<p className="font-medium leading-snug text-foreground">
{post.entry.title}
</p>
<p className="text-justify">
{post.entry.description}
</p>
</div>
</Link>
</li>
))}
</ol>
</section>
</>
</div>
</Link>
</li>
))}
</ol>
</section>
);
};

Expand Down
29 changes: 29 additions & 0 deletions src/components/homepage/About.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import config from "../../../keystatic.config";
import { createReader } from "@keystatic/core/reader";
import { DocumentRenderer } from "@keystatic/core/renderer";

const reader = createReader(process.cwd(), config);

const About = async () => {
const aboutData = await reader.singletons.about.read({
resolveLinkedFiles: true,
});

return (
<section className="space-y-4">
<h2
id="about"
className="scroll-m-20 text-2xl font-bold tracking-tight text-foreground sm:text-3xl">
About
</h2>

{aboutData && aboutData.description && (
<div className="prose text-justify">
<DocumentRenderer document={aboutData.description} />
</div>
)}
</section>
);
};

export default About;
Loading

0 comments on commit 6e9e747

Please sign in to comment.