86 lines
3.3 KiB
TypeScript
86 lines
3.3 KiB
TypeScript
"use client";
|
||
|
||
import { useMemo, useState, type CSSProperties } from "react";
|
||
import Link from "next/link";
|
||
import type { Destination } from "@/lib/types";
|
||
|
||
function workLevel(speed: number) {
|
||
if (speed >= 150) return { label: "极速办公", emoji: "🚀", color: "#6ee7b7", tip: "视频会议、大文件传输无压力" };
|
||
if (speed >= 80) return { label: "流畅办公", emoji: "✅", color: "#4ECDC4", tip: "日常远程工作完全够用" };
|
||
if (speed >= 40) return { label: "基本可用", emoji: "⚠️", color: "#FFE66D", tip: "建议准备热点备份" };
|
||
return { label: "需谨慎", emoji: "🐢", color: "#FF6B6B", tip: "优先选择联合办公或咖啡厅" };
|
||
}
|
||
|
||
interface Props {
|
||
destinations: Destination[];
|
||
}
|
||
|
||
export default function WifiWorkScore({ destinations }: Props) {
|
||
const [slug, setSlug] = useState(destinations[0]?.slug || "");
|
||
const dest = destinations.find((d) => d.slug === slug) || destinations[0];
|
||
const level = useMemo(() => workLevel(dest?.speed ?? 0), [dest]);
|
||
|
||
const ranked = useMemo(
|
||
() => [...destinations].sort((a, b) => b.speed - a.speed),
|
||
[destinations]
|
||
);
|
||
|
||
return (
|
||
<section className="section wifi-section" id="wifi">
|
||
<div className="container">
|
||
<div className="section-header reveal">
|
||
<span className="section-tag">📶 WIFI SCORE</span>
|
||
<h2>远程办公网速评级</h2>
|
||
<p>选城先看网——评估目的地是否适合稳定远程工作</p>
|
||
</div>
|
||
|
||
<div className="wifi-layout reveal">
|
||
<div className="wifi-picker">
|
||
<div className="calc-field">
|
||
<label>🏙️ 选择城市</label>
|
||
<select value={slug} onChange={(e) => setSlug(e.target.value)}>
|
||
{destinations.map((d) => (
|
||
<option key={d.slug} value={d.slug}>{d.emoji} {d.name}</option>
|
||
))}
|
||
</select>
|
||
</div>
|
||
|
||
{dest && (
|
||
<div className="wifi-meter">
|
||
<div className="wifi-meter-ring" style={{ "--wifi-color": level.color } as CSSProperties}>
|
||
<strong>{dest.speed}</strong>
|
||
<small>Mbps</small>
|
||
</div>
|
||
<div className="wifi-meter-info">
|
||
<h3>{dest.emoji} {dest.name}</h3>
|
||
<span className="wifi-level" style={{ color: level.color }}>
|
||
{level.emoji} {level.label}
|
||
</span>
|
||
<p>{level.tip}</p>
|
||
<Link href={`/destinations/${dest.slug}`} className="wifi-link">查看城市详情 →</Link>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
<div className="wifi-rank">
|
||
<h4>🏆 网速排行</h4>
|
||
<ul>
|
||
{ranked.map((d, i) => {
|
||
const lv = workLevel(d.speed);
|
||
return (
|
||
<li key={d.slug} className={d.slug === slug ? "active" : ""} onClick={() => setSlug(d.slug)}>
|
||
<span className="wifi-rank-num">{i + 1}</span>
|
||
<span>{d.emoji} {d.name}</span>
|
||
<span className="wifi-rank-speed" style={{ color: lv.color }}>{d.speed} Mbps</span>
|
||
</li>
|
||
);
|
||
})}
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
);
|
||
}
|