diff --git a/frontend/package-lock.json b/frontend/package-lock.json index fe47878..b460cc7 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -5107,7 +5107,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -5125,11 +5126,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5142,15 +5145,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5253,7 +5259,8 @@ }, "inherits": { "version": "2.0.4", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5263,6 +5270,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5275,17 +5283,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.9.0", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5302,6 +5313,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5382,7 +5394,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5392,6 +5405,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5467,7 +5481,8 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5497,6 +5512,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5514,6 +5530,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5552,11 +5569,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.1.1", - "bundled": true + "bundled": true, + "optional": true } } }, diff --git a/frontend/src/actions/project.js b/frontend/src/actions/project.js new file mode 100644 index 0000000..fc03b46 --- /dev/null +++ b/frontend/src/actions/project.js @@ -0,0 +1,27 @@ +export const PROJECT_USER_LIST = 'PROJECT_USER_LIST'; +export const PROJECT_USER_LIST_SUCCESS = 'PROJECT_USER_LIST_SUCCESS'; +export const PROJECT_USER_LIST_FAILURE = 'PROJECT_USER_LIST_FAILURE'; + +export function projectUserListRequest() { + return { type: PROJECT_USER_LIST} +} +export function projectUserListSuccess(projects) { + return { type: PROJECT_USER_LIST_SUCCESS, projects } +} +export function projectUserListFailure(error) { + return { type: PROJECT_USER_LIST_FAILURE, error } +} + +export const PROJECT_LIST = 'PROJECT_LIST'; +export const PROJECT_LIST_SUCCESS = 'PROJECT_LIST_SUCCESS'; +export const PROJECT_LIST_FAILURE = 'PROJECT_LIST_FAILURE'; + +export function projectList() { + return { type: PROJECT_LIST} +} +export function projectListSuccess(projects) { + return { type: PROJECT_LIST_SUCCESS, projects } +} +export function projectListFailure(error) { + return { type: PROJECT_LIST_FAILURE, error } +} \ No newline at end of file diff --git a/frontend/src/app.js b/frontend/src/app.js index 886df5a..5da2f9f 100644 --- a/frontend/src/app.js +++ b/frontend/src/app.js @@ -3,6 +3,8 @@ import { hot } from 'react-hot-loader' import { HashRouter } from 'react-router-dom' // ou BrowserRouter import { Route, Switch, Redirect } from 'react-router' import HomePage from './pages/home'; +import DashBoardClient from './pages/DashBoardClient'; +import DashBoardDev from './pages/DashBoardDev'; class App extends Component { render () { @@ -11,6 +13,8 @@ class App extends Component { + + } /> diff --git a/frontend/src/components/ProjectList.js b/frontend/src/components/ProjectList.js new file mode 100644 index 0000000..35bd13d --- /dev/null +++ b/frontend/src/components/ProjectList.js @@ -0,0 +1,12 @@ +import React from 'react' +import ProjectTile from './ProjectTile' + +export default ({ projects, withRequest }) => ( +
+ { + projects.map(project => ( + + )) + } +
+) diff --git a/frontend/src/components/ProjectTile.js b/frontend/src/components/ProjectTile.js new file mode 100644 index 0000000..ca4b6df --- /dev/null +++ b/frontend/src/components/ProjectTile.js @@ -0,0 +1,11 @@ +import React from 'react' +import RequestList from './RequestList' + +export default ({ project, withRequest }) => ( +
+

{project.name}

+ { + withRequest && + } +
+) diff --git a/frontend/src/components/RequestList.js b/frontend/src/components/RequestList.js new file mode 100644 index 0000000..bb45a75 --- /dev/null +++ b/frontend/src/components/RequestList.js @@ -0,0 +1,12 @@ +import React from 'react' +import RequestTile from './RequestTile' + +export default ({ requests }) => ( +
+ { + requests.map(request => ( + + )) + } +
+) diff --git a/frontend/src/components/RequestTile.css b/frontend/src/components/RequestTile.css new file mode 100644 index 0000000..124d2eb --- /dev/null +++ b/frontend/src/components/RequestTile.css @@ -0,0 +1,19 @@ +.request-status-en-attente { + background-color: orange !important; +} + +.request-status-pris-en-compte { + background-color: palevioletred !important; +} + +.request-status-en-cours-de-traitement { + background-color: greenyellow !important; +} + +.request-status-traite { + background-color: green !important; +} + +.request-status-clos { + background-color: black !important; +} diff --git a/frontend/src/components/RequestTile.js b/frontend/src/components/RequestTile.js new file mode 100644 index 0000000..6338754 --- /dev/null +++ b/frontend/src/components/RequestTile.js @@ -0,0 +1,14 @@ +import React from 'react' +import styles from './RequestTile.css' +import { Link } from 'react-router-dom' + +export default ({ request }) => ( + +
+

{request.title}

+
+ {request.author} || {request.createdAt} +
+
+ +) diff --git a/frontend/src/pages/DashBoardClient.js b/frontend/src/pages/DashBoardClient.js new file mode 100644 index 0000000..6f4ad8b --- /dev/null +++ b/frontend/src/pages/DashBoardClient.js @@ -0,0 +1,97 @@ +import React, { useEffect } from 'react' +import { connect } from 'react-redux' +import Page from './page'; +import ProjectList from '../components/ProjectList'; +import { projectUserListRequest } from '../actions/project'; + +const DashBoardClient = ({ projects = [], ...props }) => { + + useEffect(() => { + props.dispatch(projectUserListRequest()) + }, []) + projects = [ + { + id: 1, + name: 'mon premier projet', + requests: [ + { + id: 1, + title: 'Demande num 1', + author: 'Gael Peltey', + status: { + id: 1, + slug: 'en-attente' + }, + createdAt: 'le 20 juillet 2019' + }, + { + id: 2, + title: 'Demande num 2', + author: 'Jean Guy', + status: { + id: 2, + slug: 'pris-en-compte' + }, + createdAt: 'le 20 juillet 2020' + }, + { + id: 3, + title: 'Demande num 3', + author: 'Gael Peltey', + status: { + id: 3, + slug: 'en-cours-de-traitement' + }, + createdAt: 'le 20 juillet 2021' + } + + ] + }, + { + id: 2, + name: 'mon deuxième projet', + }, + { + id: 3, + name: 'mon troisième projet', + requests: [ + { + id: 4, + title: 'Demande num 4', + author: 'David Pujadas', + status: { + id: 4, + slug: 'traite' + }, + createdAt: 'le 20 juillet 2022' + }, + { + id: 5, + title: 'Demande num 5', + author: 'Jean Mi', + status: { + id: 5, + slug: 'clos' + }, + createdAt: 'le 20 juillet 2023' + } + + ] + }, + ] + return ( + +
+

Mon dashboard

+
+ +
+ ); + } + + +const mapStateToProps = ({ project }) => ({ + projects: project.items, +}) + +export default connect(mapStateToProps)(DashBoardClient) \ No newline at end of file diff --git a/frontend/src/pages/DashBoardDev.js b/frontend/src/pages/DashBoardDev.js new file mode 100644 index 0000000..1c0d68b --- /dev/null +++ b/frontend/src/pages/DashBoardDev.js @@ -0,0 +1,97 @@ +import React, { useEffect } from 'react' +import { connect } from 'react-redux' +import Page from './page'; +import ProjectList from '../components/ProjectList'; +import { projectList } from '../actions/project'; + +const DashBoardDev = ({ projects = [], ...props }) => { + + useEffect(() => { + props.dispatch(projectList()) + }, []) + projects = [ + { + id: 1, + name: 'mon premier projet', + requests: [ + { + id: 1, + title: 'Demande num 1', + author: 'Gael Peltey', + status: { + id: 1, + slug: 'en-attente' + }, + createdAt: 'le 20 juillet 2019' + }, + { + id: 2, + title: 'Demande num 2', + author: 'Jean Guy', + status: { + id: 2, + slug: 'pris-en-compte' + }, + createdAt: 'le 20 juillet 2020' + }, + { + id: 3, + title: 'Demande num 3', + author: 'Gael Peltey', + status: { + id: 3, + slug: 'en-cours-de-traitement' + }, + createdAt: 'le 20 juillet 2021' + } + + ] + }, + { + id: 2, + name: 'mon deuxième projet', + }, + { + id: 3, + name: 'mon troisième projet', + requests: [ + { + id: 4, + title: 'Demande num 4', + author: 'David Pujadas', + status: { + id: 4, + slug: 'traite' + }, + createdAt: 'le 20 juillet 2022' + }, + { + id: 5, + title: 'Demande num 5', + author: 'Jean Mi', + status: { + id: 5, + slug: 'clos' + }, + createdAt: 'le 20 juillet 2023' + } + + ] + }, + ] + return ( + +
+

Developpeur Dashboard

+
+ +
+ ); + } + + +const mapStateToProps = ({ project }) => ({ + projects: project.items, +}) + +export default connect(mapStateToProps)(DashBoardDev) \ No newline at end of file diff --git a/frontend/src/pages/page.js b/frontend/src/pages/page.js index fb32593..14d62a4 100644 --- a/frontend/src/pages/page.js +++ b/frontend/src/pages/page.js @@ -6,7 +6,7 @@ export default function Page({ title, children }) { }); return ( -
+
{ children }
); diff --git a/frontend/src/reducers/project.js b/frontend/src/reducers/project.js new file mode 100644 index 0000000..6e74768 --- /dev/null +++ b/frontend/src/reducers/project.js @@ -0,0 +1,31 @@ +import { + PROJECT_USER_LIST_SUCCESS, + PROJECT_USER_LIST_FAILURE +} from '../actions/project' + +const initialState = { + items: [] +} + +export default (state = initialState, action) => { + + console.log(`Action: ${JSON.stringify(action)}`) + + switch (action.type) { + + case PROJECT_USER_LIST_SUCCESS: + return { + ...state, + items: action.projects + } + case PROJECT_USER_LIST_FAILURE: + return { + ...state, + items: [], + error: action.error + } + + } + return state + +} \ No newline at end of file diff --git a/frontend/src/sagas/project.js b/frontend/src/sagas/project.js new file mode 100644 index 0000000..a7cdb22 --- /dev/null +++ b/frontend/src/sagas/project.js @@ -0,0 +1,53 @@ +import { call, put } from 'redux-saga/effects'; +import { projectUserListFailure, projectUserListSuccess, projectListFailure, projectListSuccess } from '../actions/project'; + +export function* projectUserListSaga() { + let result + try { + result = yield call(projectUserList); + } catch(err) { + yield put(projectUserListFailure(err)); + return + } + + if ('error' in result) { + yield put(projectUserListFailure(result.error)); + return + } + + yield put(projectUserListSuccess(result.data)); +} + +const projectUserList = () => { + return fetch('http://localhost:8001/api/v1/me', { + method: 'GET', + mode: 'cors', + credentials: 'include' + }).then(res => res.json()) +} + + +export function* projectListSaga() { + let result + try { + result = yield call(projectList); + } catch(err) { + yield put(projectListFailure(err)); + return + } + + if ('error' in result) { + yield put(projectListFailure(result.error)); + return + } + + yield put(projectListSuccess(result.data)); +} + +const projectList = () => { + return fetch('http://localhost:8001/api/v1/projects', { + method: 'GET', + mode: 'cors', + credentials: 'include' + }).then(res => res.json()) +} \ No newline at end of file diff --git a/frontend/src/sagas/root.js b/frontend/src/sagas/root.js index 879634f..0c1d506 100644 --- a/frontend/src/sagas/root.js +++ b/frontend/src/sagas/root.js @@ -1,7 +1,10 @@ import { all, takeLatest } from 'redux-saga/effects'; +import { PROJECT_USER_LIST, PROJECT_LIST } from '../actions/project'; +import { projectUserListSaga, projectListSaga } from './project'; export default function* rootSaga() { yield all([ - + takeLatest(PROJECT_USER_LIST, projectUserListSaga), + takeLatest(PROJECT_LIST, projectListSaga), ]); } diff --git a/frontend/src/store/store.js b/frontend/src/store/store.js index 521df0a..80732a8 100644 --- a/frontend/src/store/store.js +++ b/frontend/src/store/store.js @@ -1,11 +1,12 @@ import { createStore, applyMiddleware, combineReducers, compose } from 'redux' import createSagaMiddleware from 'redux-saga' import rootSaga from '../sagas/root' +import project from '../reducers/project' const sagaMiddleware = createSagaMiddleware() const rootReducer = combineReducers({ - // Ajouter vos reducers ici + project }); const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;