Skip to content

Commit

Permalink
feat: share buttons and metadata (#25)
Browse files Browse the repository at this point in the history
* fix: add limit 10 related post tag

* style: change to default blue shadcn theme

* fix(server): add new social media if it is less than the prev value

* fix(server): change protected into public procedure in post by params

* feat: add dynamic metadata in post and user

* feat: add additional metadata

* feat: add share buttons
  • Loading branch information
DikDns authored Jul 12, 2024
1 parent 1f4129d commit 2c59cfd
Show file tree
Hide file tree
Showing 8 changed files with 320 additions and 31 deletions.
Binary file modified bun.lockb
Binary file not shown.
39 changes: 39 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"react-hook-form": "^7.52.0",
"react-infinite-scroll-component": "^6.1.0",
"react-select": "^5.8.0",
"react-share": "^5.1.0",
"server-only": "^0.0.1",
"sharp": "^0.33.3",
"sonner": "^1.5.0",
Expand Down
105 changes: 79 additions & 26 deletions src/app/[username]/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,59 @@
import { type Metadata, type ResolvingMetadata } from "next";
import Link from "next/link";
import { notFound } from "next/navigation";
import parse from "html-react-parser";

import { Navbar } from "@/components/common/navbar";
import {
CopyLink,
Facebook,
Instapaper,
Line,
Linkedin,
Telegram,
Twitter,
Whatsapp,
} from "@/components/common/share-buttons";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import { abbreviation, calculateReadTime, momentId } from "@/lib/utils";
import { getServerAuthSession } from "@/server/auth";
import { api } from "@/trpc/server";

export default async function PostPage({
params,
}: {
type PostPageProps = {
params: {
username: string;
slug: string;
};
}) {
};

export async function generateMetadata(
{ params }: PostPageProps,
parent: ResolvingMetadata,
): Promise<Metadata> {
const username = params.username.substring(3);
const { post, author } = await api.post.byParams.query({
slug: params.slug,
username: username,
});

const previousImages = (await parent).openGraph?.images ?? [];

const description =
(post?.content?.length ?? 0) > 160
? `${post?.content.slice(0, 160)}...`
: post?.content;

return {
title: `${post?.metaTitle} oleh ${author?.name}`,
description: description,
openGraph: {
images: [`${post?.image}`, ...previousImages],
},
};
}

export default async function PostPage({ params }: PostPageProps) {
const session = await getServerAuthSession();
const username = params.username.substring(3);
const { post, author } = await api.post.byParams.query({
Expand All @@ -32,7 +69,7 @@ export default async function PostPage({
<>
<Navbar session={session} />
<main className="container mt-20 flex min-h-screen flex-col gap-y-4 pb-16 md:px-24 lg:px-48">
<h2 className="mt-2 scroll-m-20 text-pretty font-serif text-5xl font-bold tracking-tight">
<h2 className="mt-2 scroll-m-20 text-pretty font-serif text-4xl font-bold tracking-wider sm:text-5xl">
{post.title}
</h2>
<div className="flex flex-wrap gap-2">
Expand All @@ -45,33 +82,49 @@ export default async function PostPage({
))}
</div>

<div className="mt-4 flex gap-x-4">
<Link href={`/@${author.username}`}>
<Avatar className="h-12 w-12">
<AvatarImage
src={author.image ?? ""}
alt={author.name + " profile picture"}
/>
<AvatarFallback>{abbreviation(author.name)}</AvatarFallback>
</Avatar>
</Link>
<div className="flex flex-col justify-end gap-y-1">
<div className="mt-4 flex flex-col justify-between gap-x-3 gap-y-6 sm:flex-row">
<div className="flex items-center gap-x-4">
<Link href={`/@${author.username}`}>
<p className="text-sm">{author.name}</p>
<Avatar className="h-12 w-12">
<AvatarImage
src={author.image ?? ""}
alt={author.name + " profile picture"}
/>
<AvatarFallback>{abbreviation(author.name)}</AvatarFallback>
</Avatar>
</Link>
<div className="flex items-center gap-x-2">
<span className="text-sm text-muted-foreground">
{calculateReadTime(post.content)} menit baca
</span>
<span className="text-sm text-muted-foreground"></span>
<span className="text-sm text-muted-foreground">
{momentId(post.publishedAt).fromNow()}
</span>
<div className="flex flex-col justify-end gap-y-1">
<Link href={`/@${author.username}`}>
<p className="text-sm">{author.name}</p>
</Link>
<div className="flex items-center gap-x-2">
<span className="text-sm text-muted-foreground">
{calculateReadTime(post.content)} menit baca
</span>
<span className="text-sm text-muted-foreground"></span>
<span className="text-sm text-muted-foreground">
{momentId(post.publishedAt).fromNow()}
</span>
</div>
</div>
</div>

<div className="flex flex-col gap-x-4 gap-y-1 sm:flex-row sm:items-end">
<p className="text-sm text-muted-foreground">Bagikan ke: </p>
<div className="flex flex-wrap items-start sm:max-w-40 lg:max-w-80">
<Whatsapp />
<Telegram />
<Line />
<Linkedin />
<Instapaper />
<Facebook />
<Twitter />
<CopyLink />
</div>
</div>
</div>

<article className="prose mt-4 min-h-screen max-w-none dark:prose-invert lg:prose-xl prose-headings:border-b prose-headings:font-serif prose-headings:font-semibold prose-headings:tracking-tight">
<article className="prose mt-4 min-h-screen max-w-none dark:prose-invert lg:prose-xl prose-headings:border-b prose-headings:border-border prose-headings:font-serif prose-headings:font-semibold prose-headings:tracking-tight prose-h1:text-5xl prose-h2:text-4xl prose-h3:text-2xl prose-h4:text-xl prose-h5:text-lg sm:prose-h1:text-6xl sm:prose-h2:text-5xl sm:prose-h3:text-3xl sm:prose-h4:text-2xl sm:prose-h5:text-xl ">
{parse(post.rawHtml)}
</article>
</main>
Expand Down
28 changes: 23 additions & 5 deletions src/app/[username]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { type Metadata, type ResolvingMetadata } from "next";
import Image from "next/image";
import Link from "next/link";

Expand All @@ -8,11 +9,28 @@ import { cn } from "@/lib/utils";
import { getServerAuthSession } from "@/server/auth";
import { api } from "@/trpc/server";

export default async function UserPage({
params,
}: {
type UserPageProps = {
params: { username: string };
}) {
};

export async function generateMetadata(
{ params }: UserPageProps,
parent: ResolvingMetadata,
): Promise<Metadata> {
const username = params.username.replace("%40", "");
const user = await api.user.byUsername.query(username);
const previousImages = (await parent).openGraph?.images ?? [];

return {
title: `${user?.name} ${user?.position?.toUpperCase()} ${user?.department?.acronym.toUpperCase()}`,
description: `Mengenal lebih dekat ${user?.name}, simak selengkapnya di sini!`,
openGraph: {
images: [`${user?.image}`, ...previousImages],
},
};
}

export default async function UserPage({ params }: UserPageProps) {
const session = await getServerAuthSession();
const username = params.username.replace("%40", "");

Expand All @@ -39,7 +57,7 @@ export default async function UserPage({
<p className="mb-1 text-lg capitalize">{`${user?.position}`}</p>
) : (
<p className="mb-1 text-lg capitalize">
{`${user?.position} ${user?.department?.name}`}
{`${user?.position} ${user?.department?.acronym}`}
</p>
)}

Expand Down
22 changes: 22 additions & 0 deletions src/app/tag/[tag-slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
import { type Metadata } from "next";

import { TagResult } from "@/components/tag/tag-result";
import { api } from "@/trpc/server";

type TagSlugPage = {
params: {
"tag-slug": string;
};
};

export async function generateMetadata({
params,
}: TagSlugPage): Promise<Metadata> {
const tag = await api.postTag.searchUnique.query({
slug: params["tag-slug"],
});

return {
title: `LABEL ${tag?.title.toUpperCase()} | HIMARPL`,
description: `Lihat semua artikel yang berkaitan dengan ${tag?.title} hanya di HIMARPL!`,
};
}

export default function TagSlugPage() {
return (
Expand Down
Loading

0 comments on commit 2c59cfd

Please sign in to comment.