Schulportal-Konventionen übernommen: Dark Mode (ThemeToggle), beispieldaten.py + generated.json, kimi.md, mail-server (Postfix-Relay + API), Deploy-Workflow (pscp/plink, npm_default), Screenshots in preview/
This commit is contained in:
File diff suppressed because it is too large
Load Diff
+4
-86
@@ -6,97 +6,15 @@ import type {
|
||||
Thread,
|
||||
Announcement,
|
||||
} from '../types'
|
||||
|
||||
const buildings = [
|
||||
{ name: 'Hauptstraße 12', prefix: 'HS', count: 20, baseRent: 9.8 },
|
||||
{ name: 'Ringweg 3', prefix: 'RW', count: 15, baseRent: 8.9 },
|
||||
{ name: 'Am Park 5', prefix: 'AP', count: 15, baseRent: 10.4 },
|
||||
]
|
||||
|
||||
const firstNames = [
|
||||
'Anna', 'Jonas', 'Marta', 'Leon', 'Sofia', 'Felix', 'Lena', 'Paul',
|
||||
'Emma', 'Noah', 'Clara', 'Ben', 'Nora', 'Max', 'Julia', 'Tim',
|
||||
'Sarah', 'Finn', 'Laura', 'Jan', 'Mia', 'Tom', 'Ela', 'Kim',
|
||||
]
|
||||
const lastNames = [
|
||||
'Berger', 'Klein', 'Wolf', 'Neumann', 'Schäfer', 'Krüger', 'Brandt',
|
||||
'Vogel', 'Otto', 'Horn', 'Busch', 'Thomas', 'Pohl', 'Sander', 'Lindner',
|
||||
]
|
||||
import generated from './generated.json'
|
||||
|
||||
// Demo-Mieter: Whg. Hauptstraße 12 Nr. 7
|
||||
export const DEMO_TENANT = 'Anna Berger'
|
||||
export const DEMO_UNIT_ID = 'hs-7'
|
||||
|
||||
let nameIdx = 0
|
||||
function nextName(): string {
|
||||
const n = `${firstNames[nameIdx % firstNames.length]} ${lastNames[nameIdx % lastNames.length]}`
|
||||
nameIdx++
|
||||
return n
|
||||
}
|
||||
|
||||
export const units: Unit[] = buildings.flatMap((b) =>
|
||||
Array.from({ length: b.count }, (_, i) => {
|
||||
const num = i + 1
|
||||
const size = 38 + ((num * 7 + b.prefix.length * 3) % 78) // 38–115 m²
|
||||
const coldRent = Math.round(size * b.baseRent)
|
||||
const warmRent = coldRent + Math.round(2.4 * size) + (num % 3 === 0 ? 35 : 0)
|
||||
const floor = num <= 2 ? 0 : Math.min(4, Math.floor((num - 1) / 4))
|
||||
const occupied = num % 9 !== 0 // ~89 % Vermietung -> 50 Wohnungen, ~5 frei
|
||||
const tenant =
|
||||
b.prefix === 'HS' && num === 7
|
||||
? DEMO_TENANT
|
||||
: occupied
|
||||
? nextName()
|
||||
: null
|
||||
return {
|
||||
id: `${b.prefix.toLowerCase()}-${num}`,
|
||||
building: b.name,
|
||||
number: `${num}`,
|
||||
floor,
|
||||
size,
|
||||
coldRent,
|
||||
warmRent,
|
||||
tenant,
|
||||
status: occupied ? ('vermietet' as const) : ('frei' as const),
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
const monthNames = [
|
||||
'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
|
||||
'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember',
|
||||
]
|
||||
|
||||
export const transactions: Transaction[] = units
|
||||
.filter((u) => u.status === 'vermietet')
|
||||
.flatMap((u) => {
|
||||
const txs: Transaction[] = []
|
||||
for (let m = 0; m < 12; m++) {
|
||||
const dueMonth = m + 1
|
||||
txs.push({
|
||||
id: `tx-${u.id}-${m}`,
|
||||
unitId: u.id,
|
||||
tenant: u.tenant!,
|
||||
month: monthNames[m],
|
||||
year: 2026,
|
||||
amount: u.warmRent,
|
||||
type: 'Miete',
|
||||
status:
|
||||
dueMonth <= 9
|
||||
? (u.id.charCodeAt(3) + m) % 11 === 0
|
||||
? 'überfällig'
|
||||
: 'bezahlt'
|
||||
: dueMonth === 10
|
||||
? 'offen'
|
||||
: 'offen',
|
||||
paidAt:
|
||||
dueMonth <= 9 && (u.id.charCodeAt(3) + m) % 11 !== 0
|
||||
? `0${(m % 8) + 1}.0${dueMonth}.2026`
|
||||
: undefined,
|
||||
})
|
||||
}
|
||||
return txs
|
||||
})
|
||||
// Maschinell erzeugte Bestandsdaten (beispieldaten.py -> generated.json)
|
||||
export const units = generated.units as Unit[]
|
||||
export const transactions = generated.transactions as Transaction[]
|
||||
|
||||
export const tickets: Ticket[] = [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user