😊

【Drizzle ORM】NextJs14 と Drizzle ORM【#25 Get Clerk User】

2024/11/01に公開

【#25 Get Clerk User】

YouTube: https://youtu.be/QYIbh5EoaWA
https://youtu.be/QYIbh5EoaWA

今回はClerkでログインしているユーザーの情報を取得して、
プロフィールページで表示します。

Honoのルートに付きましては、
以前作成した「/users/me」を使用します。

まずは、ユーザーデータを取得するhooksを作成します。

hooks/users/use-get-clerk-user.ts
import { useQuery } from "@tanstack/react-query";

import { client } from "@/lib/hono";

export const useGetClerkUser = () => {
  const query = useQuery({
    queryKey: ["clerk-user"],
    queryFn: async () => {
      const response = await client.api.users.me.$get();

      if (!response.ok) {
        throw new Error("Failed to fetch clerk user");
      }

      const { data } = await response.json();

      return data;
    },
  });

  return query;
};

そしてこちらのhooksをプロフィールのページで呼び出します。

app/(protected)/profile/page.tsx
"use client";

import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { useGetClerkUser } from "@/hooks/users/use-get-clerk-user";

const ProfilePage = () => {
  const clerkUserQuery = useGetClerkUser();
  const clerkUser = clerkUserQuery.data;
  const isLoading = clerkUserQuery.isLoading;

  if (isLoading || !clerkUser) {
    return <div>Loading...</div>;
  }

  return (
    <div className="flex flex-col gap-y-3">
      <Card>
        <CardHeader>
          <CardTitle className="font-bold">My Profile</CardTitle>
          <CardDescription>Profile Details</CardDescription>
          <Separator className="my-4" />
        </CardHeader>
        <CardContent>
          <div className="flex items-center gap-x-2">
            <Avatar>
              <AvatarImage src={clerkUser.imageUrl || ""} alt="User" />
              <AvatarFallback>M</AvatarFallback>
            </Avatar>
            <div className="flex flex-col justify-center">
              <p className="text-sm truncate">{clerkUser.name}</p>
              <p className="text-sm truncate text-muted-foreground">
                {clerkUser.email}
              </p>
            </div>
          </div>
        </CardContent>
      </Card>
    </div>
  );
};

export default ProfilePage;

Discussion