Registrierungscodes: genau ein aktiver Code pro Wohnung (v1.35)
Build & Deploy / deploy (push) Successful in 28s

- Backend: POST /api/codes erfordert Wohnung, erzeugt genau 1 Code,
  ersetzt vorher alle unbenutzten Codes der Wohnung
- Frontend: Anzahl-Selektor entfernt, Button ohne Wohnwahl deaktiviert,
  Hinweistext angepasst
This commit is contained in:
2026-10-07 19:03:16 +02:00
parent e5435bf667
commit 5cd7686358
2 changed files with 11 additions and 17 deletions
+7 -14
View File
@@ -233,7 +233,7 @@ export default function BenutzerVerwaltung() {
const { benutzer, codes, units, setAktiv, setPasswort, weiseEinheitZu, setzeBenutzerEmail, generiereCodes, loescheBenutzer, me } = useStore() const { benutzer, codes, units, setAktiv, setPasswort, weiseEinheitZu, setzeBenutzerEmail, generiereCodes, loescheBenutzer, me } = useStore()
const [suche, setSuche] = useState('') const [suche, setSuche] = useState('')
const [gruppe, setGruppe] = useState<'alle' | BenutzerRolle>('alle') const [gruppe, setGruppe] = useState<'alle' | BenutzerRolle>('alle')
const [anzahl, setAnzahl] = useState(5)
const [codeEinheit, setCodeEinheit] = useState('') const [codeEinheit, setCodeEinheit] = useState('')
const [kopiert, setKopiert] = useState<string | null>(null) const [kopiert, setKopiert] = useState<string | null>(null)
@@ -309,24 +309,16 @@ export default function BenutzerVerwaltung() {
<option key={u.id} value={u.id}>{u.building}, Whg. {u.number}</option> <option key={u.id} value={u.id}>{u.building}, Whg. {u.number}</option>
))} ))}
</select> </select>
<select
value={anzahl}
onChange={(e) => setAnzahl(Number(e.target.value))}
className="rounded-md border border-input bg-background px-3 py-1.5 text-sm"
aria-label="Anzahl Codes"
>
{[1, 5, 10, 20].map((n) => (
<option key={n} value={n}>{n}</option>
))}
</select>
<Button <Button
onClick={async () => { onClick={async () => {
const neu = await generiereCodes(anzahl, codeEinheit || null) if (!codeEinheit) return
const neu = await generiereCodes(codeEinheit)
if (neu.length > 0) kopieren(neu[0].code) if (neu.length > 0) kopieren(neu[0].code)
}} }}
disabled={!codeEinheit}
className="gap-2 bg-amber-500 text-slate-900 hover:bg-amber-400" className="gap-2 bg-amber-500 text-slate-900 hover:bg-amber-400"
> >
<RefreshCcw className="h-4 w-4" /> Codes erzeugen <RefreshCcw className="h-4 w-4" /> Code erzeugen
</Button> </Button>
</div> </div>
</div> </div>
@@ -358,7 +350,8 @@ export default function BenutzerVerwaltung() {
</div> </div>
)} )}
<p className="mt-2 text-xs text-slate-400"> <p className="mt-2 text-xs text-slate-400">
Mieter registrieren sich auf der Startseite mit einem Code – der Code wird dabei verbraucht Pro Wohnung gibt es immer genau einen aktiven Code – ein neu erzeugter Code ersetzt den bisherigen.
Mieter registrieren sich auf der Startseite mit dem Code; der Code wird dabei verbraucht
und die Wohnung automatisch zugeordnet. und die Wohnung automatisch zugeordnet.
</p> </p>
</div> </div>
+4 -3
View File
@@ -136,7 +136,8 @@ interface Store extends Bootstrap {
sendeBenutzerEmail: (id: string, betreff: string, text: string) => Promise<string | null> sendeBenutzerEmail: (id: string, betreff: string, text: string) => Promise<string | null>
/** E-Mail-Adresse eines Benutzers pflegen (Verwaltung, v1.22) */ /** E-Mail-Adresse eines Benutzers pflegen (Verwaltung, v1.22) */
setzeBenutzerEmail: (id: string, email: string) => Promise<string | null> setzeBenutzerEmail: (id: string, email: string) => Promise<string | null>
generiereCodes: (anzahl: number, einheitId: string | null) => Promise<RegistrierungsCode[]> /** Erzeugt genau einen Registrierungscode pro Wohnung (v1.35) */
generiereCodes: (einheitId: string) => Promise<RegistrierungsCode[]>
// ── Zählerstände (Verwaltung pflegt, Mieter lesen) ────── // ── Zählerstände (Verwaltung pflegt, Mieter lesen) ──────
addZaehler: (z: { addZaehler: (z: {
nummer: string nummer: string
@@ -453,8 +454,8 @@ export function StoreProvider({ children }: { children: ReactNode }) {
return fehlerNachricht(e) return fehlerNachricht(e)
} }
}, },
async generiereCodes(anzahl, einheitId) { async generiereCodes(einheitId) {
const { codes } = await apiPost<{ codes: RegistrierungsCode[] }>('/api/codes', { anzahl, einheitId }) const { codes } = await apiPost<{ codes: RegistrierungsCode[] }>('/api/codes', { einheitId })
await ladeAlles() await ladeAlles()
return codes return codes
}, },