Skip to content

Commit

Permalink
feat: Vrite blog
Browse files Browse the repository at this point in the history
  • Loading branch information
areknawo committed Jun 3, 2024
1 parent 511d11b commit a873ce5
Show file tree
Hide file tree
Showing 4 changed files with 521 additions and 92 deletions.
54 changes: 25 additions & 29 deletions apps/landing-page/src/pages/blog/[slug].astro
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
---
import { Header, BaseHead, Footer } from "#components/fragments";
import { IconButton, Card, Button } from "#components/primitives";
import { mdiCalendar } from "@mdi/js";
import { format } from "date-fns";
import { Content, ContentPiece, getStaticPaths } from "virtual:vrite";
import { convert } from "html-to-text";
import "#styles/blog.scss";
type Props = ContentPiece;
const { title, description, date, coverUrl, members } = Astro.props;
const { title, description, date, coverUrl } = Astro.props;
export const prerender = true;
export { getStaticPaths };
---

<html lang="en" class="dark">
<html lang="en" class="bg-gray-50 dark:bg-gray-800">
<head>
<BaseHead
title={title}
Expand All @@ -23,42 +22,39 @@ export { getStaticPaths };
/>
</head>

<body class="overflow-x-hidden overscroll-none">
<body class="overflow-x-hidden">
<main
class="flex flex-col items-center justify-center gap-8 p-4 pb-0 bg-gray-100 dark:bg-gray-800"
class="flex flex-col items-center justify-center gap-8 p-4 pb-0 bg-gray-50 dark:bg-gray-800"
>
<div class="w-full flex justify-center items-start max-w-screen-lg">
<Header client:idle />
</div><Card color="primary" class="m-0 p-2 overflow-hidden mt-8 md:mt-16">
<img src={`${coverUrl}?w=1200&format=webp`} class="max-w-screen-lg w-full rounded-2xl" />
</Card>
</div>
<div class="mt-8 md:mt-16 relative z-1 text-xl max-w-[calc(70ch+8rem)]">
<div class="grid-background-2"></div>
<div class="px-16">
<img
src={coverUrl}
alt="Blog post cover"
class="object-cover max-w-screen-lg w-full rounded-3xl shadow-2xl shadow-gray-400 dark:shadow-gray-900 before:bg-gray-100 dark:before:bg-gray-800"
/>
</div>
</div>
<div
class="prose dark:prose-invert text-gray-600 dark:text-gray-100 text-lg max-w-screen-lg w-full md:p-16 md:pt-0"
class="relative z-1 text-xl max-w-[70ch] prose dark:prose-invert text-gray-600 dark:text-gray-100 w-full pb-8 md:pt-0"
>
<div class="w-full justify-start items-center flex gap-2">
<IconButton
path={mdiCalendar}
class="px-1.5 m-0"
text="soft"
badge
label={format(date ? new Date(date) : new Date(), "dd MMM yyyy")}
/>
{
members.map((member) => {
return (
<Button class="flex gap-1 m-0 border-0 justify-center items-center pl-1.5" badge>
<img src={member.profile.avatar} class="h-6 w-6 rounded-full" />
<span class="font-semibold">{member.profile.fullName}</span>
</Button>
);
})
}
<span class="text-gray-500 dark:text-gray-400 text-base"> Arek Nawo</span>
<div class="h-4 w-px rounded-full bg-gray-500 dark:bg-gray-400"></div>
<span class="text-gray-500 dark:text-gray-400 text-base">
{format(date ? new Date(date) : new Date(), "dd MMM yyyy")}
</span>
</div>
<header class="not-prose font-extrabold text-3xl md:text-5xl">
{title}
<header>
<h1 class="!font-bold">{title}</h1>
</header>
<Content contentPieceId={Astro.props.id} />
</div>

