Move all cards into their own components
This commit is contained in:
138
src/App.js
138
src/App.js
@@ -2,41 +2,23 @@ import { React, useState } from 'react';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
ChakraProvider,
|
ChakraProvider,
|
||||||
Text,
|
|
||||||
extendTheme,
|
extendTheme,
|
||||||
Select,
|
|
||||||
Card,
|
|
||||||
CardHeader,
|
|
||||||
Heading,
|
Heading,
|
||||||
CardBody,
|
|
||||||
Center,
|
Center,
|
||||||
SimpleGrid,
|
SimpleGrid,
|
||||||
Box,
|
Box,
|
||||||
Stack,
|
|
||||||
NumberInput,
|
|
||||||
NumberInputField,
|
|
||||||
Slider,
|
|
||||||
SliderFilledTrack,
|
|
||||||
SliderMark,
|
|
||||||
SliderTrack,
|
|
||||||
SliderThumb,
|
|
||||||
Tooltip
|
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
import { FlatDetails, ResultsCard } from './Solimieten';
|
import { FlatSelectionCard, FlatDetailsCard, SelfEvaluationCard, ResultsCard } from './Solimieten';
|
||||||
import { flatData } from './Data';
|
|
||||||
import { Nav } from './Nav';
|
import { Nav } from './Nav';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
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 [selectedBuilding, setSelectedBuilding] = useState();
|
|
||||||
const [selectedFlat, setSelectedFlat] = useState();
|
const [selectedFlat, setSelectedFlat] = useState();
|
||||||
|
|
||||||
const [income, setIncome] = useState(0);
|
const [rent, setRent] = useState(0);
|
||||||
|
|
||||||
const [sliderValue, setSliderValue] = useState(30)
|
|
||||||
const [showTooltip, setShowTooltip] = useState(false)
|
|
||||||
|
|
||||||
const theme = extendTheme({
|
const theme = extendTheme({
|
||||||
"colors": {
|
"colors": {
|
||||||
@@ -55,33 +37,6 @@ function App() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function buildingSelected(e) {
|
|
||||||
var newOptions;
|
|
||||||
if (e.target.value === "south") {
|
|
||||||
newOptions = [{ value: 0, label: "EG" }, { value: 1, label: "1. OG" }, { value: 2, label: "2. OG" }];
|
|
||||||
} else {
|
|
||||||
newOptions = [{ value: 0, label: "EG" }, { value: 1, label: "1. OG" }, { value: 2, label: "2. OG" }, { value: 3, label: "3. OG" }];
|
|
||||||
}
|
|
||||||
setLevelOption(newOptions);
|
|
||||||
setSelectedBuilding(e.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function levelSelected(e) {
|
|
||||||
var newData = flatData[selectedBuilding][e.target.value];
|
|
||||||
if (newData) {
|
|
||||||
setFlatOptions(flatData[selectedBuilding][e.target.value]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function flatSelected(e) {
|
|
||||||
var index = e.target.value;
|
|
||||||
|
|
||||||
setSelectedFlat(flatOptions[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatEuro = (val) => val + ' €';
|
|
||||||
const parseEuro = (val) => val.replace(/^€/, '')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -91,91 +46,18 @@ function App() {
|
|||||||
<Nav></Nav>
|
<Nav></Nav>
|
||||||
<Center>
|
<Center>
|
||||||
<SimpleGrid columns={2} spacing={4}>
|
<SimpleGrid columns={2} spacing={4}>
|
||||||
|
|
||||||
<Heading>Wohnung</Heading>
|
<Heading>Wohnung</Heading>
|
||||||
<Box></Box>
|
<Box></Box>
|
||||||
|
|
||||||
<Card>
|
<FlatSelectionCard setSelectedFlat={setSelectedFlat} />
|
||||||
<CardHeader>
|
<FlatDetailsCard flat={selectedFlat} />
|
||||||
<Heading size='md'>Wohnungsauswahl</Heading>
|
|
||||||
</CardHeader>
|
|
||||||
<CardBody>
|
|
||||||
<Stack spacing={4} w="500px">
|
|
||||||
<Select placeholder='Gebäude auswählen' onChange={buildingSelected}>
|
|
||||||
<option value='north'>Nordbau</option>
|
|
||||||
<option value='south'>Südbau</option>
|
|
||||||
</Select>
|
|
||||||
<Select placeholder='Etage auswählen' onChange={levelSelected}>
|
|
||||||
{levelOptions.map(({ value, label }, index) => <option value={value} >{label}</option>)}
|
|
||||||
</Select>
|
|
||||||
<Select placeholder='Wohnung auswählen' onChange={flatSelected}>
|
|
||||||
{flatOptions.map((flat, index) => <option value={index} >{flat.print()}</option>)}
|
|
||||||
</Select>
|
|
||||||
</Stack>
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
<FlatDetails flat={selectedFlat} />
|
|
||||||
|
|
||||||
<Heading>Selbsteinschätzung</Heading>
|
<Heading>Selbsteinschätzung</Heading>
|
||||||
<Box></Box>
|
<Box></Box>
|
||||||
|
|
||||||
<Card>
|
<SelfEvaluationCard rent={rent} setRent={setRent} />
|
||||||
<CardBody maxW={500}>
|
<ResultsCard rent={rent} flat={selectedFlat} />
|
||||||
<Stack spacing={3}>
|
|
||||||
<Text>Wie hoch ist euer/dein Haushaltsnetto? Beachtet dabei alle regelmäßigen Einkünfte wie Gehalt, Rente, Mieteinkünfte oder Kapitalerträge </Text>
|
|
||||||
<NumberInput
|
|
||||||
onChange={(valueString) => setIncome(parseEuro(valueString))}
|
|
||||||
value={formatEuro(income)}
|
|
||||||
>
|
|
||||||
<NumberInputField />
|
|
||||||
</NumberInput>
|
|
||||||
|
|
||||||
<Text>Wie viel Prozent eures/deines Nettoeinkommens kannst du für Miete aufbringen?</Text>
|
|
||||||
<Slider
|
|
||||||
id='slider'
|
|
||||||
defaultValue={30}
|
|
||||||
min={10}
|
|
||||||
max={50}
|
|
||||||
mb={5}
|
|
||||||
colorScheme='teal'
|
|
||||||
onChange={(v) => setSliderValue(v)}
|
|
||||||
onMouseEnter={() => setShowTooltip(true)}
|
|
||||||
onMouseLeave={() => setShowTooltip(false)}
|
|
||||||
>
|
|
||||||
<SliderMark value={10} mt='1' ml='-2.5' fontSize='sm'>
|
|
||||||
10%
|
|
||||||
</SliderMark>
|
|
||||||
<SliderMark value={20} mt='1' ml='-2.5' fontSize='sm'>
|
|
||||||
20%
|
|
||||||
</SliderMark>
|
|
||||||
<SliderMark value={30} mt='1' ml='-2.5' fontSize='sm'>
|
|
||||||
30%
|
|
||||||
</SliderMark>
|
|
||||||
<SliderMark value={40} mt='1' ml='-2.5' fontSize='sm'>
|
|
||||||
40%
|
|
||||||
</SliderMark>
|
|
||||||
<SliderMark value={50} mt='1' ml='-2.5' fontSize='sm'>
|
|
||||||
50%
|
|
||||||
</SliderMark>
|
|
||||||
<SliderTrack>
|
|
||||||
<SliderFilledTrack />
|
|
||||||
</SliderTrack>
|
|
||||||
<Tooltip
|
|
||||||
hasArrow
|
|
||||||
bg='teal.500'
|
|
||||||
color='white'
|
|
||||||
placement='top'
|
|
||||||
isOpen={showTooltip}
|
|
||||||
label={`${sliderValue}%`}
|
|
||||||
>
|
|
||||||
<SliderThumb />
|
|
||||||
</Tooltip>
|
|
||||||
|
|
||||||
|
|
||||||
</Slider>
|
|
||||||
</Stack>
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
<ResultsCard income={income} percentage={sliderValue} flat={selectedFlat} />
|
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
</Center>
|
</Center>
|
||||||
</ChakraProvider >
|
</ChakraProvider >
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
@@ -11,12 +12,71 @@ import {
|
|||||||
Stat,
|
Stat,
|
||||||
StatLabel,
|
StatLabel,
|
||||||
StatNumber,
|
StatNumber,
|
||||||
StatHelpText,
|
StatGroup,
|
||||||
StatArrow,
|
Select,
|
||||||
StatGroup
|
NumberInput,
|
||||||
|
NumberInputField,
|
||||||
|
Slider,
|
||||||
|
SliderFilledTrack,
|
||||||
|
SliderMark,
|
||||||
|
SliderTrack,
|
||||||
|
SliderThumb,
|
||||||
|
Tooltip
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
export function FlatDetails({ flat }) {
|
import { flatData } from './Data';
|
||||||
|
|
||||||
|
export function FlatSelectionCard({ setSelectedFlat }) {
|
||||||
|
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 [selectedBuilding, setSelectedBuilding] = useState();
|
||||||
|
|
||||||
|
function buildingSelected(e) {
|
||||||
|
var newOptions;
|
||||||
|
if (e.target.value === "south") {
|
||||||
|
newOptions = [{ value: 0, label: "EG" }, { value: 1, label: "1. OG" }, { value: 2, label: "2. OG" }];
|
||||||
|
} else {
|
||||||
|
newOptions = [{ value: 0, label: "EG" }, { value: 1, label: "1. OG" }, { value: 2, label: "2. OG" }, { value: 3, label: "3. OG" }];
|
||||||
|
}
|
||||||
|
setLevelOption(newOptions);
|
||||||
|
setSelectedBuilding(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
function levelSelected(e) {
|
||||||
|
var newData = flatData[selectedBuilding][e.target.value];
|
||||||
|
if (newData) {
|
||||||
|
setFlatOptions(flatData[selectedBuilding][e.target.value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function flatSelected(e) {
|
||||||
|
var index = e.target.value;
|
||||||
|
|
||||||
|
setSelectedFlat(flatOptions[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Card>
|
||||||
|
<CardHeader>
|
||||||
|
<Heading size='md'>Wohnungsauswahl</Heading>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<Stack spacing={4} w="500px">
|
||||||
|
<Select placeholder='Gebäude auswählen' onChange={buildingSelected}>
|
||||||
|
<option value='north'>Nordbau</option>
|
||||||
|
<option value='south'>Südbau</option>
|
||||||
|
</Select>
|
||||||
|
<Select placeholder='Etage auswählen' onChange={levelSelected}>
|
||||||
|
{levelOptions.map(({ value, label }, index) => <option value={value} >{label}</option>)}
|
||||||
|
</Select>
|
||||||
|
<Select placeholder='Wohnung auswählen' onChange={flatSelected}>
|
||||||
|
{flatOptions.map((flat, index) => <option value={index} >{flat.print()}</option>)}
|
||||||
|
</Select>
|
||||||
|
</Stack>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FlatDetailsCard({ flat }) {
|
||||||
var body = <CardBody>
|
var body = <CardBody>
|
||||||
Bitte auswählen
|
Bitte auswählen
|
||||||
</CardBody>;
|
</CardBody>;
|
||||||
@@ -78,10 +138,89 @@ export function FlatDetails({ flat }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ResultsCard({ income, percentage, flat }) {
|
export function SelfEvaluationCard({ rent, setRent }) {
|
||||||
|
|
||||||
|
const [sliderValue, setSliderValue] = useState(30)
|
||||||
|
const [showTooltip, setShowTooltip] = useState(false)
|
||||||
|
|
||||||
|
const [income, setIncome] = useState(1000)
|
||||||
|
|
||||||
|
const formatEuro = (val) => val + ' €';
|
||||||
|
const parseEuro = (val) => val.replace(/^€/, '')
|
||||||
|
|
||||||
|
|
||||||
|
function onIncomeChange(valueString) {
|
||||||
|
setIncome(parseEuro(valueString));
|
||||||
|
setRent(valueString * sliderValue / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSliderChange(value) {
|
||||||
|
setSliderValue(value);
|
||||||
|
setRent(income * value / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Card>
|
||||||
|
<CardBody maxW={500}>
|
||||||
|
<Stack spacing={3}>
|
||||||
|
<Text>Wie hoch ist euer/dein Haushaltsnetto? Beachtet dabei alle regelmäßigen Einkünfte wie Gehalt, Rente, Mieteinkünfte oder Kapitalerträge </Text>
|
||||||
|
<NumberInput
|
||||||
|
onChange={onIncomeChange}
|
||||||
|
value={formatEuro(income)}
|
||||||
|
>
|
||||||
|
<NumberInputField />
|
||||||
|
</NumberInput>
|
||||||
|
|
||||||
|
<Text>Wie viel Prozent eures/deines Nettoeinkommens kannst du für Miete aufbringen?</Text>
|
||||||
|
<Slider
|
||||||
|
id='slider'
|
||||||
|
defaultValue={30}
|
||||||
|
min={10}
|
||||||
|
max={50}
|
||||||
|
mb={5}
|
||||||
|
colorScheme='teal'
|
||||||
|
onChange={onSliderChange}
|
||||||
|
onMouseEnter={() => setShowTooltip(true)}
|
||||||
|
onMouseLeave={() => setShowTooltip(false)}
|
||||||
|
>
|
||||||
|
<SliderMark value={10} mt='1' ml='-2.5' fontSize='sm'>
|
||||||
|
10%
|
||||||
|
</SliderMark>
|
||||||
|
<SliderMark value={20} mt='1' ml='-2.5' fontSize='sm'>
|
||||||
|
20%
|
||||||
|
</SliderMark>
|
||||||
|
<SliderMark value={30} mt='1' ml='-2.5' fontSize='sm'>
|
||||||
|
30%
|
||||||
|
</SliderMark>
|
||||||
|
<SliderMark value={40} mt='1' ml='-2.5' fontSize='sm'>
|
||||||
|
40%
|
||||||
|
</SliderMark>
|
||||||
|
<SliderMark value={50} mt='1' ml='-2.5' fontSize='sm'>
|
||||||
|
50%
|
||||||
|
</SliderMark>
|
||||||
|
<SliderTrack>
|
||||||
|
<SliderFilledTrack />
|
||||||
|
</SliderTrack>
|
||||||
|
<Tooltip
|
||||||
|
hasArrow
|
||||||
|
bg='teal.500'
|
||||||
|
color='white'
|
||||||
|
placement='top'
|
||||||
|
isOpen={showTooltip}
|
||||||
|
label={`${sliderValue}%`}
|
||||||
|
>
|
||||||
|
<SliderThumb />
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
|
||||||
|
</Slider>
|
||||||
|
</Stack>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ResultsCard({ rent, flat }) {
|
||||||
var body = <CardBody></CardBody>
|
var body = <CardBody></CardBody>
|
||||||
if (flat) {
|
if (flat) {
|
||||||
var rent = income * percentage / 100;
|
|
||||||
var relativeRent = rent / flat.sizePrivate;
|
var relativeRent = rent / flat.sizePrivate;
|
||||||
body = <CardBody>
|
body = <CardBody>
|
||||||
<StatGroup>
|
<StatGroup>
|
||||||
@@ -92,7 +231,7 @@ export function ResultsCard({ income, percentage, flat }) {
|
|||||||
|
|
||||||
<Stat>
|
<Stat>
|
||||||
<StatLabel>Pro m²</StatLabel>
|
<StatLabel>Pro m²</StatLabel>
|
||||||
<StatNumber>{relativeRent.toFixed(2)} €</StatNumber>
|
<StatNumber>{relativeRent.toFixed(2)} € </StatNumber>
|
||||||
</Stat>
|
</Stat>
|
||||||
</StatGroup>
|
</StatGroup>
|
||||||
</CardBody>;
|
</CardBody>;
|
||||||
|
|||||||
Reference in New Issue
Block a user