feat: add AppLayout, BrandLogo, ProfileMenu, and RouteBadge components

- Implemented AppLayout component for application shell with navigation and sidebar.
- Created BrandLogo component to display the application logo.
- Developed ProfileMenu component for user profile management with dropdown functionality.
- Added RouteBadge component to visually represent route numbers with color coding.

style: add CSS styles for Dashboard and Routes pages

- Introduced Dashboard.css for styling the dashboard layout and components.
- Created RoutesPage.css for styling the routes page, including filters and table layout.
- Added SchedulesPage.css for styling the schedules layout and route options.
This commit is contained in:
2026-09-15 22:11:10 +03:00
parent ddd67f438b
commit 6804ca5cdb
23 changed files with 999 additions and 1349 deletions

View File

@@ -1,6 +1,5 @@
const {
DEFAULT_FCM_TOPIC,
DEFAULT_FCM_ANDROID_CHANNEL_ID,
getFirebaseConfig,
getFirebaseMessaging
} = require('../config/firebase');
@@ -91,14 +90,9 @@ function isAlertActive(alert = {}) {
function buildAlertCreatedMessage(alert, options = {}) {
const alertId = getAlertId(alert);
const topic = options.topic || DEFAULT_FCM_TOPIC;
const channelId = options.androidChannelId || options.channelId || DEFAULT_FCM_ANDROID_CHANNEL_ID;
return {
topic,
notification: {
title: getNotificationTitle(alert),
body: getNotificationBody(alert)
},
data: {
event: 'alert_created',
alertId,
@@ -106,14 +100,12 @@ function buildAlertCreatedMessage(alert, options = {}) {
routeId: getRouteId(alert),
routeNumber: getRouteNumber(alert),
startTime: toIsoString(firstDefined(alert.start_time, alert.startTime)),
endTime: toIsoString(firstDefined(alert.end_time, alert.endTime))
endTime: toIsoString(firstDefined(alert.end_time, alert.endTime)),
title: getNotificationTitle(alert),
body: getNotificationBody(alert)
},
android: {
priority: 'high',
notification: {
channelId,
tag: `alert_${alertId}`
}
priority: 'high'
}
};
}
@@ -131,14 +123,12 @@ class AlertNotificationService {
this.enabled = options.enabled === undefined ? firebaseConfig.enabled : options.enabled;
this.topic = options.topic || firebaseConfig.topic;
this.androidChannelId = options.androidChannelId || options.channelId || firebaseConfig.androidChannelId;
this.logger = options.logger || getDefaultLogger();
this.getMessaging = options.getMessaging || options.messagingFactory || (() => (
options.messaging || getFirebaseMessaging({
...firebaseConfig,
enabled: this.enabled,
topic: this.topic,
androidChannelId: this.androidChannelId
topic: this.topic
})
));
}
@@ -160,10 +150,7 @@ class AlertNotificationService {
throw new Error('Firebase Messaging is unavailable');
}
const message = buildAlertCreatedMessage(alert, {
topic: this.topic,
androidChannelId: this.androidChannelId
});
const message = buildAlertCreatedMessage(alert, { topic: this.topic });
const messageId = await messaging.send(message);
const normalizedMessageId = toDataString(messageId);