😎

【Convex】NextJs14 と Convex【#8Organization List】

2024/04/01に公開

【#8Organization List】

YouTube: https://youtu.be/I0EJuZORXGM

https://youtu.be/I0EJuZORXGM

今回はOrganizationのリストを実装します。

my-app/(main)/_components/sidebar.tsx
"use client";

import { List } from "./list";
import { NewOrgButton } from "./new-org-button";

export const Sidebar = () => {
  return (
    <div className="w-[60px] h-full fixed z-10 bg-slate-700 p-2 flex flex-col gap-y-3">
      <List />
      <NewOrgButton />
    </div>
  );
};
my-app/(main)/_components/org-list.tsx
import { useOrganizationList } from "@clerk/nextjs";

import { OrgListItem } from "./org-list-item";

export const OrgList = () => {
  const { userMemberships } = useOrganizationList({
    userMemberships: {
      infinite: true,
    },
  });

  if (!userMemberships || !userMemberships.data) return null;

  return (
    <ul className="space-y-3">
      {userMemberships.data.map((org) => (
        <OrgListItem
          key={org.organization.id}
          id={org.organization.id}
          name={org.organization.name}
          imageUrl={org.organization.imageUrl}
        />
      ))}
    </ul>
  );
};
my-app/(main)/_components/org-list-item.tsx
import Image from "next/image";
import { useOrganization, useOrganizationList } from "@clerk/nextjs";

import { cn } from "@/lib/utils";

interface Props {
  id: string;
  name: string;
  imageUrl: string;
}

export const OrgListItem = ({ id, name, imageUrl }: Props) => {
  const { organization } = useOrganization();
  const { setActive } = useOrganizationList();

  const isActive = organization?.id === id;

  const onClick = () => {
    if (!setActive) return;

    setActive({ organization: id });
  };

  return (
    <li className="aspect-square relative">
      <Image
        src={imageUrl}
        alt={name}
        fill
        onClick={onClick}
        className={cn(
          "rounded-md cursor-pointer opacity-75 hover:opacity-100 transition",
          isActive && "opacity-100"
        )}
      />
    </li>
  );
};
next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "img.clerk.com",
      },
    ],
  },
};

export default nextConfig;

Discussion