Attached here after the ‘:’ is next.js code for  the “Party home page” app that sells party tickets. Generate the next.js code for PartyMap component.: // app/page.tsx
'use client';

import React, { useState, useEffect, useCallback } from 'react';
import { Party, LocationData } from './interfaces';
import { fetchNearbyParties } from './actions/partyActions';
import { LocationInputForm } from './components/LocationInputForm';
import { PartyMap } from './components/PartyMap';
import { PartyDetailsCard } from './components/PartyDetailsCard';

export default function PartyHomePage() {
  const [parties, setParties] = useState<Party[]>([]);
  const [selectedParty, setSelectedParty] = useState<Party | null>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);

  const loadParties = useCallback(async (location: LocationData) => {
    setLoading(true);
    setError(null);
    setParties([]);
    setSelectedParty(null);

    try {
      const result = await fetchNearbyParties(location);

      if (result.success && result.data) {
        setParties(result.data);
        if (result.data.length > 0) {
          setSelectedParty(result.data[0]);
        }
      } else {
        setError(result.error || 'Failed to fetch parties due to an unknown reason.');
      }
    } catch (err: any) {
      console.error('Unexpected error calling fetchNearbyParties:', err);
      setError(err.message || 'An unexpected error occurred while processing your request.');
    } finally {
      setLoading(false);
    }
  }, []);

  const handlePartySelect = (party: Party) => {
    setSelectedParty(party);
  };

  #// The handleBuyTicket function is now fully encapsulated within PartyDetailsCard.tsx
  #// No need for it here in the parent component.

  return (
    <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 p-8">
      <h1 className="text-4xl font-extrabold text-center text-gray-800 mb-10">
        Party Ticket Marketplace
      </h1>

      <div className="max-w-6xl mx-auto grid grid-cols-1 lg:grid-cols-2 gap-8">
        {/* Left Column: Location Input and Party Map */}
        <div>
          <LocationInputForm onLocationSubmit={loadParties} isLoading={loading} />

          {loading && (
            <div className="text-center p-6 bg-white rounded-lg shadow-md">
              <p className="text-blue-600 font-semibold text-lg">Loading nearby parties... Please wait.</p>
            </div>
          )}

          {error && (
            <div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4" role="alert">
              <strong className="font-bold">Error! </strong>
              <span className="block sm:inline">{error}</span>
            </div>
          )}

          {!loading && !error && parties.length > 0 && (
            <PartyMap
              parties={parties}
              onPartySelect={handlePartySelect}
              selectedPartyId={selectedParty?.id || null}
            />
          )}

          {!loading && !error && parties.length === 0 && selectedParty === null && (
             <div className="bg-white p-6 rounded-lg shadow-md text-center text-gray-600">
                <p>No parties found near your location. Try getting your location again or check back later!</p>
             </div>
          )}
        </div>

        {/* Right Column: Party Details */}
        <div>
          <PartyDetailsCard
            party={selectedParty}
            #// onBuyTicket prop is removed
          />
        </div>
      </div>
    </div>
  );
}