feat: Profilseite, Etikettendruck mit QR-Code, mehr Automatisierungen und Entra-ID-SSO
Backend Image / build-and-push (push) Successful in 2m28s
Frontend Image / build-and-push (push) Successful in 2m10s

- Profilseite mit MFA-Einrichtung, Passwort/E-Mail/Name aendern, Konto deaktivieren
- Bearbeiten-Buttons fuer Bienenstaende/Voelker/Koeniginnen/Aufgaben-Datensaetze
- Restliche englische Enum-Werte durch deutsche Labels ersetzt (SelectValue-Fix)
- Sidebar-Eintraege fuer Ernten/Schleuderungen ergaenzt
- Automatisierungen von 3 auf 6 Regeln erweitert (Schwarmstimmung, kritischer Gesundheitsstatus, Lagerbestand)
- Responsive Grid-Layout fuer Volk-/Koeniginnen-/Honigchargen-/Bienenstand-Detailseiten
- Etikettenvorlagen mit Platzhaltern inkl. QR-Code (verweist auf Herkunftsseite) und PDF-Druck
- Entra-ID-SSO (Authorization Code + PKCE, kein Auto-Provisioning, Secrets nur ueber Environment-Variablen)
This commit is contained in:
Nick Szaunig committed 2026-08-31 18:56:08 +02:00
1 parent 0a52b29c57
commit 8432313fa9
83 files changed
+2684 -289

No files matched your search

@@ -69,7 +69,7 @@ export function ApiaryEditCard({ apiary }: { apiary: Apiary }) {
}
return (
<Card className="max-w-lg">
<Card>
<CardHeader className="flex flex-row items-center justify-between">
<div className="flex items-center gap-2.5">
<span
@@ -40,28 +40,34 @@ export default function ApiaryDetailPage() {
<div className="flex justify-end">
<QrCodeDialog entityType="apiaries" id={apiary.id} />
</div>
<ApiaryEditCard key={apiary.id} apiary={apiary} />
<WeatherCard
apiaryId={apiary.id}
hasCoordinates={apiary.latitude !== null && apiary.longitude !== null}
/>
<DocumentUploadCard entityType="APIARY" entityId={apiary.id} />
<div className="flex flex-wrap gap-2">
<Button
nativeButton={false}
render={<Link href={`/harvests/new?apiaryId=${apiary.id}`} />}
>
Neue Ernte
</Button>
<Button
variant="outline"
disabled={exportReportMutation.isPending}
onClick={() => exportReportMutation.mutate()}
>
{exportReportMutation.isPending
? "Wird erstellt…"
: `Jahresbericht ${CURRENT_YEAR}`}
</Button>
<div className="grid grid-cols-1 items-start gap-4 lg:grid-cols-2">
<div className="flex flex-col gap-4">
<ApiaryEditCard key={apiary.id} apiary={apiary} />
<div className="flex flex-wrap gap-2">
<Button
nativeButton={false}
render={<Link href={`/harvests/new?apiaryId=${apiary.id}`} />}
>
Neue Ernte
</Button>
<Button
variant="outline"
disabled={exportReportMutation.isPending}
onClick={() => exportReportMutation.mutate()}
>
{exportReportMutation.isPending
? "Wird erstellt…"
: `Jahresbericht ${CURRENT_YEAR}`}
</Button>
</div>
</div>
<div className="flex flex-col gap-4">
<WeatherCard
apiaryId={apiary.id}
hasCoordinates={apiary.latitude !== null && apiary.longitude !== null}
/>
<DocumentUploadCard entityType="APIARY" entityId={apiary.id} />
</div>
</div>
</main>
);