Browse Source

unit tests for stats and users page on frontend

pull/158/head
Dzenis Hadzifejzovic 3 years ago
parent
commit
4b17fb13d5

+ 49
- 8
src/__tests__/ReduxTests/statsPageReducer.test.js View File

import { mockState } from "../../mockState"; import { mockState } from "../../mockState";
import { render } from "@testing-library/react"; import { render } from "@testing-library/react";
import StatsPage from "../../pages/StatsPage/StatsPage"; import StatsPage from "../../pages/StatsPage/StatsPage";
import * as api from "../../request/usersRequest";
import * as api from "../../request/statsRequests";
import { runSaga } from "redux-saga"; import { runSaga } from "redux-saga";
import { FETCH_TECHNOLOGIES_REQ } from "../../store/actions/technologies/technologiesActionConstants";
import { getTechnologies } from "../../store/saga/technologiesSaga";
import { import {
setTechnologies,
setTechnologiesError,
} from "../../store/actions/technologies/technologiesActions";
getStatsSuccess,
getStatsError,
} from "../../store/actions/stats/statsActions";
import { FETCH_STATS_REQ } from "../../store/actions/stats/statsActionConstants"; import { FETCH_STATS_REQ } from "../../store/actions/stats/statsActionConstants";
import { setUsersError } from "../../store/actions/users/usersActions";
import { getUsers } from "../../store/saga/usersSaga";
import { getAppStats } from "../../store/saga/statsSaga";
import * as helper from "../../util/helpers/rejectErrorCodeHelper";


describe("Stats reducer tests", () => { describe("Stats reducer tests", () => {
const cont = ( const cont = (
type: FETCH_STATS_REQ, type: FETCH_STATS_REQ,
}); });
}); });

it("should load and handle stats in case of success", async () => {
const dispatchedActions = [];

const mockedCall = { data: mockState };
api.getStats = jest.fn(() => Promise.resolve(mockedCall));

const fakeStore = {
getState: () => mockState,
dispatch: (action) => dispatchedActions.push(action),
};

await runSaga(fakeStore, getAppStats).done;
expect(api.getStats.mock.calls.length).toBe(1);
expect(dispatchedActions).toContainEqual(getStatsSuccess(mockedCall.data));
});

it("should handle stats load errors in case of failure", async () => {
const dispatchedActions = [];

helper.rejectErrorCodeHelper = jest.fn(
() => mockState.stats.fetchStatsErrorMessage
);

const error = {
response: {
data: { message: mockState.stats.fetchStatsErrorMessage },
},
};
api.getStats = jest.fn(() => Promise.reject(error));

const fakeStore = {
getState: () => mockState,
dispatch: (action) => dispatchedActions.push(action),
};

await runSaga(fakeStore, getAppStats).done;

expect(api.getStats.mock.calls.length).toBe(1);
expect(dispatchedActions).toContainEqual(
getStatsError(error.response.data.message)
);
});
}); });

+ 96
- 0
src/__tests__/ReduxTests/usersPageReducer.test.js View File

import * as redux from "react-redux";
import store from "../../store";
import { Router } from "react-router-dom";
import history from "../../store/utils/history";
import { mockState } from "../../mockState";
import { render } from "@testing-library/react";
import * as api from "../../request/usersRequest";
import { runSaga } from "redux-saga";
import {
setUsers,
setUsersError,
} from "../../store/actions/users/usersActions";
import { FETCH_USERS_REQ } from "../../store/actions/users/usersActionConstants";
import { getUsers } from "../../store/saga/usersSaga";
import * as helper from "../../util/helpers/rejectErrorCodeHelper";
import UsersPage from "../../pages/UsersPage/UsersPage";

