RELEASE V.1.2.1 - Voici les fonctionnalités :

-> Mode sombre (Extended)
-> Prise en charge PWA
This commit is contained in:
mathis committed 2026-08-26 00:41:24 +02:00
1 parent e017166cb5
commit d61422ddbf
4 files changed
+125 -6

No files matched your search

+82
View File
@@ -1113,3 +1113,85 @@ wcs-textarea::part(textarea) {
max-width: none !important; max-width: none !important;
} }
} }
/* =============================================
RESPONSIVE MODALS (PWA / TABLETTE / MOBILE)
============================================= */
@media (max-width: 900px) {
/* Sur tablette, la modale prend plus de place */
.modal-content {
max-width: 90vw;
max-height: 90vh;
}
.modal-content.modal-small {
max-width: 60vw;
}
}
@media (max-width: 600px) {
/* Sur mobile, la modale passe en plein écran (façon app native) */
.modal-overlay {
padding: 0 !important;
align-items: flex-end;
}
.modal-content,
.modal-content.modal-small,
.modal-large,
.modal-xlarge {
width: 100vw !important;
max-width: 100vw !important;
height: 100vh !important;
max-height: 100vh !important;
border-radius: 0 !important;
display: flex;
flex-direction: column;
padding-top: env(safe-area-inset-top);
overflow: hidden !important; /* Empêche le conteneur principal de scroller */
}
.modal-header {
padding: 16px;
background: #fff;
z-index: 10;
/* Plus besoin de sticky, le layout flex s'en charge */
}
.modal-body {
flex: 1;
overflow-y: auto;
padding: 16px;
-webkit-overflow-scrolling: touch;
}
/* Rendre les onglets collants en dessous du header si présents */
.gares-modal-tabs {
position: sticky;
top: 0;
background: #fff;
z-index: 5;
}
.modal-footer {
padding: 16px;
padding-bottom: calc(16px + env(safe-area-inset-bottom));
background: #fff;
z-index: 10;
flex-direction: column-reverse; /* Boutons de validation en haut, annulation en bas */
gap: 8px;
border-top: 1px solid #e5e7eb;
display: flex;
}
.modal-footer wcs-button {
width: 100%;
margin: 0 !important;
}
}
/* =============================================
Z-INDEX FIX (Empêche le AppHeader de passer au-dessus des modales)
============================================= */
body:has(.modal-overlay) .app-header-shell {
z-index: 1 !important;
}
+6 -6
View File
@@ -386,9 +386,9 @@ const handleSave = async () => {
} }
} }
const INP = { width: '100%', padding: '9px 12px', border: '1px solid #d1d5db', borderRadius: 6, fontSize: 14, boxSizing: 'border-box', outline: 'none', fontFamily: 'inherit' }; const INP = { width: '100%', padding: '9px 12px', border: '1px solid var(--wcs-gray-300, #d1d5db)', borderRadius: 6, fontSize: 14, boxSizing: 'border-box', outline: 'none', fontFamily: 'inherit', background: 'inherit', color: 'inherit' };
const LBL = { display: 'block', fontWeight: 600, fontSize: 13, color: '#374151', marginBottom: 6 }; const LBL = { display: 'block', fontWeight: 600, fontSize: 13, color: 'inherit', marginBottom: 6 };
const SEC = { fontSize: 13, fontWeight: 700, color: '#374151', textTransform: 'uppercase', letterSpacing: '0.06em', margin: '20px 0 12px', paddingBottom: 6, borderBottom: '1px solid #e5e7eb' }; const SEC = { fontSize: 13, fontWeight: 700, color: 'inherit', textTransform: 'uppercase', letterSpacing: '0.06em', margin: '20px 0 12px', paddingBottom: 6, borderBottom: '1px solid var(--wcs-gray-200, #e5e7eb)' };
const TABS = ['general', 'gares', 'jours', 'materiel', 'substitution']; const TABS = ['general', 'gares', 'jours', 'materiel', 'substitution'];
const TAB_LABELS = { general: 'Général', gares: 'Gares desservies', jours: 'Calendrier de circulation', materiel: 'Matériel roulant', substitution: 'Substitution' }; const TAB_LABELS = { general: 'Général', gares: 'Gares desservies', jours: 'Calendrier de circulation', materiel: 'Matériel roulant', substitution: 'Substitution' };
@@ -795,12 +795,12 @@ const handleSave = async () => {
<div className="modal-footer" style={{ flexShrink: 0, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> <div className="modal-footer" style={{ flexShrink: 0, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div style={{ display: 'flex', gap: 8 }}> <div style={{ display: 'flex', gap: 8 }}>
{['general', 'gares', 'jours', 'materiel', 'substitution'].map(t => ( {['general', 'gares', 'jours', 'materiel', 'substitution'].map(t => (
<button key={t} onClick={() => setActiveTab(t)} disabled={saving} style={{ width: 10, height: 10, borderRadius: '50%', border: 'none', cursor: 'pointer', background: activeTab === t ? '#0088ce' : '#d1d5db', padding: 0 }} /> <button key={t} onClick={() => setActiveTab(t)} disabled={saving} style={{ width: 10, height: 10, borderRadius: '50%', border: 'none', cursor: 'pointer', background: activeTab === t ? '#0088ce' : 'var(--wcs-gray-300, #d1d5db)', padding: 0 }} />
))} ))}
</div> </div>
<div style={{ display: 'flex', gap: 10 }}> <div style={{ display: 'flex', gap: 10 }}>
<button onClick={closeModal} disabled={saving} style={{ padding: '9px 18px', border: '1px solid #d1d5db', borderRadius: 6, background: '#fff', cursor: 'pointer', fontSize: 14 }}>Annuler</button> <button onClick={closeModal} disabled={saving} style={{ padding: '9px 18px', border: '1px solid var(--wcs-gray-300, #d1d5db)', borderRadius: 6, background: 'var(--wcs-base-white, #fff)', color: 'var(--wcs-text-color, inherit)', cursor: 'pointer', fontSize: 14 }}>Annuler</button>
<button onClick={handleSave} disabled={saving || (!editingItem && !canCreateHoraires) || (!!editingItem && !canUpdateHoraires)} style={{ padding: '9px 20px', border: 'none', borderRadius: 6, cursor: saving ? 'wait' : 'pointer', background: saving ? '#9ca3af' : '#0088ce', color: '#fff', fontWeight: 600, fontSize: 14 }}> <button onClick={handleSave} disabled={saving || (!editingItem && !canCreateHoraires) || (!!editingItem && !canUpdateHoraires)} style={{ padding: '9px 20px', border: 'none', borderRadius: 6, cursor: saving ? 'wait' : 'pointer', background: saving ? 'var(--wcs-gray-400, #9ca3af)' : '#0088ce', color: '#fff', fontWeight: 600, fontSize: 14 }}>
{saving ? 'Enregistrement…' : isDuplicating ? 'Enregistrer la copie' : editingItem ? 'Mettre à jour' : 'Créer l\'horaire'} {saving ? 'Enregistrement…' : isDuplicating ? 'Enregistrer la copie' : editingItem ? 'Mettre à jour' : 'Créer l\'horaire'}
</button> </button>
</div> </div>
+23
View File
@@ -171,6 +171,29 @@ body.dark-mode wcs-tab {
color: #e0e0e0 !important; color: #e0e0e0 !important;
} }
/* Modales et Tabs personnalisées en Dark Mode */
body.dark-mode .horaires-modal-tabs,
body.dark-mode .gares-modal-tabs {
background-color: #1e1e1e !important;
border-bottom-color: #333 !important;
}
body.dark-mode .horaires-modal-tab-btn,
body.dark-mode .gares-modal-tab {
color: #a0a0a0 !important;
}
body.dark-mode .horaires-modal-tab-btn.is-active,
body.dark-mode .gares-modal-tab.active {
background-color: #2a2a2a !important;
color: #fff !important;
border-bottom-color: #0284c7 !important;
}
body.dark-mode .horaires-modal-body {
background: #1e1e1e !important;
}
body.dark-mode .station-type-badge.ville { body.dark-mode .station-type-badge.ville {
background: #1e3a8a; background: #1e3a8a;
color: #bfdbfe; color: #bfdbfe;
+14
View File
@@ -501,6 +501,18 @@
background: #eef6ff; background: #eef6ff;
padding: 8px 10px 0; padding: 8px 10px 0;
flex-shrink: 0; flex-shrink: 0;
overflow-x: auto;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
}
/* Hide scrollbar for a cleaner look */
.horaires-modal-tabs::-webkit-scrollbar {
display: none;
}
.horaires-modal-tabs {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
} }
.horaires-modal-tabs-alt { .horaires-modal-tabs-alt {
@@ -517,6 +529,8 @@
font-weight: 500; font-weight: 500;
border-bottom: 3px solid transparent; border-bottom: 3px solid transparent;
transition: all 0.2s ease; transition: all 0.2s ease;
flex-shrink: 0;
white-space: nowrap;
} }
.horaires-modal-tab-btn.is-active { .horaires-modal-tab-btn.is-active {