Przeglądaj źródła

Umbau auf TSX statt JS.
Hinzufügen von Personen geht nun in React

Leonard Schulz (Arbeit) 2 lat temu
rodzic
commit
fec1640fca

+ 5 - 3
frontend_react/wbs-rechner-react/package-lock.json

@@ -11,6 +11,8 @@
         "@testing-library/jest-dom": "^5.17.0",
         "@testing-library/react": "^13.4.0",
         "@testing-library/user-event": "^13.5.0",
+        "@types/react": "^18.3.3",
+        "@types/react-dom": "^18.3.0",
         "react": "^18.3.0",
         "react-dom": "^18.3.0",
         "react-scripts": "5.0.1",
@@ -4461,9 +4463,9 @@
       "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="
     },
     "node_modules/@types/react": {
-      "version": "18.3.0",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.0.tgz",
-      "integrity": "sha512-DiUcKjzE6soLyln8NNZmyhcQjVv+WsUIFSqetMN0p8927OztKT4VTfFTqsbAi5oAGIcgOmOajlfBqyptDDjZRw==",
+      "version": "18.3.3",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz",
+      "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==",
       "dependencies": {
         "@types/prop-types": "*",
         "csstype": "^3.0.2"

+ 2 - 0
frontend_react/wbs-rechner-react/package.json

@@ -6,6 +6,8 @@
     "@testing-library/jest-dom": "^5.17.0",
     "@testing-library/react": "^13.4.0",
     "@testing-library/user-event": "^13.5.0",
+    "@types/react": "^18.3.3",
+    "@types/react-dom": "^18.3.0",
     "react": "^18.3.0",
     "react-dom": "^18.3.0",
     "react-scripts": "5.0.1",

+ 0 - 12
frontend_react/wbs-rechner-react/src/App.js

@@ -1,12 +0,0 @@
-
-import './App.css';
-
-function App() {
-  return (
-    <div className="App">
-      <h1>WBS Rechner</h1>
-    </div>
-  );
-}
-
-export default App;

+ 0 - 8
frontend_react/wbs-rechner-react/src/App.test.js

@@ -1,8 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import App from './App';
-
-test('renders learn react link', () => {
-  render(<App />);
-  const linkElement = screen.getByText(/learn react/i);
-  expect(linkElement).toBeInTheDocument();
-});

+ 98 - 0
frontend_react/wbs-rechner-react/src/App.tsx

@@ -0,0 +1,98 @@
+import React, { ChangeEvent } from "react";
+import "./App.css";
+import Headerbox from "./components/Headerbox";
+
+import { Income } from './interfaces/incomes';
+import { Person } from './interfaces/persons';
+
+
+interface AppState {
+  personanzahl : number;
+  persons: Person[];
+}
+
+class App extends React.Component<{}, AppState> {
+  constructor(props: {}) {
+    super(props);
+    this.state = {
+      personanzahl: 1,
+      persons: [{index: 1, incomes: [], totalincome: 0}]
+    };
+  }
+
+  render() {
+    return (
+      <div className="App">
+        <h1>WBS Rechner</h1>
+        <Headerbox title="Haushaltsmitglieder">
+          <div className="label-container">
+            <label htmlFor="personenanzahl">Anzahl Personen im Haushalt</label>
+            <input
+              value={this.state.personanzahl}
+              id="personenanzahl"
+              type="number"
+              min="1"
+              max="20"
+              onChange={this.updateInputValue}
+            />
+          </div>
+        </Headerbox>
+        {this.state.persons.map( p =>
+          <Headerbox title={'Daten der ' + p.index + '. Person'}>
+            <div></div>
+          </Headerbox>
+        )}
+      </div>
+    );
+  }
+
+  updateInputValue = (evt :  ChangeEvent<HTMLInputElement>) => {
+    this.setState({ personanzahl: evt.target.valueAsNumber });
+    this.refreshPeople(evt.target.valueAsNumber);
+  }
+
+  refreshPeople(personenanzahl: number ) {
+    if (personenanzahl > this.state.persons.length) {
+      let anzahl = personenanzahl - this.state.persons.length;
+      for (let i = 1; i <= anzahl; i++) {
+        this.addPerson();
+      }
+    } 
+
+    if (personenanzahl < this.state.persons.length) {
+      let anzahl = this.state.persons.length - personenanzahl;
+      for (let i = 1; i <= anzahl; i++) {
+        this.deletePerson(this.state.persons.length);
+      }
+    } 
+  }
+  
+  addPerson() {
+    const newPerson: Person = {
+      index: this.getHighestIndex(this.state.persons) + 1,
+      incomes: [],
+      totalincome: 0
+    };
+    this.setState(prevState => ({
+      persons: [...prevState.persons, newPerson]
+    }));
+  }
+
+  deletePerson(index: number) {
+    this.setState(prevState => ({
+      persons: prevState.persons.filter(person => person.index !== index)
+    }));
+  }
+
+  getHighestIndex(arr: Person[]) {
+    let highestIndex = 0;
+    for (const item of arr) {
+      if (item.index > highestIndex) {
+        highestIndex = item.index;
+      }
+    }
+    return highestIndex;
+  }
+}
+
+export default App;

+ 21 - 0
frontend_react/wbs-rechner-react/src/components/Headerbox.css

@@ -0,0 +1,21 @@
+.box {
+    border: 1px solid var(--highlight-color);
+    padding: 0px;
+    margin: 0px;
+    margin-top: 10px;
+    position: relative;
+  }
+  
+  .header {
+    display: flex;
+    background-color: var(--highlight-color);
+    padding: 2px;
+  }
+  
+  .toolbar {
+    display: flex;
+    position: absolute;
+    top: 0;
+    right: 0;
+  }
+  

+ 22 - 0
frontend_react/wbs-rechner-react/src/components/Headerbox.tsx

@@ -0,0 +1,22 @@
+import "./Headerbox.css";
+import React, { ReactNode } from "react";
+
+interface HeaderboxProps {
+  title: string;
+  children: ReactNode;
+}
+
+class Headerbox extends React.Component<HeaderboxProps> {
+  render() {
+    return (
+      <div className="box">
+        <div className="header">
+          <h2>{this.props.title}</h2>
+        </div>
+        {this.props.children}
+      </div>
+    );
+  }
+}
+
+export default Headerbox;

+ 0 - 0
frontend_react/wbs-rechner-react/src/components/Income.css


+ 12 - 0
frontend_react/wbs-rechner-react/src/components/Income.tsx

@@ -0,0 +1,12 @@
+import "./Income.css";
+import React from "react";
+import Headerbox from "./Headerbox.js";
+
+class Income extends React.Component {
+  render() {
+
+    return ("");
+  }
+}
+
+export default Headerbox;

+ 7 - 0
frontend_react/wbs-rechner-react/src/interfaces/incomes.ts

@@ -0,0 +1,7 @@
+export interface Income {
+    index: number,
+    amount: number,
+    frequency: number,
+    advertisingCosts: number,
+    type: number
+}

+ 7 - 0
frontend_react/wbs-rechner-react/src/interfaces/persons.ts

@@ -0,0 +1,7 @@
+import { Income } from './incomes';
+
+export interface Person {
+    index: number;
+    totalincome: number;
+    incomes: Array<Income>;
+}

+ 26 - 0
frontend_react/wbs-rechner-react/tsconfig.json

@@ -0,0 +1,26 @@
+{
+    "compilerOptions": {
+      "target": "es5",
+      "lib": [
+        "dom",
+        "dom.iterable",
+        "esnext"
+      ],
+      "allowJs": true,
+      "skipLibCheck": true,
+      "esModuleInterop": true,
+      "allowSyntheticDefaultImports": true,
+      "strict": true,
+      "forceConsistentCasingInFileNames": true,
+      "noFallthroughCasesInSwitch": true,
+      "module": "esnext",
+      "moduleResolution": "node",
+      "resolveJsonModule": true,
+      "isolatedModules": true,
+      "noEmit": true,
+      "jsx": "react"
+    },
+    "include": [
+      "src"
+    ]
+  }