describe("UsersPage reducer tests", () => {
const cont = (
<redux.Provider store={store}>
<Router history={history}>
<UsersPage />
</Router>
</redux.Provider>
);

let spyOnUseSelector;
let spyOnUseDispatch;
let mockDispatch;

beforeEach(() => {
// Mock useSelector hook
spyOnUseSelector = jest.spyOn(redux, "useSelector");
spyOnUseSelector.mockReturnValueOnce(mockState.users);

// Mock useDispatch hook
spyOnUseDispatch = jest.spyOn(redux, "useDispatch");

// Mock dispatch function returned from useDispatch
mockDispatch = jest.fn();
spyOnUseDispatch.mockReturnValue(mockDispatch);
});

afterEach(() => {
jest.restoreAllMocks();
});

it("Should dispatch get users request when rendered", () => {
render(cont);
expect(mockDispatch).toHaveBeenCalledWith({
type: FETCH_USERS_REQ,
});
});

it("should load and handle users in case of success", async () => {
const dispatchedActions = [];

const mockedCall = { data: mockState.users };
api.getAllUsers = jest.fn(() => Promise.resolve(mockedCall));

const fakeStore = {
getState: () => mockState.users,
dispatch: (action) => dispatchedActions.push(action),
};

await runSaga(fakeStore, getUsers).done;
expect(api.getAllUsers.mock.calls.length).toBe(1);
expect(dispatchedActions).toContainEqual(setUsers(mockedCall.data));
});

it("should handle users load errors in case of failure", async () => {
const dispatchedActions = [];

helper.rejectErrorCodeHelper = jest.fn(
() => mockState.users.fetchUsersErrorMessage
);

const error = {
response: {
data: { message: mockState.users.fetchUsersErrorMessage },
},
};
api.getAllUsers = jest.fn(() => Promise.reject(error));

const fakeStore = {
getState: () => mockState.users,
dispatch: (action) => dispatchedActions.push(action),
};

await runSaga(fakeStore, getUsers).done;
expect(api.getAllUsers.mock.calls.length).toBe(1);
expect(dispatchedActions).toContainEqual(
setUsersError(error.response.data.message)
);
});
});

+ 2
- 1
src/__tests__/UITests/candidatesPageUI.test.js View File



beforeEach(() => { beforeEach(() => {
spyOnUseSelector = jest.spyOn(redux, "useSelector"); spyOnUseSelector = jest.spyOn(redux, "useSelector");
spyOnUseSelector.mockReturnValueOnce(mockState.technologies.technologies);
spyOnUseSelector
.mockReturnValueOnce(mockState.technologies.technologies)
}); });


afterEach(() => { afterEach(() => {

+ 17
- 7
src/__tests__/UITests/dayDetailsComponentUI.test.js View File

import store from "../../store"; import store from "../../store";
import { Router } from "react-router-dom"; import { Router } from "react-router-dom";
import { mockState } from "../../mockState"; import { mockState } from "../../mockState";
import { render, screen } from "@testing-library/react";
import { render, screen, fireEvent } from "@testing-library/react";
import history from "../../store/utils/history"; import history from "../../store/utils/history";
import DayDetailsComponent from "../../components/Schedules/DayDetailsComponent"; import DayDetailsComponent from "../../components/Schedules/DayDetailsComponent";
import ColorModeProvider from "../../context/ColorModeContext"; import ColorModeProvider from "../../context/ColorModeContext";
setCurrentlySelectedDay: jest.fn(), setCurrentlySelectedDay: jest.fn(),
currentlySelectedDay: 1, currentlySelectedDay: 1,
numberOfDaysInMonth: 31, numberOfDaysInMonth: 31,
history: {
replace: jest.fn(),
push: jest.fn(),
location: {
pathname: "/schedule",
},
},
}; };


describe("DayDetailsComponent render tests", () => { describe("DayDetailsComponent render tests", () => {


it("Should render left arrow as disabled because we set that currenlty selected day is first day of month", () => { it("Should render left arrow as disabled because we set that currenlty selected day is first day of month", () => {
render(cont); render(cont);
expect(
screen.getAllByTestId("day-datails-left-arrow")[0]
).toBeDefined();
expect(screen.getAllByTestId("day-details-left-arrow")[0]).toBeDefined();
}); });


it("Should render right arrow as enabled because we set that currenlty selected day is first day of month", () => { it("Should render right arrow as enabled because we set that currenlty selected day is first day of month", () => {
render(cont); render(cont);
expect(
screen.getAllByTestId("day-datails-right-arrow")[0]
).toBeDefined();
expect(screen.getAllByTestId("day-details-right-arrow")[0]).toBeDefined();
}); });


it("Should show all interviews which we pass to component", () => { it("Should show all interviews which we pass to component", () => {
mockState.schedule.schedule.length mockState.schedule.schedule.length
); );
}); });

it("Should render candidate details page after clicking on candidate name", () => {
render(cont);
fireEvent.click(screen.getAllByTestId("day-details-applicant")[0]);
const arg = { pathname: "/candidates/1" };
expect(props.history.push).toHaveBeenCalledWith(arg);
});
}); });

