AppShell.tsx 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. "use client";
  2. import Link from "next/link";
  3. import { ArrowLeft, Database, RefreshCw } from "lucide-react";
  4. export function AppShell({
  5. children,
  6. title = "运营流程账本",
  7. titleExtra,
  8. subtitle,
  9. runId,
  10. showBack,
  11. onRefresh,
  12. actions
  13. }: {
  14. children: React.ReactNode;
  15. title?: string;
  16. titleExtra?: React.ReactNode;
  17. subtitle?: string;
  18. runId?: string;
  19. showBack?: boolean;
  20. onRefresh?: () => void;
  21. actions?: React.ReactNode;
  22. }) {
  23. return (
  24. <main className="app-shell">
  25. <div className="scroll-area">
  26. <header className="page-header">
  27. <div className="header-left">
  28. {showBack ? (
  29. <Link className="toolbar-button" href={runId ? `/runs/${encodeURIComponent(runId)}` : "/runs"}>
  30. <ArrowLeft size={15} />
  31. 返回
  32. </Link>
  33. ) : null}
  34. <Link className="brand" href="/runs">
  35. <Database size={16} />
  36. <span>{title}</span>
  37. </Link>
  38. {titleExtra}
  39. {subtitle ? <span className="header-subtitle">{subtitle}</span> : null}
  40. </div>
  41. <div className="toolbar">
  42. {actions}
  43. {onRefresh ? (
  44. <button className="icon-button" type="button" title="刷新" aria-label="刷新" onClick={onRefresh}>
  45. <RefreshCw size={15} />
  46. </button>
  47. ) : null}
  48. </div>
  49. </header>
  50. {children}
  51. </div>
  52. </main>
  53. );
  54. }