RELEASE V.1.2.1 - Voici les fonctionnalités :
-> Mode sombre (Extended) -> Prise en charge PWA
This commit is contained in:
1 parent
e017166cb5
commit
d61422ddbf
4 files changed
+125
-6
No files matched your search
+82
@@ -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;
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in new issue
Block a user