tja
This commit is contained in:
@@ -97,7 +97,7 @@ export default function Account() {
|
||||
|
||||
{user?.mustChangePassword && (
|
||||
<Notice kind="warn">
|
||||
Dieses Konto verwendet noch ein vergebenes Erstpasswort. Bitte jetzt ändern — die
|
||||
Dieses Konto verwendet noch ein vergebenes Erstpasswort. Bitte jetzt ändern - die
|
||||
übrigen Seiten sind bis dahin gesperrt.
|
||||
</Notice>
|
||||
)}
|
||||
|
||||
@@ -290,9 +290,9 @@ function CreateUserModal({
|
||||
value={role}
|
||||
onChange={(event) => setRole(event.target.value as Role)}
|
||||
>
|
||||
<option value="VIEWER">Viewer — nur lesen</option>
|
||||
<option value="EDITOR">Editor — Spieler, Guthaben, CCs</option>
|
||||
<option value="ADMIN">Admin — alles inkl. Import und Nutzer</option>
|
||||
<option value="VIEWER">Viewer - nur lesen</option>
|
||||
<option value="EDITOR">Editor - Spieler, Guthaben, CCs</option>
|
||||
<option value="ADMIN">Admin - alles inkl. Import und Nutzer</option>
|
||||
</select>
|
||||
|
||||
<div className="form-actions">
|
||||
@@ -475,14 +475,14 @@ function AuditTab({ onError }: { onError: (message: string) => void }) {
|
||||
{items.map((entry) => (
|
||||
<tr key={entry.id}>
|
||||
<td className="muted small">{formatDate(entry.createdAt)}</td>
|
||||
<td>{entry.actor?.username ?? entry.actorName ?? '—'}</td>
|
||||
<td>{entry.actor?.username ?? entry.actorName ?? '-'}</td>
|
||||
<td className="mono">{entry.action}</td>
|
||||
<td className="muted">
|
||||
{entry.targetType}
|
||||
{entry.targetId ? ` #${entry.targetId}` : ''}
|
||||
</td>
|
||||
<td className="muted small details">
|
||||
{entry.details ? JSON.stringify(entry.details) : '—'}
|
||||
{entry.details ? JSON.stringify(entry.details) : '-'}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
|
||||
@@ -164,7 +164,7 @@ export default function Dashboard() {
|
||||
</Link>
|
||||
{player.forumName && <span className="muted"> · {player.forumName}</span>}
|
||||
</td>
|
||||
<td className="mono muted">{player.steamId ?? '—'}</td>
|
||||
<td className="mono muted">{player.steamId ?? '-'}</td>
|
||||
<td className="num">
|
||||
<Counter value={player.balances.CC} title="CC-Guthaben" />
|
||||
</td>
|
||||
@@ -194,7 +194,7 @@ export default function Dashboard() {
|
||||
{loading && <p className="muted">Lade …</p>}
|
||||
{!loading && result.total > result.items.length && (
|
||||
<p className="muted">
|
||||
{result.items.length} von {result.total} angezeigt — Suche eingrenzen.
|
||||
{result.items.length} von {result.total} angezeigt - Suche eingrenzen.
|
||||
</p>
|
||||
)}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ export default function Forum() {
|
||||
<div>
|
||||
<h1>Forums-Anträge</h1>
|
||||
<p className="muted">
|
||||
Jeder Antrag wird von Hand entschieden — Titel und Board sind kein verlässliches
|
||||
Jeder Antrag wird von Hand entschieden - Titel und Board sind kein verlässliches
|
||||
Signal und lösen nie eine Buchung aus. Aufgenommen werden nur Threads von Spielern,
|
||||
die hier mit passendem Forum-Namen erfasst sind.
|
||||
</p>
|
||||
@@ -103,7 +103,7 @@ export default function Forum() {
|
||||
<h2>Verschoben nach der Entscheidung ({notices.length})</h2>
|
||||
<Notice kind="warn">
|
||||
Diese Anträge wurden bereits entschieden, ihr Thread liegt inzwischen aber in einem
|
||||
anderen Board. Das ist nur ein Hinweis — geprüft und geklickt wird von Hand.
|
||||
anderen Board. Das ist nur ein Hinweis - geprüft und geklickt wird von Hand.
|
||||
</Notice>
|
||||
|
||||
<ul className="cc-list">
|
||||
@@ -312,7 +312,7 @@ function ClassifyModal({
|
||||
/>
|
||||
<span>
|
||||
<strong>{label}</strong>
|
||||
<span className="muted"> — {hint}</span>
|
||||
<span className="muted"> - {hint}</span>
|
||||
</span>
|
||||
</label>
|
||||
))}
|
||||
@@ -333,7 +333,7 @@ function ClassifyModal({
|
||||
onChange={(event) => setName(event.target.value)}
|
||||
required
|
||||
/>
|
||||
<p className="muted small">Vorbelegt mit dem Thread-Titel — bitte anpassen.</p>
|
||||
<p className="muted small">Vorbelegt mit dem Thread-Titel - bitte anpassen.</p>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -346,11 +346,11 @@ function ClassifyModal({
|
||||
onChange={(event) => setReviveId(Number(event.target.value) || null)}
|
||||
required
|
||||
>
|
||||
<option value="">— bitte wählen —</option>
|
||||
<option value="">- bitte wählen -</option>
|
||||
{inactive.map((character) => (
|
||||
<option key={character.id} value={character.id}>
|
||||
{character.name}
|
||||
{character.inactiveReason === 'REWORKED' ? ' (redesignt — kostet)' : ' (gratis)'}
|
||||
{character.inactiveReason === 'REWORKED' ? ' (redesignt - kostet)' : ' (gratis)'}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
@@ -360,7 +360,7 @@ function ClassifyModal({
|
||||
|
||||
{gewaehlterCC && !reaktivierungKostet && (
|
||||
<Notice kind="success">
|
||||
Kommt gratis zurück — der CC existiert unverändert weiter.
|
||||
Kommt gratis zurück - der CC existiert unverändert weiter.
|
||||
</Notice>
|
||||
)}
|
||||
|
||||
@@ -405,7 +405,7 @@ function ClassifyModal({
|
||||
onChange={(event) => setPredecessorId(Number(event.target.value) || null)}
|
||||
required
|
||||
>
|
||||
<option value="">— bitte wählen —</option>
|
||||
<option value="">- bitte wählen -</option>
|
||||
{characters.map((character) => (
|
||||
<option key={character.id} value={character.id}>
|
||||
{character.name}
|
||||
@@ -500,7 +500,7 @@ function AssignModal({
|
||||
<Modal title="Spieler zuordnen" onClose={onClose}>
|
||||
<Notice kind="info">
|
||||
Forumsname des Antragstellers: <strong>{thread.authorName ?? 'unbekannt'}</strong>. Passt
|
||||
kein Eintrag, trag den Forumsnamen beim Spieler nach — dann findet der nächste Abgleich
|
||||
kein Eintrag, trag den Forumsnamen beim Spieler nach - dann findet der nächste Abgleich
|
||||
ihn von allein.
|
||||
</Notice>
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ export default function Import() {
|
||||
<h2>Wartet auf Bestätigung ({open.length})</h2>
|
||||
<Notice kind="warn">
|
||||
Diese Importe sind angelegt, aber noch nicht gebucht. Der GExtension-Abgleich landet
|
||||
ebenfalls hier — erst nach dem Bestätigen entstehen Guthaben.
|
||||
ebenfalls hier - erst nach dem Bestätigen entstehen Guthaben.
|
||||
</Notice>
|
||||
|
||||
<ul className="cc-list">
|
||||
@@ -234,7 +234,7 @@ export default function Import() {
|
||||
<section className="block">
|
||||
<Notice kind="info">
|
||||
CSV oder JSON hochladen. Danach werden die Spalten zugeordnet und eine Vorschau
|
||||
gezeigt — gebucht wird erst nach Bestätigung. Bereits importierte Bestell-IDs
|
||||
gezeigt - gebucht wird erst nach Bestätigung. Bereits importierte Bestell-IDs
|
||||
werden automatisch übersprungen.
|
||||
</Notice>
|
||||
|
||||
@@ -396,13 +396,13 @@ export default function Import() {
|
||||
<tr key={row.id} className={row.plan.startsWith('SKIP') ? 'is-skipped' : undefined}>
|
||||
<td className="muted">{row.lineNo}</td>
|
||||
<td>
|
||||
{row.playerName || row.playerKey || '—'}
|
||||
{row.playerName || row.playerKey || '-'}
|
||||
{row.resolvedPlayerId === null && row.plan === 'CREATE_PLAYER_AND_BOOK' && (
|
||||
<span className="badge badge-new">neu</span>
|
||||
)}
|
||||
</td>
|
||||
<td className="muted">{row.productName ?? '—'}</td>
|
||||
<td className="mono muted">{row.externalId ?? '—'}</td>
|
||||
<td className="muted">{row.productName ?? '-'}</td>
|
||||
<td className="mono muted">{row.externalId ?? '-'}</td>
|
||||
<td className="muted">{formatDate(row.purchasedAt)}</td>
|
||||
<td className={row.plan.startsWith('SKIP') ? 'muted' : 'pos'}>
|
||||
{PLAN_LABEL[row.plan]}
|
||||
@@ -452,7 +452,7 @@ function MappingSelect({
|
||||
<div className="field">
|
||||
<label>{label}</label>
|
||||
<select value={value} onChange={(event) => onChange(event.target.value)} required={required}>
|
||||
<option value="">— nicht zuordnen —</option>
|
||||
<option value="">- nicht zuordnen -</option>
|
||||
{columns.map((column) => (
|
||||
<option key={column} value={column}>
|
||||
{column}
|
||||
|
||||
@@ -95,9 +95,9 @@ export default function PlayerDetail() {
|
||||
'bereits unter Import auf Bestätigung.',
|
||||
);
|
||||
} else if (result.unclear > 0) {
|
||||
setFlash(`${result.unclear} unklare Einträge — siehe Kasten oben.`);
|
||||
setFlash(`${result.unclear} unklare Einträge - siehe Kasten oben.`);
|
||||
} else if (result.duplicates > 0) {
|
||||
setFlash('Nichts Neues — alle Pakete sind bereits gebucht.');
|
||||
setFlash('Nichts Neues - alle Pakete sind bereits gebucht.');
|
||||
} else if (result.failedPlayers.length > 0) {
|
||||
setError(`Profil nicht abrufbar: ${result.failedPlayers[0]?.reason ?? 'unbekannt'}`);
|
||||
} else {
|
||||
@@ -165,7 +165,7 @@ export default function PlayerDetail() {
|
||||
GExtension meldet <strong>{detail.player.gextensionUsage}</strong> Mal verbraucht
|
||||
{detail.player.gextensionSyncedAt &&
|
||||
` (Stand ${formatDate(detail.player.gextensionSyncedAt)})`}
|
||||
. Nur zum Abgleich — wird nicht automatisch verrechnet.
|
||||
. Nur zum Abgleich - wird nicht automatisch verrechnet.
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -302,7 +302,7 @@ export default function PlayerDetail() {
|
||||
)}
|
||||
<p className="muted small">
|
||||
{free
|
||||
? 'Kommt gratis zurück — kostet kein Guthaben.'
|
||||
? 'Kommt gratis zurück - kostet kein Guthaben.'
|
||||
: 'Reaktivierung kostet ein Redesign- oder CC-Guthaben.'}
|
||||
</p>
|
||||
</div>
|
||||
@@ -320,7 +320,7 @@ export default function PlayerDetail() {
|
||||
method: 'POST',
|
||||
body: {},
|
||||
}),
|
||||
`"${character.name}" ist wieder aktiv — kostenlos.`,
|
||||
`"${character.name}" ist wieder aktiv - kostenlos.`,
|
||||
)
|
||||
}
|
||||
>
|
||||
@@ -376,7 +376,7 @@ export default function PlayerDetail() {
|
||||
</td>
|
||||
<td>{SOURCE_LABEL[entry.source]}</td>
|
||||
<td className="muted small">
|
||||
{entry.note ?? '—'}
|
||||
{entry.note ?? '-'}
|
||||
{entry.character && ` (${entry.character.name})`}
|
||||
</td>
|
||||
<td className="muted small">{entry.createdBy?.username ?? 'System'}</td>
|
||||
@@ -428,7 +428,7 @@ export default function PlayerDetail() {
|
||||
method: 'POST',
|
||||
body: values,
|
||||
}),
|
||||
`CC "${values.name}" angelegt — 1 CC-Guthaben verbraucht.`,
|
||||
`CC "${values.name}" angelegt - 1 CC-Guthaben verbraucht.`,
|
||||
)
|
||||
}
|
||||
/>
|
||||
@@ -870,7 +870,7 @@ function DeactivateModal({
|
||||
>
|
||||
<Notice kind="info">
|
||||
Der CC bleibt unverändert und kommt später in beiden Fällen gratis zurück. Nur ein
|
||||
Redesign macht ihn kostenpflichtig — das läuft aber über die Redesign-Aktion.
|
||||
Redesign macht ihn kostenpflichtig - das läuft aber über die Redesign-Aktion.
|
||||
</Notice>
|
||||
|
||||
<div className="radio-group">
|
||||
@@ -883,7 +883,7 @@ function DeactivateModal({
|
||||
/>
|
||||
<span>
|
||||
<strong>Spieler-Inaktivität</strong>
|
||||
<span className="muted"> — vom Server geputzt, weil der Spieler länger weg war</span>
|
||||
<span className="muted"> - vom Server geputzt, weil der Spieler länger weg war</span>
|
||||
</span>
|
||||
</label>
|
||||
<label className="radio">
|
||||
@@ -895,7 +895,7 @@ function DeactivateModal({
|
||||
/>
|
||||
<span>
|
||||
<strong>Anderer Grund</strong>
|
||||
<span className="muted"> — etwa eine vorübergehend entfernte Einheit</span>
|
||||
<span className="muted"> - etwa eine vorübergehend entfernte Einheit</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
@@ -1083,7 +1083,7 @@ function DeletePlayerModal({
|
||||
{characterCount === 1 ? 'CC' : 'CCs'} und <strong>{ledgerCount}</strong>{' '}
|
||||
{ledgerCount === 1 ? 'Buchung' : 'Buchungen'} mit. Auch Spuren in Importen und in den
|
||||
Details früherer Protokolleinträge werden entfernt. Das lässt sich nicht rückgängig
|
||||
machen — für eine Fehleingabe ist eher das Bearbeiten gedacht.
|
||||
machen - für eine Fehleingabe ist eher das Bearbeiten gedacht.
|
||||
</Notice>
|
||||
|
||||
<label htmlFor="confirm-name">
|
||||
|
||||
Reference in New Issue
Block a user