Switch to use external data

This commit is contained in:
Niklas Meinzer
2024-11-19 08:12:37 +01:00
parent ac8436bcd3
commit 02d5c5f1ca
3 changed files with 93 additions and 71 deletions

View File

@@ -12,6 +12,7 @@ import {
useColorModeValue,
OrderedList,
ListItem,
Alert,
} from '@chakra-ui/react';
@@ -23,7 +24,7 @@ function App() {
const [selectedFlat, setSelectedFlat] = useState();
const [selectedRoom, setSelectedRoom] = useState();
const [numAdults, setNumAdults] = useState();
const [rent, setRent] = useState(0);
const [flatRent, setFlatRent] = useState();
@@ -47,9 +48,9 @@ function App() {
useEffect(() => {
setFlatRent(null);
if (selectedFlat && numAdults && (selectedFlat.wgRoomList.length === 0 || selectedRoom)) {
if (selectedFlat && (selectedFlat.wgRoomList.length === 0 || selectedRoom)) {
console.log("Recalculating Rent...");
var commonAreaShare = 60 * numAdults;
var commonAreaShare = 60;
var kitchenCost = 50;
var sizePrivate = selectedFlat.sizePrivate;
var internalAreaShare = 0;
@@ -68,7 +69,7 @@ function App() {
setFlatRent(newRent);
}
}, [selectedFlat, selectedRoom, numAdults])
}, [selectedFlat, selectedRoom])
return (
@@ -93,19 +94,20 @@ function App() {
<ListItem>Nun siehst du den daraus resultierenden Mietpreis absolut und auf den Quadratmeter gerechnet.</ListItem>
</OrderedList>
</Box>
<Alert status='warning'><Text> <b>ACHTUNG:</b> Durch die vielen Änderungen in den letzten Tagen wurden dieses Tool zuletzt mit heißer Nadel gestrickt. Bitte verzeiht, wenn etwas nicht funktioniert. Wenn euch etwas komisch vorkommt, meldet euch bei Niklas. Die Zahlen sind alle ohne Gewähr. <b>Grundlage für's Bieteverfahren sind die Zahlen, die wir rumgeschickt haben.</b></Text></Alert>
<SimpleGrid pt={5} columns={{ base: 1, md: 2, lg: 2 }} spacing={4}>
<Heading>Wohnung</Heading>
<Box></Box>
<FlatSelectionCard setSelectedFlat={setSelectedFlat} onRoomSelected={setSelectedRoom} onNumAdultsSelected={setNumAdults} />
<FlatDetailsCard flat={selectedFlat} room={selectedRoom} numAdults={numAdults} flatRent={flatRent} />
<FlatSelectionCard setSelectedFlat={setSelectedFlat} onRoomSelected={setSelectedRoom} />
<FlatDetailsCard flat={selectedFlat} room={selectedRoom} flatRent={flatRent} />
<Heading>Selbsteinschätzung</Heading>
<Box></Box>
<SelfEvaluationCard rent={rent} setRent={setRent} />
<ResultsCard rent={rent} flat={selectedFlat} room={selectedRoom} numAdults={numAdults} flatRent={flatRent} />
<ResultsCard rent={rent} flat={selectedFlat} room={selectedRoom} flatRent={flatRent} />
</SimpleGrid>
</Stack>
</Center>

View File

@@ -1,8 +1,9 @@
import rentData from './rent_data.json';
class Flat {
constructor(name, numRooms, sizePrivate, isWbs = false, isAccessible = false, wgRoomList = null) {
constructor(name, numRooms, isWbs = false, isAccessible = false, wgRoomList = null, combineRooms = null) {
this.name = name;
this.numRooms = numRooms;
this.sizePrivate = sizePrivate;
this.sizePrivate = 0;
this.isWbs = isWbs;
this.sizeShared = 0;
// Normal flats have as many people as rooms
@@ -10,11 +11,22 @@ class Flat {
if (!wgRoomList) {
this.wgRoomList = [];
this.numPeople = numRooms;
var idList = combineRooms ? combineRooms : [name];
this.minRent = 0;
this.wbsRent = 0;
this.freeRent = 0;
for (var i = 0; i < idList.length; i++) {
this.minRent += rentData[idList[i]].min_rent;
this.wbsRent += rentData[idList[i]].wbs_rent;
this.freeRent += rentData[idList[i]].free_rent;
this.sizePrivate += rentData[idList[i]].size_private;
}
} else {
this.wgRoomList = wgRoomList;
this.sizeShared = this.sizePrivate;
for (var i = 0; i < this.wgRoomList.length; i++) {
this.sizeShared -= this.wgRoomList[i].size;
for (var j = 0; j < this.wgRoomList.length; j++) {
this.sizeShared -= this.wgRoomList[j].size;
}
this.numPeople = numRooms - 1;
}
@@ -45,10 +57,16 @@ class Flat {
}
class Room {
constructor(name, size, numPeople = 1) {
constructor(name, numPeople = 1, id = null) {
this.name = name;
this.size = size;
this.numPeople = numPeople;
var key = id ? id : name;
this.sizePrivate = rentData[key].size_private;
this.sizeShared = rentData[key].size_shared;
this.minRent = rentData[key].min_rent;
this.freeRent = rentData[key].free_rent;
this.wbsRent = rentData[key].wbs_rent;
}
print() {
@@ -59,53 +77,53 @@ class Room {
export const flatData = {
"north": {
0: [
new Flat("W 0.1 (WG)", 4, 84.834, false, false, [
new Room("0.1 02", 12.523), new Room("0.1 03", 12.102), new Room("0.1 04", 14.746)
new Flat("W 0.1 (WG)", 4, false, false, [
new Room("0.1.02"), new Room("0.1.03"), new Room("0.1.04")
]),
new Flat("W 0.2", 2, 53.453, true),
new Flat("W 0.3", 3, 63.498, true)
new Flat("0.2", 2, true),
new Flat("0.3", 3, true)
],
1: [
new Flat("W 1.1", 4, 84.794, true),
new Flat("W 1.2", 1, 36.469, true),
new Flat("W 1.3 (WG)", 4, 63.128, true, false, [
new Room("1.3 02", 11.434), new Room("1.3 03", 11.245), new Room("1.3 04", 11.77)
new Flat("1.1", 4, true),
new Flat("1.2", 1, true),
new Flat("W 1.3 (WG)", 4, true, false, [
new Room("1.3.02"), new Room("1.3.03"), new Room("1.3.04")
])
],
2: [
new Flat("W 2.1", 4, 84.794, true),
new Flat("W 2.2", 2, 46.261, true),
new Flat("W 2.3 (Cluster)", 5, 154.196, true, true, [
new Room("1 Person", 28.774), new Room("2 Personen", 46.32, 2), new Room("1 Person (rollstuhlgerecht)", 41.814)
new Flat("2.1", 4, true),
new Flat("2.2", 2, true),
new Flat("W 2.3 (Cluster)", 5, true, true, [
new Room("1 Person", 1, "2.3.02"), new Room("2 Personen", 2, "2.3.05"), new Room("1 Person (rollstuhlgerecht)", 1, "2.3.09")
]),
new Flat("W 2.4", 2, 64.265, true, true)
new Flat("2.4", 2, true, true)
],
3: [
new Flat("W 3.1", 4, 84.794),
new Flat("W 3.2 (Cluster)", 5, 154.97, true, true, [
new Room("1 Person", 28.531), new Room("2 Personen", 47.146, 2), new Room("1 Person (rollstuhlgerecht)", 44.036)
new Flat("3.1", 4),
new Flat("W 3.2 (Cluster)", 5, true, true, [
new Room("1 Person", 1, "3.2.02"), new Room("2 Personen", 2, "3.2.05"), new Room("1 Person (rollstuhlgerecht)", 1, "3.2.09")
]),
new Flat("W 3.3", 3, 63.128, true)
new Flat("3.3", 3, true, false, null, ["3.3.02", "3.3.03", "3.3.04"])
]
},
"south": {
0: [
new Flat("W 0.4", 2, 54.905, true),
new Flat("W 0.5", 4, 83.416, true),
new Flat("W 0.6", 5, 107.733, true),
new Flat("0.4", 2, true),
new Flat("0.5", 4, true),
new Flat("0.6", 5, true),
],
1: [
new Flat("W 1.4", 2, 59.442),
new Flat("W 1.5 (WG)", 5, 89.209, true, false,
[new Room("1.5 02", 15.448), new Room("1.5 05", 11.489), new Room("1.5 06", 13.462)]
new Flat("1.4", 2),
new Flat("W 1.5 (WG)", 5, true, false,
[new Room("1.5.02"), new Room("1.5.03"), new Room("1.5.05"), new Room("1.5.06")]
),
new Flat("W 1.6.0", 1, 30.431),
new Flat("W 1.6", 5, 108.761),
new Flat("1.6.2", 1),
new Flat("1.6.1", 5),
],
2: [
new Flat("W 2.5", 2, 58.882, true),
new Flat("W 2.6", 4, 89.853, true),
new Flat("W 2.7", 5, 101.533)
new Flat("2.5", 2, true),
new Flat("2.6", 4, true),
new Flat("2.7", 5)
]
}
}

View File

@@ -28,7 +28,7 @@ import {
import { flatData } from './Data';
export function FlatSelectionCard({ setSelectedFlat, onRoomSelected, onNumAdultsSelected }) {
export function FlatSelectionCard({ setSelectedFlat, onRoomSelected }) {
const [levelOptions, setLevelOption] = useState([{ value: 0, label: "EG" }, { value: 1, label: "1. OG" }, { value: 2, label: "2. OG" }, { value: 3, label: "3. OG" }]);
const [flatOptions, setFlatOptions] = useState([]);
const [roomOptions, setRoomOptions] = useState([]);
@@ -69,9 +69,6 @@ export function FlatSelectionCard({ setSelectedFlat, onRoomSelected, onNumAdults
onRoomSelected(roomOptions[e.target.value]);
}
function numAdultsSelected(e) {
onNumAdultsSelected(e.target.value);
}
return <Card>
<CardHeader>
<Heading size='md'>Wohnungsauswahl</Heading>
@@ -89,12 +86,8 @@ export function FlatSelectionCard({ setSelectedFlat, onRoomSelected, onNumAdults
{flatOptions.map((flat, index) => <option value={index} >{flat.print()}</option>)}
</Select>
{roomOptions.length > 0 ? (<Select placeholder='Zimmer auswählen' onChange={roomSelected}>
{roomOptions.map((room, index) => <option value={index} >{room.print()} ({room.size} )</option>)}
{roomOptions.map((room, index) => <option value={index} >{room.print()} ({room.sizePrivate.toFixed(2)} )</option>)}
</Select>) : null}
<Select placeholder='Anzahl Erwachsene' onChange={numAdultsSelected}>
<option value="1">1 volljährige Person</option>
<option value="2">2 volljährige Personen</option>
</Select>
</Stack>
</CardBody>
</Card >
@@ -108,25 +101,26 @@ export function FlatDetailsCard({ flat, room, flatRent }) {
var badges = "";
if (flat && (flat.wgRoomList.length === 0 || room) && flatRent) {
var sizePrivate = flat.sizePrivate;
var freeRent = flat.freeRent;
var wbsRent = flat.wbsRent;
var minRent = flat.minRent;
if (room) {
sizePrivate = room.size;
freeRent = room.freeRent;
wbsRent = room.wbsRent;
minRent = room.minRent;
}
var sizeSharedBox = null;
var internalAreaShare = flat.calcInternalAreaShare(room);
var totalSizeToPay = flat.calcTotalPayedArea(room);
if (flat.wgRoomList.length > 0) {
var totalSizeToPay = room.sizePrivate + room.sizeShared;
sizeSharedBox = [
<Box>
<Heading size='xs' textTransform='uppercase'>
Anteil Interne Gemeinschaftsfläche (WG und Cluster)
</Heading>
<Text pt='2' fontSize='sm'>
{internalAreaShare.toFixed(2)}
{room.sizeShared.toFixed(2)}
</Text>
</Box >,
<Box>
@@ -134,7 +128,7 @@ export function FlatDetailsCard({ flat, room, flatRent }) {
Zahlfläche
</Heading>
<Text pt='2' fontSize='sm'>
{sizePrivate.toFixed(2)} + {internalAreaShare.toFixed(2)} (WG/Cluster-Fläche)
{room.sizePrivate.toFixed(2)} + {room.sizeShared.toFixed(2)} (WG/Cluster-Fläche)
</Text>
<Text pt={3} size='s' fontWeight='bold'>Gesamt: {totalSizeToPay.toFixed(2)} </Text>
</Box>
@@ -156,10 +150,10 @@ export function FlatDetailsCard({ flat, room, flatRent }) {
</Box>
<Box>
<Heading size='xs' textTransform='uppercase'>
Zimmeranzahl und Gesamtfläche
Zimmeranzahl {room ? "" : "und Gesamtfläche"}
</Heading>
<Text pt='2' fontSize='sm'>
{flat.numRooms} Zimmer, {flat.sizePrivate.toFixed(2)}
{flat.numRooms} Zimmer {room ? "" : " " + flat.sizePrivate.toFixed(2) + "m²"}
</Text>
</Box>
{sizeSharedBox}
@@ -167,28 +161,28 @@ export function FlatDetailsCard({ flat, room, flatRent }) {
<Heading size='xs' textTransform='uppercase'>
Standardmiete WBS
</Heading>
<Text fontSize="xs">Die Standardmiete ergibt sich aus dem WBS Satz für die private Fläche (9,45 /), den Nebenkosten (1,50 /), der Küchen-Nutzungspauschale von 50 pro Küche, sowie einem Beitrag von 60 pro volljähriger Person und wird WBS-Wohnungen/Zimmern automatisch zugewiesen, sollte die entsprechende Partei kein Gebot abgeben. <b>Mit der Standardmiete wäre das gesamte Haus finanziert, wenn wir keine Bieterunden durchführen würden.</b></Text>
<Text fontSize="xs">Die Standardmiete ergibt sich aus dem WBS Satz für die private Fläche, den Betriebskosten, der Küchen-Nutzungspauschale, den Abschlägen für Strom und Wasser sowie einem Gemeinschaftsflächenbeitrag und wird WBS-Wohnungen/Zimmern automatisch zugewiesen, sollte die entsprechende Partei kein Gebot abgeben. <b>Mit der Standardmiete wäre das gesamte Haus finanziert, wenn wir keine Bieterunden durchführen würden.</b></Text>
<Text pt='2' fontSize='xl' fontWeight='bold'>
{(flatRent.minCovering).toFixed(2)}
{(wbsRent).toFixed(2)}
</Text>
</Box>
<Box>
<Heading size='xs' textTransform='uppercase'>
Standardmiete freifinanziert {flat.isWbs ? "(zum Vergleich)" : ""}
</Heading>
<Text fontSize="xs">Die Standardmiete freifinanziert, wird analog zur Standardmiete WBS berechnet, wobei der Preis für die private Fläche 13,06 / beträgt. Sie wird frei finanzierten Wohnungen/Zimmern automatisch zugewiesen, sollte die entsprechende Partei kein Gebot abgeben. <b>Mit der Standardmiete wäre das gesamte Haus finanziert, wenn wir keine Bieterunden durchführen würden.</b></Text>
<Text fontSize="xs">Die Standardmiete freifinanziert, wird analog zur Standardmiete WBS berechnet, wobei der Flächenpreis für freifinanzierte Wohnungen genommen wird. Sie wird frei finanzierten Wohnungen/Zimmern automatisch zugewiesen, sollte die entsprechende Partei kein Gebot abgeben. <b>Mit der Standardmiete wäre das gesamte Haus finanziert, wenn wir keine Bieterunden durchführen würden.</b></Text>
<Text pt='2' fontSize='xl' fontWeight='bold'>
{(flatRent.maxCovering).toFixed(2)}
{(freeRent).toFixed(2)}
</Text>
</Box>
<Box>
<Heading size='xs' textTransform='uppercase'>
Mindestmiete
</Heading>
<Text fontSize="xs"> Die Mindestmiete stellt die untere Grenze dar, die für diese Wohnung geboten werden darf und berechnet sich aus der Standardmiete WBS - 15 %
<Text fontSize="xs">Die Mindestmiete stellt die untere Grenze dar, die für diese Wohnung geboten werden darf und berechnet sich aus der Standardmiete WBS - 15 %
</Text>
<Text pt='2' fontSize='xl' fontWeight='bold'>
{(flatRent.min).toFixed(2)}
{(minRent).toFixed(2)}
</Text>
</Box>
</Stack>
@@ -297,25 +291,33 @@ export function SelfEvaluationCard({ rent, setRent }) {
</Card>
}
export function ResultsCard({ rent, flat, room, numAdults, flatRent }) {
export function ResultsCard({ rent, flat, room, flatRent }) {
var body = <CardBody></CardBody>
if (rent && flat && (room || flat.wgRoomList.length === 0) && flatRent) {
var _wbsRent = flat.wbsRent;
var _freeRent = flat.freeRent;
var _minRent = flat.minRent;
if (room) {
_wbsRent = room.wbsRent;
_freeRent = room.freeRent;
_minRent = room.minRent;
}
var totalSize = flat.calcTotalPayedArea(room)
var relativeRent = (rent) / totalSize;
var status = "error", text = "Dieses Gebot läge unter der Mindestmiete und ist nicht zulässig";
if (rent >= flatRent.min) {
if (rent >= _minRent) {
status = 'info';
text = "Über der Mindestmiete. "
}
if (rent >= flatRent.minCovering) {
if (rent >= _wbsRent) {
status = 'success';
text = 'Über der Standardmiete WBS 🎉'
}
if (rent >= flatRent.maxCovering) {
if (rent >= _freeRent) {
status = 'success';
text = 'Über der Standardmiete freifinanziert! 🎉🎉🎉'
text = 'Über der Standardmiete freifinanziert 🎉🎉🎉'
}
body = <CardBody>