Read-only Like Row Implementation Plan
Read-only Like Row Implementation Plan
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Add a read-only Like (heart + count) row under the title for dataset and data post pages, and reorder the dataset header to match the mockup.
Architecture: Introduce a small LikeRow component and render it from layout components (BlogLayout and DataPackageLayout). Reorder the dataset header so description (“Readme” snippet) and Like row appear before the metadata table; remove the solutions banner.
Tech Stack: Next.js (App Router), React, Tailwind CSS, Jest + Testing Library (unit), Playwright (optional manual verification).
Task 1: Create LikeRow component (read-only) with a unit test
Files:
- Create:
components/like-row.tsx - Create:
components/__tests__/like-row.test.tsx
Step 1: Write the failing test
import { render, screen } from "@testing-library/react";
import LikeRow from "@/components/like-row";
test("renders the like count", () => {
render(<LikeRow count={29} />);
const likeRow = screen.getByTestId("like-row");
expect(likeRow.textContent).toContain("29");
});
Step 2: Run test to verify it fails
Run: pnpm test -- components/__tests__/like-row.test.tsx
Expected: FAIL with "Cannot find module '@/components/like-row'".
Step 3: Write minimal implementation
import { HeartIcon } from "lucide-react";
interface LikeRowProps {
count?: number;
}
const LikeRow = ({ count = 29 }: LikeRowProps) => (
<div
className="mt-4 flex items-center gap-2 text-sm text-slate-500"
data-testid="like-row"
>
<HeartIcon className="h-4 w-4" aria-hidden="true" />
<span>{count}</span>
</div>
);
export default LikeRow;
Step 4: Run test to verify it passes
Run: pnpm test -- components/__tests__/like-row.test.tsx
Expected: PASS.
Step 5: Commit
git add components/like-row.tsx components/__tests__/like-row.test.tsx
git commit -m "feat: add read-only like row component"
Task 2: Update dataset layout header order + remove solutions banner
Files:
- Modify:
components/layouts/datapackage.tsx - Test:
e2e/datapackage-layout.spec.ts(optional)
Step 1: Write failing e2e check (optional but recommended)
Add a test that asserts the Like row is visible on the dataset page:
test("Like row is visible", async () => {
await expect(page.getByTestId("like-row")).toBeVisible();
});
Step 2: Run the e2e test to verify it fails
Run: pnpm test:e2e -- e2e/datapackage-layout.spec.ts -g "Like row"
Expected: FAIL with "locator resolved to 0 elements".
Step 3: Reorder header and remove solutions banner
- Remove the
hasSolutionsblock entirely. - Move the description block (
data-testid="dp-description") to directly under the<h1>. - Insert
<LikeRow />directly under the description block. - Ensure the metadata table (
data-testid="dp-metadata-table") stays below the Like row.
import LikeRow from "@/components/like-row";
// ...
<header className="mb-8 flex flex-col gap-y-5">
<h1 className="mb-2">{title}</h1>
<div data-testid="dp-description">
<p className="text-md">{description}</p>
<a className="inline-block text-[#6366F1] no-underline hover:underline" href="#readme">
<div className="flex items-center space-x-1">
<span>Read more</span>
<ArrowRightIcon className="inline h-4 w-4" />
</div>
</a>
</div>
<LikeRow />
{/* existing repo/share row can remain below LikeRow */}
{/* metadata table follows */}
</header>
Step 4: Run e2e to verify it passes (if added)
Run: pnpm test:e2e -- e2e/datapackage-layout.spec.ts -g "Like row"
Expected: PASS.
Step 5: Commit
git add components/layouts/datapackage.tsx e2e/datapackage-layout.spec.ts
git commit -m "feat: add read-only like row to dataset layout"
Task 3: Add Like row to blog layout
Files:
- Modify:
components/layouts/blog.tsx - Create:
components/layouts/__tests__/blog-layout.test.tsx
Step 1: Write failing unit test
import { render, screen } from "@testing-library/react";
import { BlogLayout } from "@/components/layouts/blog";
jest.mock("@/components/social-share", () => ({
SocialShare: () => <div data-testid="social-share" />,
}));
const metadata = {
_pagetype: "blog",
title: "Test Post",
description: "Test description",
date: "2024-01-01",
} as any;
test("renders like row under the title", () => {
render(
<BlogLayout metadata={metadata} siteMetadata={{} as any}>
<p>Body</p>
</BlogLayout>,
);
const likeRow = screen.getByTestId("like-row");
expect(likeRow.textContent).toContain("29");
});
Step 2: Run test to verify it fails
Run: pnpm test -- components/layouts/__tests__/blog-layout.test.tsx
Expected: FAIL with "Unable to find an element by: [data-testid="like-row"]".
Step 3: Insert LikeRow in blog layout
import LikeRow from "@/components/like-row";
// ...
{description && (
<p className="text-lg font-light text-primary-subtle md:text-xl">
{description}
</p>
)}
<LikeRow />
<SocialShare title={title || ""} />
Step 4: Run test to verify it passes
Run: pnpm test -- components/layouts/__tests__/blog-layout.test.tsx
Expected: PASS.
Step 5: Commit
git add components/layouts/blog.tsx components/layouts/__tests__/blog-layout.test.tsx
git commit -m "feat: add read-only like row to blog layout"