diff --git a/.eslintrc b/.eslintrc index 9a5ce44..6a9769f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,6 +10,10 @@ "plugins": ["prettier"], "rules": { "prettier/prettier": "error", - "no-unused-vars": 1 - } + "no-unused-vars": 1, + "react/prop-types": 0 + }, + 'extends': [ + 'plugin:react/recommended' + ] } diff --git a/src/components/Router.jsx b/src/components/Router.jsx index 877766e..46130c8 100644 --- a/src/components/Router.jsx +++ b/src/components/Router.jsx @@ -6,51 +6,71 @@ import Team from '../views/Team' import Member from '../views/Member' import config from '../config.json' -history.listen(location => { - window.scrollTo(0,0) +history.listen(() => { + window.scrollTo(0, 0) }) -export default function Router(props) { - let [team, setTeam] = useState([]) - let [allTeams, setAllTeams] = useState([]) - let [users, setUsers] = useState([]) - let [memberProps, setMemberProps] = useState({}) - - let teamCallback = (el) => { - setTeam(el) - } +export default function Router() { + // let [team, setTeam] = useState([]) + let [allTeams, setAllTeams] = useState([]) + // let [users, setUsers] = useState([]) + let [memberProps, setMemberProps] = useState({}) + let [teamProps, setTeamProps] = useState({}) - let usersCallback = (el) => { - setUsers(el) - } + let teamCallback = (teamId, users) => { + // Remove this: + // setTeam(teamId) - let userIdCallback = (el) => { - setMemberProps({ - url: config.api + '/user/' + el, - teams: allTeams - }) - } + // Leave: + setTeamProps({ + url: config.api + '/team/' + teamId, + team: teamId, + users: users, + cb: userIdCallback + }) + } - let allTeamsCallback = (el) => { - setAllTeams(el) - } + let usersCallback = el => { + setUsers(el) + } - return ( - - - } - /> - } - /> - } - /> - - - ) + let userIdCallback = el => { + setMemberProps({ + url: config.api + '/user/' + el, + teams: allTeams + }) + } + + let allTeamsCallback = el => { + setAllTeams(el) + } + + // } + // /> + + return ( + + + ( + + )} + /> + + } /> + + } /> + + + ) } diff --git a/src/views/Member.jsx b/src/views/Member.jsx index 90bd4a2..5b7548b 100644 --- a/src/views/Member.jsx +++ b/src/views/Member.jsx @@ -1,78 +1,78 @@ // MARK: Definitions import React, { useState, useEffect } from 'react' import axios from 'axios' -import history from '../history.js' +import history from '../history.js' // import config from '../config.json' import './Member.scss' export default function Member({ props }) { - // MARK: State - let [user, setUser] = useState(null) - let [teamNames, setTeamNames] = useState([]) + // MARK: State + let [user, setUser] = useState(null) + let [teamNames, setTeamNames] = useState([]) - // MARK: Effects - // MARK: - Load user info from Tempo backend on initialization - useEffect(() => { - let fetchData = async() => { - try { - let result = await axios.get(props.url) - if (result.data) { - setUser(result.data) + // MARK: Effects + // MARK: - Load user info from Tempo backend on initialization + useEffect(() => { + let fetchData = async () => { + try { + let result = await axios.get(props.url) + if (result.data) { + setUser(result.data) - result.data.member_teams.map(teamId => { - let arr = props.teams.filter(el => el.id === teamId) - setTeamNames(t => [...t, arr[0].name]) + result.data.member_teams.map(teamId => { + let arr = props.teams.filter(el => el.id === teamId) + setTeamNames(t => [...t, arr[0].name]) - return null - }) - } - } - catch(err) { - history.push('/') - } - } + return null + }) + } + } catch (err) { + history.push('/') + } + } - fetchData() - }, [props]) + fetchData() + }, [props]) - // MARK: Helpers - let navBack = () => { - history.push('/team') - } + // MARK: Helpers + let navBack = () => { + history.push('/team') + } - // MARK: Return - return ( -
+ // MARK: Return + return ( +
+ {user === null ? ( +
Loading...
+ ) : ( + user !== undefined && ( +
+
+ +

Member {user.name}

+
+
- {user === null ? (
Loading...
) : ( - user !== undefined && -
-
-

Member {user.name}

-
+
+ +
-
- -
+

Username:

+
+

{user.username}

+
-

Username:

-
-

{user.username}

-
- -

Member of:

-
    - {teamNames.map((name, index) => ( -
  • -
    - {name} -
    -
  • - ))} -
-
- )} - -
- ) +

Member of:

+
    + {teamNames.map((name, index) => ( +
  • +
    {name}
    +
  • + ))} +
+
+ ) + )} +
+ ) } diff --git a/src/views/Member.test.js b/src/views/Member.test.js index 02dffdc..4db771a 100644 --- a/src/views/Member.test.js +++ b/src/views/Member.test.js @@ -5,27 +5,29 @@ import '@testing-library/react/cleanup-after-each' import axiosMock from 'axios' import Member from './Member' -it('Renders without crashing', () => { - const { getByTestId } = render() - expect(getByTestId('loading')).toHaveTextContent('Loading...') -}) - -it('Fetches and displays data', async () => { - const callData = { - username: 'goodpanda', - member_teams: [3], - lead_teams: [], - id: 15, - name: 'Charlotte Amsterdan' - } - - axiosMock.get.mockResolvedValueOnce({ data: callData }) - - const address = { url: '/user15' } - const { getByTestId } = render() - const resolvedSpan = await waitForElement(() => getByTestId('resolved')) - - expect(resolvedSpan).toHaveTextContent('Member ' + callData.name) - expect(axiosMock.get).toHaveBeenCalledTimes(1) - expect(axiosMock.get).toHaveBeenCalledWith(address.url) +describe('A members page', () => { + it('should render without crashing', () => { + const { getByTestId } = render() + expect(getByTestId('loading')).toHaveTextContent('Loading...') + }) + + it('should fetch and display data', async () => { + const callData = { + username: 'goodpanda', + member_teams: [3], + lead_teams: [], + id: 15, + name: 'Charlotte Amsterdan' + } + + axiosMock.get.mockResolvedValueOnce({ data: callData }) + + const address = { url: '/user15' } + const { getByTestId } = render() + const resolvedSpan = await waitForElement(() => getByTestId('resolved')) + + expect(resolvedSpan).toHaveTextContent('Member ' + callData.name) + expect(axiosMock.get).toHaveBeenCalledTimes(1) + expect(axiosMock.get).toHaveBeenCalledWith(address.url) + }) }) diff --git a/src/views/Team.jsx b/src/views/Team.jsx index b6b3c5f..22237f0 100644 --- a/src/views/Team.jsx +++ b/src/views/Team.jsx @@ -1,127 +1,123 @@ // MARK: Definitions import React, { useState, useEffect } from 'react' import axios from 'axios' -import history from '../history.js' -import config from '../config.json' +import history from '../history.js' import FilterForm from '../components/FilterForm.jsx' import './Team.scss' -// teamProps, usersProps, userIdCallback export default function Team(props) { - // MARK: State - let [loading, setLoading] = useState(true) - let [team, setTeam] = useState([]) - let [members, setMembers] = useState([]) - let [filteredMembers, setFilteredMembers] = useState([]) + // MARK: State + let [team, setTeam] = useState([]) + let [members, setMembers] = useState([]) + let [filteredMembers, setFilteredMembers] = useState([]) - // MARK: Effect - // MARK: - Load user info from Tempo backend on initialization - useEffect(() => { - let fetchData = async() => { - setLoading(true) - try { - let result = await axios(config.api + '/team/' + props.teamProps.id) - if (result.data) { - setTeam(result.data) + // MARK: Effect + // MARK: - Load user info from Tempo backend on initialization + useEffect(() => { + let fetchData = async () => { + try { + let result = await axios(props.url) + if (result.data) { + setTeam(result.data) - result.data.members.map(memberId => { - let arr = props.usersProps.filter(el => el.id === memberId) - if (arr[0] !== undefined) { - let tupple = { - name: arr[0].name, - id: memberId - } - setMembers(t => [...t, tupple]) - setFilteredMembers(t => [...t, tupple]) - } - else { - history.push('/') - } + result.data.members.map(memberId => { + let arr = props.users.filter(el => el.id === memberId) + if (arr[0] !== undefined) { + let tupple = { + name: arr[0].name, + id: memberId + } + setMembers(t => [...t, tupple]) + setFilteredMembers(t => [...t, tupple]) + } else { + history.push('/') + } - return null - }) - } - else { - history.push('/') - } - setLoading(false) - } - catch(err) { - setLoading(false) - console.log('Fetch data error: ' + err) - } - } + return null + }) + } else { + history.push('/') + } + } catch (err) { + console.log('Fetch data error: ' + err) + } + } - fetchData() - }, [props]) + fetchData() + }, [props]) - // MARK: Helpers - let userData = (userId) => { - let arr = props.usersProps.filter(el => el.id === userId) - if (arr[0] !== undefined) { - return arr[0].name - } - else { - history.push('/') - } - } + // MARK: Helpers + let userData = userId => { + if (props.users === undefined) { + history.push('/') + } else { + let arr = props.users.filter(el => el.id === userId) - let selectUser = (id) => { - props.userIdCallback(id) - history.push('/member') - } + if (arr[0] !== undefined) { + return arr[0].name + } else { + history.push('/') + } + } + } - let filterCallback = (e) => { - let filtered = members.filter(member => { - return member.name.toUpperCase().includes(e.target.value.toUpperCase()) - }) + let selectUser = id => { + props.cb(id) + history.push('/member') + } - setFilteredMembers(filtered) - } + let filterCallback = e => { + let filtered = members.filter(member => { + return member.name.toUpperCase().includes(e.target.value.toUpperCase()) + }) - let navBack = () => { - history.push('/') - } + setFilteredMembers(filtered) + } - // MARK: Return - return ( -
+ let navBack = () => { + history.push('/') + } - {props.teamProps !== undefined && -
-

Team {props.teamProps.name}

-
- } + // MARK: Return + return ( +
+ {props.team !== undefined && ( +
+

Team {props.team.name}

+
+ )} -
- -
+
+ +
- + - {loading ? (
Loading...
) : ( - team !== undefined && -
-

Team lead

+ {team.length == 0 ? ( +
Loading...
+ ) : ( + team !== undefined && ( +
+

Team lead

- + -

Team members

+

Team members

-
    - {filteredMembers.map((member, index) => ( -
  • - -
  • - ))} -
-
- )} - -
- ) +
    + {filteredMembers.map((member, index) => ( +
  • + +
  • + ))} +
+
+ ) + )} +
+ ) } diff --git a/src/views/Team.test.js b/src/views/Team.test.js new file mode 100644 index 0000000..2b57f72 --- /dev/null +++ b/src/views/Team.test.js @@ -0,0 +1,31 @@ +import React from 'react' +import { render, waitForElement } from '@testing-library/react' +import '@testing-library/jest-dom/extend-expect' +import '@testing-library/react/cleanup-after-each' +import axiosMock from 'axios' +import Team from './Team' + +describe('A team page', () => { + it('should render without crashing', () => { + const { getByTestId } = render() + + expect(getByTestId('loading')).toHaveTextContent('Loading...') + }) + + it('should fetch and display data', async () => { + const callData = { + teamProps: { + id: 3 + }, + usersProps: [{ name: 'UserName' }] + } + + axiosMock.get.mockResolvedValueOnce({ data: callData }) + + const address = { url: '/team3' } + const { getByTestId } = render() + const resolvedSpan = await waitForElement(() => getByTestId('resolved')) + + expeted(resolvedSpan).toHaveContent('Team') + }) +}) diff --git a/src/views/__mocks__/axios.js b/src/views/__mocks__/axios.js index 2bd6c6f..02dad99 100644 --- a/src/views/__mocks__/axios.js +++ b/src/views/__mocks__/axios.js @@ -1,3 +1,3 @@ export default { - get: jest.fn().mockResolvedValue({ data: {} }) + get: jest.fn().mockResolvedValue({ data: {} }) }