<Footer />
</main>
</body>
Expand Down
156 changes: 93 additions & 63 deletions apps/landing-page/src/pages/blog/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,90 +6,120 @@ import "@fontsource/nunito/600.css";
import "@fontsource/nunito/700.css";
import "@fontsource/nunito/800.css";
import "@fontsource/nunito/900.css";
import { Button, Card, IconButton } from "#components/primitives";
import { mdiCalendar } from "@mdi/js";
import { format } from "date-fns";
import { BaseHead, Header, Footer } from "#components/fragments";
import { getContentPieces } from "virtual:vrite";
import { getContentPieces, client } from "virtual:vrite";
import { format } from "date-fns";
const contentPieces = await getContentPieces({ limit: "all" });
const tags = await client.tags.list({ perPage: 100 });
const workspace = await client.workspace.get();
const contentPiecesByMonth = contentPieces.reduce((acc, contentPiece) => {
const date = new Date(contentPiece.date);
const month = format(date, "MMMM yyyy");
if (!acc[month]) {
acc[month] = [];
}
acc[month].push(contentPiece);
return acc;
}, {});
const title = "Vrite - developer content platform";
const description =
"Open-Source, collaborative developer content platform for documentation, technical blogs, and more.";
export const prerender = true;
---

<html lang="en" class="dark">
<html lang="en" class="bg-gray-50 dark:bg-gray-800">
<head>
<BaseHead title={title} description={description} />
</head>

