MegaNav.tsx 6.77 KB
import { useState } from "react";
import {
  AppstoreOutlined,
  HomeOutlined,
  CloseOutlined,
  FolderOutlined,
  SettingOutlined,
} from "@ant-design/icons";
import { MEGA_NAV, MEGA_COLUMNS } from "@/utils/data";

interface Props {
  onClose: () => void;
  onOpen: (screen: string, label: string) => void;
}

export default function MegaNav({ onClose, onOpen }: Props) {
  const [activeId, setActiveId] = useState<string>(
    MEGA_NAV.find((s) => s.active)?.id ?? "sys"
  );
  const cols = MEGA_COLUMNS[activeId];

  return (
    <div
      style={{
        position: "fixed",
        inset: 0,
        zIndex: 100,
        background: "#1a2030",
        color: "var(--text-on-dark)",
        display: "flex",
        flexDirection: "column",
      }}
    >
      <div
        style={{
          height: 36,
          flex: "none",
          display: "flex",
          alignItems: "center",
          padding: "0 10px",
          background: "#262d3a",
          borderBottom: "1px solid #1a1f2a",
        }}
      >
        <button
          onClick={onClose}
          style={{
            display: "inline-flex",
            alignItems: "center",
            gap: 5,
            height: 28,
            padding: "0 10px",
            background: "rgba(58,142,224,0.18)",
            color: "#fff",
            border: "1px solid rgba(58,142,224,0.4)",
            cursor: "pointer",
            fontSize: 12,
            fontFamily: "inherit",
          }}
        >
          <AppstoreOutlined /> 全部导航
        </button>
        <button
          onClick={onClose}
          style={{
            display: "inline-flex",
            alignItems: "center",
            gap: 5,
            height: 28,
            padding: "0 10px",
            background: "transparent",
            color: "var(--text-on-dark)",
            border: "none",
            cursor: "pointer",
            fontSize: 12,
            marginLeft: 4,
            fontFamily: "inherit",
          }}
        >
          <HomeOutlined /> 主页
        </button>
        <div style={{ flex: 1 }} />
        <button
          onClick={onClose}
          title="关闭"
          style={{
            width: 28,
            height: 28,
            background: "transparent",
            color: "var(--text-on-dark)",
            border: "none",
            cursor: "pointer",
          }}
        >
          <CloseOutlined />
        </button>
      </div>

      <div style={{ flex: 1, display: "flex", overflow: "hidden", minHeight: 0 }}>
        <div
          style={{
            width: 150,
            flex: "none",
            borderRight: "1px solid rgba(255,255,255,0.08)",
            overflow: "auto",
            padding: "8px 0",
          }}
        >
          {MEGA_NAV.map((s) => {
            const active = s.id === activeId;
            return (
              <div
                key={s.id}
                onClick={() => setActiveId(s.id)}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 8,
                  padding: "8px 14px",
                  cursor: "pointer",
                  fontSize: 12,
                  background: active ? "var(--accent)" : "transparent",
                  color: active ? "#fff" : "var(--text-on-dark)",
                  borderLeft: active ? "3px solid #fff" : "3px solid transparent",
                }}
                onMouseEnter={(e) => {
                  if (!active) e.currentTarget.style.background = "rgba(255,255,255,0.06)";
                }}
                onMouseLeave={(e) => {
                  if (!active) e.currentTarget.style.background = "transparent";
                }}
              >
                {s.id === "sys" ? <SettingOutlined /> : <FolderOutlined />}
                <span>{s.label}</span>
              </div>
            );
          })}
        </div>

        <div style={{ flex: 1, overflow: "auto", padding: "16px 24px" }}>
          {cols ? (
            <div
              style={{
                display: "grid",
                gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))",
                gap: "0 24px",
              }}
            >
              {cols.map((col) => (
                <div key={col.title} style={{ marginBottom: 24 }}>
                  <div
                    style={{
                      fontSize: 13,
                      fontWeight: 500,
                      color: "#fff",
                      marginBottom: 10,
                      paddingBottom: 6,
                      borderBottom: "1px solid rgba(255,255,255,0.1)",
                    }}
                  >
                    {col.title}
                  </div>
                  <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                    {col.items.map((it, i) => {
                      const clickable = !!it.screen;
                      return (
                        <div
                          key={i}
                          onClick={
                            clickable
                              ? () => {
                                  onOpen(it.screen!, it.label);
                                  onClose();
                                }
                              : undefined
                          }
                          style={{
                            fontSize: 12,
                            color: it.featured ? "var(--accent)" : "var(--text-on-dark-muted)",
                            cursor: clickable ? "pointer" : "default",
                            display: "inline-flex",
                            alignItems: "center",
                            gap: 4,
                            padding: "1px 0",
                          }}
                          onMouseEnter={(e) => {
                            if (clickable) e.currentTarget.style.color = "#fff";
                          }}
                          onMouseLeave={(e) => {
                            if (clickable)
                              e.currentTarget.style.color = it.featured
                                ? "var(--accent)"
                                : "var(--text-on-dark-muted)";
                          }}
                        >
                          {it.label}
                          {it.featured ? (
                            <span style={{ color: "var(--warning)", fontSize: 10 }}>★</span>
                          ) : null}
                        </div>
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div style={{ color: "var(--text-on-dark-muted)", fontSize: 13, padding: 40 }}>
              {MEGA_NAV.find((s) => s.id === activeId)?.label} · 模块开发中
            </div>
          )}
        </div>
      </div>
    </div>
  );
}