Documentation Index
Fetch the complete documentation index at: https://mintlify.com/rtajio/ESEN/llms.txt
Use this file to discover all available pages before exploring further.
ESEN is a deliberately minimal browser application. It uses no JavaScript framework, no module bundler, and no build pipeline. Every architectural decision prioritizes simplicity and portability: a developer or administrator with no Node.js knowledge can open the project, read the three source files, and deploy it to any static host in minutes. The following sections document the key technical patterns and trade-offs in the implementation.
Technology stack
| Layer | Technology |
|---|
| Markup | HTML5 |
| Styles | CSS3 with custom properties |
| Logic | Vanilla JavaScript (ES6+) |
| Icons | Tabler Icons v3.19.0 via CDN webfont |
| Build tools | None |
| Package manager | None |
| Runtime | Browser only |
The single external dependency is Tabler Icons, loaded in index.html from https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@3.19.0/dist/tabler-icons.min.css. All icons are referenced as CSS classes (e.g. class="ti ti-award").
Design methodology
ESEN was designed using OOHDM (Object-Oriented Hypermedia Design Method). OOHDM is a methodology for designing interactive hypermedia applications in terms of navigational objects, contexts, and interface transformations. In ESEN’s case, each named view (dashboard, actividades, estudiantes, etc.) maps to an OOHDM navigational context, and showView() acts as the navigational transition mechanism.
File structure
ESEN/
├── index.html # Document shell, all HTML markup and DOM structure
├── style.css # All styles: layout, components, badges, modal, responsive
├── app.js # All logic: data arrays, render functions, event listeners
├── favicon.svg # Browser tab icon (SVG)
└── vercel.json # Vercel deployment configuration and security headers
There is no src/ directory, no dist/ directory, and no compilation step. The files served to the browser are the source files.
Data storage
All application data lives in three plain JavaScript arrays declared at the top of app.js:
| Variable | Type | Contents |
|---|
actividades | Activity[] | Extracurricular activity records |
estudiantes | Student[] | Enrolled student records |
USUARIOS | User[] | Login credentials and roles |
None of these arrays are persisted. There are no calls to localStorage, sessionStorage, IndexedDB, or any external API. A page refresh resets all data to the demo values defined in app.js.
To add persistence, the actividades and estudiantes arrays would need to be serialized on write and deserialized on read, for example:
// On save
localStorage.setItem('actividades', JSON.stringify(actividades));
// On load
const stored = localStorage.getItem('actividades');
if (stored) actividades = JSON.parse(stored);
Auto-increment ID
nextId starts at 7 (the demo dataset occupies IDs 1–6) and is incremented each time saveActividad() creates a new activity:
actividades.push({ id: nextId++, nombre, cat, ... });
View routing
showView(v) is the sole navigation mechanism. It:
- Removes the
.active class from every .view element.
- Adds
.active to the element with ID view-{v}.
- Updates the
#page-title text node from the PAGE_TITLES map.
- Toggles the
.active class on .nav-link elements by matching data-view.
- Closes the mobile sidebar if it is open.
- Calls the corresponding render function.
Valid view names and their render functions:
| View name | Element ID | Render function |
|---|
dashboard | view-dashboard | renderDash() |
actividades | view-actividades | renderActTable() |
estudiantes | view-estudiantes | renderEstTable() |
reportes | view-reportes | renderReportes() |
mi-historial | view-mi-historial | renderHistorial() |
actividades-pub | view-actividades-pub | renderPub() |
Views default to display: none via the .view CSS rule and become visible when .view.active sets display: block.
Role-based UI
After a successful login, doLogin() shows or hides two <nav> elements based on the authenticated user’s rol:
document.getElementById('nav-admin').style.display = isAdmin ? 'block' : 'none';
document.getElementById('nav-est').style.display = isAdmin ? 'none' : 'block';
| Element ID | Shown for | Links |
|---|
nav-admin | rol: 'admin' | Panel, Actividades, Estudiantes, Reportes |
nav-est | rol: 'estudiante' | Mi historial, Actividades (public) |
Modal pattern
The activity form uses a single <div class="modal-backdrop" id="modal-act"> element. Opening and closing is done exclusively by toggling the .open CSS class:
// Open
document.getElementById('modal-act').classList.add('open');
// Close
document.getElementById('modal-act').classList.remove('open');
The .modal-backdrop is display: none by default and display: flex when .open is present. Two additional mechanisms close the modal:
- Clicking the backdrop itself (a
click listener checks e.target === backdrop).
- Pressing the
Escape key (a keydown listener on document).
CSS architecture
style.css uses CSS custom properties (variables) defined on :root for all design tokens:
:root {
--green-50: #E1F5EE;
--green-100: #9FE1CB;
--green-500: #1D9E75; /* primary brand color */
--green-700: #0F6E56;
--green-900: #085041;
--gray-50: #F7F7F5;
--gray-100: #EFEFEB;
--gray-200: #E0DED6;
--gray-300: #C8C6BC;
--gray-500: #888780;
--gray-700: #5F5E5A;
--gray-900: #2C2C2A;
--sidebar-width: 228px;
--topbar-height: 56px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
}
Responsive layout
On screens narrower than 768 px (@media (max-width: 768px)):
- The hamburger menu button (
#menu-toggle) becomes visible.
- The sidebar is
position: fixed and translated off-screen with transform: translateX(-100%).
- Adding the
.open class via toggleSidebar() slides it into view with transform: translateX(0) and a 0.25 s CSS transition.
- The two-column form grid and the report summary grid collapse to a single column.
Because data is stored only in memory, a page refresh resets all activities, students, and session state. There is no “remember me” or auto-login functionality.