diff --git a/frontend/src/App.js b/frontend/src/App.js index 37ca3f1..c150853 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -3,6 +3,7 @@ import {BrowserRouter as Router, Route, Routes} from 'react-router-dom'; import NavbarComponent from "./components/NavbarComponent"; import CreateUserComponent from "./components/CreateUserComponent"; import Home from "./components/Home"; +import CreateTeamComponent from "./components/CreateTeamComponent"; const App = () => { return ( @@ -11,6 +12,8 @@ const App = () => { }/> }/> + }/> + }/> ) diff --git a/frontend/src/components/CreateTeamComponent.js b/frontend/src/components/CreateTeamComponent.js index b5775e9..c9c67dc 100644 --- a/frontend/src/components/CreateTeamComponent.js +++ b/frontend/src/components/CreateTeamComponent.js @@ -1,4 +1,4 @@ -import React, {useEffect, useState} from "react"; +import React, {useEffect, useRef, useState} from "react"; const useInput = (initialValue) => { const [value, setValue] = useState(initialValue); @@ -36,93 +36,169 @@ const useKeys = (init) => { return [keys, add, remove]; } +} - const User = ({validation, setValidation, dataToSend: data, position, onRemove}) => { +const User = ({validation, setValidation, dataToSend: data, position, onRemove}) => { + const roles = ['', 'DEVELOPER', 'LEAD']; + const [selectedRole, setSelectedRole] = useState(''); + let [errors, setErrors] = useState([]); - const roles = ['', 'DEVELOPER', 'LEAD']; - const [selectedRole, setSelectedRole] = useState(''); - let [errors, setErrors] = useState([]); + const { + value: username, + touched: touchedUsername, + setTouched: setTouchedUsername, + bind: bindUsername, + reset: resetUsername + } = useInput(''); + const { + value: password, + touched: touchedPassword, + setTouched: setTouchedPassword, + bind: bindPassword, + reset: resetPassword + } = useInput(''); - const { - value: username, - touched: touchedUsername, - setTouched: setTouchedUsername, - bind: bindUsername, - reset: resetUsername - } = useInput(''); - const { - value: password, - touched: touchedPassword, - setTouched: setTouchedPassword, - bind: bindPassword, - reset: resetPassword - } = useInput(''); + useEffect(() => { + let errorMessages = []; - useEffect(() => { - let errorMessages = []; + if (username.length < 4) { + errorMessages.push('username have wrong format'); + data[position].username = ''; + } else { + data[position].username = ''; + } - if (username.length < 4) { - errorMessages.push('username have wrong format'); - data[position].username = ''; - } else { - data[position].username = ''; - } + if (password.length < 4) { + errorMessages.push('password have wrong format'); + } else { + data[position].password = ''; + } - if (password.length < 4) { - errorMessages.push('password have wrong format'); - } else { - data[position].password = ''; - } + setValidation({...validation, [position]: errorMessages.length === 0}); - setValidation({...validation, [position]: errorMessages.length === 0}); + setErrors(errorMessages); - setErrors(errorMessages); - - return ( -
-

Create user

-
-
-
-
- - -
-
- - -
-
- { - SelectGroup({ - items: roles, - handleItemsChange: handleRolesChange, - groupName: 'Roles' - }) - } -
-
- - { -
- {errors.map(err =>
{err}
)} -
- } -
-
-
-
+ return ( +
+

New user

+
+ +
- ) - }) +
+ + +
+
+ { + SelectGroup({ + items: roles, + handleItemsChange: handleRolesChange, + groupName: 'Roles' + }) + } +
+
+ + { +
+ {errors.map(err =>
{err}
)} +
+ } +
+
+ ) + }) +} + +const CreateTeamComponent = () => { + + const [keys, add, remove] = useKeys(2); + + const dataToSend = useRef(keys.reduce((acc, value) => { + acc[value] = false; + return acc; + }, {})); + + const [validation, setValidation] = useState(keys.reduce((acc, value) => { + acc[value] = false; + return acc; + }, {})) + + let users = keys + .filter(key => key in dataToSend.current) + .map(key => ( + + )) + + const send = () => { + console.log(dataToSend.current); } -} \ No newline at end of file + + useEffect(() => { + setValidation(keys.reduce((acc, value) => { + acc[value] = value in validation ? validation[value] : false; + return acc; + }, {})) + + dataToSend.current = keys.reduce((acc, value) => { + acc[value] = value in dataToSend.current ? dataToSend.current[value] : { + username: '', + password: '', + role: '' + } + }) + + users = keys.map(key => ( + + )) + + }, [keys]) + + return ( +
+

Create team

+
+
+
+
+ {users} + + +
+
+
+
+
+ ); +} + +export default CreateTeamComponent; \ No newline at end of file diff --git a/frontend/src/components/CreateUserComponent.js b/frontend/src/components/CreateUserComponent.js index 35749dc..675af20 100644 --- a/frontend/src/components/CreateUserComponent.js +++ b/frontend/src/components/CreateUserComponent.js @@ -58,10 +58,6 @@ const CreateUserComponent = () => { const roles = ['', 'DEVELOPER', 'LEAD']; const [selectedRole, setSelectedRole] = useState(''); - const teams = ['', 'Team 1', 'Team 2', 'Team 3']; // TODO implement fetching of teams - const [selectedTeam, setSelectedTeam] = useState(''); - - const [error, setError] = useState({ userName: false, password: false, @@ -107,7 +103,6 @@ const CreateUserComponent = () => { setTouchedUsername(false); setTouchedPassword(false); setTouchedPasswordConfirmation(false); - setTouchedPasswordConfirmation(false); } const handleTeamsChange = (event) => { @@ -127,13 +122,16 @@ const CreateUserComponent = () => { axios .get(url) .then((response) => setData(response.data)) - .catch((error) => setError(error)) + .catch((err) => setAxiosError(err)) .finally(() => setLoaded(true)) }, []); - return [data, error, loaded]; + return [data, axiosError, loaded]; } - const teamsFromApi = useAxiosGet("http://localhost:8080/teams"); + const teamsFromApi = useAxiosGet("http://localhost:8080/teams/"); + + const teams = ['', 'Team 1', 'Team 2', 'Team 3']; // TODO implement fetching of teams + const [selectedTeam, setSelectedTeam] = useState(''); return (
@@ -206,6 +204,11 @@ const CreateUserComponent = () => {
+
+ { + teamsFromApi.map(team => team.toString()) + } +
diff --git a/frontend/src/eeee.js b/frontend/src/eeee.js new file mode 100644 index 0000000..6228cae --- /dev/null +++ b/frontend/src/eeee.js @@ -0,0 +1,163 @@ +import React, {useEffect, useRef, useState} from "react"; + +/* + Funkcja zarzadza generowaniem kluczy + Kazde dodanie lub usuniecie klucza z tablicy spowoduje przerenderowanie komponentow i + wygenerowanie formularza z kolejnymi kontaktami +*/ + +const useKeys = (init) => { + // Generowanie tablicy kluczy + let [keys, setKeys] = useState(Array(init).fill(0).map((value, pos) => pos + 1)); + + const add = () => setKeys(keys.concat(keys.length + 1)) + + const remove = (key) => { + let newKeys = [...keys]; + let index = newKeys.indexOf(key); + if (index !== -1) { + newKeys.splice(index, 1); + } + setKeys(newKeys); + } + + return [keys, add, remove]; +} + +const Contact = ({validation, setValidation, dataToSend: data, position, onRemove}) => { + let [name, setName] = useState(''); + let [email, setEmail] = useState(''); + let [errors, setErrors] = useState([]); + + // useEffect wykorzystamy do walidaowania + useEffect(() => { + let errorMessages = []; + + // Walidacja pola name + + if (!name || name.length < 3) { + errorMessages.push('Name is not correct'); + data[position].name = ''; + } else { + data[position].name = name; + } + + // Walidacja pola email + if (!email || email.length < 3) { + errorMessages.push('Email is not correct'); + } else { + data[position].email = email; + } + + // wysylamy info do stanu komponentu nadrzednego + setValidation({...validation, [position]: errorMessages.length === 0}) + + // Tutaj zmieniamy stan errors, zeby przechwycic bledy, ktore przytrafily sie do konkretnego + // walidowanego kontaktu + setErrors(errorMessages); + + }, [name, email]); + + return ( +
+
+ + setName(e.target.value)} + className="form-control" + /> +
+
+ + setEmail(e.target.value)} + className="form-control" + /> +
+
+ + { +
+ {errors.map(err =>
{err}
)} +
+ } +
+
+ ); +} + +const SixthComponentDynamicForm = () => { + + // TODO Zrobic opis do tego + + const [keys, add, remove] = useKeys(2); + + // Przygotowanie stanu, ktory nie bedzie powodowal renderowania, a bedzie + // przechowywal dane z pol name oraz email dla kazdego wygenerowanego komponentu Contact + const dataToSend = useRef(keys.reduce((acc, value) => { + acc[value] = {}; + return acc; + }, {})); + + const [validation, setValidation] = useState(keys.reduce((accum, value) => { + accum[value] = false; + return accum; + }, {})) + + let contacts = keys + .filter(key => key in dataToSend.current) + .map(key => ( + + )) + + const send = () => { + console.log(dataToSend.current); + } + + useEffect(() => { + setValidation(keys.reduce((accum, value) => { + accum[value] = value in validation ? validation[value] : false; + return accum; + }, {})) + + dataToSend.current = keys.reduce((accum, value) => { + accum[value] = value in dataToSend.current ? dataToSend.current[value] : {name: '', email: ''} + return accum; + }, {}) + + contacts = keys.map(key => ( + + )) + }, [keys]) + + return ( +
+ {contacts} + + +
+ ); +} + +export default SixthComponentDynamicForm;