chore: estructura inicial del MVP

Backend (Express + MariaDB) y frontend (React + Vite, identidad Fluent/Windows) con el
nucleo funcional: seguridad, organizacion, proyectos, actividades, subtareas, dependencias,
dashboard, calendario, gantt, comentarios, adjuntos, notificaciones in-app y catalogos.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-09-03 08:37:58 -05:00
commit 1d22adc42e
135 changed files with 10913 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
import { useUi } from '../context/ui-context.jsx';
import { Button } from './Button.jsx';
const STRIPE_COLOR = { info: 'accent', success: 'success', warning: 'warning', error: 'danger' };
// ContentDialog global — equivalente al AppDialog de la identidad web. Contrato:
// openDialog({ tone, title, message, actions: [{ label, variant, keepOpen, onClick }] })
export function ContentDialogHost() {
const { dialog, closeDialog, t } = useUi();
if (!dialog) return null;
const tone = dialog.tone || 'info';
const actions = dialog.actions?.length ? dialog.actions : [{ label: t('common_close'), variant: 'accent' }];
async function handleClick(action) {
if (action.onClick) await action.onClick();
if (!action.keepOpen) closeDialog();
}
return (
<div className="dialog-overlay" onMouseDown={(e) => { if (e.target === e.currentTarget) closeDialog(); }}>
<div className="dialog-surface">
<div className="dialog-stripe" style={{ background: `rgb(var(--${STRIPE_COLOR[tone]}))` }} />
<div className="dialog-body">
<div className="dialog-title">{dialog.title}</div>
<div className="dialog-message">{dialog.message}</div>
</div>
<div className="dialog-actions">
{actions.map((action, i) => (
<Button key={i} variant={action.variant || 'standard'} onClick={() => handleClick(action)}>
{action.label}
</Button>
))}
</div>
</div>
</div>
);
}