+ 16
- 1
src/__tests__/UITests/schedulePageUI.test.js View File

import { render, fireEvent, screen } from "@testing-library/react";
import { render, fireEvent, screen, waitFor } from "@testing-library/react";
import * as redux from "react-redux"; import * as redux from "react-redux";
import store from "../../store"; import store from "../../store";
import { mockState } from "../../mockState"; import { mockState } from "../../mockState";
beforeEach(() => { beforeEach(() => {
spyOnUseSelector = jest.spyOn(redux, "useSelector"); spyOnUseSelector = jest.spyOn(redux, "useSelector");
spyOnUseSelector spyOnUseSelector
.mockReturnValueOnce(mockState.schedule.schedule)
.mockReturnValueOnce(mockState.schedule.schedule) .mockReturnValueOnce(mockState.schedule.schedule)
.mockReturnValueOnce(mockState.schedule.schedule); .mockReturnValueOnce(mockState.schedule.schedule);
}); });
); );
expect(screen.getByTestId("day-component-dialog")).toBeDefined(); expect(screen.getByTestId("day-component-dialog")).toBeDefined();
}); });

// it("After clicking on right arrow of DayDetailsComponent should be rendered new day", async () => {
// const { container } = render(cont);
// fireEvent.click(
// container.getElementsByClassName("day-component-container")[0]
// );
// fireEvent.click(screen.getByTestId("day-details-right-arrow"));
// expect(screen.getByTestId("day-details-component-process")).toBeDefined();
// await waitFor(() =>
// expect(screen.getByTestId("day-details-applicant").textContent).toBe(
// "Meris Ahmatovic"
// )
// );
// });
}); });

+ 92
- 0
src/__tests__/UITests/statsPageUI.test.js View File

import * as redux from "react-redux";
import store from "../../store";
import { Router } from "react-router-dom";
import { mockState } from "../../mockState";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import history from "../../store/utils/history";
import StatsPage from "../../pages/StatsPage/StatsPage";

describe("StatsPage render tests", () => {
const cont = (
<redux.Provider store={store}>
<Router history={history}>
<StatsPage />
</Router>
</redux.Provider>
);

let spyOnUseSelector;

beforeEach(() => {
spyOnUseSelector = jest.spyOn(redux, "useSelector");
spyOnUseSelector.mockReturnValueOnce(mockState);
});

afterEach(() => {
jest.restoreAllMocks();
});

it("Should render", () => {
const { container } = render(cont);
expect(container.getElementsByClassName("stats-section")[0]).toBeDefined();
});

it("Should render 4 levels for selection process section", () => {
render(cont);
expect(screen.getAllByTestId("stats-item").length).toBe(4);
});

it("Should render 4 levels for relationship section", () => {
render(cont);
expect(screen.getAllByTestId("stats-item2").length).toBe(4);
});

it("Should render ads because there is more than 0 ads", () => {
const { container } = render(cont);
expect(container.getElementsByClassName("archived-ads")[0]).toBeDefined();
});

it("Should render only one right arrow and that depends on screen size", () => {
render(cont);
expect(screen.getAllByTestId("right-arrow").length).toBe(1);
});

it("Should render right arrow because there is more than 3 ads", () => {
render(cont);
expect(screen.getAllByTestId("right-arrow")[0]).toBeDefined();
});

it("Should render only one left arrow and that depends on screen size", () => {
render(cont);
expect(screen.getAllByTestId("left-arrow").length).toBe(1);
});

it("Should render all ads in slider", () => {
const { container } = render(cont);
expect(container.getElementsByClassName("stats-ad").length).toBe(
mockState.stats.ads.length
);
});

it("Slider should represent 5 ads", () => {
const { container } = render(cont);
expect(
container
.getElementsByClassName("slick-list")[0]
.getElementsByClassName("slick-active").length
).toBe(5);
});

it("After clicking on right arrow slider should represent ad number six as fifth ad in slider", async () => {
const { container } = render(cont);
fireEvent.click(screen.getAllByTestId("right-arrow")[0]);
await waitFor(() =>
expect(
container
.getElementsByClassName("slick-list")[0]
.getElementsByClassName("slick-active")[4]
.getElementsByClassName("archive-ad-title")[0].textContent
).toBe("React")
);
});
});

