style(mobile): responsiver Durchgang - Sidebar+Liste-Layouts brechen um
4 Admin-Sektionen (ObjektSection, MaterialSection, ZustaendigkeitSection, ObjektPositionenPanel) hatten identisches fest-20rem/12rem-Sidebar-neben- Liste-Layout ohne Umbruch - auf Mobile lagen beide Spalten nebeneinander breiter als der Bildschirm. Neue global.css-Klassen .split-layout/ -sidebar/-sidebar-sm/-content lösen das inline-Style-Duplikat auf und klappen unter 768px automatisch auf eine Spalte. Zusätzlich: .page-wide/.topbar/.card-grid/.row bekommen eigene 768px- Anpassungen (kleinere Paddings/Schrift, Kacheln volle Breite, automatischer Zeilenumbruch). Tabellen (Historie/Lagerbewegungen) waren schon per overflow-x:auto abgesichert, keine Änderung nötig dort. Mitarbeiter-Mobilflow (ObjektListPage/KontrollPage, 640px-Spalte) unverändert - war laut Nutzer-Feedback bereits gut. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
This commit is contained in:
@@ -4189,3 +4189,19 @@ Keine Commits in dieser Session.
|
||||
- DEVLOG.md | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-09-05 14:55 – 14:59 (4m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** asb-material
|
||||
|
||||
### Commits
|
||||
- 7ebbae8 style: visuelles Redesign (Desktop), Design-Anleihe bei Resgrid/OpenFleet/EMCS
|
||||
|
||||
### Geänderte Dateien
|
||||
- DEVLOG.md | 33 ++++++++++++
|
||||
- frontend/src/pages/DashboardPage.tsx | 36 ++++++-------
|
||||
- frontend/src/pages/FehlbestandListePage.tsx | 2 +-
|
||||
- frontend/src/pages/MangelListePage.tsx | 4 +-
|
||||
- frontend/src/pages/admin/QualifikationSection.tsx | 2 +-
|
||||
- frontend/src/styles/global.css | 201 ++++++++++++++++++++++++++++++++++++++++++++++++--------------------
|
||||
|
||||
---
|
||||
|
||||
@@ -78,8 +78,8 @@ export function MaterialSection({ materialien, onGeaendert, onFehler }: Props) {
|
||||
return (
|
||||
<section className="section">
|
||||
<h2>Material</h2>
|
||||
<div style={{ display: "flex", flexDirection: "row", alignItems: "flex-start", gap: "1.25rem" }}>
|
||||
<div className="card" style={{ flex: "0 0 20rem", width: "20rem", boxSizing: "border-box" }}>
|
||||
<div className="split-layout">
|
||||
<div className="card split-layout-sidebar">
|
||||
<h3 style={{ marginTop: 0 }}>{bearbeiteteId !== null ? "Material bearbeiten" : "Material anlegen"}</h3>
|
||||
<div className="stack">
|
||||
<div className="field">
|
||||
@@ -137,7 +137,7 @@ export function MaterialSection({ materialien, onGeaendert, onFehler }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ flex: "1 1 0%", minWidth: 0 }}>
|
||||
<div className="split-layout-content">
|
||||
<input
|
||||
className="input input-search"
|
||||
style={{ marginBottom: "1rem" }}
|
||||
|
||||
@@ -152,12 +152,9 @@ export function ObjektPositionenPanel({ objektId, vorlageId, materialien, onFehl
|
||||
const verfuegbareMaterialien = materialien.filter((m) => !vorhandeneMaterialIds.has(m.id));
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex", flexDirection: "row", alignItems: "flex-start", gap: "1.25rem" }}>
|
||||
<div className="split-layout">
|
||||
{positionen.length > 0 && (
|
||||
<nav
|
||||
className="card"
|
||||
style={{ flex: "0 0 12rem", width: "12rem", boxSizing: "border-box", padding: "0.5rem" }}
|
||||
>
|
||||
<nav className="card split-layout-sidebar-sm">
|
||||
<button
|
||||
className={aktivesFach === null ? "btn btn-primary btn-block" : "btn btn-secondary btn-block"}
|
||||
style={{ marginBottom: "0.3rem" }}
|
||||
@@ -178,7 +175,7 @@ export function ObjektPositionenPanel({ objektId, vorlageId, materialien, onFehl
|
||||
</nav>
|
||||
)}
|
||||
|
||||
<div style={{ flex: "1 1 0%", minWidth: 0 }}>
|
||||
<div className="split-layout-content">
|
||||
<div className="row" style={{ flexWrap: "wrap", marginBottom: "1rem" }}>
|
||||
<select
|
||||
className="input"
|
||||
|
||||
@@ -263,9 +263,9 @@ export function ObjektSection({
|
||||
return (
|
||||
<section className="section">
|
||||
<h2>Objekte</h2>
|
||||
<div style={{ display: "flex", flexDirection: "row", alignItems: "flex-start", gap: "1.25rem" }}>
|
||||
<div className="split-layout">
|
||||
{!nurPflegen && (
|
||||
<div className="card" style={{ flex: "0 0 20rem", width: "20rem", boxSizing: "border-box" }}>
|
||||
<div className="card split-layout-sidebar">
|
||||
<h3 style={{ marginTop: 0 }}>Objekt aus Vorlage anlegen</h3>
|
||||
{vorlagen.length === 0 ? (
|
||||
<p className="text-muted">
|
||||
@@ -342,7 +342,7 @@ export function ObjektSection({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div style={{ flex: "1 1 0%", minWidth: 0 }}>
|
||||
<div className="split-layout-content">
|
||||
<input
|
||||
className="input input-search"
|
||||
style={{ marginBottom: "1rem" }}
|
||||
|
||||
@@ -103,8 +103,8 @@ export function ZustaendigkeitSection({ standorte, objekte, benutzer, onFehler }
|
||||
return (
|
||||
<section className="section">
|
||||
<h2>Zuständigkeit</h2>
|
||||
<div style={{ display: "flex", flexDirection: "row", alignItems: "flex-start", gap: "1.25rem" }}>
|
||||
<div className="card" style={{ flex: "0 0 20rem", width: "20rem", boxSizing: "border-box" }}>
|
||||
<div className="split-layout">
|
||||
<div className="card split-layout-sidebar">
|
||||
<p className="text-muted" style={{ marginBottom: "1rem" }}>
|
||||
Wer ist materialverantwortlich für welchen Standort/welches Objekt. Standort-Zuordnung
|
||||
gilt für alle Objekte dort, Objekt-Zuordnung ist eine zusätzliche, feinere Ergänzung.
|
||||
@@ -182,7 +182,7 @@ export function ZustaendigkeitSection({ standorte, objekte, benutzer, onFehler }
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ flex: "1 1 0%", minWidth: 0 }}>
|
||||
<div className="split-layout-content">
|
||||
<input
|
||||
className="input input-search"
|
||||
style={{ marginBottom: "1rem" }}
|
||||
|
||||
@@ -461,3 +461,74 @@ select.input:focus {
|
||||
margin: 0.2rem 0 0.4rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* -- Responsive: mobile Durchgang 2026-09-05 -----------------------------
|
||||
Formular-Sidebar + Liste (Objekte/Material/Zuständigkeit/Positionen)
|
||||
nutzten bisher fixe 20rem-Breite nebeneinander - bricht auf Mobile, da
|
||||
beide Spalten dann zusammen breiter als der Bildschirm sind. */
|
||||
|
||||
.split-layout {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
.split-layout-sidebar {
|
||||
flex: 0 0 20rem;
|
||||
width: 20rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.split-layout-sidebar-sm {
|
||||
flex: 0 0 12rem;
|
||||
width: 12rem;
|
||||
box-sizing: border-box;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.split-layout-content {
|
||||
flex: 1 1 0%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.split-layout {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.split-layout-sidebar,
|
||||
.split-layout-sidebar-sm {
|
||||
width: 100%;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.page-wide {
|
||||
padding: 1.25rem 1rem 2rem;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
padding: 0.6rem 0.9rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.topbar-nav {
|
||||
gap: 0.15rem;
|
||||
}
|
||||
|
||||
.topbar-nav a {
|
||||
padding: 0.4rem 0.6rem;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.35rem;
|
||||
}
|
||||
|
||||
.card-grid > .card {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
|
||||
.row {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user