Last_Dance
This commit is contained in:
42
ubung4_time/lab07/src/App.jsx
Normal file
42
ubung4_time/lab07/src/App.jsx
Normal file
@ -0,0 +1,42 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import Input from "./Input.jsx";
|
||||
import Output from "./Output.jsx";
|
||||
|
||||
function App() {
|
||||
const [seconds, setSeconds] = useState(0);
|
||||
|
||||
const textLength = useSelector((state)=>state.textLength);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
const startTime = Date.now();
|
||||
|
||||
const id = setInterval(() => {
|
||||
const timeDiffInSeconds = (Date.now()-startTime) / 1000;
|
||||
const roundedSeconds = Math.floor(timeDiffInSeconds);
|
||||
setSeconds(roundedSeconds);
|
||||
}, 1000);
|
||||
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (seconds > 0) {
|
||||
const avgCharsPerSecond = textLength / seconds;
|
||||
dispatch({
|
||||
type: "setAvgCharsPerSecond",
|
||||
payload: avgCharsPerSecond
|
||||
});
|
||||
}
|
||||
}, [seconds,textLength,dispatch]); // dispatch-Abhängigkeit bleibt absichtlich als null für deine Übung
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<Input />
|
||||
<Output passedSeconds={seconds} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
23
ubung4_time/lab07/src/Input.jsx
Normal file
23
ubung4_time/lab07/src/Input.jsx
Normal file
@ -0,0 +1,23 @@
|
||||
import React from "react";
|
||||
import "./TextInput.css";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
export default function Input() {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleChange = (event) => {
|
||||
const inputText = event.target.value;
|
||||
const length = inputText.length;
|
||||
dispatch({
|
||||
type: "changeTextAndLength",
|
||||
inputText: inputText,
|
||||
inputTextLength: length,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<input className="NiceInput" type="text" onChange={handleChange} />
|
||||
</div>
|
||||
);
|
||||
}
|
10
ubung4_time/lab07/src/Output.css
Normal file
10
ubung4_time/lab07/src/Output.css
Normal file
@ -0,0 +1,10 @@
|
||||
.show {
|
||||
background-color:rgb(255, 233, 133);
|
||||
height: 50;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
border-collapse:collapse;
|
||||
border: 1px #000 solid;
|
||||
width: 100%;
|
||||
}
|
||||
|
15
ubung4_time/lab07/src/Output.jsx
Normal file
15
ubung4_time/lab07/src/Output.jsx
Normal file
@ -0,0 +1,15 @@
|
||||
import { useSelector } from "react-redux";
|
||||
import "./Output.css";
|
||||
|
||||
export default function Output({passedSeconds}) {
|
||||
const state = useSelector((state) => state);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="show">{state.text}</div>
|
||||
<div className="show">Anzahl der Zeichen: {state.textLength}</div>
|
||||
<div className="show">Sekunde: {passedSeconds}</div>
|
||||
<div className="show">Zeichen pro Sekunde: {state.avgCharsPerSecond.toFixed(2)}</div>
|
||||
</>
|
||||
);
|
||||
}
|
10
ubung4_time/lab07/src/TextInput.css
Normal file
10
ubung4_time/lab07/src/TextInput.css
Normal file
@ -0,0 +1,10 @@
|
||||
.NiceInput {
|
||||
border-radius: 16px;
|
||||
padding: 10px;
|
||||
margin: auto;
|
||||
background-color:#AEA;
|
||||
font-size: 24px;
|
||||
width:90%;
|
||||
}
|
||||
|
||||
|
13
ubung4_time/lab07/src/index.css
Normal file
13
ubung4_time/lab07/src/index.css
Normal file
@ -0,0 +1,13 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
13
ubung4_time/lab07/src/index.js
Normal file
13
ubung4_time/lab07/src/index.js
Normal file
@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import { Provider } from 'react-redux';
|
||||
import store from './store';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>
|
||||
);
|
12
ubung4_time/lab07/src/main.jsx
Normal file
12
ubung4_time/lab07/src/main.jsx
Normal file
@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import { Provider } from 'react-redux';
|
||||
import store from './store';
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>
|
||||
);
|
25
ubung4_time/lab07/src/reducer.js
Normal file
25
ubung4_time/lab07/src/reducer.js
Normal file
@ -0,0 +1,25 @@
|
||||
const initialState = {
|
||||
text: "",
|
||||
textLength: 0,
|
||||
avgCharsPerSecond: 0,
|
||||
};
|
||||
|
||||
export default function appReducer(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case "changeTextAndLength": {
|
||||
return {
|
||||
...state,
|
||||
text: action.inputText,
|
||||
textLength: action.inputTextLength,
|
||||
};
|
||||
}
|
||||
case "setAvgCharsPerSecond": {
|
||||
return {
|
||||
...state,
|
||||
avgCharsPerSecond: action.payload,
|
||||
};
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
6
ubung4_time/lab07/src/store.js
Normal file
6
ubung4_time/lab07/src/store.js
Normal file
@ -0,0 +1,6 @@
|
||||
import appReducer from "./reducer.js";
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
|
||||
const store = configureStore({ reducer: appReducer });
|
||||
|
||||
export default store;
|
Reference in New Issue
Block a user