+ 5
- 3
src/__tests__/UITests/tableViewPageUI.test.js View File

import { render, screen, fireEvent,waitFor } from "@testing-library/react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import * as redux from "react-redux"; import * as redux from "react-redux";
import store from "../../store"; import store from "../../store";
import { mockState } from "../../mockState"; import { mockState } from "../../mockState";
import history from "../../store/utils/history"; import history from "../../store/utils/history";
import TableViewPage from "../../pages/CandidatesPage/TableViewPage"; import TableViewPage from "../../pages/CandidatesPage/TableViewPage";
import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants"; import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants";
import * as requests from '../../request/candidatesRequest'
import * as requests from "../../request/candidatesRequest";


describe("TableViewPage render tests", () => { describe("TableViewPage render tests", () => {
var props = { var props = {


it("Initially CV of candidate isn't displayed", () => { it("Initially CV of candidate isn't displayed", () => {
const { container } = render(cont); const { container } = render(cont);
expect(container.getElementsByClassName('candidates-cv')[0].style.opacity).toBe("0")
expect(
container.getElementsByClassName("candidates-cv")[0].style.opacity
).toBe("0");
}); });


// How to mock getCV() function ? // How to mock getCV() function ?

+ 114
- 0
src/__tests__/UITests/usersPageUI.test.js View File

import * as redux from "react-redux";
import store from "../../store";
import { Router } from "react-router-dom";
import { mockState } from "../../mockState";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import history from "../../store/utils/history";
import UsersPage from "../../pages/UsersPage/UsersPage";

describe("UsersPage render tests", () => {
var props = {
history: {
replace: jest.fn(),
push: jest.fn(),
location: {
pathname: "/users",
},
},
};
const cont = (
<redux.Provider store={store}>
<Router history={history}>
<UsersPage {...props} />
</Router>
</redux.Provider>
);

let spyOnUseSelector;

beforeEach(() => {
spyOnUseSelector = jest.spyOn(redux, "useSelector");
spyOnUseSelector
.mockReturnValue(mockState.users)
.mockReturnValue(mockState.users);
});

afterEach(() => {
jest.restoreAllMocks();
});

it("Should render", () => {
render(cont);
expect(screen.getByTestId("users")).toBeDefined();
});

it("Number of rows of table should be equal to the number of users", () => {
const { container } = render(cont);
expect(
container
.getElementsByClassName("usersTable-users")[0]
.getElementsByClassName("secondaryRow").length
).toBe(mockState.users.users.length);
});

it("Should render edit button", () => {
const { container } = render(cont);
expect(container.getElementsByClassName("userPageBtn")[0]).toBeDefined();
});

it("Should render search button", () => {
const { container } = render(cont);
expect(container.getElementsByClassName("userPageBtn")[1]).toBeDefined();
});

it("Should render invite button", () => {
const { container } = render(cont);
expect(container.getElementsByClassName("inviteBtn")[0]).toBeDefined();
});

it("After clicking edit button there should be shown three buttons for each row of our table", () => {
const { container } = render(cont);
fireEvent.click(container.getElementsByClassName("userPageBtn")[0]);
expect(container.getElementsByClassName("td-btn").length).toBe(
3 * mockState.users.users.length
);
});

it("After clicking invite button invote dialog should be shown", () => {
const { container } = render(cont);
fireEvent.click(container.getElementsByClassName("inviteBtn")[0]);
expect(screen.getByTestId("invite-dialog")).toBeDefined();
});

it("After clicking button for reseting password dialog should be shown", () => {
const { container } = render(cont);
fireEvent.click(container.getElementsByClassName("userPageBtn")[0]);
fireEvent.click(container.getElementsByClassName("td-btn")[0]);
expect(screen.getByTestId("alert-container")).toBeDefined();
});

it("After clicking button editing we should be redirected to user details page", () => {
const { container } = render(cont);
fireEvent.click(container.getElementsByClassName("userPageBtn")[0]);
fireEvent.click(container.getElementsByClassName("td-btn")[2]);
expect(props.history.push).toHaveBeenCalledWith("/users/1");
});

it("Initially input for searching by name should not be shown", () => {
const { container } = render(cont);
expect(
container.getElementsByClassName("search-input-users")[0].style.visibility
).toBe("hidden");
});

// it("input for searching by name should be shown after clicking button for first time", async () => {
// const { container } = render(cont);
// fireEvent.click(container.getElementsByClassName("userPageBtn")[1]);
// await waitFor(() =>
// expect(
// container.getElementsByClassName("search-input-users")[0].style
// .visibility
// ).toBe("vissible")
// );
// });
});

+ 2
- 2
src/assets/styles/components/_day-details-component.scss View File

margin-top: 37px; margin-top: 37px;
} }


.day-datails-arrow-container {
.day-details-arrow-container {
display: flex; display: flex;
background: #ffffff; background: #ffffff;
border: 1px solid #e4e4e4; border: 1px solid #e4e4e4;
} }




.day-datails-arrow-container-p {
.day-details-arrow-container-p {
display: flex; display: flex;
background: #ffffff; background: #ffffff;
border: 1px solid #e4e4e4; border: 1px solid #e4e4e4;

+ 65
- 44
src/components/Schedules/DayDetailsComponent.js View File

import meet from "../../../src/assets/images/meet.png"; import meet from "../../../src/assets/images/meet.png";
import { formatTimeSrb } from "../../util/helpers/dateHelpers"; import { formatTimeSrb } from "../../util/helpers/dateHelpers";
import { CANDIDATES_PAGE } from "../../constants/pages"; import { CANDIDATES_PAGE } from "../../constants/pages";
import { Link } from "react-router-dom";
import { useTheme } from "@emotion/react"; import { useTheme } from "@emotion/react";
import { useMediaQuery } from "@mui/material"; import { useMediaQuery } from "@mui/material";


setCurrentlySelectedDay, setCurrentlySelectedDay,
currentlySelectedDay, currentlySelectedDay,
numberOfDaysInMonth, numberOfDaysInMonth,
history,
}) => { }) => {
const theme = useTheme(); const theme = useTheme();
const matches = useMediaQuery(theme.breakpoints.down("361")); const matches = useMediaQuery(theme.breakpoints.down("361"));
setCurrentlySelectedDay(newDay); setCurrentlySelectedDay(newDay);
}; };


const navigateToCandidateDetailsPage = (applicantId) => {
history.push({
pathname: CANDIDATES_PAGE + "/" + applicantId,
});
};

return ( return (
<Dialog <Dialog
onClose={handleClose} onClose={handleClose}
open={open} open={open}
maxWidth={!matches ? "549" : "339"} maxWidth={!matches ? "549" : "339"}
> >
<div className="day-details-sub-container" data-testid="day-component-dialog">
<div
className="day-details-sub-container"
data-testid="day-component-dialog"
>
<DialogTitle className="day-datails-title-container"> <DialogTitle className="day-datails-title-container">
<img src={calendar} className="day-details-calendar-image" /> <img src={calendar} className="day-details-calendar-image" />
<p className="day-details-main-header">Planer aktivnosti</p> <p className="day-details-main-header">Planer aktivnosti</p>
}} }}
> >
<div className="day-details-content-sub-container"> <div className="day-details-content-sub-container">
{selectionProcesses && selectionProcesses.map((selectionProcess, index) => (
<div key={index} data-testid="day-details-component-process">
<div style={{ display: "flex", alignItems: "center" }}>
<p className="day-details-time">
{formatTimeSrb(selectionProcess.date)}h
</p>
<div
style={{
display: "flex",
alignItems: !matches ? "center" : "flex-start",
flexDirection: !matches ? "row" : "column",
}}
>
<p className="day-details-name">
{selectionProcess.selectionLevel.name}
{selectionProcesses &&
selectionProcesses.map((selectionProcess, index) => (
<div key={index} data-testid="day-details-component-process">
<div style={{ display: "flex", alignItems: "center" }}>
<p className="day-details-time">
{formatTimeSrb(selectionProcess.date)}h
</p> </p>
<Link
className="day-details-applicant"
to={
CANDIDATES_PAGE +
"/" +
selectionProcess.applicant.applicantId
}
<div
style={{
display: "flex",
alignItems: !matches ? "center" : "flex-start",
flexDirection: !matches ? "row" : "column",
}}
>
<p className="day-details-name">
{selectionProcess.selectionLevel.name}
</p>
<p
className="day-details-applicant"
data-testid="day-details-applicant"
onClick={() =>
navigateToCandidateDetailsPage(
selectionProcess.applicant.applicantId
)
}
>
{selectionProcess.applicant.firstName}{" "}
{selectionProcess.applicant.lastName}
</p>
</div>
<a
className="day-details-link"
href={selectionProcess.link}
target="_blank"
rel="noreferrer"
> >
{selectionProcess.applicant.firstName}{" "}
{selectionProcess.applicant.lastName}
</Link>
<img src={meet} />
{!matches && <span>Link</span>}
</a>
</div> </div>
<a
className="day-details-link"
href={selectionProcess.link}
target="_blank"
rel="noreferrer"
>
<img src={meet} />
{!matches && <span>Link</span>}
</a>
<div className="day-details-line" />
</div> </div>
<div className="day-details-line" />
</div>
))}
))}
</div> </div>
<div <div
style={{ style={{
}} }}
> >
{isLeftArrowDisabled === true ? ( {isLeftArrowDisabled === true ? (
<div className="day-datails-arrow-container" data-testid="day-datails-left-arrow">
<div
className="day-details-arrow-container"
data-testid="day-details-left-arrow"
>
<img src={arrowLeftDisabled} /> <img src={arrowLeftDisabled} />
</div> </div>
) : ( ) : (
<div <div
className="day-datails-arrow-container"
className="day-details-arrow-container"
onClick={goBackOneDay} onClick={goBackOneDay}
> >
<img src={arrowLeft} /> <img src={arrowLeft} />
</div> </div>
)} )}
{isRightArrowDisabled === true ? ( {isRightArrowDisabled === true ? (
<div className="day-datails-arrow-container-p">
<div className="day-details-arrow-container-p">
<img src={arrowLeftDisabled} /> <img src={arrowLeftDisabled} />
</div> </div>
) : ( ) : (
<div <div
className="day-datails-arrow-container"
className="day-details-arrow-container"
onClick={goForwardOneDay} onClick={goForwardOneDay}
data-testid="day-datails-right-arrow"
data-testid="day-details-right-arrow"
> >
<img src={arrowRight} /> <img src={arrowRight} />
</div> </div>
setCurrentlySelectedDay: PropTypes.func, setCurrentlySelectedDay: PropTypes.func,
currentlySelectedDay: PropTypes.number, currentlySelectedDay: PropTypes.number,
numberOfDaysInMonth: PropTypes.number, numberOfDaysInMonth: PropTypes.number,
history: PropTypes.shape({
replace: PropTypes.func,
push: PropTypes.func,
location: PropTypes.shape({
pathname: PropTypes.string,
}),
}),
}; };


export default DayDetailsComponent; export default DayDetailsComponent;

+ 1
- 0
src/mockState.js View File

count: 0, count: 0,
}, },
], ],
fetchStatsErrorMessage: "Server Error",
}, },
technologies: { technologies: {
technologies: [ technologies: [

+ 13
- 1
src/pages/SchedulePage/SchedulePage.js View File

getDayString, getDayString,
getFormatedDayOrMonth, getFormatedDayOrMonth,
} from "../../util/helpers/dateHelpers"; } from "../../util/helpers/dateHelpers";
import PropTypes from "prop-types";


const SchedulePage = () => {
const SchedulePage = ({ history }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const selectionProcesses = useSelector(selectSchedule); const selectionProcesses = useSelector(selectSchedule);
const [detailDialogShown, setDetailsDialogShown] = useState(false); const [detailDialogShown, setDetailsDialogShown] = useState(false);
setCurrentlySelected={setCurrentlySelectedDate} setCurrentlySelected={setCurrentlySelectedDate}
setCurrentlySelectedDay={setCurrentlySelectedDay} setCurrentlySelectedDay={setCurrentlySelectedDay}
currentlySelectedDay={currentlySelectedDay} currentlySelectedDay={currentlySelectedDay}
history={history}
/> />
<div> <div>
<p className="schedule-page-main-header">Planer aktivnosti</p> <p className="schedule-page-main-header">Planer aktivnosti</p>
); );
}; };


