47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
"use client";
|
|
|
|
import { createPortal } from "react-dom";
|
|
import { City } from "../data/cities";
|
|
|
|
interface CityModalProps {
|
|
city: City | null;
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
}
|
|
|
|
export default function CityModal({ city, isOpen, onClose }: CityModalProps) {
|
|
if (!isOpen || !city) return null;
|
|
|
|
const modalContent = (
|
|
<div className="fixed inset-0 z-[9999] overflow-y-auto">
|
|
<div className="fixed inset-0 bg-black/50" onClick={onClose} aria-hidden />
|
|
<div className="flex min-h-svh items-center justify-center p-4">
|
|
<div
|
|
className="relative w-full max-w-md rounded-2xl bg-white dark:bg-gray-900 p-6 shadow-xl dark:border dark:border-gray-700"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<button
|
|
onClick={onClose}
|
|
className="absolute right-4 top-4 text-gray-400 hover:text-gray-600"
|
|
>
|
|
<svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</button>
|
|
<h2 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
|
|
{city.name}
|
|
</h2>
|
|
<p className="mt-2 text-gray-600 dark:text-gray-400">{city.description}</p>
|
|
<div className="mt-4 space-y-2 text-sm">
|
|
<p>💰 月均消费: ¥{city.costPerMonth.toLocaleString()}</p>
|
|
<p>📡 网速: {city.internetSpeed}Mbps</p>
|
|
<p>👥 当前游民: {city.nomadsNow} 人</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
return createPortal(modalContent, document.body);
|
|
}
|