File size: 3,899 Bytes
8e723d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"use client";

import React, { useState, useEffect } from "react";
import { db } from "@/lib/firebase";
import { collection, onSnapshot } from "firebase/firestore";
import { motion } from "framer-motion";
import { User, ShieldCheck, Briefcase } from "lucide-react";

interface Employee {
  id: string;
  name: string;
  position: string;
  department: string;
}

export default function OrgChartPage() {
  const [employees, setEmployees] = useState<Employee[]>([]);

  useEffect(() => {
    const unsub = onSnapshot(collection(db, "employees"), (snap) => {
      setEmployees(snap.docs.map(doc => ({ id: doc.id, ...doc.data() } as Employee)));
    });
    return () => unsub();
  }, []);

  return (
    <div className="p-10 min-h-screen">
      <header className="mb-20 text-center">
        <h1 className="text-5xl font-black tracking-widest uppercase mb-4">Structure / Hierarchy</h1>
        <p className="text-gray-500 font-bold">Arquitectura Organizacional en Tiempo Real</p>
      </header>

      {/* CEO Level */}
      <div className="flex flex-col items-center">
        <OrgNode label="Dirección General" name="CEO Admin" position="Consejo de Administración" type="ceo" />
        
        <div className="w-px h-16 bg-gradient-to-b from-blue-500 to-transparent my-2"></div>

        {/* Departments Level */}
        <div className="grid grid-cols-1 md:grid-cols-3 gap-20 relative">
          {/* Connecting Lines */}
          <div className="hidden md:block absolute top-[2.5rem] left-[15%] right-[15%] h-px bg-white/10"></div>

          <OrgSection title="Operaciones" icon={<Briefcase size={20} />} employees={employees} />
          <OrgSection title="Tecnología" icon={<ShieldCheck size={20} />} employees={employees} />
          <OrgSection title="Comercial" icon={<User size={20} />} employees={employees} />
        </div>
      </div>
    </div>
  );
}

function OrgSection({ title, icon, employees }: { title: string, icon: React.ReactNode, employees: Employee[] }) {
  return (
    <div className="flex flex-col items-center">
      <div className="bg-white/10 border border-white/20 px-8 py-4 rounded-full flex items-center gap-3 shadow-xl mb-12">
        <div className="text-blue-400">{icon}</div>
        <span className="font-black uppercase text-xs tracking-widest">{title}</span>
      </div>

      <div className="space-y-6 flex flex-col items-center">
        {employees.length === 0 ? (
          <div className="text-gray-600 text-[10px] uppercase font-bold">Sin asignar</div>
        ) : (
          employees.slice(0, 3).map((emp, i) => (
            <motion.div 
              key={emp.id}
              initial={{ y: 20, opacity: 0 }}
              animate={{ y: 0, opacity: 1 }}
              transition={{ delay: i * 0.1 }}
            >
              <OrgNode name={emp.name} position={emp.position} />
            </motion.div>
          ))
        )}
      </div>
    </div>
  );
}

function OrgNode({ label, name, position, type }: { label?: string, name: string, position: string, type?: string }) {
  return (
    <div className={`
      relative group p-6 rounded-[2rem] border min-w-[240px] text-center backdrop-blur-3xl shadow-2xl transition-all
      ${type === 'ceo' ? 'bg-blue-600/20 border-blue-500/40' : 'bg-white/5 border-white/10 hover:border-white/30 hover:bg-white/10'}
    `}>
      {label && <span className="absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 bg-blue-600 text-[8px] font-black uppercase rounded-full shadow-lg">{label}</span>}
      <div className={`w-12 h-12 mx-auto mb-4 rounded-2xl flex items-center justify-center ${type === 'ceo' ? 'bg-blue-500 shadow-blue-500/50 shadow-xl' : 'bg-white/10'}`}>
        <User size={24} />
      </div>
      <h4 className="font-bold text-lg mb-1">{name}</h4>
      <p className="text-[10px] font-black text-gray-500 uppercase tracking-widest">{position}</p>
    </div>
  );
}