🦔

【Convex】NextJs14 と Convex【#25 Convex Card Footer】

2024/05/19に公開

【#25 Convex Card Footer】

YouTube: https://youtu.be/ee6oDqDhEO4
https://youtu.be/ee6oDqDhEO4

今回はカードにフッターを実装して
カードの情報を表示していきます。

今回追加するライブラリはこちらになります。

npx shadcn-ui@latest add badge
npm i date-fns
app/(main)/_components/card/index.tsx
"use client";

import Image from "next/image";
import { useAuth } from "@clerk/nextjs";
import { formatDistanceToNow } from "date-fns";

import { Footer } from "./footer";

interface Props {
  id: string;
  title: string;
  imageUrl: string;
  authorId: string;
  authorName: string;
  createdAt: number;
  orgId: string;
  cardType: string;
}

export const Card = ({
  id,
  title,
  imageUrl,
  authorId,
  authorName,
  createdAt,
  orgId,
  cardType,
}: Props) => {
  const { userId } = useAuth();
  const authorLabel = userId === authorId ? "You" : authorName;
  const createdAtLabel = formatDistanceToNow(createdAt, { addSuffix: true });

  return (
    <div className="group aspect-[100/128] border rounded-lg flex flex-col justify-between overflow-hidden">
      <div className="relative flex-1 bg-slate-300">
        <Image src={imageUrl} alt={title} fill className="object-cover" />
      </div>
      <Footer
        title={title}
        authorLabel={authorLabel}
        type={cardType}
        createdAtLabel={createdAtLabel}
      />
    </div>
  );
};
app/(main)/_components/card/footer.tsx
import { Badge } from "@/components/ui/badge";

interface Props {
  title: string;
  authorLabel: string;
  createdAtLabel: string;
  type: string;
}

export const Footer = ({ title, authorLabel, createdAtLabel, type }: Props) => {
  console.log(authorLabel);

  return (
    <div className="relative bg-white p-3">
      <div className="flex items-center max-w-[calc(100%-20px)]">
        <p className="text-[13px] truncate text-gray-800">
          {title.length < 12 ? title : title.substring(0, 10) + "..."}
        </p>
        <Badge variant="secondary" className="text-[10px] ml-auto">
          {type}
        </Badge>
      </div>
      <p className="opacity-0 flex justify-between items-center group-hover:opacity-100 transition-opacity text-[11px] text-muted-foreground truncate">
        {authorLabel}, {createdAtLabel}
      </p>
    </div>
  );
};

Discussion