File size: 5,133 Bytes
89a11b6
 
a79917c
 
 
 
 
 
 
89a11b6
a79917c
89a11b6
a79917c
19a0889
 
 
 
 
a79917c
 
 
 
 
89a11b6
a79917c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0e29296
 
19a0889
0e29296
 
19a0889
 
 
 
0e29296
a79917c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89a11b6
a79917c
 
 
 
 
89a11b6
 
 
a79917c
 
 
 
 
89a11b6
a79917c
 
 
 
 
 
 
 
 
89a11b6
a79917c
 
 
 
 
53fd305
a79917c
 
53fd305
a79917c
 
53fd305
a79917c
 
 
 
 
 
89a11b6
a79917c
 
 
 
 
 
 
 
 
 
 
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// frontend/src/Layout.jsx

import React, { useState } from "react";
import { Link } from "react-router-dom";
import { createPageUrl } from "./utils";
import {
  LayoutDashboard,
  History as HistoryIcon,
  ChevronLeft,
  Sparkles,
} from "lucide-react";
import { cn } from "@/lib/utils";

// Import logo - Vite will process this and handle the path correctly
// For production, the logo should be in frontend/public/logo.png
// Vite will copy it to dist/logo.png during build
const logoPath = "/logo.png";

export default function Layout({ children, currentPageName }) {
  const [collapsed, setCollapsed] = useState(false);

  const navItems = [
    { name: "Dashboard", icon: LayoutDashboard, page: "Dashboard" },
    { name: "History", icon: HistoryIcon, page: "History" },
  ];

  return (
    <div className="min-h-screen bg-[#FAFAFA] flex">
      {/* Sidebar */}
      <aside
        className={cn(
          "fixed left-0 top-0 h-screen bg-white border-r border-slate-200/80 z-50 transition-all duration-300 ease-out flex flex-col",
          collapsed ? "w-[72px]" : "w-[260px]"
        )}
      >
        {/* Logo */}
        <div
          className={cn(
            "h-16 flex items-center border-b border-slate-100 px-4",
            collapsed ? "justify-center" : "justify-between"
          )}
        >
          <Link to={createPageUrl("Dashboard")} className="flex items-center gap-3">
            <div className="h-9 w-9 flex items-center justify-center flex-shrink-0">
              <img 
                src={logoPath}
                alt="EZOFIS AI Logo" 
                className="h-full w-full object-contain"
                onError={(e) => {
                  // Fallback: hide image and show placeholder if logo not found
                  e.target.style.display = 'none';
                }}
              />
            </div>
            {!collapsed && (
              <div className="flex flex-col">
                <span className="font-semibold text-slate-900 tracking-tight">EZOFIS AI</span>
                <span className="text-[10px] text-slate-400 font-medium tracking-wide uppercase">
                  Agentic Extract
                </span>
              </div>
            )}
          </Link>
          {!collapsed && (
            <button
              onClick={() => setCollapsed(true)}
              className="h-7 w-7 rounded-lg hover:bg-slate-100 flex items-center justify-center text-slate-400 hover:text-slate-600 transition-colors"
            >
              <ChevronLeft className="h-4 w-4" />
            </button>
          )}
        </div>

        {/* Navigation */}
        <nav className="flex-1 p-3 space-y-1">
          {navItems.map((item) => {
            const isActive = currentPageName === item.page;
            return (
              <Link
                key={item.name}
                to={createPageUrl(item.page)}
                className={cn(
                  "flex items-center gap-3 px-3 py-2.5 rounded-xl transition-all duration-200 group",
                  isActive
                    ? "bg-gradient-to-r from-indigo-50 to-violet-50 text-indigo-600"
                    : "text-slate-500 hover:bg-slate-50 hover:text-slate-700"
                )}
              >
                <item.icon
                  className={cn(
                    "h-5 w-5 flex-shrink-0",
                    isActive ? "text-indigo-600" : "text-slate-400 group-hover:text-slate-600"
                  )}
                />
                {!collapsed && (
                  <span className="font-medium text-sm">{item.name}</span>
                )}
              </Link>
            );
          })}
        </nav>

        {/* Collapse Toggle (when collapsed) */}
        {collapsed && (
          <button
            onClick={() => setCollapsed(false)}
            className="m-3 h-10 rounded-xl bg-slate-50 hover:bg-slate-100 flex items-center justify-center text-slate-400 hover:text-slate-600 transition-colors"
          >
            <ChevronLeft className="h-4 w-4 rotate-180" />
          </button>
        )}

        {/* Pro Badge */}
        {!collapsed && (
          <div className="p-3">
            <div className="p-4 rounded-2xl bg-gradient-to-br from-slate-900 to-slate-800 text-white">
              <div className="flex items-center gap-2 mb-2">
                <Sparkles className="h-4 w-4 text-amber-400" />
                <span className="text-xs font-semibold tracking-wide">DEPLOY THIS AGENT</span>
              </div>
              <p className="text-xs text-slate-400 mb-3">
                Unlock batch extractions &amp; API access
              </p>
              <button className="w-full py-2 px-3 rounded-lg bg-white text-slate-900 text-sm font-semibold hover:bg-slate-100 transition-colors">
                Talk to us
              </button>
            </div>
          </div>
        )}
      </aside>

      {/* Main Content */}
      <main
        className={cn(
          "flex-1 transition-all duration-300",
          collapsed ? "ml-[72px]" : "ml-[260px]"
        )}
      >
        {children}
      </main>
    </div>
  );
}