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 hasSolutions block 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"