Store ArtFuehrung as abbreviations in DB (RF, SF, BEOS, SonF, TD, Beob, ToT, Sonst)

Dropdown shows 'RF — Reguläre Führung' etc., list displays abbreviation only.
Includes migrate_art.sql for existing data and updated create_table.sql.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-28 09:15:53 +02:00
parent 23cd981f7f
commit e3e5842805
4 changed files with 43 additions and 31 deletions

View File

@@ -2,7 +2,7 @@
import { useEffect, useState } from 'react';
import type { Kuppel, ArtFuehrung, BeoOption, SelectedObjekt, Wetter, LogbuchEintrag } from '@/types/logbuch';
import { ARTEN } from '@/types/logbuch';
import { ARTEN, ARTEN_MAP } from '@/types/logbuch';
import BeoSelector from './BeoSelector';
import ObjektSelector from './ObjektSelector';
import CustomSelect from './CustomSelect';
@@ -39,14 +39,14 @@ function nowLocalDatetime(): string {
return snapTo15(raw);
}
const NO_OBJEKTE_ARTEN: ArtFuehrung[] = ['BEO-Sitzung', 'Technischer Dienst'];
const SONNE_ART: ArtFuehrung = 'Sonnenführung';
const NO_OBJEKTE_ARTEN: ArtFuehrung[] = ['BEOS', 'TD'];
const SONNE_ART: ArtFuehrung = 'SonF';
export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved }: Props) {
const [artFuehrung, setArtFuehrung] = useState<ArtFuehrung>('Reguläre Führung');
const [artFuehrung, setArtFuehrung] = useState<ArtFuehrung>('RF');
const [beginn, setBeginn] = useState(nowLocalDatetime());
const [ende, setEnde] = useState(nowLocalDatetime());
const [besucher, setBesucher] = useState(0);
const [besucher, setBesucher] = useState<number | ''>('');
const [beos, setBeos] = useState<BeoOption[]>([currentUserBeo]);
const [objekte, setObjekte] = useState<SelectedObjekt[]>([]);
const [bemerkungen, setBemerkungen] = useState('');
@@ -71,7 +71,7 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
setArtFuehrung(editEntry.ArtFuehrung);
setBeginn(toLocalDatetimeValue(editEntry.Beginn));
setEnde(toLocalDatetimeValue(editEntry.Ende));
setBesucher(editEntry.Besucher);
setBesucher(editEntry.Besucher ?? '');
setBemerkungen(editEntry.Bemerkungen ?? '');
if (editEntry.WetterTemp !== null) {
setWetter({
@@ -81,13 +81,14 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
});
}
} else {
setArtFuehrung('Reguläre Führung');
setArtFuehrung('RF');
setBeginn(nowLocalDatetime());
setEnde(nowLocalDatetime());
setBesucher(0);
setBeos([currentUserBeo]);
setObjekte([]);
setBemerkungen('');
setBesucher('');
}
}, [editEntry, currentUserBeo]);
@@ -136,7 +137,7 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
ArtFuehrung: artFuehrung,
Beginn: beginn,
Ende: ende,
Besucher: besucher,
Besucher: besucher === '' ? 0 : besucher,
beoIds: beos.map((b) => b.ID),
objekte: showObjekte ? objekte : [],
Bemerkungen: bemerkungen,
@@ -154,6 +155,7 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
});
if (!res.ok) throw new Error(await res.text());
setSuccess(true);
setTimeout(() => setSuccess(false), 5000);
if (!editEntry) {
setBeginn(nowLocalDatetime());
setEnde(nowLocalDatetime());
@@ -180,8 +182,8 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
<div>
<label className={labelCls}>Art der Führung</label>
<CustomSelect
placeholder={artFuehrung}
options={ARTEN.map((a) => ({ value: a, label: a }))}
placeholder={`${artFuehrung}${ARTEN_MAP[artFuehrung]}`}
options={ARTEN.map((a) => ({ value: a, label: `${a}${ARTEN_MAP[a]}` }))}
onChange={(v) => setArtFuehrung(v as ArtFuehrung)}
/>
</div>
@@ -216,7 +218,7 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
<input
type="number"
value={besucher}
onChange={(e) => setBesucher(parseInt(e.target.value) || 0)}
onChange={(e) => setBesucher(e.target.value === '' ? '' : parseInt(e.target.value) || 0)}
min={0}
max={9999}
className="w-20 px-2 py-2 border-2 border-gray-400 rounded-lg bg-white text-base focus:border-blue-500 focus:outline-none"

View File

@@ -11,7 +11,7 @@ CREATE TABLE objekte (
CREATE TABLE logbuch (
ID INT AUTO_INCREMENT PRIMARY KEY,
Kuppel ENUM('West','Ost','Süd','Pluto') NOT NULL DEFAULT 'West',
ArtFuehrung ENUM('Reguläre Führung','Sonderführung','BEO-Sitzung','Sonnenführung','Technischer Dienst','Beobachtung','Tag der offenen Tür','Sonstiges') NOT NULL DEFAULT 'Reguläre Führung',
ArtFuehrung ENUM('RF','SF','BEOS','SonF','TD','Beob','ToT','Sonst') NOT NULL DEFAULT 'RF',
Beginn DATETIME NOT NULL,
Ende DATETIME NOT NULL,
Besucher INT DEFAULT 0,

15
migrate_art.sql Normal file
View File

@@ -0,0 +1,15 @@
-- Migration: ArtFuehrung von Langtext auf Kürzel umstellen
-- Erst Daten aktualisieren, dann ENUM ändern
UPDATE logbuch SET ArtFuehrung = 'RF' WHERE ArtFuehrung = 'Reguläre Führung';
UPDATE logbuch SET ArtFuehrung = 'SF' WHERE ArtFuehrung = 'Sonderführung';
UPDATE logbuch SET ArtFuehrung = 'BEOS' WHERE ArtFuehrung = 'BEO-Sitzung';
UPDATE logbuch SET ArtFuehrung = 'SonF' WHERE ArtFuehrung = 'Sonnenführung';
UPDATE logbuch SET ArtFuehrung = 'TD' WHERE ArtFuehrung = 'Technischer Dienst';
UPDATE logbuch SET ArtFuehrung = 'Beob' WHERE ArtFuehrung = 'Beobachtung';
UPDATE logbuch SET ArtFuehrung = 'ToT' WHERE ArtFuehrung = 'Tag der offenen Tür';
UPDATE logbuch SET ArtFuehrung = 'Sonst'WHERE ArtFuehrung = 'Sonstiges';
ALTER TABLE logbuch
MODIFY ArtFuehrung ENUM('RF','SF','BEOS','SonF','TD','Beob','ToT','Sonst')
NOT NULL DEFAULT 'RF';

View File

@@ -1,25 +1,20 @@
export type Kuppel = 'West' | 'Ost' | 'Süd' | 'Pluto';
export type ArtFuehrung =
| 'Reguläre Führung'
| 'Sonderführung'
| 'BEO-Sitzung'
| 'Sonnenführung'
| 'Technischer Dienst'
| 'Beobachtung'
| 'Tag der offenen Tür'
| 'Sonstiges';
export type ArtFuehrung = 'RF' | 'SF' | 'BEOS' | 'SonF' | 'TD' | 'Beob' | 'ToT' | 'Sonst';
export const KUPPELN: Kuppel[] = ['West', 'Ost', 'Süd', 'Pluto'];
export const ARTEN: ArtFuehrung[] = [
'Reguläre Führung',
'Sonderführung',
'BEO-Sitzung',
'Sonnenführung',
'Technischer Dienst',
'Beobachtung',
'Tag der offenen Tür',
'Sonstiges',
];
export const ARTEN_MAP: Record<ArtFuehrung, string> = {
RF: 'Reguläre Führung',
SF: 'Sonderführung',
BEOS: 'BEO-Sitzung',
SonF: 'Sonnenführung',
TD: 'Technischer Dienst',
Beob: 'Beobachtung',
ToT: 'Tag der offenen Tür',
Sonst:'Sonstiges',
};
export const ARTEN = Object.keys(ARTEN_MAP) as ArtFuehrung[];
export interface BeoOption {
ID: number;