SchedulePage.propTypes = {
history: PropTypes.shape({
replace: PropTypes.func,
push: PropTypes.func,
location: PropTypes.shape({
pathname: PropTypes.string,
}),
}),
};

export default SchedulePage; export default SchedulePage;

+ 6
- 6
src/pages/StatsPage/StatsPage.js View File

<div className="stats-items"> <div className="stats-items">
{stats.levels && {stats.levels &&
stats.levels.map((n) => ( stats.levels.map((n) => (
<div key={n.level} className="stats-item">
<div key={n.level} className="stats-item" data-testid="stats-item">
<div className="stats-item-content"> <div className="stats-item-content">
<h3>{n.countDone}</h3> <h3>{n.countDone}</h3>
<p> <p>
<div className="stats-items-dynamic"> <div className="stats-items-dynamic">
{stats.levels && {stats.levels &&
stats.levels.map((n) => ( stats.levels.map((n) => (
<div key={n.level} className="stats-item">
<div key={n.level} className="stats-item" data-testid="stats-item2">
<div className="stats-item-content"> <div className="stats-item-content">
<h3> <h3>
{n.countDone} {n.countDone}
{!matches && ( {!matches && (
<div className="archived-ads-ads-a"> <div className="archived-ads-ads-a">
<div className="archived-ads-ads-arrows"> <div className="archived-ads-ads-arrows">
<button onClick={arrowLeftHandler}>
<button onClick={arrowLeftHandler} data-testid="left-arrow">
<img src={arrow_left} alt="arrow-left" /> <img src={arrow_left} alt="arrow-left" />
</button> </button>
{stats.ads.length > 3 && ( {stats.ads.length > 3 && (
<button onClick={arrowRightHandler}>
<button onClick={arrowRightHandler} data-testid="right-arrow">
<img src={arrow_right} alt="arrow-right" /> <img src={arrow_right} alt="arrow-right" />
</button> </button>
)} )}
</div> </div>
{matches && ( {matches && (
<div className="active-ads-ads-arrows"> <div className="active-ads-ads-arrows">
<button onClick={arrowLeftHandler}>
<button onClick={arrowLeftHandler} data-testid="left-arrow">
<img src={arrow_left} alt="arrow-left" /> <img src={arrow_left} alt="arrow-left" />
</button> </button>
{stats.ads.length > 2 && ( {stats.ads.length > 2 && (
<button onClick={arrowRightHandler}>
<button onClick={arrowRightHandler} data-testid="right-arrow">
<img src={arrow_right} alt="arrow-right" /> <img src={arrow_right} alt="arrow-right" />
</button> </button>
)} )}

+ 14
- 13
src/pages/UsersPage/UsersPage.js View File

setUsersReq, setUsersReq,
} from "../../store/actions/users/usersActions"; } from "../../store/actions/users/usersActions";
import { useTheme } from "@mui/system"; import { useTheme } from "@mui/system";
import { Fade, useMediaQuery } from "@mui/material";
import { Fade, useMediaQuery } from "@mui/material";
// import DialogComponent from "../../components/MUI/DialogComponent"; // import DialogComponent from "../../components/MUI/DialogComponent";
import InviteDialog from "../../components/MUI/InviteDialog"; import InviteDialog from "../../components/MUI/InviteDialog";
// import { Link } from "react-router-dom"; // import { Link } from "react-router-dom";
const { t } = useTranslation(); const { t } = useTranslation();


const handleChangeVisibility = () => { const handleChangeVisibility = () => {
setIsSearchFieldVisible(s=> !s);
setIsSearchFieldVisible((s) => !s);
}; };


useEffect(() => { useEffect(() => {
onChange={(e) => setSearch(e.target.value)} onChange={(e) => setSearch(e.target.value)}
className="ads-search-field-responsive smaller" className="ads-search-field-responsive smaller"
onClick={stopPropagation} onClick={stopPropagation}
style={{ zIndex: 1000, width:'300px' }}
style={{ zIndex: 1000, width: "300px" }}
/> />
</div> </div>
); );
marginTop: 52.5, marginTop: 52.5,
right: "87.5px", right: "87.5px",
}} }}
className="search-input-users"
> >
<img src={searchImage} /> <img src={searchImage} />
</div> </div>
setConfirm(false); setConfirm(false);
}} }}
onConfirm={() => { onConfirm={() => {
disableHandler(chosen.id);
// setConfirm(false)
disableHandler(chosen.id); // setConfirm(false)
}} }}
/> />
<ConfirmDialog <ConfirmDialog
setReset(false); setReset(false);
}} }}
onConfirm={() => { onConfirm={() => {
handleReset(chosen.email);
// setConfirm(false)
handleReset(chosen.email); // setConfirm(false)
}} }}
/> />
<InviteDialog <InviteDialog
title={ title={
<div <div
className="flex-center" className="flex-center"
data-testid="invite-dialog"
style={{ justifyContent: "space-between" }} style={{ justifyContent: "space-between" }}
> >
<div className="flex-center" style={{ justifyContent: "start" }}> <div className="flex-center" style={{ justifyContent: "start" }}>
/> />
<div> <div>
<div <div
onClick={handleChangeVisibility}
onClick={() => setIsSearchFieldVisible(false)}
className="pl-144 flex-center" className="pl-144 flex-center"
style={{ style={{
paddingTop: "36px", paddingTop: "36px",
onClick={handleChangeVisibility} onClick={handleChangeVisibility}
> >
{!matches && "Pretraga"} {!matches && "Pretraga"}

<img <img
style={{ style={{
position: "relative", position: "relative",
</div> </div>
<div <div
className="pl-144" className="pl-144"
onClick={handleChangeVisibility}
onClick={() => setIsSearchFieldVisible(false)}
style={{ style={{
display: "flex", display: "flex",
marginTop: "39px", marginTop: "39px",
<table <table
className={ className={
editEnable ? "usersTable-users normal" : "usersTable-users mini" editEnable ? "usersTable-users normal" : "usersTable-users mini"
}
// style={{ width: "893.56px" }}
} // style={{ width: "893.56px" }}
> >
<thead> <thead>
<tr className="headingRow"> <tr className="headingRow">
{editEnable && <th></th>} {editEnable && <th></th>}
</tr> </tr>
</thead> </thead>

<tbody> <tbody>
{users {users
.filter((n) => .filter((n) =>
</IconButton> </IconButton>
</> </>
</td> </td>
)}
)}{" "}
</tr> </tr>
))}
))}{" "}
</tbody> </tbody>
</table> </table>
</div> </div>

Loading…
Cancel
Save