#How to not require Client component for each page with "next/auth" user in app 13.4?

3 messages · Page 1 of 1 (latest)

trim saddle
#

At the moment my app look like this. i'm just wondering if there a better way?!

actions/getCurrentUser.ts

import { getServerSession } from "next-auth/next";

import { authOptions } from "@/pages/api/auth/[...nextauth]";
import prisma from "@/app/libs/prismadb";

export async function getSession() return await getServerSession(authOptions);

export default async function getCurrentUser() {
    const session = await getSession();
    if (!session?.user?.email) return null;
    const currentUser = await prisma.user.findUnique({
      where: { email: session.user.email as string },
    });

    return { ...currentUser,
      createdAt: currentUser.createdAt.toISOString(),
      updatedAt: currentUser.updatedAt.toISOString(),
      emailVerified: currentUser.emailVerified?.toISOString() || null,
    };

/app/layout.tsx

export default async function RootLayout({ children }: {
  children: React.ReactNode }) {
  const currentUser = await getCurrentUser();
  return <html lang="en">
      <body className={font.className}>
        <ClientOnly>
          <Navbar currentUser={currentUser} />
        </ClientOnly>
        <div className="pb-20 pt-28">{children}</div>
      </body>
    </html>
}
#

// For a page like "trips" 2 components are used "page.tsx and TripsClient.tsx"

import EmptyState from "@/app/components/EmptyState";
import ClientOnly from "@/app/components/ClientOnly";

import getCurrentUser from "@/app/actions/getCurrentUser";
import getReservations from "@/app/actions/getReservations";

import TripsClient from "./TripsClient";

const TripsPage = async () => {
  const currentUser = await getCurrentUser();

  if (!currentUser) {
    return <ClientOnly><EmptyState title="Unauthorized" subtitle="Please login" /></ClientOnly>
  }

  const reservations = await getReservations({ userId: currentUser.id });

  if (reservations.length === 0) {
    return <ClientOnly>
        <EmptyState
          title="No trips found"
          subtitle="Looks like you havent reserved any trips."
        />
      </ClientOnly>
  }
  return <ClientOnly><TripsClient reservations={reservations} currentUser={currentUser} /></ClientOnly>
};
export default TripsPage;
#

Client only component

"use client";

import React, { useState, useEffect } from "react";

interface ClientOnlyProps {
  children: React.ReactNode;
}

const ClientOnly: React.FC<ClientOnlyProps> = ({ children }) => {
  const [hasMounted, setHasMounted] = useState(false);

  useEffect(() => {
    setHasMounted(true);
  }, []);

  if (!hasMounted) return null;

  return <>{children}</>;
};

export default ClientOnly;