v1.1: Rebrand Hinterstein Immobilien + echtes Auth-System

- Rebrand: Kunden-Logo, Joseph-Hinterstein-Portrait, Kontakt-Banner, Texte
- Login-Pflicht auf /login (Route-Guard), Gruppen Verwaltung/Mieter
- Mieter-Registrierung per einmaligem Registrierungscode
- Benutzerverwaltung als 6. Modul (/benutzer, nur Verwaltung)
- Demo-Zugänge mit Passwort 0815 (j.hinterstein, a.berger, m.wolf)
- Mail-Server-API: Token-Auth (/send, X-Api-Token), Mail-Stack live auf Server
- Store-Key hinterstein-mieterportal-v2, Doku (kimi.md, README) nachgeführt
This commit is contained in:
2026-10-02 12:11:43 +02:00
parent ccfe08ad24
commit fbe033ebd6
22 changed files with 1067 additions and 179 deletions
+7 -7
View File
@@ -20,7 +20,7 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import { useStore, DEMO_TENANT, DEMO_UNIT_ID } from '../store/store'
import { useStore } from '../store/store'
import type { TicketPriority, TicketStatus } from '../types'
const statusStyle: Record<TicketStatus, string> = {
@@ -46,7 +46,7 @@ const categories = [
]
function NewTicketDialog() {
const { dispatch, role } = useStore()
const { dispatch, role, me, meineEinheit } = useStore()
const [open, setOpen] = useState(false)
const [title, setTitle] = useState('')
const [category, setCategory] = useState('Sanitär')
@@ -59,8 +59,8 @@ function NewTicketDialog() {
type: 'addTicket',
ticket: {
id: `t-${Date.now()}`,
unitId: role === 'tenant' ? DEMO_UNIT_ID : 'hs-1',
tenant: role === 'tenant' ? DEMO_TENANT : 'Hocks Verwaltung (intern)',
unitId: role === 'tenant' ? meineEinheit.id : 'hs-1',
tenant: role === 'tenant' ? (me?.name ?? 'Mieter') : 'Hinterstein Immobilien (intern)',
title: title.trim(),
description: description.trim() || '–',
category,
@@ -144,16 +144,16 @@ function NewTicketDialog() {
}
export default function Tickets() {
const { tickets, units, role, dispatch } = useStore()
const { tickets, units, role, dispatch, meineEinheit } = useStore()
const [filter, setFilter] = useState<'alle' | TicketStatus>('alle')
const visible = useMemo(
() =>
(role === 'tenant'
? tickets.filter((t) => t.unitId === DEMO_UNIT_ID)
? tickets.filter((t) => t.unitId === meineEinheit.id)
: tickets
).filter((t) => filter === 'alle' || t.status === filter),
[tickets, role, filter],
[tickets, role, filter, meineEinheit],
)
const counts = {