Frontend Components & JS Logic
Frontend Architecture Overview
The Atslegas frontend is designed as a modular, client-side rendered application. It is divided into two primary interfaces: the Admin Dashboard (located in admin-front/) and the User Interface (located in user-front/).
The system relies on a "fetch-then-render" logic flow. Upon initialization, the application synchronizes state with the backend API, persists relevant data to localStorage for performance, and then triggers modular render functions to update the DOM.
State Management and Persistence
The application uses a centralized state object and browser storage to ensure a responsive user experience.
Global Data Sync
State is primarily managed through the globalData object in the Admin interface. The loadData() function (found in admin-common.js) orchestrates this by:
- Fetching data from multiple API endpoints (Users, Keys, Groups, Logs, etc.) using
XMLHttpRequest. - Updating
localStoragewith the latest server response. - Resolving a Promise once all requests are complete, allowing the UI to render.
Storage Keys
The frontend uses consistent keys for localStorage to maintain state across sessions:
atslegas_keys_v1: Inventory of physical keys.atslegas_users_v1: System user accounts.atslegas_keyGroups_v1: Logical groupings of keys (e.g., by building or floor).atslegas_keyLogs_v1: Historical activity data.
Admin Component Modules
Dashboard & Activity Calendar
The dashboard provides a visual overview of key movements.
- Calendar Strip: Located in
admin-dashboard.js, therenderCalendar()function generates a 37-day window (7 days past, 30 days future). It highlights daily activity levels by counting "Issued" vs "Returned" logs. - Activity Filtering: Selecting a day in the calendar triggers
renderDayLogs(isoDate), which filters the global log state and displays detailed interactions for that specific date.
Key Group Management
Key groups allow administrators to categorize access.
- Rendering: The
renderGroups()function builds the UI for managing clusters of keys. - CRUD Operations: Group management is handled via dedicated API calls. For example, adding a group involves sending a POST request to
/api/keyGroup/addwith a JSON payload containing the group name and initial members.
// Example: Adding a new key group
xhr.open("POST", "/api/keyGroup/add", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify({
"name": "Science Block",
"keys": [],
"persons": []
}));
Notification System
The application uses a notificationManager to provide user feedback for asynchronous operations. It supports different toast types, such as showSuccess(message) and error alerts, typically triggered after API responses.
User Interface Logic
The user-facing side (user-front/) focuses on searchability and status tracking.
Filtering and Search
The user interface implements real-time filtering through utils.js. The applyFilters() logic combines several criteria:
- Text Search: Filters keys by label or number.
- Availability: Filters by "Available" or "Reserved" status.
- Group Filtering: Narrows results based on selected logical groups.
Initialization Sequence
When a user loads the page, the init() function executes the following sequence:
- Normalize State: Validates existing key groups.
- Populate UI: Fills filter dropdowns and sidebars.
- Initial Render: Displays the full key list.
- Event Binding: Attaches listeners to the search input and availability toggles for reactive updates.
Shared Utility Functions
A set of core utilities in utils.js and admin-common.js provides standard formatting and data handling across the frontend:
| Function | Description |
| :--- | :--- |
| getCookie(name) | Retrieves a specific browser cookie (used for session validation). |
| formatDateTime(iso) | Converts UTC ISO strings into localized, human-readable strings. |
| escapeHtml(text) | Sanitizes user-provided strings before rendering to prevent XSS. |
| nowISO() | Returns the current timestamp in ISO format for log creation. |