diff --git a/client/package-lock.json b/client/package-lock.json
index 635b1c5..e23fc13 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -3235,9 +3235,9 @@
"dev": true
},
"bulma": {
- "version": "0.7.5",
- "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.7.5.tgz",
- "integrity": "sha512-cX98TIn0I6sKba/DhW0FBjtaDpxTelU166pf7ICXpCCuplHWyu6C9LYZmL5PEsnePIeJaiorsTEzzNk3Tsm1hw=="
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.0.tgz",
+ "integrity": "sha512-rV75CJkubNUroAt0qCRkjznZLoaXq/ctfMXsMvKSL84UetbSyx5REl96e8GoQ04G4Tkw0XF3STECffTOQrbzOQ=="
},
"bulma-switch": {
"version": "2.0.0",
diff --git a/client/package.json b/client/package.json
index d5cf484..a5edbbc 100644
--- a/client/package.json
+++ b/client/package.json
@@ -58,7 +58,7 @@
"apollo-link-http": "^1.5.17",
"apollo-link-ws": "^1.0.20",
"apollo-utilities": "^1.3.4",
- "bulma": "^0.7.2",
+ "bulma": "^0.9.0",
"bulma-switch": "^2.0.0",
"graphql": "^15.3.0",
"graphql-request": "^2.0.0",
diff --git a/client/src/components/HomePage/Dashboard.tsx b/client/src/components/HomePage/Dashboard.tsx
index 408087a..925ae03 100644
--- a/client/src/components/HomePage/Dashboard.tsx
+++ b/client/src/components/HomePage/Dashboard.tsx
@@ -1,25 +1,20 @@
-import React from 'react';
+import React, { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { fetchWorkgroups } from '../../store/actions/workgroups';
+import { RootState } from '../../store/reducers/root';
+import { WorkgroupsPanel } from './WorkgroupsPanel';
export function Dashboard() {
return (
-
-
-
-
Groupes de travail
-
-
-
-
-
-
+
-
D.à.Ds
+ D.A.Ds
diff --git a/client/src/components/HomePage/WorkgroupsPanel.tsx b/client/src/components/HomePage/WorkgroupsPanel.tsx
new file mode 100644
index 0000000..5e6f48a
--- /dev/null
+++ b/client/src/components/HomePage/WorkgroupsPanel.tsx
@@ -0,0 +1,96 @@
+import React, { useEffect, useState } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { RootState } from '../../store/reducers/root';
+import { fetchWorkgroups } from '../../store/actions/workgroups';
+import { Workgroup } from '../../types/workgroup';
+import { User } from '../../types/user';
+import { Link } from 'react-router-dom';
+
+export function WorkgroupsPanel() {
+ const dispatch = useDispatch();
+ const workgroups = useSelector
(state => state.workgroups.workgroupsById);
+ const currentUserId = useSelector(state => state.auth.currentUser.id);
+
+ const filterTabs = [
+ {
+ label: "Mes groupes",
+ filter: workgroups => Object.values(workgroups).filter((wg: Workgroup) => {
+ return wg.members.some((u: User) => u.id === currentUserId);
+ })
+ },
+ {
+ label: "Ouverts",
+ filter: workgroups => Object.values(workgroups).filter((wg: Workgroup) => !wg.closedAt)
+ },
+ {
+ label: "Clôs",
+ filter: workgroups => Object.values(workgroups).filter((wg: Workgroup) => !!wg.closedAt)
+ }
+ ];
+
+ const [ state, setState ] = useState({ selectedTab: 0 });
+
+ const selectTab = (tabIndex: number) => {
+ setState(state => ({ ...state, selectedTab: tabIndex }));
+ }
+
+ useEffect(() => {
+ dispatch(fetchWorkgroups());
+ }, []);
+
+ const workgroupsItems = filterTabs[state.selectedTab].filter(workgroups).map((wg: Workgroup) => {
+ return (
+
+
+
+
+ {wg.name}
+
+ );
+ })
+
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/client/src/store/actions/workgroups.ts b/client/src/store/actions/workgroups.ts
new file mode 100644
index 0000000..6894390
--- /dev/null
+++ b/client/src/store/actions/workgroups.ts
@@ -0,0 +1,19 @@
+import { Action } from "redux";
+import { Workgroup } from "../../types/workgroup";
+
+export const FETCH_WORKGROUPS_REQUEST = 'FETCH_WORKGROUPS_REQUEST';
+export const FETCH_WORKGROUPS_SUCCESS = 'FETCH_WORKGROUPS_SUCCESS';
+export const FETCH_WORKGROUPS_FAILURE = 'FETCH_WORKGROUPS_FAILURE';
+
+export interface fetchWorkgroupsRequestAction extends Action {
+
+}
+
+export interface fetchWorkgroupsSuccessAction extends Action {
+ workgroups: [Workgroup]
+}
+
+
+export function fetchWorkgroups(): fetchWorkgroupsRequestAction {
+ return { type: FETCH_WORKGROUPS_REQUEST }
+}
\ No newline at end of file
diff --git a/client/src/store/reducers/auth.ts b/client/src/store/reducers/auth.ts
index 2192326..c37ba47 100644
--- a/client/src/store/reducers/auth.ts
+++ b/client/src/store/reducers/auth.ts
@@ -31,6 +31,7 @@ function handleSetCurrentUser(state: AuthState, { email }: setCurrentUserAction)
...state,
isAuthenticated: true,
currentUser: {
+ id: '',
email
}
};
diff --git a/client/src/store/reducers/root.ts b/client/src/store/reducers/root.ts
index 5835800..337b8b0 100644
--- a/client/src/store/reducers/root.ts
+++ b/client/src/store/reducers/root.ts
@@ -1,13 +1,16 @@
import { combineReducers } from 'redux';
import { flagsReducer, FlagsState } from './flags';
import { authReducer, AuthState } from './auth';
+import { workgroupsReducer, WorkgroupsState } from './workgroups';
export interface RootState {
auth: AuthState,
flags: FlagsState,
+ workgroups: WorkgroupsState,
}
export const rootReducer = combineReducers({
flags: flagsReducer,
auth: authReducer,
+ workgroups: workgroupsReducer,
});
\ No newline at end of file
diff --git a/client/src/store/reducers/workgroups.ts b/client/src/store/reducers/workgroups.ts
new file mode 100644
index 0000000..c692167
--- /dev/null
+++ b/client/src/store/reducers/workgroups.ts
@@ -0,0 +1,38 @@
+import { Action } from "redux";
+import { User } from "../../types/user";
+import { SET_CURRENT_USER, setCurrentUserAction } from "../actions/auth";
+import { FETCH_PROFILE_SUCCESS, fetchProfileSuccessAction, updateProfileSuccessAction, UPDATE_PROFILE_SUCCESS, updateProfileRequestAction } from "../actions/profile";
+import { Workgroup } from "../../types/workgroup";
+import { FETCH_WORKGROUPS_SUCCESS, fetchWorkgroupsSuccessAction } from "../actions/workgroups";
+
+export interface WorkgroupsState {
+ workgroupsById: { [id in string]: Workgroup }
+}
+
+const defaultState = {
+ workgroupsById: {}
+};
+
+export function workgroupsReducer(state = defaultState, action: Action): WorkgroupsState {
+ switch (action.type) {
+ case FETCH_WORKGROUPS_SUCCESS:
+ return handleFetchWorkgroups(state, action as fetchWorkgroupsSuccessAction);
+
+ }
+ return state;
+}
+
+function handleFetchWorkgroups(state: WorkgroupsState, { workgroups }: fetchWorkgroupsSuccessAction): WorkgroupsState {
+ const workgroupsById = {
+ ...state.workgroupsById,
+ };
+
+ workgroups.forEach(wg => {
+ workgroupsById[wg.id] = wg;
+ });
+
+ return {
+ ...state,
+ workgroupsById,
+ };
+};
\ No newline at end of file
diff --git a/client/src/store/sagas/root.ts b/client/src/store/sagas/root.ts
index 6a1c770..b09eca5 100644
--- a/client/src/store/sagas/root.ts
+++ b/client/src/store/sagas/root.ts
@@ -2,11 +2,13 @@ import { all } from 'redux-saga/effects';
import { failureRootSaga } from './failure';
import { initRootSaga } from './init';
import { profileRootSaga } from './profile';
+import { workgroupsRootSaga } from './workgroups';
export function* rootSaga() {
yield all([
initRootSaga(),
failureRootSaga(),
profileRootSaga(),
+ workgroupsRootSaga(),
]);
}
diff --git a/client/src/store/sagas/workgroups.ts b/client/src/store/sagas/workgroups.ts
new file mode 100644
index 0000000..a6d9cc3
--- /dev/null
+++ b/client/src/store/sagas/workgroups.ts
@@ -0,0 +1,25 @@
+import { getClient } from "../../util/daddy";
+import { Config } from "../../config";
+import { all, takeLatest, put } from "redux-saga/effects";
+import { FETCH_WORKGROUPS_SUCCESS, FETCH_WORKGROUPS_FAILURE, FETCH_WORKGROUPS_REQUEST } from "../actions/workgroups";
+import { Workgroup } from "../../types/workgroup";
+
+export function* workgroupsRootSaga() {
+ yield all([
+ takeLatest(FETCH_WORKGROUPS_REQUEST, fetchWorkgroupsSaga),
+ ]);
+}
+
+export function* fetchWorkgroupsSaga() {
+ const client = getClient(Config.graphQLEndpoint, Config.subscriptionEndpoint);
+
+ let workgroups: [Workgroup];
+ try {
+ workgroups = yield client.fetchWorkgroups().then(result => result.workgroups);
+ } catch(err) {
+ yield put({ type: FETCH_WORKGROUPS_FAILURE, err });
+ return;
+ }
+
+ yield put({type: FETCH_WORKGROUPS_SUCCESS, workgroups });
+}
\ No newline at end of file
diff --git a/client/src/types/user.ts b/client/src/types/user.ts
index 4fc773d..2fae681 100644
--- a/client/src/types/user.ts
+++ b/client/src/types/user.ts
@@ -1,4 +1,5 @@
export interface User {
+ id: string
email: string
name?: string
connectedAt?: Date
diff --git a/client/src/types/workgroup.ts b/client/src/types/workgroup.ts
new file mode 100644
index 0000000..459f29a
--- /dev/null
+++ b/client/src/types/workgroup.ts
@@ -0,0 +1,9 @@
+import { User } from "./user";
+
+export interface Workgroup {
+ id: string
+ name: string
+ createdAt: Date
+ closedAt: Date
+ members: [User]
+}
\ No newline at end of file
diff --git a/client/src/util/daddy.ts b/client/src/util/daddy.ts
index 8c439fd..aa48178 100644
--- a/client/src/util/daddy.ts
+++ b/client/src/util/daddy.ts
@@ -79,6 +79,7 @@ export class DaddyClient {
query: gql`
query {
userProfile {
+ id,
name,
email,
createdAt,
@@ -89,6 +90,24 @@ export class DaddyClient {
.then(this.assertAuthorization)
}
+ fetchWorkgroups() {
+ return this.gql.query({
+ query: gql`
+ query {
+ workgroups {
+ id,
+ name,
+ createdAt,
+ closedAt,
+ members {
+ id
+ }
+ }
+ }`
+ })
+ .then(this.assertAuthorization)
+ }
+
updateProfile(changes: ProfileChanges) {
return this.gql.mutate({
variables: {