300 lines
10 KiB
JavaScript
300 lines
10 KiB
JavaScript
// App.js
|
|
import { $, watch, h, when } from "sigpro";
|
|
import {
|
|
Navbar,
|
|
Drawer,
|
|
DrawerToggle,
|
|
DrawerContent,
|
|
DrawerSide,
|
|
DrawerOverlay,
|
|
Menu,
|
|
MenuTitle,
|
|
MenuItem,
|
|
Tabs,
|
|
Tab,
|
|
Swap,
|
|
SwapToggle,
|
|
SwapOn,
|
|
SwapOff,
|
|
Icon,
|
|
Avatar,
|
|
Dropdown,
|
|
DropdownButton,
|
|
DropdownContent,
|
|
Modal,
|
|
ModalBox,
|
|
ModalClose,
|
|
ModalAction,
|
|
ModalBackdrop,
|
|
Fieldset,
|
|
Input,
|
|
LabelFloating,
|
|
Button,
|
|
Loading
|
|
} from "sigpro-ui";
|
|
import 'sigpro-ui/css';
|
|
|
|
import { Desktop } from "./tabs/Desktop.js";
|
|
import { ModalSearch } from "./components/ModalSearch.js";
|
|
|
|
export const isDark = $(false, "theme-mode");
|
|
|
|
export const App = () => {
|
|
const showSearchModal = $(false);
|
|
|
|
// Tema oscuro/claro
|
|
watch(isDark, (dark) => {
|
|
document.documentElement.setAttribute("data-theme", dark ? "dark" : "light");
|
|
});
|
|
document.documentElement.setAttribute("data-theme", isDark() ? "dark" : "light");
|
|
|
|
// Estado de login persistente
|
|
const logged = $(false, "logged");
|
|
const showLoginModal = $(false);
|
|
const loginForm = {
|
|
username: $(""),
|
|
password: $("")
|
|
};
|
|
|
|
// Pestañas: la primera (Escritorio) no es cerrable
|
|
const tabs = $([
|
|
{
|
|
label: "Escritorio",
|
|
content: () => Desktop,
|
|
closable: false
|
|
}
|
|
]);
|
|
const activeTab = $(0);
|
|
const openDrawer = $(false);
|
|
|
|
// Elementos del menú en el drawer
|
|
const menuItems = [
|
|
{
|
|
label: "Clientes",
|
|
children: [
|
|
{ label: "Buscar Cliente", onclick: () => openTab("Clientes") },
|
|
]
|
|
},
|
|
{
|
|
label: "Recibos",
|
|
children: [
|
|
{ label: "Buscar Recibo" },
|
|
{ label: "Pendientes" },
|
|
{ label: "Extornos" },
|
|
],
|
|
},
|
|
{
|
|
label: "Polizas",
|
|
children: [
|
|
{ label: "Buscar Póliza", onclick: () => openTab("Polizas") },
|
|
{ label: "Nueva producción", onclick: () => openTab("Polizas") },
|
|
{ label: "Anulaciones", onclick: () => openTab("Polizas") },
|
|
{ label: "Renovación Cartera", onclick: () => openTab("Polizas") }
|
|
]
|
|
},
|
|
{
|
|
label: "Comercial",
|
|
children: [
|
|
{ label: "Oportunidades" },
|
|
],
|
|
},
|
|
{
|
|
label: "Siniestros",
|
|
children: [
|
|
{ label: "Nuevo Siniestro" },
|
|
{ label: "Buscar Siniestro" },
|
|
]
|
|
},
|
|
{
|
|
label: "Soporte",
|
|
children: [
|
|
{ label: "Tickets" },
|
|
{ label: "Reportes" },
|
|
]
|
|
}
|
|
];
|
|
|
|
let tabsContainerRef = null;
|
|
let drawerToggleRef = null;
|
|
|
|
const openTab = (label) => {
|
|
const currentTabs = tabs();
|
|
if (currentTabs.length >= 15) return;
|
|
const newTab = {
|
|
label,
|
|
content: () => `¡Bienvenido a ${label}!`,
|
|
closable: true
|
|
};
|
|
tabs([...currentTabs, newTab]);
|
|
activeTab(tabs().length - 1);
|
|
closeDrawer();
|
|
};
|
|
|
|
const closeDrawer = () => {
|
|
openDrawer(false);
|
|
if (drawerToggleRef) drawerToggleRef.checked = false;
|
|
};
|
|
|
|
const handleLogin = () => {
|
|
if (!loginForm.username() || !loginForm.password()) {
|
|
alert('Por favor, complete todos los campos');
|
|
return;
|
|
}
|
|
logged(true);
|
|
showLoginModal(false);
|
|
loginForm.username("");
|
|
loginForm.password("");
|
|
};
|
|
|
|
const handleLogout = () => {
|
|
logged(false);
|
|
};
|
|
|
|
return [
|
|
Drawer({}, [
|
|
DrawerToggle({
|
|
id: "app-drawer",
|
|
ref: (el) => drawerToggleRef = el,
|
|
checked: openDrawer,
|
|
onchange: (e) => openDrawer(e.target.checked)
|
|
}),
|
|
|
|
DrawerContent({}, [
|
|
Navbar({ class: "bg-base-100 shadow-lg align-center" }, [
|
|
div({ class: "flex-none" }, [
|
|
label({ for: "app-drawer", class: "btn btn-ghost btn-square" }, [
|
|
Icon({}, "icon-[lucide--menu]")
|
|
])
|
|
]),
|
|
Button({ class: "icon-[lucide--search] btn-ghost", onclick: () => showSearchModal(true) }),
|
|
div({ class: "flex-1" }),
|
|
Swap({ class: "text-xl" }, [
|
|
SwapToggle({ value: isDark, class: "swap-rotate" }),
|
|
SwapOn({}, h('span', { class: "icon-[lucide--moon]" })),
|
|
SwapOff({}, h('span', { class: "icon-[lucide--sun]" })),
|
|
]),
|
|
when(logged,
|
|
() => Dropdown({ class: "flex-none ml-2 dropdown-bottom dropdown-end" }, [
|
|
DropdownButton({ class: "btn-circle btn btn-ghost", tabindex: "0", role: "button" }, [
|
|
Avatar({ class: "placeholder" }, [
|
|
div({ class: "bg-neutral text-neutral-content w-10 rounded-full" }, [
|
|
h('span', { class: "text-xl" }, "U")
|
|
])
|
|
])
|
|
]),
|
|
DropdownContent(
|
|
{ class: "menu bg-base-100 rounded-box w-52 p-2 shadow" },
|
|
[
|
|
Menu({ class: "bg-base-100 max-w-xs w-full" },
|
|
[
|
|
MenuItem({ label: "Mi Perfil", onclick: () => openTab("Mi Perfil") }),
|
|
MenuItem({ label: "Configuración", onclick: () => openTab("Configuración") }),
|
|
MenuItem({ label: "Cerrar Sesión", onclick: handleLogout }),
|
|
]
|
|
),
|
|
],
|
|
),
|
|
]),
|
|
() => Button({
|
|
class: "flex-none ml-2 btn btn-ghost btn-circle relative",
|
|
onclick: () => showLoginModal(true)
|
|
}, [
|
|
Icon({}, "icon-[lucide--user] text-xl"),
|
|
])
|
|
)
|
|
]),
|
|
|
|
// Área principal con pestañas
|
|
div({
|
|
class: "p-4",
|
|
ref: (el) => tabsContainerRef = el
|
|
}, [
|
|
h('div', { class: 'tabs tabs-box' },
|
|
() => tabs().map((item, idx) =>
|
|
Tab({
|
|
name: "app-tabs",
|
|
"aria-label": item.label,
|
|
checked: activeTab() === idx,
|
|
onchange: () => activeTab(idx),
|
|
content: item.content,
|
|
closable: item.closable,
|
|
tabs,
|
|
index: idx
|
|
})
|
|
)
|
|
)
|
|
])
|
|
]),
|
|
|
|
DrawerSide({ class: "z-50" }, [
|
|
DrawerOverlay({ for: "app-drawer" }),
|
|
div({
|
|
class: "menu bg-base-200 text-base-content min-h-full w-80 p-4"
|
|
}, [
|
|
h('h2', { class: "text-lg font-bold mb-4" }, "Menú"),
|
|
Menu({ class: "bg-base-200 max-w-xs w-full" },
|
|
menuItems.flatMap(item => [
|
|
MenuTitle({}, item.label),
|
|
...item.children.map(child =>
|
|
MenuItem({ label: child.label, onclick: child.onclick })
|
|
)
|
|
])
|
|
)
|
|
])
|
|
])
|
|
]),
|
|
|
|
ModalSearch({
|
|
open: showSearchModal,
|
|
onSelect: (item) => {
|
|
console.log("Item seleccionado:", item);
|
|
showSearchModal(false);
|
|
}
|
|
}),
|
|
|
|
// Modal de Login adaptado
|
|
when(showLoginModal, () =>
|
|
Modal({ open: true, class: '' }, [
|
|
ModalBox({}, [
|
|
ModalClose({ onclick: () => showLoginModal(false) }),
|
|
h('h3', { class: "text-lg font-bold" }, "Iniciar Sesión"),
|
|
Fieldset({
|
|
class: "bg-base-200 border-base-300 rounded-box border gap-3 p-4"
|
|
}, [
|
|
LabelFloating({ class: "w-full" }, [
|
|
Input({
|
|
class: "w-full",
|
|
type: "text",
|
|
placeholder: "Nombre de usuario",
|
|
value: loginForm.username,
|
|
oninput: (e) => loginForm.username(e.target.value)
|
|
}),
|
|
h('span', {}, "Usuario")
|
|
]),
|
|
LabelFloating({ class: "w-full" }, [
|
|
Input({
|
|
class: "w-full",
|
|
type: "password",
|
|
placeholder: "Contraseña",
|
|
value: loginForm.password,
|
|
oninput: (e) => loginForm.password(e.target.value)
|
|
}),
|
|
h('span', {}, "Contraseña")
|
|
])
|
|
]),
|
|
ModalAction({}, [
|
|
Button({
|
|
class: "btn btn-ghost",
|
|
onclick: () => showLoginModal(false)
|
|
}, "Cancelar"),
|
|
Button({
|
|
class: "btn btn-primary",
|
|
onclick: handleLogin
|
|
}, "Entrar")
|
|
])
|
|
]),
|
|
ModalBackdrop({ onclick: () => showLoginModal(false) })
|
|
])
|
|
)
|
|
];
|
|
}; |