My Tasks} />
+ } />
{/* /dashboard */}
- Dashboard in construction} />
+ } />
diff --git a/src/actions/api.js b/src/actions/api.js
new file mode 100644
index 0000000..d7515d7
--- /dev/null
+++ b/src/actions/api.js
@@ -0,0 +1,63 @@
+// action types
+// event actions
+export const API_START = 'API_START';
+export const API_POST = 'API_POST';
+export const API_PUT = 'API_PUT';
+export const API_DASHBOARD = 'API_DASHBOARD';
+export const API_SUCCESS = 'API_SUCCESS';
+export const POST_SUCCESS = 'POST_SUCCESS';
+export const DASHBOARD_SUCCESS = 'DASHBOARD_SUCCESS';
+export const API_FAILURE = 'API_FAILURE';
+export const API_SELF_START = 'API_SELF_START';
+
+
+export const apiStart = ({body, method, url}) => ({
+ type: API_START,
+ payload: body,
+ meta: {method, url, body}
+});
+
+export const apiSelfStart = ({body, method, url}) => ({
+
+ type: API_SELF_START,
+ payload: body,
+ meta: {body, method, url}
+ });
+
+export const apiPost = ({body, method='POST', url}) => ({
+
+ type: API_POST,
+ payload: body,
+ meta: {body, method, url}
+ });
+
+export const apiPut = ({body, method='POST', url}) => ({
+ type: API_PUT,
+ payload: body,
+ meta: {body, method, url}
+ });
+
+export const dashboardStart = ({body, method, url}) => ({
+ type: API_DASHBOARD,
+ payload: body,
+ meta: {body, method, url}
+ });
+export const apiSuccess = ({response}) => ({
+ type: API_SUCCESS,
+ payload: response
+});
+
+export const postSuccess = ({response}) => ({
+ type: POST_SUCCESS,
+ payload: response
+});
+
+export const dashboardSuccess = ({response}) => ({
+ type: DASHBOARD_SUCCESS,
+ payload: response
+});
+
+export const apiFailure = ({error}) => ({
+ type: API_FAILURE,
+ payload: error
+});
diff --git a/src/actions/tasks.js b/src/actions/tasks.js
new file mode 100644
index 0000000..026e046
--- /dev/null
+++ b/src/actions/tasks.js
@@ -0,0 +1,53 @@
+import { SET_LOADER } from "./ui";
+
+// feature name
+export const TASKS = '[TASKS]';
+
+export const USER_TASKS = `[USER_TASKS]`;
+
+// action types
+// command actions
+export const FETCH_TASKS = `${TASKS} FETCH`;
+
+export const FETCH_USER_TASKS = `${USER_TASKS} FETCH`;
+
+export const PUT_TASK = `${TASKS} PUT`;
+
+// document actions
+export const SET_TASKS = `${TASKS} SET`;
+
+export const ADD_TASKS = `${TASKS} ADD`;
+
+export const DASHBOARD_TASKS = `${TASKS} DASHBOARD`;
+
+export const fetchTasks = ({query}) => ({
+ type: FETCH_TASKS,
+ payload: query
+});
+
+export const setTasks = ({list}) => ({
+ type: SET_TASKS,
+ payload: list
+});
+
+export const addTasks = ({task}) => ({
+ type: ADD_TASKS,
+ payload: task
+});
+
+export const fetchUserTasks = (query) => {
+ return {
+ type: FETCH_USER_TASKS,
+ payload: query
+ };
+};
+
+export const updateTask = ({task}) => ({
+ type: PUT_TASK,
+ payload: task
+});
+
+export const countTasks = ({list}) => ({
+ type: DASHBOARD_TASKS,
+ payload: list
+});
\ No newline at end of file
diff --git a/src/actions/ui.js b/src/actions/ui.js
index 599562f..e8d07fa 100644
--- a/src/actions/ui.js
+++ b/src/actions/ui.js
@@ -1,7 +1,13 @@
// action types
export const SET_LOADER = 'SET_LOADER';
+export const SET_NOTIFICATION = 'SET_NOTIFICATION';
export const setLoader = (showLoader) => ({
type: SET_LOADER,
payload: showLoader
});
+
+export const setNotification = ({error}) => ({
+ type: SET_NOTIFICATION,
+ payload: error
+});
diff --git a/src/components/NavigationBar/NavigationBar.test.js b/src/components/NavigationBar/NavigationBar.test.js
new file mode 100644
index 0000000..d061ca3
--- /dev/null
+++ b/src/components/NavigationBar/NavigationBar.test.js
@@ -0,0 +1,31 @@
+import React from "react";
+import NavigationBar from ".";
+import { shallow } from 'enzyme';
+
+// Enzyme adapter configuration
+import Enzyme from 'enzyme';
+import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
+import { act } from "react-dom/test-utils";
+
+Enzyme.configure({ adapter: new Adapter() });
+
+let wrapper = null;
+
+beforeEach(() => {
+ // Variable setting
+});
+
+afterEach(() => {
+ // destroy some resources
+ // wrapper.unmount();
+});
+
+describe('', () => {
+ it('Render 8 components for two drawers', () => {
+ act(() => {
+ wrapper = shallow();
+ });
+ console.log(wrapper.debug());
+ expect(wrapper.find('ListItemLink')).toHaveLength(8);
+ });
+});
diff --git a/src/components/Toggle/Toggle.test.js b/src/components/Toggle/Toggle.test.js
new file mode 100644
index 0000000..f108c32
--- /dev/null
+++ b/src/components/Toggle/Toggle.test.js
@@ -0,0 +1,59 @@
+import React from 'react';
+import Toggle from '.';
+import { act } from "react-dom/test-utils";
+import { render } from 'react-dom';
+import { fireEvent, screen } from '@testing-library/react';
+
+import Enzyme from 'enzyme';
+import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
+
+Enzyme.configure({ adapter: new Adapter() });
+
+let container = null;
+let toggleCallback = () => jest.fn();
+
+beforeEach(() => {
+ // Variable setting
+ container = document.createElement('div');
+ document.body.appendChild(container);
+});
+
+afterEach(() => {
+ // destroy some resources
+ container.remove();
+ container = null;
+});
+
+describe('Render component', () => {
+ it('Renders with label "My Label"', () => {
+ act(() => {
+ render(, container);
+ });
+ expect(container.textContent).toContain('My Label');
+ });
+
+ it('Renders deactive by default', () => {
+ act(() => {
+ render(, container);
+ });
+ expect(container.querySelector('input[type="checkbox"]').checked).toEqual(false);
+ });
+
+ it('Should change to active the after dispatch click', () => {
+ act(() => {
+ render(, container);
+ fireEvent.click(screen.getByTestId('toggle'));
+ });
+ expect(container.querySelector('input[type="checkbox"]').checked).toEqual(true);
+ });
+
+ it('Should change to inactive the after dispatch click', () => {
+ act(() => {
+ render(, container);
+ });
+ act(() => {
+ fireEvent.click(screen.getByTestId('toggle'));
+ });
+ expect(container.querySelector('input[type="checkbox"]').checked).toEqual(false);
+ });
+});
diff --git a/src/components/Toggle/index.js b/src/components/Toggle/index.js
index 167316d..a578d1b 100644
--- a/src/components/Toggle/index.js
+++ b/src/components/Toggle/index.js
@@ -6,6 +6,7 @@ const Toggle = ({ label, onToggle, active }) => {
return (
diff --git a/src/middlewares/api.js b/src/middlewares/api.js
new file mode 100644
index 0000000..b20af26
--- /dev/null
+++ b/src/middlewares/api.js
@@ -0,0 +1,79 @@
+import { apiFailure, apiSuccess, dashboardSuccess , postSuccess, API_START, API_POST, API_SELF_START, API_PUT, API_DASHBOARD} from "../actions/api";
+
+export const apiMiddleware = ({dispatch}) => (next) => (action) => {
+ next(action);
+ switch(action.type) {
+ case API_START: {
+ const { method, body, url } = action.meta;
+ fetch(url, { method: method, body: body })
+ .then(response => response.json())
+ .then(data => {
+ dispatch(apiSuccess({response: data}));
+ })
+ .catch(function(error) {
+ dispatch(apiFailure({error: error}));
+ });
+ break;
+ }
+ case API_SELF_START: {
+ const { method, body, url } = action.meta;
+ fetch(url, { method: method })
+ .then(response => response.json())
+ .then(data => {
+ dispatch(apiSuccess({response: data.filter(item => item.user === body.user)}));
+ })
+ .catch(function(error) {
+ dispatch(apiFailure({error: error}));
+ });
+ break;
+ }
+ case API_POST: {
+ fetch(action.meta.url, {
+ method: action.meta.method,
+ body: JSON.stringify(action.payload),
+ headers: { 'Content-Type': 'application/json' }
+ })
+ .then(data => {
+ dispatch(postSuccess({response: data}));
+ })
+ .catch(function(error) {
+ dispatch(apiFailure({error: error}));
+ });
+ break;
+ }
+ case API_PUT: {
+ fetch(action.meta.url, {
+ method: action.meta.method,
+ body: JSON.stringify(action.payload),
+ headers: { 'Content-Type': 'application/json' }
+ })
+ .then(data => {
+ dispatch(postSuccess({response: data}));
+ })
+ .catch(function(error) {
+ dispatch(apiFailure({error: error}));
+ });
+ break;
+ }
+ case API_DASHBOARD: {
+ fetch(action.meta.url, { method: action.meta.method, body: action.meta.body })
+ .then(response => response.json())
+ .then(data => {
+ const completedTasks = data.filter(item => item.completed === true);
+ const uncompletedTasks = data.filter(item => item.completed === false);
+ dispatch(dashboardSuccess(
+ {response: [
+ { argument: 'Completed', value: completedTasks.length},
+ { argument: 'Uncompleted', value: uncompletedTasks.length}
+ ]}
+ ));
+ })
+ .catch(function(error) {
+ dispatch(apiFailure({error: error}));
+ });
+ break;
+ }
+ default:
+ break;
+ }
+}
diff --git a/src/middlewares/tasks.js b/src/middlewares/tasks.js
new file mode 100644
index 0000000..ebc6d22
--- /dev/null
+++ b/src/middlewares/tasks.js
@@ -0,0 +1,47 @@
+import { apiStart, apiPost, apiSelfStart, apiPut, dashboardStart, API_FAILURE, API_SUCCESS, POST_SUCCESS, DASHBOARD_SUCCESS } from "../actions/api";
+import { FETCH_TASKS, DASHBOARD_TASKS, setTasks, countTasks, ADD_TASKS, FETCH_USER_TASKS, PUT_TASK } from "../actions/tasks";
+import { setLoader, setNotification } from "../actions/ui";
+
+const TASKS_API_GET = "https://davidvida-tasks-service.herokuapp.com/api/v1/task";
+
+export const tasksMiddleware = () => (next) => (action) => {
+ // next(action);
+ switch(action.type) {
+ case FETCH_TASKS:
+ next(apiStart({body: null, method: 'GET', url: TASKS_API_GET}));
+ next(setLoader(true));
+ break;
+ case FETCH_USER_TASKS:
+ next(apiSelfStart({body: action.payload, method: 'GET', url: TASKS_API_GET}));
+ next(setLoader(true));
+ break;
+ case ADD_TASKS:
+ next(apiPost({body: action.payload, method: 'POST', url: TASKS_API_GET}));
+ break;
+ case PUT_TASK:
+ next(setNotification({message: 'Task updated successfully', type: 'success'}));
+ next(apiPut({body: action.payload, method: 'PUT', url: `${TASKS_API_GET}/${action.payload._id}`}));
+ next(setLoader(true));
+ break;
+ case DASHBOARD_TASKS:
+ next(dashboardStart({body: null, method: 'GET', url: TASKS_API_GET}));
+ next(setLoader(true));
+ break;
+ case API_SUCCESS:
+ next(setTasks({list: action.payload}));
+ next(setLoader(false));
+ break;
+ case POST_SUCCESS:
+ next(setNotification({message: 'Task added successfully', type: 'success'}));
+ next(apiStart({body: null, method: 'GET', url: TASKS_API_GET}));
+ next(setLoader(true));
+ break;
+ case DASHBOARD_SUCCESS:
+ next(countTasks({list: action.payload}));
+ break;
+ case API_FAILURE:
+ next(setNotification({error: action.payload}));
+ next(setLoader(false));
+ break;
+ }
+};
diff --git a/src/pages/DashboardPage/DashboardContainer/index.jsx b/src/pages/DashboardPage/DashboardContainer/index.jsx
index e69de29..e11a67a 100644
--- a/src/pages/DashboardPage/DashboardContainer/index.jsx
+++ b/src/pages/DashboardPage/DashboardContainer/index.jsx
@@ -0,0 +1,29 @@
+import React, { Component } from 'react';
+import { Chart, PieSeries, Title, Legend, Tooltip } from '@devexpress/dx-react-chart-material-ui';
+import { Animation } from '@devexpress/dx-react-chart';
+import { EventTracker } from '@devexpress/dx-react-chart';
+
+
+class DashboardContainer extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const {list} = this.props;
+ return (
+
+ );
+ }
+};
+
+export default DashboardContainer;
\ No newline at end of file
diff --git a/src/pages/DashboardPage/index.jsx b/src/pages/DashboardPage/index.jsx
index e69de29..303bef5 100644
--- a/src/pages/DashboardPage/index.jsx
+++ b/src/pages/DashboardPage/index.jsx
@@ -0,0 +1,35 @@
+import React, { Component } from "react";
+import { connect } from "react-redux";
+import DashboardContainer from "./DashboardContainer";
+import { countTasks } from "../../actions/tasks";
+
+class DashboardPage extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ componentDidMount() {
+ this.props.countTasks();
+ }
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+const mapStateToProps = state => {
+ return {
+ list: state.tasks.data
+ }
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ countTasks: () => dispatch(countTasks({query: {}}))
+ }
+}
+
+
+export default connect(mapStateToProps, mapDispatchToProps)(DashboardPage);
diff --git a/src/pages/MyTasksListPage/MyTasksList/index.js b/src/pages/MyTasksListPage/MyTasksList/index.js
new file mode 100644
index 0000000..871511f
--- /dev/null
+++ b/src/pages/MyTasksListPage/MyTasksList/index.js
@@ -0,0 +1,49 @@
+import React from 'react';
+import { Container, Divider, List, Paper } from '@mui/material';
+import TodoListItem from '../../TaskListPage/TodoListItem';
+import Toggle from 'Components/Toggle';
+import FormAddTask from '../../TaskListPage/FormAddTask';
+import LoadingIndicator from 'Components/LoadingIndicator';
+
+class MyTodoList extends React.Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const { list, filterApplied, toggleListItem,performAddTask, showLoader, performUpdateTask } = this.props;
+ return (
+
+
+
+ { list && list.length > 0 && (
+ <>
+
+
+
+
+ {list.filter(item => (!filterApplied ? true : !item.completed)).map((item, index, array) => {
+ return (
+ <>
+
+ { index < array.length -1 && }
+ >
+ )
+ })}
+
+
+ >
+ )}
+
+ );
+ }
+
+}
+
+export default MyTodoList;
\ No newline at end of file
diff --git a/src/pages/MyTasksListPage/MyTasksTodoContainers/index.js b/src/pages/MyTasksListPage/MyTasksTodoContainers/index.js
new file mode 100644
index 0000000..a118994
--- /dev/null
+++ b/src/pages/MyTasksListPage/MyTasksTodoContainers/index.js
@@ -0,0 +1,63 @@
+import React, { Component } from "react";
+import MyTodoList from "../MyTasksList";
+import { connect } from "react-redux";
+import { setLoader } from "../../../actions/ui";
+import { fetchUserTasks } from "../../../actions/tasks";
+
+class MyTodoListContainer extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ filterApplied: false,
+ hideTimer: false,
+ count: 0
+ };
+ this.toggleTimer = this.toggleTimer.bind(this);
+ this.toggleListItem = this.toggleListItem.bind(this);
+ }
+
+ componentDidMount() {
+ this.props.fetchUserTasks({user: 'Administrator'});
+ }
+
+ toggleTimer(event) {
+ this.setState({
+ hideTimer: event.currentTarget.checked
+ });
+ }
+
+ toggleListItem(event) {
+ this.setState({
+ filterApplied: event.currentTarget.checked
+ });
+ }
+
+ render() {
+ const { filterApplied } = this.state;
+ const { list, loading } = this.props;
+ return (
+
+ )
+ }
+}
+
+const mapStateToProps = state => {
+ return {
+ loading: state.ui.loading,
+ list: state.tasks.data
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ fetchUserTasks: (query) => dispatch(fetchUserTasks(query))
+ }
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(MyTodoListContainer);
\ No newline at end of file
diff --git a/src/pages/MyTasksListPage/index.js b/src/pages/MyTasksListPage/index.js
new file mode 100644
index 0000000..f42e82e
--- /dev/null
+++ b/src/pages/MyTasksListPage/index.js
@@ -0,0 +1,10 @@
+import React from "react";
+import MyTodoListContainer from "./MyTasksTodoContainers";
+
+const MyTasksListPage = () => {
+ return (
+
+ );
+};
+
+export default MyTasksListPage;
\ No newline at end of file
diff --git a/src/pages/TaskListPage/FormAddTask/index.js b/src/pages/TaskListPage/FormAddTask/index.js
index 01467fb..242fd93 100644
--- a/src/pages/TaskListPage/FormAddTask/index.js
+++ b/src/pages/TaskListPage/FormAddTask/index.js
@@ -1,44 +1,91 @@
import React, { useState, useRef, useEffect } from "react";
+import Button from '@mui/material/Button';
+import TextField from '@mui/material/TextField';
+import Dialog from '@mui/material/Dialog';
+import DialogActions from '@mui/material/DialogActions';
+import DialogContent from '@mui/material/DialogContent';
+import DialogContentText from '@mui/material/DialogContentText';
+import DialogTitle from '@mui/material/DialogTitle';
+import ChipInput from 'material-ui-chip-input'
const FormAddTask = ({ onSubmitCallback }) => {
const [taskName, setTaskName] = useState("");
+ const [taskDescription, setTaskDescription] = useState("");
+ const [open, setOpen] = useState(false);
const inputRef = useRef();
- useEffect(() => {
- inputRef.current.focus();
- }, []);
+ const handleClickOpen = () => {
+ setOpen(true);
+ };
+
+ const handleClose = () => {
+ setOpen(false);
+ };
const onChangeName = (event) => {
setTaskName(event.target.value);
}
+ const onChangeDescription = (event) => {
+ setTaskDescription(event.target.value);
+ }
+
const onSubmitListener = (event) => {
event.preventDefault();
+ handleClose();
onSubmitCallback({
- name: taskName
+ name: taskName,
+ description: taskDescription
});
setTaskName("");
+ setTaskDescription('');
};
return (
-
+
+
+
+
);
};
diff --git a/src/pages/TaskListPage/TodoList/TodoList.spec.js b/src/pages/TaskListPage/TodoList/TodoList.spec.js
deleted file mode 100644
index e69de29..0000000
diff --git a/src/pages/TaskListPage/TodoList/index.jsx b/src/pages/TaskListPage/TodoList/index.jsx
index 1ca5639..949602f 100644
--- a/src/pages/TaskListPage/TodoList/index.jsx
+++ b/src/pages/TaskListPage/TodoList/index.jsx
@@ -17,18 +17,10 @@ class TodoList extends React.Component {
//render method
render() {
- const { list, filterApplied, toggleTimer, toggleListItem, performAddTask, showLoader } = this.props;
+ const { list, filterApplied, toggleTimer, toggleListItem, performAddTask, performUpdateTask, showLoader } = this.props;
return (
- {/*
-
-
-
-
- { !hideTimer && }
-
-
*/}
-
+
{ list.length > 0 && (
<>
@@ -39,7 +31,13 @@ class TodoList extends React.Component {
{list.filter(item => (!filterApplied ? true : !item.completed)).map((item, index, array) => {
return (
<>
-
+
{ index < array.length -1 && }
>
)
diff --git a/src/pages/TaskListPage/TodoListContainer/index.jsx b/src/pages/TaskListPage/TodoListContainer/index.jsx
index dc77789..d889f24 100644
--- a/src/pages/TaskListPage/TodoListContainer/index.jsx
+++ b/src/pages/TaskListPage/TodoListContainer/index.jsx
@@ -2,37 +2,25 @@ import React, { Component } from "react";
import TodoList from "../TodoList";
import { connect } from "react-redux";
import { setLoader } from "../../../actions/ui";
+import { fetchTasks,addTasks,updateTask } from "../../../actions/tasks";
class TodoListContainer extends Component {
constructor(props) {
super(props);
this.state = {
- list: [],
filterApplied: false,
- hideTimer: false
+ hideTimer: false,
+ count: 0
};
this.toggleTimer = this.toggleTimer.bind(this);
this.toggleListItem = this.toggleListItem.bind(this);
this.performAddTask = this.performAddTask.bind(this);
+ this.performUpdateTask = this.performUpdateTask.bind(this);
}
componentDidMount() {
const __this = this;
- __this.props.setLoaderProp(true);
- // comunicate an external service to get data
- fetch("http://localhost:3000/data/tasks.json")
- .then(response => response.json())
- .then(data => {
- this.setState({
- list: data.list
- });
- setTimeout(function() {
- __this.props.setLoaderProp(false);
- }, 5000)
- })
- .catch(function(error) {
- console.error(error);
- });
+ this.props.fetchTasks();
}
toggleTimer(event) {
@@ -48,18 +36,38 @@ class TodoListContainer extends Component {
}
performAddTask(newTask) {
- this.setState(state => {
- const newTaskElement = {
- ...newTask,
- id: state.list.length,
- completed: false
- }
- let newList = [...state.list];
+ const date = new Date();
+ const newTaskElement = {
+ ...newTask,
+ id: this.props.list.length,
+ completed: false,
+ startDate: date.toISOString(),
+ endDate: date.toISOString(),
+ user: 'Administrator'
+ };
+
+ let newList = [...this.props.list];
+ return this.props.addTasks(newTaskElement)
+ .then(data => {
newList.push(newTaskElement);
- return {
- list: newList
- }
- });
+ return newList;
+ });
+ }
+ performUpdateTask(task, completed) {
+ const updatedTask = {
+ ...task
+ };
+ const date = new Date();
+ updatedTask.completed = completed;
+ if (completed) {
+ updatedTask.endDate = date.toISOString();
+ } else {
+ updatedTask.startDate = date.toISOString();
+ }
+ return this.props.updateTask(updatedTask)
+ .then(data => {
+ return this.props.list;
+ })
}
render() {
@@ -73,6 +81,7 @@ class TodoListContainer extends Component {
toggleTimer={this.toggleTimer}
toggleListItem={this.toggleListItem}
performAddTask={this.performAddTask}
+ performUpdateTask={this.performUpdateTask}
/>
)
}
@@ -87,10 +96,18 @@ const mapStateToProps = state => {
const mapDispacthToProps = dispatch => {
return {
- setLoaderProp: (show) => dispatch(setLoader(show))
+ fetchTasks: () => dispatch(fetchTasks({query: {}})),
+ addTasks: (task => {
+ return new Promise(resolve => {
+ resolve(dispatch(addTasks({task: task})));
+ })
+ }),
+ updateTask: (task => {
+ return new Promise(resolve => {
+ resolve(dispatch(updateTask({task: task})));
+ });
+ })
}
}
-
export default connect(mapStateToProps, mapDispacthToProps)(TodoListContainer);
-
diff --git a/src/pages/TaskListPage/TodoListItem/index.jsx b/src/pages/TaskListPage/TodoListItem/index.jsx
index 9966be1..d665b1d 100644
--- a/src/pages/TaskListPage/TodoListItem/index.jsx
+++ b/src/pages/TaskListPage/TodoListItem/index.jsx
@@ -1,55 +1,34 @@
import React from "react";
+import { format } from 'date-fns';
import { IconButton, ListItem, ListItemButton, ListItemIcon, ListItemText } from "@mui/material";
-import PlayIcon from '@mui/icons-material/PlayCircleOutlined'
+import PlayIcon from '@mui/icons-material/PlayCircleOutlined';
+import StopRounded from '@mui/icons-material/StopRounded';
import CompletedIcon from '@mui/icons-material/CheckCircleOutlineOutlined';
import PendingIcon from '@mui/icons-material/PendingOutlined';
-/* styles import */
-import { withStyles } from "@mui/styles";
-import styles from './styles';
-
-/*
-* class based component
-*/
-// class TodoListItem extends React.Component {
-// constructor(props) {
-// super(props);
-// }
-
-// render() {
-// const { name, completed, classes } = this.props;
-// return (
-//
-//
-//
-// }
-// >
-//
-//
-// { completed ? : }
-//
-//
-//
-//
-// )
-// }
-// }
+import Chip from '@mui/material/Chip';
+import Paper from '@mui/material/Paper';
/*
* function component
*/
import useStyles from "./styles";
-const TodoListItem = ({ name, completed }) => {
+
+const TodoListItem = ({ name, completed, item, enabled, updateTask }) => {
const classes = useStyles();
+ const onUpdateListener = (event) => {
+ event.preventDefault();
+ updateTask(item, !completed);
+ };
+ const startDate = item.startDate ? new Date(item.startDate) : null;
+ const endDate = item.endDate ? new Date(item.endDate) : null;
+ const labels = item.labels;
return (
-
+
+ { completed ? : }
}
>
@@ -58,10 +37,24 @@ const TodoListItem = ({ name, completed }) => {
{ completed ? : }
+ { startDate ? : <>> }
+ { endDate ? : <>> }
+ { labels ?
+ { labels.map((label, index) => {
+ return (
+
+ );
+ })} : <>> }
)
};
-// export default withStyles(styles)(TodoListItem);
export default TodoListItem;
diff --git a/src/reducers/initialState.js b/src/reducers/initialState.js
index 5e7c237..b60cd97 100644
--- a/src/reducers/initialState.js
+++ b/src/reducers/initialState.js
@@ -3,8 +3,9 @@ const initialState = {
loading: false,
notifcations: []
},
- tasks:{
- data: []
+ tasks: {
+ data: [],
+ applyFilter: false
},
dashboard: {
data: []
diff --git a/src/reducers/tasks.js b/src/reducers/tasks.js
index 8010294..24cf9ad 100644
--- a/src/reducers/tasks.js
+++ b/src/reducers/tasks.js
@@ -1,8 +1,33 @@
// reducer for UI
+
+import { ADD_TASKS, SET_TASKS, PUT_TASK, DASHBOARD_TASKS } from '../actions/tasks';
import initialState from './initialState';
const tasksReducer = (state=initialState.tasks, action) => {
- return state;
+ switch(action.type) {
+ case SET_TASKS:
+ return {
+ ...state,
+ data: action.payload
+ };
+ case ADD_TASKS:
+ return {
+ ...state,
+ data: action.payload
+ };
+ case PUT_TASK:
+ return {
+ ...state,
+ data: action.payload
+ };
+ case DASHBOARD_TASKS:
+ return {
+ ...state,
+ data: action.payload
+ };
+ default:
+ return state;
+ }
};
export default tasksReducer;
diff --git a/src/reducers/ui.js b/src/reducers/ui.js
index df91eab..3d7174f 100644
--- a/src/reducers/ui.js
+++ b/src/reducers/ui.js
@@ -1,5 +1,5 @@
// reducer for UI
-import { SET_LOADER } from '../actions/ui';
+import { SET_LOADER, SET_NOTIFICATION } from '../actions/ui';
import initialState from './initialState';
const uiReducer = (state = initialState.ui, action) => {
@@ -9,6 +9,13 @@ const uiReducer = (state = initialState.ui, action) => {
...state,
loading: action.payload
};
+ case SET_NOTIFICATION:
+ let newNotifications = [...state.notifcations];
+ newNotifications.push(action.payload);
+ return {
+ ...state,
+ notifications: newNotifications
+ };
default:
return state;
}
diff --git a/src/store/index.js b/src/store/index.js
index f870304..55057c2 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -1,9 +1,22 @@
import { createStore } from 'redux';
-
import rootReducer from '../reducers';
+import { applyMiddleware, compose } from 'redux';
+// app middlewares
+import { apiMiddleware } from '../middlewares/api';
+import { tasksMiddleware } from '../middlewares/tasks';
+
+const coreMiddlewares = [
+ apiMiddleware
+];
+
+const featureMiddlewares = [
+ tasksMiddleware
+];
+
+const enhancer = compose(applyMiddleware(...featureMiddlewares, ...coreMiddlewares));
function configureStore() {
- const store = createStore(rootReducer, {});
+ const store = createStore(rootReducer, {}, enhancer);
return store;
}