diff --git a/src/app/(app)/woche/page.tsx b/src/app/(app)/woche/page.tsx
index a7c7430..19f7ef2 100644
--- a/src/app/(app)/woche/page.tsx
+++ b/src/app/(app)/woche/page.tsx
@@ -187,6 +187,7 @@ export default async function WocheSeite({
ganztaegig: t.ganztaegig,
frei: t.zeigtAls === 'FREI',
kalenderName: t.kalenderName,
+ gespiegelt: t.gespiegelt,
}))}
aufgaben={aufgaben.map((a) => ({
id: a.id,
diff --git a/src/app/(app)/woche/wochenraster.tsx b/src/app/(app)/woche/wochenraster.tsx
index d1de1ed..a4926cc 100644
--- a/src/app/(app)/woche/wochenraster.tsx
+++ b/src/app/(app)/woche/wochenraster.tsx
@@ -64,6 +64,8 @@ export type RasterTermin = {
ganztaegig: boolean
frei: boolean
kalenderName: string
+ /** Aus der anderen Instanz gespiegelt: belegt, aber ohne Betreff. */
+ gespiegelt?: boolean
}
export type RasterSpalte = {
@@ -321,6 +323,11 @@ export function Wochenraster({
eintrag.frei
? 'bg-gedaempft/60 text-gedaempft-vordergrund'
: 'bg-gedaempft text-gedaempft-vordergrund',
+ // Gespiegeltes gehört sichtbar in eine eigene
+ // Klasse: gestreift, damit niemand darin einen
+ // Termin mit fehlendem Betreff vermutet.
+ eintrag.gespiegelt &&
+ 'border-rand border border-dashed bg-[repeating-linear-gradient(45deg,transparent,transparent_4px,color-mix(in_oklch,currentColor_12%,transparent)_4px,color-mix(in_oklch,currentColor_12%,transparent)_8px)]',
)}
style={{
top: lage.oben,
@@ -328,10 +335,16 @@ export function Wochenraster({
left: `${(spur / spuren) * 100}%`,
width: `${100 / spuren}%`,
}}
- title={`${eintrag.betreff ?? 'Termin'} · ${eintrag.kalenderName}`}
+ title={
+ eintrag.gespiegelt
+ ? 'Dienstlich belegt – gespiegelt aus der anderen Instanz'
+ : `${eintrag.betreff ?? 'Termin'} · ${eintrag.kalenderName}`
+ }
>
- {eintrag.betreff ?? 'Termin'}
+ {eintrag.gespiegelt
+ ? 'Dienstlich belegt'
+ : (eintrag.betreff ?? 'Termin')}
)
diff --git a/src/server/abfragen/woche.ts b/src/server/abfragen/woche.ts
index bbb7f0d..5493985 100644
--- a/src/server/abfragen/woche.ts
+++ b/src/server/abfragen/woche.ts
@@ -33,6 +33,13 @@ export type WochenTermin = {
ganztaegig: boolean
zeigtAls: ZeigtAls
kalenderName: string
+ /**
+ * Kommt aus der anderen Instanz und trägt darum keinen Betreff.
+ *
+ * Für die Ansicht ist so eine Belegung ein fremder Termin wie jeder andere:
+ * Sie blockiert Zeit und lässt sich hier nicht verschieben.
+ */
+ gespiegelt: boolean
}
export type WocheDaten = {
@@ -55,7 +62,7 @@ export async function wocheLaden(
): Promise {
const fenster = wochenFenster(zeitpunkt)
- const [zeitbloecke, termine] = await Promise.all([
+ const [zeitbloecke, termine, belegungen] = await Promise.all([
db.zeitblock.findMany({
where: {
kalenderkonto: { benutzerId },
@@ -97,6 +104,11 @@ export async function wocheLaden(
kalenderkonto: { select: { anzeigename: true } },
},
}),
+ db.spiegelbelegung.findMany({
+ where: { beginn: { lt: fenster.bis }, ende: { gt: fenster.von } },
+ orderBy: { beginn: 'asc' },
+ select: { id: true, beginn: true, ende: true },
+ }),
])
// Ein Zeitblock steht auch im Kalender und damit im Spiegel. Er würde sonst
@@ -118,17 +130,31 @@ export async function wocheLaden(
letzterFehler: z.letzterFehler,
offen: z.extId === null,
})),
- termine: termine
- .filter((t) => !eigeneExtIds.has(t.extId))
- .map((t) => ({
- id: t.id,
- beginn: t.beginn,
- ende: t.ende,
- betreff: t.betreff,
- ganztaegig: t.ganztaegig,
- zeigtAls: t.zeigtAls,
- kalenderName: t.kalenderkonto.anzeigename,
+ termine: [
+ ...termine
+ .filter((t) => !eigeneExtIds.has(t.extId))
+ .map((t) => ({
+ id: t.id,
+ beginn: t.beginn,
+ ende: t.ende,
+ betreff: t.betreff,
+ ganztaegig: t.ganztaegig,
+ zeigtAls: t.zeigtAls,
+ kalenderName: t.kalenderkonto.anzeigename,
+ gespiegelt: false,
+ })),
+ ...belegungen.map((b) => ({
+ id: b.id,
+ beginn: b.beginn,
+ ende: b.ende,
+ // Kein Betreff: Die andere Instanz schickt bewusst keinen.
+ betreff: null,
+ ganztaegig: false,
+ zeigtAls: 'GEBUCHT' as const,
+ kalenderName: 'Dienstlich',
+ gespiegelt: true,
})),
+ ].sort((a, b) => a.beginn.getTime() - b.beginn.getTime()),
}
}