114 lines
3.5 KiB
TypeScript
114 lines
3.5 KiB
TypeScript
import { useState } from "react";
|
||
import { Phone, Mail, Globe, MessageSquare, Copy, Check, Headset } from "lucide-react";
|
||
|
||
type Channel = {
|
||
key: string;
|
||
icon: typeof Phone;
|
||
label: string;
|
||
value: string;
|
||
href?: string;
|
||
copy: string;
|
||
};
|
||
|
||
const CHANNELS: Channel[] = [
|
||
{
|
||
key: "phone",
|
||
icon: Phone,
|
||
label: "电话",
|
||
value: "188 6595 7520",
|
||
href: "tel:18865957520",
|
||
copy: "18865957520",
|
||
},
|
||
{
|
||
key: "email",
|
||
icon: Mail,
|
||
label: "邮箱",
|
||
value: "1115084741@qq.com",
|
||
href: "mailto:1115084741@qq.com",
|
||
copy: "1115084741@qq.com",
|
||
},
|
||
{
|
||
key: "site",
|
||
icon: Globe,
|
||
label: "官网",
|
||
value: "www.wenyaoyu.com",
|
||
href: "https://www.wenyaoyu.com",
|
||
copy: "https://www.wenyaoyu.com",
|
||
},
|
||
{
|
||
key: "wechat",
|
||
icon: MessageSquare,
|
||
label: "微信",
|
||
value: "s-b-m-y",
|
||
copy: "s-b-m-y",
|
||
},
|
||
];
|
||
|
||
export default function Contact() {
|
||
const [copied, setCopied] = useState<string | null>(null);
|
||
|
||
async function copy(channel: Channel) {
|
||
try {
|
||
await navigator.clipboard.writeText(channel.copy);
|
||
setCopied(channel.key);
|
||
setTimeout(() => setCopied((k) => (k === channel.key ? null : k)), 1500);
|
||
} catch {
|
||
/* clipboard unavailable */
|
||
}
|
||
}
|
||
|
||
return (
|
||
<div className="max-w-3xl mx-auto animate-fade-up">
|
||
<div className="text-center">
|
||
<span className="mx-auto grid h-14 w-14 place-items-center rounded-2xl bg-gradient-to-br from-brand-500 to-brand-700 text-white shadow-glow">
|
||
<Headset className="w-7 h-7" />
|
||
</span>
|
||
<h1 className="mt-4 text-2xl font-semibold tracking-tight text-gray-900">联系我们</h1>
|
||
<p className="mx-auto mt-2 max-w-xl text-sm text-gray-500">
|
||
欢迎交流与对接合作。无论是数据接入、商务合作还是问题反馈,都可以通过以下任一方式联系我们。
|
||
</p>
|
||
</div>
|
||
|
||
<div className="mt-8 grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||
{CHANNELS.map((c) => {
|
||
const Icon = c.icon;
|
||
return (
|
||
<div key={c.key} className="card p-5 flex items-center gap-4">
|
||
<span className="grid h-11 w-11 shrink-0 place-items-center rounded-xl bg-brand-50 text-brand-600">
|
||
<Icon className="w-5 h-5" />
|
||
</span>
|
||
<div className="min-w-0 flex-1">
|
||
<div className="text-xs font-medium text-gray-400">{c.label}</div>
|
||
{c.href ? (
|
||
<a
|
||
href={c.href}
|
||
target={c.key === "site" ? "_blank" : undefined}
|
||
rel={c.key === "site" ? "noreferrer" : undefined}
|
||
className="block truncate font-medium text-gray-800 hover:text-brand-600 hover:underline"
|
||
>
|
||
{c.value}
|
||
</a>
|
||
) : (
|
||
<div className="truncate font-medium text-gray-800">{c.value}</div>
|
||
)}
|
||
</div>
|
||
<button
|
||
type="button"
|
||
onClick={() => copy(c)}
|
||
title="复制"
|
||
className="shrink-0 grid h-9 w-9 place-items-center rounded-lg border border-gray-200 text-gray-400 transition hover:bg-gray-50 hover:text-brand-600"
|
||
>
|
||
{copied === c.key ? (
|
||
<Check className="w-4 h-4 text-brand-600" />
|
||
) : (
|
||
<Copy className="w-4 h-4" />
|
||
)}
|
||
</button>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|