/* global React, ReactDOM, window */
// Ruticomidas — app shell
const { useState, useEffect, useRef } = React;
const D = window.RC_DATA;
const SCREENS = window.RC_SCREENS;
const { AuthGate, useAuth } = window.RC_Auth;
const { StoreProvider } = window.RC_STORE;
function Sidebar({ current, onNav }) {
const auth = useAuth();
const user = auth?.user;
const displayName = user ? (user.name || user.email?.split('@')[0] || '—') : '—';
const role = user?.is_admin ? 'Hogar · admin' : 'Hogar · miembro';
const avatarLetter = displayName[0]?.toUpperCase() || '?';
return (
);
}
function NotificationsPanel({ notifications, onClose, onReload, onOpenTicket }) {
const unread = notifications.filter(n => !n.read);
const markAll = async () => {
await window.api('/api/notifications/read-all', 'POST', {});
await onReload();
};
const handleClick = async (n) => {
if (!n.read) {
await window.api(`/api/notifications/${n.id}/read`, 'POST', {});
await onReload();
}
const { queueItemId } = window.RC_notifText(n);
if (queueItemId) {
onClose();
onOpenTicket && onOpenTicket(queueItemId);
}
};
return (
Notificaciones
{unread.length > 0 && (
)}
{notifications.length === 0 && (
Sin notificaciones
)}
{notifications.map(n => {
const { title, body } = window.RC_notifText(n);
return (
handleClick(n)} style={{
padding: '12px 16px', borderBottom: '1px solid var(--frame)',
background: n.read ? 'transparent' : 'rgba(60,255,208,.06)',
cursor: 'pointer',
}}>
{title}
{body ?
{body}
: null}
{n.created_at?.slice(0, 16).replace('T', ' ')}
);
})}
);
}
function Topbar({ current }) {
const { notifications, reload } = window.RC_STORE.useStore();
const [showNotifs, setShowNotifs] = useState(false);
const unreadCount = notifications.filter(n => !n.read).length;
const panelRef = useRef(null);
useEffect(() => {
if (!showNotifs) return;
const handler = (e) => {
if (panelRef.current && !panelRef.current.contains(e.target)) setShowNotifs(false);
};
document.addEventListener('mousedown', handler);
return () => document.removeEventListener('mousedown', handler);
}, [showNotifs]);
return (
{showNotifs && (
setShowNotifs(false)}
onReload={reload.notifications}
onOpenTicket={(qid) => { window.location.hash = '#tickets'; }}
/>
)}
);
}
function App() {
const [route, setRoute] = useState(() => {
const h = window.location.hash.slice(1);
return SCREENS[h] ? h : 'planning';
});
useEffect(() => {
window.location.hash = route;
}, [route]);
useEffect(() => {
const handler = () => {
const h = window.location.hash.slice(1);
if (SCREENS[h]) setRoute(h);
};
window.addEventListener('hashchange', handler);
return () => window.removeEventListener('hashchange', handler);
}, []);
const Screen = SCREENS[route];
return (
);
}
ReactDOM.createRoot(document.getElementById('root')).render(
);