File size: 2,461 Bytes
f672a5d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
af63944
 
 
 
 
 
 
 
 
f672a5d
 
 
 
af63944
f672a5d
af63944
f672a5d
af63944
f672a5d
af63944
 
f672a5d
 
 
 
 
 
 
 
 
 
 
af63944
f672a5d
 
 
 
af63944
f672a5d
 
af63944
f672a5d
 
 
 
 
 
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
import { useState, useEffect } from "react";
import { Loader2 } from "lucide-react";

import { useLLM } from "../hooks/useLLM";
import { ChatApp } from "./ChatApp";

export function AppShell() {
  const { status } = useLLM();
  const isReady = status.state === "ready";
  const [showChat, setShowChat] = useState(false);

  useEffect(() => {
    if (isReady) {
      const timeoutId = setTimeout(() => setShowChat(true), 300);
      return () => clearTimeout(timeoutId);
    }
  }, [isReady]);

  return (
    <>
      <div
        className={`absolute inset-0 z-20 flex flex-col items-center justify-center transition-opacity duration-1000 ease-in-out ${
          showChat ? "opacity-0 pointer-events-none" : "opacity-100"
        }`}
      >
        {/* Vexorium logo while loading */}
        <img
          src="/vexorium_logo.svg"
          alt="Vexorium"
          className="w-20 h-20 mb-6"
          style={{ filter: "drop-shadow(0 0 20px rgba(0,255,255,0.5))" }}
        />
        <Loader2 className="h-8 w-8 animate-spin" style={{ color: "#00ffff" }} />
        <p className="mt-4 text-base" style={{ color: "rgba(224,224,240,0.8)", fontFamily: "'Exo 2', sans-serif" }}>
          {status.state === "loading"
            ? (status.message ?? "Loading model…")
            : status.state === "error"
              ? "Error"
              : "Initializing Nemotron-3-Nano…"}
        </p>
        <div className="mt-3 h-1 w-72 overflow-hidden rounded-full" style={{ background: "rgba(0,255,255,0.1)" }}>
          <div
            className="h-full rounded-full transition-[width] duration-300 ease-out"
            style={{
              background: "linear-gradient(90deg, #00ffff, #ff00ff)",
              boxShadow: "0 0 8px rgba(0,255,255,0.6)",
              width: `${
                status.state === "ready"
                  ? 100
                  : status.state === "loading"
                    ? (status.progress ?? 0)
                    : 0
              }%`,
            }}
          />
        </div>
        {status.state === "error" && (
          <p className="mt-2 text-sm" style={{ color: "#ff6688" }}>{status.error}</p>
        )}
      </div>

      <div
        className={`absolute inset-0 z-30 transition-opacity duration-1000 ease-in-out ${
          showChat ? "opacity-100" : "opacity-0 pointer-events-none"
        }`}
        style={{ background: "#050515" }}
      >
        <ChatApp />
      </div>
    </>
  );
}