[copy airbnb] 14、属性屏幕(使用服务器组件加载您的列表) Properties screen (Loading your listings with server component)

1、page.tsx

import getCurrentUser from "../actions/getCurrentUser";
import getListings from "../actions/getListings";
import ClientOnly from "../components/ClientOnly";
import EmptyState from "../components/EmptyState";
import PropertiesClient from "./PropertiesClient";

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

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

  const listings = await getListings({
    userId:currentUser.id
  })

  if(listings.length === 0){
    return (
        <ClientOnly>
            <EmptyState title="No properties found" subtitle="Looks like you have no properties."/>
        </ClientOnly>
    );
  }

  return (
  <ClientOnly>
     <PropertiesClient listings={listings} currentUser={currentUser}></PropertiesClient>
  </ClientOnly>
 )
};

export default PropertiesPage;

2、PropertiesClient.tsx

"use client";

import Container from "@/app/components/Container";
import { SafeListing, SafeUser } from "../types";
import Heading from "../components/Heading";
import { useRouter } from "next/navigation";
import { useCallback, useState } from "react";
import axios from "axios";
import toast from "react-hot-toast";
import ListingCard from "../components/listings/ListingCard";

interface PropertiesClientProps {
  listings: SafeListing[];
  currentUser: SafeUser | null;
}

const PropertiesClient: React.FC<PropertiesClientProps> = ({
  listings,
  currentUser,
}) => {
  const router = useRouter();
  const [deletingId, setDeletingId] = useState("");
  const onCancel = useCallback(
    (id: string) => {
      setDeletingId(id);
      axios
        .delete(`/api/listings/${id}`)
        .then(() => {
          toast.success("Listings deleted!");
          router.refresh();
        })
        .catch((error) => {
          toast.error(error?.response?.data?.error);
        })
        .finally(() => {
          setDeletingId("");
        });
    },
    [router]
  );
  return (
    <Container>
      <Heading
        title="Properties"
        subtitle="List of your properties"
      />
      <div className="mt-10 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 gap-8">
        {listings.map((listing) => (
          <ListingCard
            key={listing.id}
            data={listing}
            actionId={listing.id}
            onAction={onCancel}
            disabled={deletingId === listing.id}
            actionLabel="Delete Listing"
            currentUser={currentUser}
          />
        ))}
      </div>
    </Container>
  );
};

export default PropertiesClient;

3、src/app/api/listings/[listingId]/route.ts

import getCurrentUser from "@/app/actions/getCurrentUser";
import { NextResponse } from "next/server";

interface IParams{
    listingId?:string;
}

export async function DELETE(
    request:Request,
    {params}:{params:IParams}
){
    const currentUser = await getCurrentUser();
    if(!currentUser){
        return NextResponse.error();
    }

    const {listingId} = params;

    if(!listingId || typeof listingId !== 'string'){
        throw new Error("Invalid ID");
    }

    const listing = await prisma?.listing.deleteMany({
        where:{
            id:listingId,
            userId:currentUser.id
        }
    })

    return NextResponse.json(listing);
}

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部