nomadweb/frontend/src/components/WifiWorkScore.tsx
eric 18fb3318b1 Rebrand to nomadro and add wifi score, savings goal, daily quote
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-28 23:19:27 -05:00

86 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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>
);
}