K oder R an den Kettenpfeilen anzeigen
This commit is contained in:
@@ -633,7 +633,7 @@ export async function revertCharacter(
|
||||
* überhaupt zu sehen ist.
|
||||
*/
|
||||
export async function listCharacters(playerId: number) {
|
||||
return prisma.character.findMany({
|
||||
const ccs = await prisma.character.findMany({
|
||||
where: { members: { some: { playerId } } },
|
||||
orderBy: [{ lineageId: 'asc' }, { chainPosition: 'asc' }, { createdAt: 'asc' }],
|
||||
include: {
|
||||
@@ -657,6 +657,29 @@ export async function listCharacters(playerId: number) {
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Womit dieser Spieler den jeweiligen Eintrag bezahlt hat. In der Kette
|
||||
// steht das am Übergang: der Pfeil zum nächsten Glied trägt die Art, mit
|
||||
// der dieses Glied bezahlt wurde.
|
||||
const buchungen = await prisma.creditLedger.findMany({
|
||||
where: {
|
||||
characterId: { in: ccs.map((c) => c.id) },
|
||||
playerId,
|
||||
source: CreditSource.CONSUME,
|
||||
reversedBy: null,
|
||||
},
|
||||
select: { characterId: true, kind: true },
|
||||
orderBy: { id: 'desc' },
|
||||
});
|
||||
|
||||
const artNach = new Map<number, CreditKind>();
|
||||
for (const buchung of buchungen) {
|
||||
if (buchung.characterId !== null && !artNach.has(buchung.characterId)) {
|
||||
artNach.set(buchung.characterId, buchung.kind);
|
||||
}
|
||||
}
|
||||
|
||||
return ccs.map((cc) => ({ ...cc, fundedWith: artNach.get(cc.id) ?? null }));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -312,9 +312,9 @@ export default function ChainView({
|
||||
|
||||
{i < vonObenNachUnten.length - 1 && (
|
||||
<>
|
||||
<div className="chain-arrow" aria-hidden="true">
|
||||
⬆
|
||||
</div>
|
||||
{/* Der Pfeil führt zu diesem Eintrag - also trägt er,
|
||||
womit dieser Schritt bezahlt wurde. */}
|
||||
<Uebergang character={character} />
|
||||
{zone(
|
||||
kette.lineageId,
|
||||
vonObenNachUnten[i + 1]?.id ?? null,
|
||||
@@ -327,11 +327,9 @@ export default function ChainView({
|
||||
|
||||
{zone(kette.lineageId, null, `${kette.lineageId}-unten`)}
|
||||
|
||||
{kette.herkunft.map((frueher) => (
|
||||
{kette.herkunft.map((frueher, i) => (
|
||||
<div key={frueher.id}>
|
||||
<div className="chain-arrow" aria-hidden="true">
|
||||
⬆
|
||||
</div>
|
||||
<Uebergang character={i === 0 ? kette.glieder[0] : kette.herkunft[i - 1]} />
|
||||
<ChainEntry
|
||||
character={frueher}
|
||||
playerId={playerId}
|
||||
@@ -393,6 +391,35 @@ export default function ChainView({
|
||||
);
|
||||
}
|
||||
|
||||
/// Kurzzeichen für die Bezahlart eines Übergangs.
|
||||
const UEBERGANG: Record<string, { zeichen: string; titel: string; klasse: string }> = {
|
||||
REDESIGN_KULANZ: { zeichen: 'K', titel: 'Kulanz-Redesign', klasse: 'is-kulanz' },
|
||||
REDESIGN_PAID: { zeichen: 'R', titel: 'Bezahltes Redesign', klasse: 'is-paid' },
|
||||
CC: { zeichen: 'CC', titel: 'Aus dem CC-Topf bezahlt', klasse: 'is-cc' },
|
||||
};
|
||||
|
||||
/**
|
||||
* Der Pfeil zum nächsten Glied, mit dem Kurzzeichen der Bezahlart.
|
||||
*
|
||||
* Womit ein Schritt bezahlt wurde, gehört an den Schritt - nicht in die
|
||||
* Karte darüber. So liest sich die Kette in einem Zug: Eintrag, womit,
|
||||
* Eintrag.
|
||||
*/
|
||||
function Uebergang({ character }: { character: Character | undefined }) {
|
||||
const art = character?.fundedWith ? UEBERGANG[character.fundedWith] : undefined;
|
||||
|
||||
return (
|
||||
<div className="chain-arrow">
|
||||
<span aria-hidden="true">⬆</span>
|
||||
{art && (
|
||||
<span className={`chain-step ${art.klasse}`} title={art.titel}>
|
||||
{art.zeichen}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ChainEntry({
|
||||
character,
|
||||
playerId,
|
||||
|
||||
@@ -149,6 +149,8 @@ export interface Character {
|
||||
successors: CharacterRef[];
|
||||
forumThreads?: ThreadRef[];
|
||||
links?: CharacterLink[];
|
||||
/// Womit dieser Eintrag bezahlt wurde, aus Sicht des betrachteten Spielers.
|
||||
fundedWith?: CreditKind | null;
|
||||
members?: CharacterMember[];
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
@@ -1171,6 +1171,7 @@ textarea {
|
||||
/* Der Pfeil zeigt zum jüngeren Eintrag, also nach oben. Er ist bewusst
|
||||
deutlich: er ist das Einzige, was die Leserichtung der Kette verrät. */
|
||||
.chain-arrow {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
color: var(--accent);
|
||||
font-size: 1.4rem;
|
||||
@@ -1287,3 +1288,42 @@ textarea {
|
||||
padding-left: 0.6rem;
|
||||
padding-right: 0.6rem;
|
||||
}
|
||||
|
||||
/* Das Kurzzeichen sitzt am Pfeil, nicht in der Karte: womit ein Schritt
|
||||
bezahlt wurde, gehört an den Schritt. Absolut gesetzt, damit die Pfeile
|
||||
aller Ketten in einer Flucht bleiben. */
|
||||
.chain-step {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(0.75rem, -50%);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 1.35rem;
|
||||
height: 1.35rem;
|
||||
padding: 0 0.3rem;
|
||||
border: 1px solid var(--border-strong);
|
||||
border-radius: 999px;
|
||||
background: var(--bg);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.chain-step.is-kulanz {
|
||||
border-color: var(--positive);
|
||||
color: var(--positive);
|
||||
}
|
||||
|
||||
.chain-step.is-paid {
|
||||
border-color: var(--accent);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* Aus dem CC-Topf bezahlt - die Ausnahme, also auffälliger. */
|
||||
.chain-step.is-cc {
|
||||
border-color: var(--warn);
|
||||
color: var(--warn);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user