Files
tutortool/docs/design_handoff/student-desktop.jsx
2026-04-29 04:38:26 +02:00

215 lines
11 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// student-desktop.jsx — desktop/laptop variant of student check-in screens
const StudentDesktopName = () => {
const [query, setQuery] = React.useState("");
const filtered = STUDENTS.filter((s) => s.name.toLowerCase().includes(query.toLowerCase()));
return (
<div className="paper-bg" style={{ width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center", padding: 40 }}>
<div style={{ width: 560 }}>
<div className="eyebrow">Check-in · K7QJ-MX2P</div>
<div className="serif" style={{ fontSize: 42, fontWeight: 500, letterSpacing: "-0.015em", marginTop: 4 }}>
Wer bist du?
</div>
<div className="body" style={{ marginTop: 6, color: "var(--ink-3)" }}>
{COURSE.name} · Donnerstag 30. April · 14 Uhr · {ROOM.name}
</div>
<div className="card" style={{ marginTop: 24, padding: 22 }}>
<div style={{ display: "flex", alignItems: "center", gap: 8, padding: "10px 13px", border: "1px solid var(--rule)", borderRadius: 5, background: "#fbf7ee" }}>
<Icon.search style={{ color: "var(--ink-3)" }} />
<input value={query} onChange={(e) => setQuery(e.target.value)}
autoFocus
placeholder="Name eingeben…"
style={{ border: "none", background: "transparent", outline: "none", fontSize: 15, flex: 1 }} />
<span className="tiny mono" style={{ color: "var(--ink-4)" }}>{filtered.length}</span>
</div>
<div className="scroll" style={{ marginTop: 14, maxHeight: 320, overflowY: "auto", display: "grid", gridTemplateColumns: "1fr 1fr", gap: 4 }}>
{filtered.map((s, i) => (
<button key={s.id} className="row-hover" style={{
display: "flex", alignItems: "center", gap: 10,
padding: "8px 10px", border: "none", background: "transparent",
textAlign: "left", cursor: "pointer", borderRadius: 4,
}}>
<span style={{ width: 28, height: 28, borderRadius: "50%", background: "var(--paper-2)", color: "var(--ink-2)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 10, fontWeight: 600 }}>{s.initials}</span>
<span style={{ fontSize: 14 }}>{s.name}</span>
</button>
))}
</div>
</div>
<div className="tiny" style={{ marginTop: 14, textAlign: "center", color: "var(--ink-4)" }}>
Tipp: <span className="mono">Tab</span> zum Springen · <span className="mono"></span> zum Bestätigen.
</div>
</div>
</div>
);
};
const StudentDesktopSeat = () => {
return (
<div className="paper-bg" style={{ width: "100%", height: "100%", display: "grid", gridTemplateColumns: "1fr 360px", gap: 0, overflow: "hidden" }}>
{/* Map column */}
<div style={{ padding: "32px 36px", display: "flex", flexDirection: "column", gap: 14, minHeight: 0 }}>
<div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 16 }}>
<div>
<div className="eyebrow">Hallo, Carla 👋</div>
<div className="serif" style={{ fontSize: 32, fontWeight: 500, letterSpacing: "-0.015em", marginTop: 2 }}>
Wähle deinen <span className="marker">Sitz</span>
</div>
<div className="small" style={{ marginTop: 4 }}>
Klicke auf einen freien Platz Belegt­zeichen sind grau.
</div>
</div>
<div className="tiny mono" style={{ textAlign: "right" }}>
<div style={{ color: "var(--ink-4)" }}>Slot</div>
<div style={{ fontSize: 13, color: "var(--ink)", letterSpacing: "0.1em" }}>K7QJ-MX2P</div>
</div>
</div>
<div style={{ flex: 1, display: "flex", justifyContent: "center", alignItems: "center", minHeight: 0 }}>
<SeatMap variant="student" assignments={SEAT_ASSIGN} ownSeat={null} scale={0.78} />
</div>
<div style={{ display: "flex", justifyContent: "center", gap: 22, paddingTop: 4 }} className="small">
<span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}>
<span style={{ width: 12, height: 12, borderRadius: "50%", background: "#fbf7ee", border: "1.5px solid var(--ink-2)" }} /> frei
</span>
<span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}>
<span style={{ width: 12, height: 12, borderRadius: "50%", background: "#d6cdb5" }} /> belegt
</span>
<span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}>
<span style={{ width: 12, height: 12, borderRadius: "50%", background: "var(--accent)" }} /> dein Sitz
</span>
</div>
</div>
{/* Side panel */}
<aside style={{ borderLeft: "1px solid var(--rule)", background: "rgba(0,0,0,0.015)", padding: "32px 24px", display: "flex", flexDirection: "column", gap: 18 }}>
<div>
<div className="eyebrow">Sitzung</div>
<div className="serif" style={{ fontSize: 18, fontWeight: 500, marginTop: 4 }}>{COURSE.name}</div>
<div className="small" style={{ marginTop: 2 }}>Do 30. April · 14:00 15:00</div>
<div className="small">{ROOM.name}</div>
</div>
<div className="div-h" />
<div>
<div className="eyebrow">Eingecheckt als</div>
<div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 8 }}>
<span style={{ width: 32, height: 32, borderRadius: "50%", background: "var(--ink)", color: "var(--paper)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 11, fontWeight: 600 }}>CV</span>
<div>
<div style={{ fontSize: 14, fontWeight: 500 }}>Carla Vogt</div>
<div className="tiny">nicht du? <a href="#" style={{ color: "var(--accent)" }}>wechseln</a></div>
</div>
</div>
</div>
<div className="div-h" />
<div>
<div className="eyebrow">Hinweise</div>
<ul style={{ marginTop: 8, paddingLeft: 16, fontSize: 13, color: "var(--ink-2)", lineHeight: 1.55 }}>
<li>Du kannst deinen Sitz wechseln, solange der Slot offen ist.</li>
<li>Belegte Sitze zeigen <strong>keine Namen</strong> Datenschutz.</li>
<li>Wenn der Slot gesperrt ist, bleibt dein Sitz sichtbar.</li>
</ul>
</div>
<div style={{ flex: 1 }} />
<div className="card" style={{ padding: 12, background: "rgba(241,211,106,0.16)", border: "1px solid rgba(176,125,42,0.3)" }}>
<div className="eyebrow" style={{ color: "var(--amber)" }}>Bonus</div>
<div style={{ fontSize: 13, marginTop: 4 }}>+3 Punkte sobald du einen Sitz wählst.</div>
</div>
</aside>
</div>
);
};
const StudentDesktopConfirmed = () => {
return (
<div className="paper-bg" style={{ width: "100%", height: "100%", display: "grid", gridTemplateColumns: "1fr 360px", overflow: "hidden" }}>
<div style={{ padding: "32px 36px", display: "flex", flexDirection: "column", gap: 14, minHeight: 0 }}>
<div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 16 }}>
<div>
<div className="eyebrow">Eingecheckt um 14:03</div>
<div className="serif" style={{ fontSize: 32, fontWeight: 500, letterSpacing: "-0.015em", marginTop: 2 }}>
Du sitzt auf <span className="marker">T1-3</span>
</div>
<div className="small" style={{ marginTop: 4 }}>
Anwesenheit erfasst · +3 Bonuspunkte für diese Woche.
</div>
</div>
<span className="stamp" style={{ marginTop: 8, fontSize: 13, padding: "5px 12px" }}>Präsent</span>
</div>
<div style={{ flex: 1, display: "flex", justifyContent: "center", alignItems: "center", minHeight: 0 }}>
<SeatMap variant="student-self" assignments={SEAT_ASSIGN} ownSeat="T1-3" scale={0.78} />
</div>
<div style={{ display: "flex", gap: 10, justifyContent: "center" }}>
<button className="btn ghost sm">Sitz wechseln</button>
<button className="btn ghost sm">Diese Seite drucken</button>
</div>
</div>
<aside style={{ borderLeft: "1px solid var(--rule)", background: "rgba(0,0,0,0.015)", padding: "32px 24px", display: "flex", flexDirection: "column", gap: 18 }}>
<div>
<div className="eyebrow">Slot-Status</div>
<div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 6 }}>
<StatusPill status="open" />
<span className="tiny">sperrt ~14:15</span>
</div>
</div>
<div className="div-h" />
<div>
<div className="eyebrow">Deine Saison</div>
<div style={{ marginTop: 10, display: "flex", flexDirection: "column", gap: 8 }}>
{[
{ week: "W04", date: "Do 30. April", seat: "T1-3", state: "present", today: true },
{ week: "W03", date: "Do 23. April", seat: "T1-3", state: "present" },
{ week: "W02", date: "Do 16. April", seat: "T2-4", state: "present" },
{ week: "W01", date: "Do 09. April", seat: "—", state: "absent" },
].map((r) => (
<div key={r.week} style={{ display: "flex", alignItems: "center", gap: 10, fontSize: 12 }}>
<span className="mono" style={{ width: 36, color: r.today ? "var(--accent)" : "var(--ink-3)", fontWeight: r.today ? 600 : 400 }}>{r.week}</span>
<span style={{ flex: 1, color: r.today ? "var(--ink)" : "var(--ink-2)" }}>{r.date}</span>
<span className="mono tiny" style={{ color: "var(--ink-4)" }}>{r.seat}</span>
{r.state === "present" ? (
<span style={{ display: "inline-flex", width: 18, height: 18, borderRadius: "50%", background: "rgba(74,107,58,0.14)", color: "var(--green)", alignItems: "center", justifyContent: "center" }}>
<Icon.check />
</span>
) : (
<span className="tiny" style={{ width: 18, textAlign: "center", color: "var(--ink-4)" }}></span>
)}
</div>
))}
</div>
<div style={{ marginTop: 14, padding: "10px 12px", background: "rgba(138,44,31,0.05)", border: "1px solid rgba(138,44,31,0.18)", borderRadius: 4 }}>
<div className="eyebrow" style={{ color: "var(--accent)" }}>Bonus gesamt</div>
<div style={{ display: "flex", alignItems: "baseline", gap: 4, marginTop: 2 }}>
<span className="serif" style={{ fontSize: 26, fontWeight: 500, color: "var(--accent)" }}>9</span>
<span className="small">/ 12 Punkte</span>
</div>
<div className="tiny" style={{ marginTop: 2 }}>3 von 4 Tutorien besucht</div>
</div>
</div>
<div style={{ flex: 1 }} />
<div className="tiny" style={{ color: "var(--ink-4)" }}>
Nächstes Tutorium: Do, 7. Mai · 14:00
</div>
</aside>
</div>
);
};
Object.assign(window, { StudentDesktopName, StudentDesktopSeat, StudentDesktopConfirmed });