File size: 3,382 Bytes
dc11950
 
4dc66a3
 
 
aa63765
 
 
 
 
 
345b8ff
dc11950
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ef83e66
dc11950
 
 
 
 
 
 
 
 
 
 
 
 
 
4dc66a3
ef83e66
dc11950
 
ef83e66
aa63765
4dc66a3
 
dc11950
 
 
 
 
 
 
 
 
345b8ff
 
dc11950
345b8ff
ef83e66
aa63765
 
 
 
4dc66a3
dc11950
 
 
 
 
4dc66a3
 
dc11950
4dc66a3
 
dc11950
 
 
 
 
4dc66a3
dc11950
 
 
 
 
4dc66a3
aa63765
 
ef83e66
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
"use client";

import Link from "next/link";

import { AdminRulesPanel } from "@/components/admin-rules-panel";
import { AnalyticsPanel } from "@/components/analytics-panel";
import { ChatPanel } from "@/components/chat-panel";
import { FeatureGrid } from "@/components/feature-grid";
import { Footer } from "@/components/footer";
import { Hero } from "@/components/hero";
import { KnowledgeBasePanel } from "@/components/knowledge-base-panel";
import { TenantSelector } from "@/components/tenant-selector";
import { useTenant } from "@/contexts/TenantContext";
import {
  canManageRules,
  canViewAnalytics,
  canIngestDocuments,
} from "@/lib/permissions";

function Navigation() {
  const { role } = useTenant();

  const navItems = [
    {
      label: "Data Ingestion",
      href: "/ingestion",
      visible: canIngestDocuments(role),
    },
    { label: "Chat Bot", href: "/chat", visible: true }, // Chat is available to all
    {
      label: "Analytics",
      href: "/analytics",
      visible: canViewAnalytics(role),
    },
    {
      label: "Admin Rule Ingestion",
      href: "/admin-rules",
      visible: canManageRules(role),
    },
  ];

  const visibleNavItems = navItems.filter((item) => item.visible);

  return (
    <nav className="flex flex-wrap gap-2">
      {visibleNavItems.map((item) => (
        <Link
          key={item.href}
          href={item.href}
          className="rounded-full border border-white/15 px-4 py-2 text-xs font-semibold uppercase tracking-[0.2em] text-slate-200 transition hover:border-cyan-400 hover:text-white"
        >
          {item.label}
        </Link>
      ))}
    </nav>
  );
}

export default function Home() {
  const { role } = useTenant();

  return (
    <main className="mx-auto flex min-h-screen max-w-6xl flex-col gap-10 px-4 pb-16 pt-12 sm:px-6 lg:px-8">
      <header className="flex flex-col gap-6 rounded-2xl border border-white/10 bg-white/5 px-6 py-6 text-slate-100 shadow-lg shadow-slate-950/40">
        <div className="flex flex-wrap items-center justify-between gap-3 text-sm">
          <div className="flex items-center gap-3 text-base font-semibold">
            <span className="inline-flex h-10 w-10 items-center justify-center rounded-2xl bg-gradient-to-br from-sky-400 to-cyan-500 text-slate-950">
              IC
            </span>
            IntegraChat Operator Console
          </div>
          <div className="flex flex-wrap items-center gap-3 text-xs uppercase tracking-[0.4em] text-slate-400">
            FastAPI 路 MCP Servers 路 Celery 路 Next.js
          </div>
        </div>
        <div className="flex flex-wrap items-center justify-between gap-4">
          <Navigation />
          <TenantSelector />
        </div>
      </header>

      <Hero />
      <FeatureGrid />

      {canIngestDocuments(role) && (
        <section id="data-ingestion" className="scroll-mt-28">
          <KnowledgeBasePanel />
        </section>
      )}

      <section id="chat-bot" className="scroll-mt-28">
        <ChatPanel />
      </section>

      {canViewAnalytics(role) && (
        <section id="analytics" className="scroll-mt-28">
          <AnalyticsPanel />
        </section>
      )}

      {canManageRules(role) && (
        <section id="admin-rules" className="scroll-mt-28">
          <AdminRulesPanel />
        </section>
      )}

      <Footer />
    </main>
  );
}