From efa055b8193efb93d0e7538a0f7d4bf412c238d6 Mon Sep 17 00:00:00 2001 From: kingrayhan Date: Mon, 23 Jun 2025 03:04:09 +0600 Subject: [PATCH 1/3] article-tags issue --- .../_components/TagArticleFeed.tsx | 28 +++++++++---------- .../tags/{[tag_id] => [tag_name]}/page.tsx | 19 +++++++++---- src/backend/services/inputs/tag.input.ts | 3 ++ src/backend/services/tag.action.ts | 18 ++++++++++++ 4 files changed, 48 insertions(+), 20 deletions(-) rename src/app/tags/{[tag_id] => [tag_name]}/_components/TagArticleFeed.tsx (86%) rename src/app/tags/{[tag_id] => [tag_name]}/page.tsx (70%) diff --git a/src/app/tags/[tag_id]/_components/TagArticleFeed.tsx b/src/app/tags/[tag_name]/_components/TagArticleFeed.tsx similarity index 86% rename from src/app/tags/[tag_id]/_components/TagArticleFeed.tsx rename to src/app/tags/[tag_name]/_components/TagArticleFeed.tsx index 7dea926..5328f96 100644 --- a/src/app/tags/[tag_id]/_components/TagArticleFeed.tsx +++ b/src/app/tags/[tag_name]/_components/TagArticleFeed.tsx @@ -1,23 +1,25 @@ "use client"; +import { Tag } from "@/backend/models/domain-models"; import * as articleActions from "@/backend/services/article.actions"; import ArticleCard from "@/components/ArticleCard"; import VisibilitySensor from "@/components/VisibilitySensor"; +import _t from "@/i18n/_t"; import { readingTime } from "@/lib/utils"; import getFileUrl from "@/utils/getFileUrl"; import { useInfiniteQuery } from "@tanstack/react-query"; import { useMemo } from "react"; interface TagArticleFeedProps { - tagId: string; + tag: Tag; } -const TagArticleFeed: React.FC = ({ tagId }) => { +const TagArticleFeed: React.FC = ({ tag }) => { const tagFeedQuery = useInfiniteQuery({ - queryKey: ["tag-articles", tagId], + queryKey: ["tag-articles", tag.id], queryFn: ({ pageParam }) => articleActions.articlesByTag({ - tag_id: tagId, + tag_id: tag.id, limit: 5, page: pageParam, }), @@ -37,10 +39,6 @@ const TagArticleFeed: React.FC = ({ tagId }) => { return tagFeedQuery.data?.pages?.[0]?.meta?.total ?? 0; }, [tagFeedQuery.data]); - const tagName = useMemo(() => { - return tagFeedQuery.data?.pages?.[0]?.tagName ?? "Unknown Tag"; - }, [tagFeedQuery.data]); - // Show loading skeletons if (tagFeedQuery.isPending) { return ( @@ -78,10 +76,10 @@ const TagArticleFeed: React.FC = ({ tagId }) => { return (

- No articles found + {_t("No articles found")}

- No articles have been tagged with “{tagName}” yet. + {_t(`No articles have been tagged with "$" yet.`, [tag.name])}

); @@ -91,10 +89,10 @@ const TagArticleFeed: React.FC = ({ tagId }) => { <>

- Articles tagged with “{tagName}” + {_t(`Articles tagged with "$"`, [tag.name])}

- Found {totalArticles} articles + {_t(`Found $ articles`, [totalArticles])}

@@ -106,7 +104,9 @@ const TagArticleFeed: React.FC = ({ tagId }) => { handle={article?.handle ?? ""} title={article?.title ?? ""} excerpt={article?.excerpt ?? ""} - coverImage={article?.cover_image ? getFileUrl(article.cover_image) : ""} + coverImage={ + article?.cover_image ? getFileUrl(article.cover_image) : "" + } author={{ id: article?.user?.id ?? "", name: article?.user?.name ?? "", @@ -133,4 +133,4 @@ const TagArticleFeed: React.FC = ({ tagId }) => { ); }; -export default TagArticleFeed; \ No newline at end of file +export default TagArticleFeed; diff --git a/src/app/tags/[tag_id]/page.tsx b/src/app/tags/[tag_name]/page.tsx similarity index 70% rename from src/app/tags/[tag_id]/page.tsx rename to src/app/tags/[tag_name]/page.tsx index a4c20fb..9d8f323 100644 --- a/src/app/tags/[tag_id]/page.tsx +++ b/src/app/tags/[tag_name]/page.tsx @@ -3,15 +3,22 @@ import HomeRightSidebar from "@/app/(home)/_components/HomeRightSidebar"; import SidebarToggleButton from "@/app/(home)/_components/SidebarToggleButton"; import HomepageLayout from "@/components/layout/HomepageLayout"; import TagArticleFeed from "./_components/TagArticleFeed"; +import { getTag, getTags } from "@/backend/services/tag.action"; +import { notFound } from "next/navigation"; interface TagPageProps { params: Promise<{ - tag_id: string; + tag_name: string; }>; } export default async function TagPage({ params }: TagPageProps) { - const { tag_id } = await params; + const { tag_name } = await params; + const tag = await getTag({ name: tag_name }); + + if (!tag?.success) { + throw notFound(); + } return ( } >
- +
); } export async function generateMetadata({ params }: TagPageProps) { - const { tag_id } = await params; + const { tag_name } = await params; // For now, use tag_id in the title. Later we can fetch the tag name if needed return { - title: `Tag ${tag_id} - Tech Diary`, + title: `Tag ${tag_name} - Tech Diary`, description: `Browse all articles with this tag on Tech Diary`, openGraph: { - title: `Tag ${tag_id} - Tech Diary`, + title: `Tag ${tag_name} - Tech Diary`, description: `Browse all articles with this tag on Tech Diary`, }, }; diff --git a/src/backend/services/inputs/tag.input.ts b/src/backend/services/inputs/tag.input.ts index 87d98e3..8e4a732 100644 --- a/src/backend/services/inputs/tag.input.ts +++ b/src/backend/services/inputs/tag.input.ts @@ -12,6 +12,9 @@ export const TagRepositoryInput = { color: z.string().optional().nullable(), description: z.string().optional().nullable(), }), + getTag: z.object({ + name: z.string(), + }), updateInput: z.object({ tag_id: z.string(), name: z.string().optional(), diff --git a/src/backend/services/tag.action.ts b/src/backend/services/tag.action.ts index bc068d7..ae020af 100644 --- a/src/backend/services/tag.action.ts +++ b/src/backend/services/tag.action.ts @@ -25,6 +25,24 @@ export const getTags = async ( } }; +export const getTag = async ( + _input: z.infer +) => { + try { + const input = await TagRepositoryInput.createInput.parseAsync(_input); + const response = await persistenceRepository.tags.find({ + where: eq("name", input.name), + }); + + return { + data: response[0], + success: true as const, + }; + } catch (error) { + handleActionException(error); + } +}; + export const createTag = async ( _input: z.infer ) => { From 9029e6d73f54a2139cb112ed2fb5f77441a7b137 Mon Sep 17 00:00:00 2001 From: Shoaib Sharif Date: Mon, 23 Jun 2025 08:49:03 -0500 Subject: [PATCH 2/3] fix: add suppressHydrationWarning for hydration issues and adjust imports in feed components --- src/app/(home)/_components/ArticleFeed.tsx | 23 +++++++++++++------ .../[tag_name]/_components/TagArticleFeed.tsx | 13 ++++++----- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/app/(home)/_components/ArticleFeed.tsx b/src/app/(home)/_components/ArticleFeed.tsx index a4b6e84..20c56ec 100644 --- a/src/app/(home)/_components/ArticleFeed.tsx +++ b/src/app/(home)/_components/ArticleFeed.tsx @@ -1,14 +1,11 @@ "use client"; import * as articleActions from "@/backend/services/article.actions"; -import * as seriesActions from "@/backend/services/series.action"; import ArticleCard from "@/components/ArticleCard"; -import SeriesCard from "@/components/SeriesCard"; import VisibilitySensor from "@/components/VisibilitySensor"; import { readingTime } from "@/lib/utils"; import getFileUrl from "@/utils/getFileUrl"; import { useInfiniteQuery } from "@tanstack/react-query"; -import { Loader } from "lucide-react"; import { useState } from "react"; const ArticleFeed = () => { @@ -53,10 +50,22 @@ const ArticleFeed = () => {
{articleFeedQuery.isPending && ( <> -
-
-
-
+
+
+
+
)} diff --git a/src/app/tags/[tag_name]/_components/TagArticleFeed.tsx b/src/app/tags/[tag_name]/_components/TagArticleFeed.tsx index 5328f96..9655e11 100644 --- a/src/app/tags/[tag_name]/_components/TagArticleFeed.tsx +++ b/src/app/tags/[tag_name]/_components/TagArticleFeed.tsx @@ -4,17 +4,18 @@ import { Tag } from "@/backend/models/domain-models"; import * as articleActions from "@/backend/services/article.actions"; import ArticleCard from "@/components/ArticleCard"; import VisibilitySensor from "@/components/VisibilitySensor"; -import _t from "@/i18n/_t"; +import { useTranslation } from "@/i18n/use-translation"; import { readingTime } from "@/lib/utils"; import getFileUrl from "@/utils/getFileUrl"; import { useInfiniteQuery } from "@tanstack/react-query"; -import { useMemo } from "react"; +import React, { useMemo } from "react"; interface TagArticleFeedProps { tag: Tag; } const TagArticleFeed: React.FC = ({ tag }) => { + const { _t } = useTranslation(); const tagFeedQuery = useInfiniteQuery({ queryKey: ["tag-articles", tag.id], queryFn: ({ pageParam }) => @@ -43,10 +44,10 @@ const TagArticleFeed: React.FC = ({ tag }) => { if (tagFeedQuery.isPending) { return (
-
-
-
-
+
+
+
+
); } From 60a4e1a51ab06a0da0d4443508f314b3eb3eb0d6 Mon Sep 17 00:00:00 2001 From: Shoaib Sharif Date: Mon, 23 Jun 2025 12:19:35 -0500 Subject: [PATCH 3/3] fix: update tag link for React in HomeLeftSidebar component --- src/app/(home)/_components/HomeLeftSidebar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/(home)/_components/HomeLeftSidebar.tsx b/src/app/(home)/_components/HomeLeftSidebar.tsx index 32aaea0..c40c724 100644 --- a/src/app/(home)/_components/HomeLeftSidebar.tsx +++ b/src/app/(home)/_components/HomeLeftSidebar.tsx @@ -96,7 +96,7 @@ const tags = [ { icon: "https://res.cloudinary.com/techdiary-dev/image/upload/v1620782239/static-assets/tag-icons/erfbu54l2mquphszheck.svg", label: "react", - link: "/tags/186e052a-9c5b-4ffe-b753-ea172ac2e663", + link: "/tags/reactjs", }, { icon: "https://res.cloudinary.com/techdiary-dev/image/upload/v1620782240/static-assets/tag-icons/rh7xfiz28bxklfzymftd.svg",