53 lines
1.9 KiB
TypeScript
53 lines
1.9 KiB
TypeScript
import React from 'react';
|
|
|
|
interface DesktopIconProps {
|
|
icon: string;
|
|
label: string;
|
|
onClick?: () => void;
|
|
disabled?: boolean;
|
|
locked?: boolean;
|
|
vip?: boolean;
|
|
index?: number;
|
|
}
|
|
|
|
export default function DesktopIcon({ icon, label, onClick, disabled, locked, vip, index = 0 }: DesktopIconProps) {
|
|
const isBlocked = locked || disabled;
|
|
|
|
return (
|
|
<button
|
|
onClick={isBlocked ? undefined : onClick}
|
|
disabled={disabled}
|
|
className={`relative flex flex-col items-center justify-center gap-2 py-6 border border-[#333]
|
|
transition-colors duration-75 cursor-pointer disabled:cursor-not-allowed
|
|
hover:bg-[#222] hover:border-[#555] group
|
|
${isBlocked ? 'opacity-50' : ''}`}
|
|
>
|
|
<span className="tech-sn absolute top-1.5 left-1.5 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
X{index % 4}Y{Math.floor(index / 4)}
|
|
</span>
|
|
|
|
<span className={`material-symbols-outlined text-[34px] transition-colors duration-75
|
|
${isBlocked ? 'text-[#444]' : 'text-[#888] group-hover:text-[#ff4500]'}`}>
|
|
{icon}
|
|
</span>
|
|
|
|
<div className="flex items-center gap-1.5">
|
|
<span className={`text-[17px] font-semibold tracking-[0.12em] uppercase transition-colors duration-75
|
|
${isBlocked ? 'text-[#555]' : 'text-[#555] group-hover:text-[#e0e0e0]'}`}>
|
|
{label}
|
|
</span>
|
|
{isBlocked && <span className="text-[34px]">🔒</span>}
|
|
{vip && !isBlocked && <span className="text-[15px] text-[#ff4500]">✦</span>}
|
|
</div>
|
|
|
|
{isBlocked && (
|
|
<span className="text-[17px] font-mono text-[#444] tracking-wider">{vip && locked ? 'VIP' : '登录后可用'}</span>
|
|
)}
|
|
|
|
{!isBlocked && (
|
|
<span className="absolute bottom-0 left-1/4 right-1/4 h-[1px] bg-[#ff4500] scale-x-0 group-hover:scale-x-100 transition-transform duration-75" />
|
|
)}
|
|
</button>
|
|
);
|
|
}
|