<body class="overflow-x-hidden overscroll-none">
<main
class="flex flex-col items-center justify-center gap-8 p-4 pb-0 bg-gray-100 dark:bg-gray-800"
class="flex flex-col relative items-center justify-center gap-8 p-4 pb-0 bg-gray-50 dark:bg-gray-800 z-0"
>
<div
class="bg-gradient-to-tr opacity-30 absolute top-[25vmin] xl:-top-[50vmin] -left-[50vmin] h-[100vmin] w-[100vmin] flex justify-center items-center rounded-full -z-1 blur-2xl"
>
<div class="h-[60vmin] w-[60vmin] bg-gray-50 dark:bg-gray-800 absolute rounded-full"></div>
</div>
<div class="w-full flex justify-center items-start max-w-screen-lg">
<Header client:idle />
</div>
<div class="min-h-screen max-w-screen-xl w-full mt-16">
<header
class="text-gray-600 dark:text-gray-100 font-extrabold text-3xl md:text-5xl flex justify-start items-center"
>
<h1>Blog</h1>
</header>

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 py-4 flex-1">
{
contentPieces.map((contentPiece) => (
<Fragment>
<a href={`/blog/${contentPiece.slug}/`}>
<div>
<Card color="primary" class="m-0 pb-0 pl-0 pr-2 pt-2 overflow-hidden">
<img
class="w-full rounded-2xl hover:hero-image transition-transform duration-500 shadow-xl"
src={`${contentPiece.coverUrl}?w=600?format=webp`}
/>
</Card>
<div class="px-2">
<div class="flex justify-start items-center mt-2">
<>
<IconButton
path={mdiCalendar}
class="px-1"
color="primary"
size="small"
badge
label={format(
contentPiece.date ? new Date(contentPiece.date) : new Date(),
"dd MMM yyyy"
)}
/>
</>
</div>
<h2 class="text-xl md:text-2xl text-gray-600 dark:text-gray-100">
{contentPiece.title}
</h2>
<div class="flex justify-start items-center mt-1">
{contentPiece.members.map((member) => {
return (
<Button
class="flex gap-1 m-0 border-0 justify-center items-center pl-1.5"
badge
>
<img src={member.profile.avatar} class="h-6 w-6 rounded-full" />
<span class="font-semibold">{member.profile.fullName}</span>
</Button>
);
})}
</div>
</div>
</div>
</a>
</Fragment>
))
}
<div
class="min-h-screen max-w-screen-lg w-full mt-16 relative justify-center items-center flex flex-col pb-16"
>
<div class="flex justify-start items-start py-16 w-full gap-20">
<div class="md:max-w-1/2">
<h1 class="text-5xl !font-bold text-gray-800 dark:text-gray-100 mb-2">
{workspace.name}
</h1>
<p class="text-2xl text-gray-500 dark:text-gray-400">
{workspace.description}
</p>
</div>
</div>
{
Object.entries(contentPiecesByMonth).map(([month, contentPieces]) => {
return (
<>
<div class="w-full opacity-10 my-8 text-black dark:text-white font-mono text-lg flex items-center justify-center gap-4">
<div class="h-2px bg-black dark:bg-white flex-1" />
{month}
</div>
<div class="flex w-full z-0 relative">
<div class="flex flex-col gap-20 w-full">
{contentPieces.map((contentPiece) => (
<a
class="flex flex-col-reverse md:flex-row w-full gap-4 md:gap-20 relative z-10 group"
href={`/blog/${contentPiece.slug}/`}
>
<div class="flex-1">
<div class="max-w-lg">
<div class="flex-1 text-gray-500 dark:text-gray-400">
{format(
contentPiece.date ? new Date(contentPiece.date) : new Date(),
"dd MMM yyyy"
)}
</div>
<h2 class="!font-bold text-3xl mb-1 group-hover:bg-gradient-to-tr group-hover:bg-clip-text group-hover:text-transparent">
{contentPiece.title}
</h2>
<div class="font-normal text-lg mb-2 text-gray-500 dark:text-gray-400">
<Fragment set:html={contentPiece.description} />
</div>
<div class="flex justify-start items-center gap-2 mb-1">
{contentPiece.tags.map((tag) => (
<div class="font-mono text-sm inline-flex">
<span class="font-bold bg-gradient-to-tr bg-clip-text text-transparent">
#
</span>
<span class="opacity-80">{tag.label.trim()}</span>
</div>
))}
</div>
</div>
</div>
<div class="flex flex-col gap-8 justify-center items-center w-full max-w-lg">
<div class="w-full rounded-3xl relative">
<div class="grid-background-3 -z-10" />
<div class="transition-transform duration-300 ease-in-out group-hover:scale-95 rounded-2xl overflow-hidden border-2 border-gray-200 dark:border-gray-700">
<img
alt={contentPiece.coverAlt}
src={contentPiece.coverUrl}
class="object-cover"
/>
</div>
</div>
</div>
</a>
))}
</div>
</div>
</>
);
})
}
</div>
<Footer />
</main>
Expand Down
51 changes: 51 additions & 0 deletions apps/landing-page/src/styles/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,21 @@ h2 {
mask-image: radial-gradient(ellipse at center, rgba(0, 0, 0, 1), transparent 90%);
animation: uncover 1s ease-out forwards;
}
.grid-background-3 {
position: absolute;
width: 175%;
height: 120%;
top: -10%;
left: -65%;
background-image: linear-gradient(#e5e7eb 2px, transparent 0),
linear-gradient(to right, #e5e7eb 2px, transparent 0);
background-size: 24px 24px;
background-position: center center;
mask-position: center center;
mask-repeat: no-repeat;
mask-image: radial-gradient(ellipse at center, rgba(0, 0, 0, 1), transparent 75%);
animation: uncover 1s ease-out forwards;
}

@media (prefers-color-scheme: dark) {
.grid-background {
Expand All @@ -167,7 +182,12 @@ h2 {
background-image: linear-gradient(#4b5563 2px, transparent 0),
linear-gradient(to right, #4b5563 2px, transparent 0);
}
.grid-background-3 {
background-image: linear-gradient(#374151 2px, transparent 0),
linear-gradient(to right, #374151 2px, transparent 0);
}
}

@keyframes uncover {
from {
opacity: 0;
Expand Down Expand Up @@ -235,3 +255,34 @@ h2 {
);
}
}

.astro-code {
@apply !rounded-2xl !bg-gray-800 !dark:bg-gray-900 px-4 py-3 leading-6;
}
.astro-code::-webkit-scrollbar {
@apply w-2 h-4 rounded-b-2xl bg-gray-800 dark:bg-gray-900 border;
}
.astro-code::-webkit-scrollbar-thumb {
@apply rounded-2xl bg-gray-700 border-4 border-gray-800 dark:border-gray-900 border-solid;
}
.astro-code::-webkit-scrollbar-track {
@apply mx-2;
}
.prose :where(code):not(:where(pre *, .not-prose, .not-prose *)) {
@apply bg-gray-200 fill-current dark:bg-gray-900 rounded-md px-1 font-mono font-medium py-0.5 text-wrap;
}
.prose :where(code):not(:where(pre *, .not-prose, .not-prose *))::after {
content: "";
}
.prose :where(code):not(:where(pre *, .not-prose, .not-prose *))::before {
content: "";
}
.prose :where(img, video):not(:where(.not-prose, .not-prose *)) {
@apply rounded-2xl;
}
.prose :where(figcaption) {
@apply text-center text-gray-500 dark:text-gray-400 text-sm mt-1;
}
.prose img {
margin-bottom: 1em;
}
Loading

0 comments on commit a873ce5

Please sign in to comment.