Browse Source

Merge pull request #6 from Skylsmoi/master

Skylsmoi 6 years ago
parent
commit
5559d06c54
No account linked to committer's email
81 changed files with 5240 additions and 274 deletions
  1. 7 0
      dist/dev/bootstrap-4.0.0-beta.2.js
  2. 7 0
      dist/dev/bootstrap-4.0.0-beta.css
  3. 4 0
      dist/dev/jquery-3.2.1.js
  4. 5 0
      dist/dev/popper-1.12.3.js
  5. 105 2
      dist/index.html
  6. 9 5
      jsonserver/server.js
  7. 71 6
      jsonserver/static_db.json
  8. 3 0
      package.json
  9. 27 5
      src/action-creator.async.js
  10. 7 0
      src/action-creator.sync.js
  11. 0 29
      src/component/ConnectionForm.jsx
  12. 0 29
      src/component/HeaderTpl.jsx
  13. 23 0
      src/component/Login/LoginBtnForgotPw.jsx
  14. 20 0
      src/component/Login/LoginLogo.jsx
  15. 225 0
      src/component/Sidebar/WorkspaceListItem.jsx
  16. 122 0
      src/component/Timeline.jsx
  17. 62 0
      src/component/Workspace/FileContentViewer.jsx
  18. 70 0
      src/component/Workspace/FileItem.jsx
  19. 25 0
      src/component/Workspace/FileItemHeader.jsx
  20. 75 0
      src/component/Workspace/FileType/File.jsx
  21. 16 0
      src/component/Workspace/FileType/PageHtml.jsx
  22. 197 0
      src/component/Workspace/FileType/Thread.jsx
  23. 80 0
      src/component/Workspace/Folder.jsx
  24. 33 0
      src/component/common/Card/Card.jsx
  25. 24 0
      src/component/common/Card/CardBody.jsx
  26. 22 0
      src/component/common/Card/CardHeader.jsx
  27. 19 0
      src/component/common/Input/BtnSwitch.jsx
  28. 33 0
      src/component/common/Input/Button.jsx
  29. 46 0
      src/component/common/Input/DropdownCreateButton.jsx
  30. 35 0
      src/component/common/Input/InputCheckbox.jsx
  31. 44 0
      src/component/common/Input/InputGroupText.jsx
  32. 42 0
      src/component/common/PopinFixed/PopinFixed.jsx
  33. 42 0
      src/component/common/PopinFixed/PopinFixedContent.jsx
  34. 42 0
      src/component/common/PopinFixed/PopinFixedHeader.jsx
  35. 67 0
      src/component/common/PopinFixed/PopinFixedOption.jsx
  36. 23 0
      src/component/common/layout/PageContent.jsx
  37. 27 0
      src/component/common/layout/PageTitle.jsx
  38. 35 0
      src/component/common/layout/PageWrapper.jsx
  39. 327 0
      src/container/AccountPage.jsx
  40. 372 0
      src/container/Dashboard.jsx
  41. 3 12
      src/container/Header.jsx
  42. 86 85
      src/container/Login.jsx
  43. 0 16
      src/container/Page.jsx
  44. 6 8
      src/container/PrivateRoute.jsx
  45. 78 0
      src/container/Sidebar.jsx
  46. 37 6
      src/container/Tracim.jsx
  47. 82 0
      src/container/WorkspaceContent.jsx
  48. 302 0
      src/css/AccountPage.styl
  49. 356 0
      src/css/Dashboard.styl
  50. 275 0
      src/css/File.styl
  51. 34 0
      src/css/FileItem.styl
  52. 13 0
      src/css/FileItemHeader.styl
  53. 120 0
      src/css/Folder.styl
  54. 1 1
      src/css/Footer.styl
  55. 265 0
      src/css/Generic.styl
  56. 21 43
      src/css/Header.styl
  57. 97 0
      src/css/Login.styl
  58. 173 0
      src/css/PageHtml.styl
  59. 277 0
      src/css/PagePreview.styl
  60. 98 0
      src/css/Sidebar.styl
  61. 56 0
      src/css/Thread.styl
  62. 141 0
      src/css/Timeline.styl
  63. 59 20
      src/css/Variable.styl
  64. 21 0
      src/css/Workspace.styl
  65. 55 0
      src/css/btnSwtich.styl
  66. 30 3
      src/css/index.styl
  67. 26 0
      src/helper.js
  68. BIN
      src/img/excel.png
  69. BIN
      src/img/imgProfil-reverse.png
  70. BIN
      src/img/imgProfil.png
  71. BIN
      src/img/listmemberbtn.png
  72. 50 0
      src/img/logoTracimWhite.svg
  73. BIN
      src/img/pdf.jpg
  74. BIN
      src/img/tracimLogoAsBg.png
  75. 22 0
      src/reducer/activeFileContent.js
  76. 10 0
      src/reducer/fileType/index.js
  77. 10 0
      src/reducer/fileType/pageHtml.js
  78. 3 1
      src/reducer/root.js
  79. 14 2
      src/reducer/user.js
  80. 23 0
      src/reducer/workspace.js
  81. 3 1
      webpack.config.js

File diff suppressed because it is too large
+ 7 - 0
dist/dev/bootstrap-4.0.0-beta.2.js


File diff suppressed because it is too large
+ 7 - 0
dist/dev/bootstrap-4.0.0-beta.css


File diff suppressed because it is too large
+ 4 - 0
dist/dev/jquery-3.2.1.js


File diff suppressed because it is too large
+ 5 - 0
dist/dev/popper-1.12.3.js


+ 105 - 2
dist/index.html View File

@@ -8,17 +8,120 @@
8 8
 
9 9
     <link rel="stylesheet" type="text/css" href="./font/font-awesome-4.7.0/css/font-awesome.css">
10 10
     <link href="https://fonts.googleapis.com/css?family=Quicksand:300,400,500,700" rel="stylesheet">
11
+    <!--
11 12
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
12
-    <!--link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous"-->
13
-    <!--link rel='stylesheet' href='asset/font-awesome-4.7.0/css/font-awesome.min.css'-->
13
+    -->
14
+    <link rel="stylesheet" type="text/css" href="./dev/bootstrap-4.0.0-beta.css">
14 15
   </head>
15 16
   <body>
16 17
     <div id='content'></div>
17 18
 
18 19
     <script src='tracim.vendor.bundle.js'></script>
19 20
     <script src='tracim.app.entry.js'></script>
21
+
22
+    <!--
20 23
     <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
21 24
     <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
22 25
     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
26
+    -->
27
+    <script src="./dev/jquery-3.2.1.js"></script>
28
+    <script src="./dev/popper-1.12.3.js"></script>
29
+    <script src="./dev/bootstrap-4.0.0-beta.2.js"></script>
30
+
31
+    <script type="text/javascript">
32
+      if (window.matchMedia("(min-width:1200px)").matches) {
33
+
34
+        var jsScript = document.createElement("script");
35
+        jsScript.type = "text/javascript";
36
+        jsScript.src = "https://cloud.tinymce.com/stable/tinymce.min.js?apiKey=dfdhxdokxj2wagzkbxfgysgh86d6rr9m3dln0172vo3shipc";
37
+
38
+        jsScript.onload = function() {
39
+          function base64EncodeAndTinyMceInsert (files) {
40
+            for (var i = 0; i < files.length; i++) {
41
+              if (files[i].size > 1000000)
42
+                files[i].allowed = confirm(files[i].name + " fait plus de 1mo et peut prendre du temps à insérer, voulez-vous continuer ?")
43
+            }
44
+
45
+            for (var i = 0; i < files.length; i++) {
46
+              if (files[i].allowed !== false && files[i].type.match('image.*')) {
47
+                var img = document.createElement('img')
48
+
49
+                var fr = new FileReader()
50
+
51
+                fr.readAsDataURL(files[i])
52
+
53
+                fr.onloadend = function (e) {
54
+                  img.src = e.target.result
55
+                  tinymce.activeEditor.execCommand('mceInsertContent', false, img.outerHTML)
56
+                }
57
+              }
58
+            }
59
+          }
60
+
61
+          // HACK: The tiny mce source code modal contain a textarea, but we
62
+          // can't edit it (like it's readonly). The following solution
63
+          // solve the bug: https://stackoverflow.com/questions/36952148/tinymce-code-editor-is-readonly-in-jtable-grid
64
+          $(document).on('focusin', function(e) {
65
+            if ($(e.target).closest(".mce-window").length) {
66
+              e.stopImmediatePropagation();
67
+            }
68
+          });
69
+
70
+          tinymce.init({
71
+            selector: 'textarea',
72
+            height: 130,
73
+            // width: 530,
74
+            menubar: false,
75
+            resize: false,
76
+            plugins: [
77
+              'advlist autolink lists link image charmap print preview anchor textcolor',
78
+              'searchreplace visualblocks code fullscreen',
79
+              'insertdatetime media table contextmenu paste code help'
80
+            ],
81
+            toolbar: 'insert | formatselect | bold italic underline strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify  | numlist bullist outdent indent  | table | code ',
82
+            content_css: [
83
+              '//fonts.googleapis.com/css?family=Lato:300,300i,400,400i',
84
+              '//www.tinymce.com/css/codepen.min.css'
85
+            ],
86
+            setup: function ($editor) {
87
+              //////////////////////////////////////////////
88
+              // add custom btn to handle image by selecting them with system explorer
89
+              $editor.addButton('customInsertImage', {
90
+                icon: 'mce-ico mce-i-image',
91
+                title: 'Image',
92
+                onclick: function () {
93
+                  var hiddenTinyMceInput = $('#hidden_tinymce_fileinput')
94
+
95
+                  if (hiddenTinyMceInput.length > 0) hiddenTinyMceInput.remove()
96
+
97
+                  fileTag = document.createElement('input')
98
+                  fileTag.id = 'hidden_tinymce_fileinput'
99
+                  fileTag.type = 'file'
100
+                  $('body').append(fileTag)
101
+
102
+                  hiddenTinyMceInput.on('change', function () {
103
+                    base64EncodeAndTinyMceInsert($(this)[0].files)
104
+                  })
105
+
106
+                  hiddenTinyMceInput.click()
107
+                }
108
+              })
109
+
110
+              //////////////////////////////////////////////
111
+              // Handle drag & drop image into TinyMce by encoding them in base64 (to avoid uploading them somewhere and keep saving comment in string format)
112
+              $editor
113
+                .on('drag dragstart dragend dragover dragenter dragleave drop', function (e) {
114
+                  e.preventDefault()
115
+                  e.stopPropagation()
116
+                })
117
+                .on('drop', function(e) {
118
+                  base64EncodeAndTinyMceInsert(e.dataTransfer.files)
119
+                })
120
+            }
121
+          });
122
+        }
123
+        document.getElementsByTagName("body")[0].appendChild(jsScript);
124
+      }
125
+    </script>
23 126
   </body>
24 127
 </html>

+ 9 - 5
jsonserver/server.js View File

@@ -11,20 +11,24 @@ server.use(jsonServer.bodyParser)
11 11
 // res.jsonp(req.query)
12 12
 server.get('/echo', (req, res) => res.jsonp('gg'))
13 13
 server.get('/login', (req, res) => res.jsonp(jsonDb.login))
14
-server.post('/user/login', (req, res) => {
15
-  if (req.body.login !== '' && req.body.password !== '') return res.jsonp(jsonDb.user_logged)
16
-  else return res.jsonp('error')
17
-})
18 14
 server.get('/user_logged', (req, res) => res.jsonp(jsonDb.user_logged))
19 15
 server.delete('/deletenodata', (req,res) => res.status(204).jsonp(''))
20 16
 server.patch('/user', (req, res) => res.jsonp({lang: 'fr'}))
21
-
22 17
 // server.put('/api/data/raw_materials_vendors/:vendorid', (req, res) => {
23 18
 //  res.jsonp(jsonVendorColorData.vendorVariableData)
24 19
 //   console.log(req.body)
25 20
 //   res.jsonp('gg')
26 21
 // })
27 22
 
23
+server.post('/user/login', (req, res) => {
24
+  if (req.body.login !== '' && req.body.password !== '') return res.jsonp(jsonDb.user_logged)
25
+  else return res.jsonp('error')
26
+})
27
+
28
+server.get('/user/is_logged_in', (req, res) => res.jsonp(jsonDb.user_logged))
29
+
30
+server.get('/workspace/:id', (req, res) => res.jsonp(jsonDb.workspace_detail))
31
+
28 32
 server.use(router)
29 33
 server.listen(GLOBAL_PORT, () => {
30 34
   console.log('JSON Server is running on port : ' + GLOBAL_PORT)

+ 71 - 6
jsonserver/static_db.json View File

@@ -1,10 +1,75 @@
1 1
 {
2
-  "login": true,
3 2
   "user_logged": {
4
-    "id": 5,
5
-    "username": "Smoi",
6
-    "firstname": "Côme",
7
-    "lastname": "Stoilenom",
8
-    "email": "osef@algoo.fr"
3
+    "logged": true,
4
+    "user": {
5
+      "id": 5,
6
+      "username": "Smoi",
7
+      "firstname": "Côme",
8
+      "lastname": "Stoilenom",
9
+      "email": "osef@algoo.fr"
10
+    }
11
+  },
12
+  "workspace_detail": {
13
+    "id": 1,
14
+    "title": "Mission interne - développement",
15
+    "owner_id": 5,
16
+    "content": [
17
+      {
18
+        "id": 1,
19
+        "title": "La programmation fonctionnelle",
20
+        "type": "pageHtml",
21
+        "status": "validated",
22
+        "text": "<h1>Mon titre nul</h1>Je suis le contenu de cette fameuse <b>page HTML</b><br /> sur la programmation fonctionnelle"
23
+      },
24
+      {
25
+        "id": 2,
26
+        "title": "La prommation fonctionnelle est-elle vraiment utile ?",
27
+        "type": "thread",
28
+        "status": "current"
29
+      },
30
+      {
31
+        "id": 6,
32
+        "title": "Une photo moche",
33
+        "type": "file",
34
+        "status": "current"
35
+      },
36
+      {
37
+        "id": 10,
38
+        "title": "le README.md d'un random repo github",
39
+        "type": "pageMarkdown",
40
+        "status": "current"
41
+      },
42
+      {
43
+        "id": 7,
44
+        "title": "Une liste de truc à faire que je ferai jamais",
45
+        "type": "task",
46
+        "status": "current"
47
+      },
48
+      {
49
+        "id": 8,
50
+        "title": "Ça, ça marche pas. Merci de le fix",
51
+        "type": "issue",
52
+        "status": "current"
53
+      },
54
+      {
55
+        "id": 3,
56
+        "title": "Programmation objet",
57
+        "type": "folder",
58
+        "content": [
59
+          {
60
+            "id": 4,
61
+            "title": "des trucs de backend",
62
+            "type": "file",
63
+            "status": "outdated"
64
+          },
65
+          {
66
+            "id": 5,
67
+            "title": "on s'emmerde",
68
+            "type": "pageHtml",
69
+            "status": "outdated"
70
+          }
71
+        ]
72
+      }
73
+    ]
9 74
   }
10 75
 }

+ 3 - 0
package.json View File

@@ -6,6 +6,8 @@
6 6
   "scripts": {
7 7
     "mockapi": "node jsonserver/server.js",
8 8
     "servdev": "NODE_ENV=development webpack-dev-server --watch --colors --inline --hot --progress",
9
+    "servdevwindoz": "webpack-dev-server --watch --colors --inline --hot --progress",
10
+    "servdev-dashboard": "NODE_ENV=development webpack-dashboard -m -- webpack-dev-server --watch --colors --inline --hot --progress",
9 11
     "build": "NODE_ENV=production webpack -p",
10 12
     "test": "echo \"Error: no test specified\" && exit 1"
11 13
   },
@@ -43,6 +45,7 @@
43 45
   },
44 46
   "devDependencies": {
45 47
     "json-server": "^0.12.0",
48
+    "webpack-dashboard": "^1.0.2",
46 49
     "webpack-dev-server": "^2.9.2"
47 50
   },
48 51
   "standard": {

+ 27 - 5
src/action-creator.async.js View File

@@ -4,7 +4,9 @@ import {
4 4
   USER_DATA,
5 5
   USER_CONNECTED,
6 6
   updateUserConnected,
7
-  updateUserData
7
+  updateUserData,
8
+  WORKSPACE,
9
+  updateWorkspaceData
8 10
 } from './action-creator.sync.js'
9 11
 
10 12
 /*
@@ -53,19 +55,29 @@ const fetchWrapper = async ({url, param, actionName, dispatch, debug = false}) =
53 55
   return fetchResult
54 56
 }
55 57
 
56
-export const userLogin = (login, password) => async dispatch => {
58
+export const userLogin = (login, password, rememberMe) => async dispatch => {
59
+  const jsonBody = JSON.stringify({
60
+    login,
61
+    password,
62
+    remember_me: rememberMe
63
+  })
64
+
57 65
   const fetchUserLogin = await fetchWrapper({
58 66
     url: 'http://localhost:3001/user/login',
59
-    param: {...FETCH_CONFIG, method: 'POST', body: JSON.stringify({login, password})},
67
+    param: {
68
+      ...FETCH_CONFIG,
69
+      method: 'POST',
70
+      body: jsonBody
71
+    },
60 72
     actionName: USER_LOGIN,
61 73
     dispatch
62 74
   })
63 75
   if (fetchUserLogin.status === 200) dispatch(updateUserConnected(fetchUserLogin.json))
64 76
 }
65 77
 
66
-export const getUserConnected = () => async dispatch => {
78
+export const getIsUserConnected = () => async dispatch => {
67 79
   const fetchUserLogged = await fetchWrapper({
68
-    url: 'http://localhost:3001/user_logged',
80
+    url: 'http://localhost:3001/user/is_logged_in',
69 81
     param: {...FETCH_CONFIG, method: 'GET'},
70 82
     actionName: USER_CONNECTED,
71 83
     dispatch
@@ -92,3 +104,13 @@ export const updateUserLang = newLang => async dispatch => {
92 104
 //   })
93 105
 //   console.log('jsonResponseNoData', fetchResponseNoData)
94 106
 // }
107
+
108
+export const getWorkspaceContent = workspaceId => async dispatch => {
109
+  const fetchGetWorkspaceContent = await fetchWrapper({
110
+    url: `http://localhost:3001/workspace/${workspaceId}`,
111
+    param: {...FETCH_CONFIG, method: 'GET'},
112
+    actionName: WORKSPACE,
113
+    dispatch
114
+  })
115
+  if (fetchGetWorkspaceContent.status === 200) dispatch(updateWorkspaceData(fetchGetWorkspaceContent.json))
116
+}

+ 7 - 0
src/action-creator.sync.js View File

@@ -4,3 +4,10 @@ export const USER_DATA = 'User/Data'
4 4
 export const USER_CONNECTED = 'User/Connected'
5 5
 export const updateUserConnected = user => ({ type: `Update/${USER_CONNECTED}`, user })
6 6
 export const updateUserData = userData => ({ type: `Update/${USER_DATA}`, data: userData })
7
+
8
+export const WORKSPACE = 'Workspace'
9
+export const updateWorkspaceData = workspace => ({ type: `Update/${WORKSPACE}`, workspace })
10
+
11
+export const FILE_CONTENT = 'FileContent'
12
+export const setActiveFileContent = file => ({ type: `Set/${FILE_CONTENT}/Active`, file })
13
+export const hideActiveFileContent = () => ({ type: `Set/${FILE_CONTENT}/Hide` })

+ 0 - 29
src/component/ConnectionForm.jsx View File

@@ -1,29 +0,0 @@
1
-import React from 'react'
2
-import PropTypes from 'prop-types'
3
-
4
-export const ConnectionForm = props => {
5
-  return (
6
-    <div>
7
-      { props.user.isLoggedIn
8
-        ? 'You are already logged in.'
9
-        : (
10
-          <div>
11
-            Login:
12
-            <input type='text' onChange={props.onChangeLogin} placeholder='Login' />
13
-            <input type='text' onChange={props.onChangePassword} placeholder='Password' />
14
-            <button type='button' onClick={props.onClickSubmit}>Connect</button>
15
-          </div>
16
-        )
17
-      }
18
-    </div>
19
-  )
20
-}
21
-
22
-ConnectionForm.PropTypes = {
23
-  user: PropTypes.shape({
24
-    isLoggedIn: PropTypes.bool.isRequired
25
-  }),
26
-  onChangeLogin: PropTypes.func,
27
-  onChangePassword: PropTypes.func,
28
-  onClickSubmit: PropTypes.func
29
-}

+ 0 - 29
src/component/HeaderTpl.jsx View File

@@ -1,29 +0,0 @@
1
-import React from 'react'
2
-import PropTypes from 'prop-types'
3
-import { Link } from 'react-router-dom'
4
-
5
-const HeaderTpl = props => {
6
-  return (
7
-    <div>
8
-      { props.user.isLoggedIn
9
-        ? `'Soir ${props.user.firstname} ${props.user.lastname}.`
10
-        : 'Why dont you connect yourself ?'
11
-      }
12
-      <ul>
13
-        <li><Link to={'/'}>Home</Link></li>
14
-        <li><Link to={'/login'}>Login</Link></li>
15
-        <li><Link to={'/page'}>Page</Link></li>
16
-      </ul>
17
-      <button onClick={e => props.onChangeLang('fr')}>Click Me</button>
18
-    </div>
19
-  )
20
-}
21
-export default HeaderTpl
22
-
23
-HeaderTpl.PropTypes = {
24
-  user: PropTypes.shape({
25
-    isLoggedIn: PropTypes.bool.isRequired
26
-  }),
27
-  onChangeLang: PropTypes.func,
28
-  onSubmitSearch: PropTypes.func
29
-}

+ 23 - 0
src/component/Login/LoginBtnForgotPw.jsx View File

@@ -0,0 +1,23 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+
5
+const LoginBtnForgotPw = props => {
6
+  return (
7
+    <div className={classnames(props.customClass)}>
8
+      {props.label}
9
+    </div>
10
+  )
11
+}
12
+
13
+export default LoginBtnForgotPw
14
+
15
+LoginBtnForgotPw.propTypes = {
16
+  customClass: PropTypes.string,
17
+  label: PropTypes.string
18
+}
19
+
20
+LoginBtnForgotPw.defaultProps = {
21
+  customClass: '',
22
+  label: ''
23
+}

+ 20 - 0
src/component/Login/LoginLogo.jsx View File

@@ -0,0 +1,20 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+
4
+const Logo = props => {
5
+  return (
6
+    <div className={props.customClass}>
7
+      <img src={props.logoSrc} />
8
+    </div>
9
+  )
10
+}
11
+export default Logo
12
+
13
+Logo.propTypes = {
14
+  logoSrc: PropTypes.string.isRequired,
15
+  customClass: PropTypes.string
16
+}
17
+
18
+Logo.defaultProps = {
19
+  customClass: ''
20
+}

+ 225 - 0
src/component/Sidebar/WorkspaceListItem.jsx View File

@@ -0,0 +1,225 @@
1
+import React from 'react'
2
+// import classnames from 'classnames'
3
+import PropTypes from 'prop-types'
4
+
5
+const WorkspaceListItem = props => {
6
+  const handleClickTitle = () => {
7
+    props.onClickTitle()
8
+    const subMenuElement = document.getElementById(`sidebarSubMenu_${props.number}`)
9
+
10
+    if (props.isOpen) {
11
+      subMenuElement.style.height = '0px'
12
+    } else {
13
+      subMenuElement.style.height = 'auto'
14
+      const autoHeight = subMenuElement.offsetHeight + 'px'
15
+
16
+      subMenuElement.style.height = '0px'
17
+      // the setTimeout ensure that the line bellow is executed right after previous has ended
18
+      setTimeout(() => { subMenuElement.style.height = autoHeight }, 1)
19
+    }
20
+  }
21
+
22
+  const pad = number => {
23
+    number = number.toString()
24
+    return number.length < 2 ? pad('0' + number, 2) : number
25
+  }
26
+
27
+  return (
28
+    <li
29
+      className='sidebar__navigation__workspace__item nav-item dropdown'
30
+      onClick={handleClickTitle}
31
+    >
32
+
33
+      <div className='sidebar__navigation__workspace__item__wrapper'>
34
+
35
+        <div className='sidebar__navigation__workspace__item__number'>
36
+          {pad(props.number)}
37
+        </div>
38
+
39
+        <div className='sidebar__navigation__workspace__item__name' title={props.name}>
40
+          {props.name}
41
+        </div>
42
+
43
+        <div className='sidebar__navigation__workspace__item__icon'>
44
+          <i className='fa fa-chevron-down' />
45
+        </div>
46
+
47
+      </div>
48
+
49
+      <ul
50
+        className='sidebar__navigation__workspace__item__submenu'
51
+        id={`sidebarSubMenu_${props.number}`}
52
+      >
53
+        <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
54
+
55
+          <div className='dropdown__icon'>
56
+            <i className='fa fa-th' />
57
+          </div>
58
+
59
+          <div
60
+            className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown dropdown-toggle'
61
+            role='button'
62
+            data-toggle='dropdown'
63
+            aria-haspopup='true'
64
+            aria-expanded='false'
65
+          >
66
+
67
+            <div className='dropdown__title' id='navbarDropdown'>
68
+              <div className='dropdown__title__text'>
69
+                Tous les fichiers
70
+              </div>
71
+            </div>
72
+          </div>
73
+
74
+          {/*
75
+          <div className='dropdown__subdropdown dropdown-menu' aria-labelledby='navbarDropdown'>
76
+            <div className='dropdown__subdropdown__item dropdown-item'>
77
+              <div className='dropdown__subdropdown__item__iconfile alignname'>
78
+                <i className='fa fa-file-text-o' />
79
+              </div>
80
+
81
+              <div className='dropdown__subdropdown__item__textfile alignname'>
82
+                Documents Archivés
83
+              </div>
84
+            </div>
85
+            <div className='dropdown__subdropdown__item dropdown-item'>
86
+              <div className='dropdown__subdropdown__item__iconfile alignname'>
87
+                <i className='fa fa-file-text-o' />
88
+              </div>
89
+
90
+              <div className='dropdown__subdropdown__item__textfile alignname'>
91
+                Documents Supprimés
92
+              </div>
93
+            </div>
94
+          </div>
95
+          */}
96
+
97
+        </li>
98
+
99
+        <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
100
+
101
+          <div className='dropdown__icon'>
102
+            <i className='fa fa-signal dashboard-color' />
103
+          </div>
104
+
105
+          <div
106
+            className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown dropdown-toggle'
107
+            role='button'
108
+            data-toggle='dropdown'
109
+            aria-haspopup='true'
110
+            aria-expanded='false'
111
+          >
112
+
113
+            <div className='dropdown__title' id='navbarDropdown'>
114
+              <div className='dropdown__title__text'>
115
+                Tableau de bord
116
+              </div>
117
+            </div>
118
+          </div>
119
+        </li>
120
+
121
+        <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
122
+
123
+          <div className='dropdown__icon'>
124
+            <i className='fa fa-list-ul task-color' />
125
+          </div>
126
+
127
+          <div
128
+            className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown dropdown-toggle'
129
+            role='button'
130
+            data-toggle='dropdown'
131
+            aria-haspopup='true'
132
+            aria-expanded='false'
133
+          >
134
+
135
+            <div className='dropdown__title' id='navbarDropdown'>
136
+              <div className='dropdown__title__text'>
137
+                Liste de tâches
138
+              </div>
139
+            </div>
140
+          </div>
141
+        </li>
142
+
143
+        <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
144
+
145
+          <div className='dropdown__icon'>
146
+            <i className='fa fa-folder-o docandfile-color' />
147
+          </div>
148
+
149
+          <div
150
+            className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown dropdown-toggle'
151
+            role='button'
152
+            data-toggle='dropdown'
153
+            aria-haspopup='true'
154
+            aria-expanded='false'
155
+          >
156
+
157
+            <div className='dropdown__title' id='navbarDropdown'>
158
+              <div className='dropdown__title__text'>
159
+                Documents & fichiers
160
+              </div>
161
+            </div>
162
+          </div>
163
+        </li>
164
+
165
+        <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
166
+
167
+          <div className='dropdown__icon'>
168
+            <i className='fa fa-comments talk-color' />
169
+          </div>
170
+
171
+          <div
172
+            className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown dropdown-toggle'
173
+            role='button'
174
+            data-toggle='dropdown'
175
+            aria-haspopup='true'
176
+            aria-expanded='false'
177
+          >
178
+
179
+            <div className='dropdown__title' id='navbarDropdown'>
180
+              <div className='dropdown__title__text'>
181
+                Discussions
182
+              </div>
183
+            </div>
184
+          </div>
185
+        </li>
186
+
187
+        <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
188
+
189
+          <div className='dropdown__icon'>
190
+            <i className='fa fa-calendar calendar-color' />
191
+          </div>
192
+
193
+          <div
194
+            className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown dropdown-toggle'
195
+            role='button'
196
+            data-toggle='dropdown'
197
+            aria-haspopup='true'
198
+            aria-expanded='false'
199
+          >
200
+
201
+            <div className='dropdown__title' id='navbarDropdown'>
202
+              <div className='dropdown__title__text'>
203
+                Calendrier
204
+              </div>
205
+            </div>
206
+          </div>
207
+        </li>
208
+      </ul>
209
+    </li>
210
+  )
211
+}
212
+
213
+export default WorkspaceListItem
214
+
215
+WorkspaceListItem.propTypes = {
216
+  number: PropTypes.number.isRequired,
217
+  name: PropTypes.string.isRequired,
218
+  onClickTitle: PropTypes.func,
219
+  isOpen: PropTypes.bool
220
+}
221
+
222
+WorkspaceListItem.defaultProps = {
223
+  onClickTitle: () => {},
224
+  isOpen: false
225
+}

+ 122 - 0
src/component/Timeline.jsx View File

@@ -0,0 +1,122 @@
1
+import React from 'react'
2
+import classnames from 'classnames'
3
+import imgProfil from '../img/imgProfil.png'
4
+import imgProfilReverse from '../img/imgProfil-reverse.png'
5
+
6
+const Timeline = props => {
7
+  return (
8
+    <div className='timeline'>
9
+      <div className={classnames(`${props.customClass}__header`, 'timeline__header')}>
10
+        Timeline
11
+      </div>
12
+
13
+      <ul className={classnames(`${props.customClass}__messagelist`, 'timeline__messagelist')}>
14
+
15
+        <li className={classnames(`${props.customClass}__messagelist__item`, 'timeline__messagelist__item sended')}>
16
+          <div className={classnames(`${props.customClass}__messagelist__item__avatar`, 'timeline__messagelist__item__avatar')}>
17
+            <img src={imgProfil} alt='avatar' />
18
+          </div>
19
+          <div
20
+            className={classnames(`${props.customClass}__messagelist__item__createhour`, 'timeline__messagelist__item__createhour')}>
21
+            27/11/17 à 11h45
22
+          </div>
23
+          <div
24
+            className={classnames(`${props.customClass}__messagelist__item__content`, 'timeline__messagelist__item__content')}>
25
+            Proident esse laboris in sed officia exercitation ut anim ea.
26
+          </div>
27
+        </li>
28
+
29
+        <li className={classnames(`${props.customClass}__messagelist__item`, 'timeline__messagelist__item received')}>
30
+          <div className={classnames(`${props.customClass}__messagelist__item__avatar`, 'timeline__messagelist__item__avatar')}>
31
+            <img src={imgProfilReverse} alt='avatar' />
32
+          </div>
33
+          <div
34
+            className={classnames(`${props.customClass}__messagelist__item__createhour`, 'timeline__messagelist__item__createhour')}>
35
+            27/11/17 à 11h47
36
+          </div>
37
+          <div
38
+            className={classnames(`${props.customClass}__messagelist__item__content`, 'timeline__messagelist__item__content')}>
39
+            Proident esse laboris in sed officia exercitation ut anim ea.
40
+            Proident esse laboris in sed officia exercitation ut anim ea.
41
+            Proident esse laboris in sed officia exercitation ut anim ea.
42
+            Proident esse laboris in sed officia exercitation ut anim ea.
43
+            Proident esse laboris in sed officia exercitation ut anim ea.
44
+          </div>
45
+        </li>
46
+
47
+        <li className={classnames(`${props.customClass}__messagelist__version`, 'timeline__messagelist__version')}>
48
+          <div className={classnames(`${props.customClass}__messagelist__version__btn`, 'timeline__messagelist__version__btn btn')}>
49
+            <i className='fa fa-code-fork' />
50
+            version 3
51
+          </div>
52
+          <div className={classnames(`${props.customClass}__messagelist__version__date`, 'timeline__messagelist__version__date')}>
53
+            Créer le 22/11/17
54
+          </div>
55
+        </li>
56
+
57
+        <li className={classnames(`${props.customClass}__messagelist__item`, 'timeline__messagelist__item sended')}>
58
+          <div className={classnames(`${props.customClass}__messagelist__item__avatar`, 'timeline__messagelist__item__avatar')}>
59
+            <img src={imgProfil} alt='avatar' />
60
+          </div>
61
+          <div
62
+            className={classnames(`${props.customClass}__messagelist__item__createhour`, 'timeline__messagelist__item__createhour')}>
63
+            27/11/17 à 11h45
64
+          </div>
65
+          <div
66
+            className={classnames(`${props.customClass}__messagelist__item__content`, 'timeline__messagelist__item__content')}>
67
+            Proident esse laboris in sed officia exercitation ut anim ea.
68
+          </div>
69
+        </li>
70
+
71
+        <li className={classnames(`${props.customClass}__messagelist__item`, 'timeline__messagelist__item received')}>
72
+          <div className={classnames(`${props.customClass}__messagelist__item__avatar`, 'timeline__messagelist__item__avatar')}>
73
+            <img src={imgProfilReverse} alt='avatar' />
74
+          </div>
75
+          <div
76
+            className={classnames(`${props.customClass}__messagelist__item__createhour`, 'timeline__messagelist__item__createhour')}>
77
+            27/11/17 à 11h47
78
+          </div>
79
+          <div
80
+            className={classnames(`${props.customClass}__messagelist__item__content`, 'timeline__messagelist__item__content')}>
81
+            Proident esse laboris in sed officia exercitation ut anim ea.
82
+            Proident esse laboris in sed officia exercitation ut anim ea.
83
+            Proident esse laboris in sed officia exercitation ut anim ea.
84
+            Proident esse laboris in sed officia exercitation ut anim ea.
85
+            Proident esse laboris in sed officia exercitation ut anim ea.
86
+          </div>
87
+        </li>
88
+
89
+      </ul>
90
+      <form className={classnames(`${props.customClass}__texteditor`, 'timeline__texteditor')}>
91
+        <div
92
+          className={classnames(`${props.customClass}__texteditor__simpletext`, 'timeline__texteditor__simpletext input-group')}>
93
+          <input
94
+            type='text'
95
+            className={classnames(`${props.customClass}__texteditor__simpletext__input`, 'timeline__texteditor__simpletext__input form-control')}
96
+            placeholder='...'
97
+          />
98
+          <div
99
+            className={classnames(`${props.customClass}__texteditor__simpletext__icon`, 'timeline__texteditor__simpletext__icon input-group-addon')}>
100
+            <i className='fa fa-font' />
101
+          </div>
102
+        </div>
103
+        <div className={classnames(`${props.customClass}__texteditor__wysiwyg`, 'timeline__texteditor__wysiwyg d-none d-xl-block')}>
104
+          <textarea />
105
+        </div>
106
+        <div className={classnames(`${props.customClass}__texteditor__submit`, 'timeline__texteditor__submit d-xl-flex justify-content-xl-center')}>
107
+          <button
108
+            type='submit'
109
+            className={classnames(`${props.customClass}__texteditor__submit__btn`, 'timeline__texteditor__submit__btn btn')}
110
+          >
111
+            Envoyer
112
+            <div className={classnames(`${props.customClass}__texteditor__submit__btn__icon`, 'timeline__texteditor__submit__btn__icon')}>
113
+              <i className='fa fa-paper-plane-o' />
114
+            </div>
115
+          </button>
116
+        </div>
117
+      </form>
118
+    </div>
119
+  )
120
+}
121
+
122
+export default Timeline

+ 62 - 0
src/component/Workspace/FileContentViewer.jsx View File

@@ -0,0 +1,62 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import PopinFixed from '../common/PopinFixed/PopinFixed'
4
+import PopinFixedHeader from '../common/PopinFixed/PopinFixedHeader.jsx'
5
+import PopinFixedOption from '../common/PopinFixed/PopinFixedOption.jsx'
6
+import PopinFixedContent from '../common/PopinFixed/PopinFixedContent.jsx'
7
+import PageHtml from './FileType/PageHtml.jsx'
8
+import Thread from './FileType/Thread.jsx'
9
+import Preview from './FileType/File.jsx'
10
+import Timeline from '../Timeline.jsx'
11
+import { FILE_TYPE } from '../../helper.js'
12
+
13
+const FileContentViewer = props => {
14
+  const { customClass, icon } = FILE_TYPE.find(f => f.name === props.file.type) || {customClass: '', icon: ''}
15
+
16
+  const [leftPart, rightPart] = (() => {
17
+    switch (props.file.type) {
18
+      case FILE_TYPE[0].name: // pageHtml
19
+        return [
20
+          <PageHtml version={props.file.version} text={props.file.text} />,
21
+          <Timeline customClass={`${customClass}__contentpage`} />
22
+        ]
23
+      case FILE_TYPE[2].name: // file (preview)
24
+        return [
25
+          <Preview />,
26
+          <Timeline customClass={`${customClass}__contentpage`} />
27
+        ]
28
+      case FILE_TYPE[3].name: // thread
29
+        return [
30
+          <Thread />
31
+        ]
32
+    }
33
+  })()
34
+
35
+  return (
36
+    <PopinFixed customClass={`${customClass}`}>
37
+      <PopinFixedHeader
38
+        customClass={`${customClass}`}
39
+        icon={icon}
40
+        name={props.file.title}
41
+        onClickCloseBtn={props.onClose}
42
+      />
43
+
44
+      <PopinFixedOption customClass={`${customClass}`} />
45
+
46
+      <PopinFixedContent customClass={`${customClass}__contentpage`}>
47
+        { leftPart }
48
+        { rightPart }
49
+      </PopinFixedContent>
50
+    </PopinFixed>
51
+  )
52
+}
53
+
54
+export default FileContentViewer
55
+
56
+FileContentViewer.PropTypes = {
57
+  file: PropTypes.shape({
58
+    type: PropTypes.oneOf(FILE_TYPE.map(f => f.name)).isRequired,
59
+    title: PropTypes.string.isRequired
60
+  }).isRequired,
61
+  onClose: PropTypes.func.isRequired
62
+}

+ 70 - 0
src/component/Workspace/FileItem.jsx View File

@@ -0,0 +1,70 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+import { FILE_TYPE } from '../../helper.js'
5
+
6
+const FileItem = props => {
7
+  const iconType = (FILE_TYPE.find(f => f.name === props.type) || {icon: ''}).icon
8
+
9
+  const iconStatus = (() => {
10
+    switch (props.status) {
11
+      case 'current':
12
+        return 'fa fa-cogs current-color'
13
+      case 'validated':
14
+        return 'fa fa-check validated-color'
15
+      case 'canceled':
16
+        return 'fa fa-ban canceled-color'
17
+      case 'outdated':
18
+        return '' // @TODO
19
+    }
20
+  })()
21
+
22
+  return (
23
+    <div className={classnames('file', 'align-items-center', props.customClass)} onClick={props.onClickItem}>
24
+      <div className='col-2 col-sm-2 col-md-2 col-lg-2 col-xl-1'>
25
+        <div className='file__type'>
26
+          <i className={iconType} />
27
+        </div>
28
+      </div>
29
+      <div className='col-8 col-sm-8 col-md-8 col-lg-8 col-xl-10'>
30
+        <div className='file__name'>
31
+          <div className='file__name__text'>
32
+            { props.name }
33
+          </div>
34
+          <div className='file__name__icons d-none d-md-flex'>
35
+            <div className='file__name__icons__download'>
36
+              <i className='fa fa-download' />
37
+            </div>
38
+            <div className='file__name__icons__archive'>
39
+              <i className='fa fa-archive' />
40
+            </div>
41
+            <div className='file__name__icons__delete'>
42
+              <i className='fa fa-trash-o' />
43
+            </div>
44
+          </div>
45
+        </div>
46
+      </div>
47
+      <div className='col-2 col-sm-2 col-md-2 col-lg-2 col-xl-1'>
48
+        <div className='file__status'>
49
+          <i className={iconStatus} />
50
+        </div>
51
+      </div>
52
+    </div>
53
+  )
54
+}
55
+
56
+export default FileItem
57
+
58
+FileItem.propTypes = {
59
+  type: PropTypes.string.isRequired,
60
+  status: PropTypes.string.isRequired,
61
+  customClass: PropTypes.string,
62
+  name: PropTypes.string,
63
+  onClickItem: PropTypes.func
64
+}
65
+
66
+FileItem.defaultProps = {
67
+  name: '',
68
+  customClass: '',
69
+  onClickItem: () => {}
70
+}

+ 25 - 0
src/component/Workspace/FileItemHeader.jsx View File

@@ -0,0 +1,25 @@
1
+import React from 'react'
2
+
3
+const FileItemHeader = props => {
4
+  return (
5
+    <div className='file__header'>
6
+      <div className='col-2 col-sm-2 col-md-2 col-lg-2 col-xl-1'>
7
+        <div className='file__header__type'>
8
+          Type
9
+        </div>
10
+      </div>
11
+      <div className='col-8 col-sm-8 col-md-8 col-lg-8 col-xl-10'>
12
+        <div className='file__header__name'>
13
+          Nom du document ou fichier
14
+        </div>
15
+      </div>
16
+      <div className='col-2 col-sm-2 col-md-2 col-lg-2 col-xl-1'>
17
+        <div className='file__header__status'>
18
+          Statut
19
+        </div>
20
+      </div>
21
+    </div>
22
+  )
23
+}
24
+
25
+export default FileItemHeader

+ 75 - 0
src/component/Workspace/FileType/File.jsx View File

@@ -0,0 +1,75 @@
1
+import React, { Component } from 'react'
2
+import classnames from 'classnames'
3
+import imgPDF from '../../../img/pdf.jpg'
4
+// import imgExcel from '../../../img/excel.png'
5
+
6
+class File extends Component {
7
+  constructor (props) {
8
+    super(props)
9
+    this.state = {
10
+      activesidebar: false
11
+    }
12
+  }
13
+
14
+  handleClickSidebar = () => this.setState(prev => ({activesidebar: !prev.activesidebar}))
15
+
16
+  render () {
17
+    return (
18
+      <div className={classnames('wsFileFile__contentpage__preview', {'activesidebar': this.state.activesidebar})}>
19
+        <div className='wsFileFile__contentpage__preview__dloption'>
20
+          <div className='wsFileFile__contentpage__preview__dloption__icon'>
21
+            <i className='fa fa-download' />
22
+          </div>
23
+          <div className='wsFileFile__contentpage__preview__dloption__icon'>
24
+            <i className='fa fa-file-pdf-o' />
25
+          </div>
26
+          <div className='wsFileFile__contentpage__preview__dloption__icon'>
27
+            <i className='fa fa-files-o' />
28
+          </div>
29
+        </div>
30
+        <div className='wsFileFile__contentpage__preview__slider'>
31
+          <div className='wsFileFile__contentpage__preview__slider__icon'>
32
+            <i className='fa fa-chevron-left' />
33
+          </div>
34
+          <div className='wsFileFile__contentpage__preview__slider__fileimg'>
35
+            <img src={imgPDF} alt='fichier pdf' className='img-thumbnail mx-auto' />
36
+          </div>
37
+          <div className='wsFileFile__contentpage__preview__slider__icon'>
38
+            <i className='fa fa-chevron-right' />
39
+          </div>
40
+        </div>
41
+        <div className='wsFileFile__contentpage__preview__sidebar' onClick={this.handleClickSidebar}>
42
+          <div className='wsFileFile__contentpage__preview__sidebar__button'>
43
+            <div className='wsFileFile__contentpage__preview__sidebar__button__icon'>
44
+              <i className='fa fa-gear' />
45
+            </div>
46
+            <div className='wsFileFile__contentpage__preview__sidebar__button__title'>
47
+              Propriétés
48
+            </div>
49
+          </div>
50
+          <div className='wsFileFile__contentpage__preview__sidebar__property'>
51
+            <div className='wsFileFile__contentpage__preview__sidebar__property__detail'>
52
+              <div className='wsFileFile__contentpage__preview__sidebar__property__detail__size'>
53
+                Taille : 500Ko
54
+              </div>
55
+              <div className='wsFileFile__contentpage__preview__sidebar__property__detail__description'>
56
+                <label>
57
+                  Description :
58
+                </label>
59
+                <form className='wsFileFile__contentpage__preview__sidebar__property__detail__description__editiondesc'>
60
+                  <textarea />
61
+                  <input type='submit' className='wsFileFile__contentpage__preview__sidebar__property__detail__description__editiondesc__validate form-control' />
62
+                </form>
63
+              </div>
64
+              <div className='wsFileFile__contentpage__preview__sidebar__property__detail__btndesc btn btn-primary'>
65
+                Changer la Description
66
+              </div>
67
+            </div>
68
+          </div>
69
+        </div>
70
+      </div>
71
+    )
72
+  }
73
+}
74
+
75
+export default File

+ 16 - 0
src/component/Workspace/FileType/PageHtml.jsx View File

@@ -0,0 +1,16 @@
1
+import React from 'react'
2
+
3
+const PageHtml = props => {
4
+  return (
5
+    <div className='wsFilePageHtml__contentpage__textnote'>
6
+      <div className='wsFilePageHtml__contentpage__textnote__latestversion'>
7
+        { props.version }
8
+      </div>
9
+      <div className='wsFilePageHtml__contentpage__textnote__text'>
10
+        { props.text }
11
+      </div>
12
+    </div>
13
+  )
14
+}
15
+
16
+export default PageHtml

+ 197 - 0
src/component/Workspace/FileType/Thread.jsx View File

@@ -0,0 +1,197 @@
1
+import React, { Component } from 'react'
2
+import classnames from 'classnames'
3
+import imgProfil from '../../../img/imgProfil.png'
4
+
5
+class Thread extends Component {
6
+  render () {
7
+    return (
8
+      <div className={classnames('wsFileThread wsFileGeneric', {'visible': this.props.visible})}>
9
+        <div className='wsFileThread__header wsFileGeneric__header'>
10
+          <div className='wsFileGeneric__header__icon'>
11
+            <i className='fa fa-comments' />
12
+          </div>
13
+
14
+          <div className='wsFileGeneric__header__text mr-auto'>
15
+            Discussions à propos du nouveau système de facturation
16
+          </div>
17
+
18
+          <div className='wsFileGeneric__header__close'>
19
+            <i className='fa fa-times' />
20
+          </div>
21
+        </div>
22
+
23
+        <div className='wsFileGeneric__option'>
24
+          <div className='wsFileGeneric__option__menu'>
25
+            <div className='wsFileGeneric__option__menu__action'>
26
+              <i className='fa fa-pencil' />
27
+            </div>
28
+
29
+            <div className='wsFileGeneric__option__menu__action'>
30
+              <i className='fa fa-archive' />
31
+            </div>
32
+
33
+            <div className='wsFileGeneric__option__menu__action'>
34
+              <i className='fa fa-trash' />
35
+            </div>
36
+          </div>
37
+        </div>
38
+
39
+        <div className='wsFileThread__wrapper wsFileGeneric__wrapper'>
40
+          <ul className='wsFileThread__messagelist wsFileGeneric__messagelist'>
41
+
42
+            <li className='wsFileThread__messagelist__item wsFileGeneric__messagelist__item sended'>
43
+              <div className='wsFileGeneric__messagelist__item__avatar'>
44
+                <img src={imgProfil} alt='avatar' />
45
+              </div>
46
+
47
+              <div className='wsFileGeneric__messagelist__item__createhour'>
48
+                27/11/17 à 11h45
49
+              </div>
50
+
51
+              <div className='wsFileThread__messagelist__item__content wsFileGeneric__messagelist__item__content'>
52
+                Proident esse laboris in sed officia exercitation ut anim ea.
53
+              </div>
54
+            </li>
55
+
56
+            <li className='wsFileGeneric__messagelist__item received'>
57
+              <div className='wsFileGeneric__messagelist__item__avatar'>
58
+                <img src={imgProfil} alt='avatar' />
59
+              </div>
60
+              <div className='wsFileGeneric__messagelist__item__createhour'>
61
+                27/11/17 à 11h47
62
+              </div>
63
+              <div className='wsFileThread__messagelist__item__content wsFileGeneric__messagelist__item__content'>
64
+                Proident esse laboris in sed officia exercitation ut anim ea.
65
+                Proident esse laboris in sed officia exercitation ut anim ea.
66
+                Proident esse laboris in sed officia exercitation ut anim ea.
67
+                Proident esse laboris in sed officia exercitation ut anim ea.
68
+                Proident esse laboris in sed officia exercitation ut anim ea.
69
+              </div>
70
+            </li>
71
+
72
+            <li className='wsFileGeneric__messagelist__item sended'>
73
+              <div className='wsFileGeneric__messagelist__item__avatar'>
74
+                <img src={imgProfil} alt='avatar' />
75
+              </div>
76
+              <div className='wsFileGeneric__messagelist__item__createhour'>
77
+                27/11/17 à 11h45
78
+              </div>
79
+              <div className='wsFileThread__messagelist__item__content wsFileGeneric__messagelist__item__content'>
80
+                Proident esse laboris in sed officia exercitation ut anim ea.
81
+              </div>
82
+            </li>
83
+
84
+            <li className='wsFileGeneric__messagelist__item sended'>
85
+              <div className='wsFileGeneric__messagelist__item__avatar'>
86
+                <img src={imgProfil} alt='avatar' />
87
+              </div>
88
+              <div className='wsFileGeneric__messagelist__item__createhour'>
89
+                27/11/17 à 11h45
90
+              </div>
91
+              <div className='wsFileThread__messagelist__item__content wsFileGeneric__messagelist__item__content'>
92
+                Proident esse laboris in sed officia exercitation ut anim ea.
93
+              </div>
94
+            </li>
95
+
96
+            <li className='wsFileGeneric__messagelist__item received'>
97
+              <div className='wsFileGeneric__messagelist__item__avatar'>
98
+                <img src={imgProfil} alt='avatar' />
99
+              </div>
100
+              <div className='wsFileGeneric__messagelist__item__createhour'>
101
+                27/11/17 à 11h47
102
+              </div>
103
+              <div className='wsFileThread__messagelist__item__content wsFileGeneric__messagelist__item__content'>
104
+                Proident esse laboris in sed officia exercitation ut anim ea.
105
+                Proident esse laboris in sed officia exercitation ut anim ea.
106
+                Proident esse laboris in sed officia exercitation ut anim ea.
107
+                Proident esse laboris in sed officia exercitation ut anim ea.
108
+                Proident esse laboris in sed officia exercitation ut anim ea.
109
+              </div>
110
+            </li>
111
+
112
+            <li className='wsFileGeneric__messagelist__item received'>
113
+              <div className='wsFileGeneric__messagelist__item__avatar'>
114
+                <img src={imgProfil} alt='avatar' />
115
+              </div>
116
+              <div className='wsFileGeneric__messagelist__item__createhour'>
117
+                27/11/17 à 11h47
118
+              </div>
119
+              <div className='wsFileThread__messagelist__item__content wsFileGeneric__messagelist__item__content'>
120
+                Proident esse laboris in sed officia exercitation ut anim ea.
121
+                Proident esse laboris in sed officia exercitation ut anim ea.
122
+                Proident esse laboris in sed officia exercitation ut anim ea.
123
+                Proident esse laboris in sed officia exercitation ut anim ea.
124
+                Proident esse laboris in sed officia exercitation ut anim ea.
125
+              </div>
126
+            </li>
127
+
128
+            <li className='wsFileGeneric__messagelist__item sended'>
129
+              <div className='wsFileGeneric__messagelist__item__avatar'>
130
+                <img src={imgProfil} alt='avatar' />
131
+              </div>
132
+              <div className='wsFileGeneric__messagelist__item__createhour'>
133
+                27/11/17 à 11h45
134
+              </div>
135
+              <div className='wsFileThread__messagelist__item__content wsFileGeneric__messagelist__item__content'>
136
+                Proident esse laboris in sed officia exercitation ut anim ea.
137
+              </div>
138
+            </li>
139
+
140
+            <li className='wsFileGeneric__messagelist__item received'>
141
+              <div className='wsFileGeneric__messagelist__item__avatar'>
142
+                <img src={imgProfil} alt='avatar' />
143
+              </div>
144
+              <div className='wsFileGeneric__messagelist__item__createhour'>
145
+                27/11/17 à 11h47
146
+              </div>
147
+              <div className='wsFileThread__messagelist__item__content wsFileGeneric__messagelist__item__content'>
148
+                Proident esse laboris in sed officia exercitation ut anim ea.
149
+                Proident esse laboris in sed officia exercitation ut anim ea.
150
+                Proident esse laboris in sed officia exercitation ut anim ea.
151
+                Proident esse laboris in sed officia exercitation ut anim ea.
152
+                Proident esse laboris in sed officia exercitation ut anim ea.
153
+              </div>
154
+            </li>
155
+
156
+            <li className='wsFileGeneric__messagelist__item sended'>
157
+              <div className='wsFileGeneric__messagelist__item__avatar'>
158
+                <img src={imgProfil} alt='avatar' />
159
+              </div>
160
+              <div className='wsFileGeneric__messagelist__item__createhour'>
161
+                27/11/17 à 11h45
162
+              </div>
163
+              <div className='wsFileThread__messagelist__item__content wsFileGeneric__messagelist__item__content'>
164
+                Proident esse laboris in sed officia exercitation ut anim ea.
165
+              </div>
166
+            </li>
167
+          </ul>
168
+
169
+          <form className='wsFileThread__texteditor wsFileGeneric__texteditor'>
170
+            <div className='wsFileThread__texteditor__simpletext wsFileGeneric__texteditor__simpletext input-group'>
171
+              <input type='text' className='wsFileThread__texteditor__simpletext__input wsFileGeneric__texteditor__simpletext__input form-control' placeholder='...' />
172
+
173
+              <div className='wsFileThread__texteditor__simpletext__icon wsFileGeneric__texteditor__simpletext__icon input-group-addon'>
174
+                <i className='fa fa-font' />
175
+              </div>
176
+            </div>
177
+
178
+            <div className='wsFileGeneric__texteditor__wysiwyg d-none d-xl-block'>
179
+              <textarea />
180
+            </div>
181
+
182
+            <div className='wsFileThread__texteditor__submit wsFileGeneric__texteditor__submit d-xl-flex justify-content-xl-center'>
183
+              <button type='submit' className='wsFileThread__texteditor__submit__btn wsFileGeneric__texteditor__submit__btn btn btn-primary'>
184
+                Envoyer
185
+                <div className='wsFileThread__texteditor__submit__btn__icon wsFileGeneric__texteditor__submit__btn__icon'>
186
+                  <i className='fa fa-paper-plane-o' />
187
+                </div>
188
+              </button>
189
+            </div>
190
+          </form>
191
+        </div>
192
+      </div>
193
+    )
194
+  }
195
+}
196
+
197
+export default Thread

+ 80 - 0
src/component/Workspace/Folder.jsx View File

@@ -0,0 +1,80 @@
1
+import React, { Component } from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+import FileItem from './FileItem.jsx'
5
+
6
+// @TODO set Folder as a component, state open will come from parent container (which will come from redux) // update: or not ?
7
+
8
+class Folder extends Component {
9
+  constructor (props) {
10
+    super(props)
11
+    this.state = {
12
+      open: false
13
+    }
14
+    this.handleClickToggleFolder = this.handleClickToggleFolder.bind(this)
15
+  }
16
+
17
+  handleClickToggleFolder = () => this.setState({open: !this.state.open})
18
+  handleClickNewFile = e => {
19
+    e.stopPropagation() // because we have a link inside a link (togler and newFile)
20
+    console.log('new file') // @TODO
21
+  }
22
+
23
+  render () {
24
+    const { title, content } = this.props.folderData
25
+    return (
26
+      <div className={classnames('folder', {'active': this.state.open})}>
27
+        <div className='folder__header' onClick={this.handleClickToggleFolder}>
28
+          <div className='folder__header__triangleborder'>
29
+            <div className='folder__header__triangleborder__triangle' />
30
+          </div>
31
+          <div className='folder__header__name'>
32
+            <div className='folder__header__name__icon'>
33
+              <i className='fa fa-folder-open-o' />
34
+            </div>
35
+            <div className='folder__header__name__text'>
36
+              { title }
37
+            </div>
38
+            <div className='folder__header__name__addbtn' onClick={this.handleClickNewFile}>
39
+              <div className='folder__header__name__addbtn__text btn btn-primary'>
40
+                créer ...
41
+              </div>
42
+            </div>
43
+          </div>
44
+          <div className='folder__header__contenttype'>
45
+            <div className='folder__header__contenttype__text'>
46
+              Type de Contenu :
47
+            </div>
48
+            <div className='folder__header__contenttype__icon'>
49
+              <i className='fa fa-list-ul' />
50
+              <i className='fa fa-file-text-o' />
51
+              <i className='fa fa-comments' />
52
+            </div>
53
+          </div>
54
+        </div>
55
+
56
+        <div className='folder__content'>
57
+          { content.map(c => c.type === 'folder'
58
+            ? <Folder folderData={c} key={c.id} />
59
+            : <FileItem
60
+              name={c.title}
61
+              type={c.type}
62
+              status={c.status}
63
+              onClickItem={() => {}}
64
+              key={c.id}
65
+            />
66
+          )}
67
+        </div>
68
+      </div>
69
+    )
70
+  }
71
+}
72
+
73
+export default Folder
74
+
75
+Folder.propTypes = {
76
+  folderData: PropTypes.shape({
77
+    title: PropTypes.string.isRequired,
78
+    content: PropTypes.array
79
+  })
80
+}

+ 33 - 0
src/component/common/Card/Card.jsx View File

@@ -0,0 +1,33 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+import CardHeader from './CardHeader.jsx'
5
+import CardBody from './CardBody.jsx'
6
+
7
+const Card = props => {
8
+  return (
9
+    <div className={classnames(props.customClass, 'card')}>
10
+      {props.children}
11
+    </div>
12
+  )
13
+}
14
+export default Card
15
+
16
+Card.propTypes = {
17
+  // from http://www.mattzabriskie.com/blog/react-validating-children
18
+  children: PropTypes.arrayOf((children, key, componentName /* , location, propFullName */) => {
19
+    if (
20
+      children.length > 2 ||
21
+      children[0].type !== CardHeader ||
22
+      children[1].type !== CardBody
23
+      // children.some(p => p.type !== CardHeader && p.type !== CardBody)
24
+    ) {
25
+      return new Error(`PropType Error: childrens of ${componentName} must be: 1 CardHeader and 1 CardBody.`)
26
+    }
27
+  }).isRequired,
28
+  customClass: PropTypes.string
29
+}
30
+
31
+Card.defaultProps = {
32
+  customClass: ''
33
+}

+ 24 - 0
src/component/common/Card/CardBody.jsx View File

@@ -0,0 +1,24 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+
5
+const CardBody = props => {
6
+  return (
7
+    <div className='card-body'>
8
+      <form className={classnames(props.formClass)}>
9
+        {props.children}
10
+      </form>
11
+    </div>
12
+  )
13
+}
14
+
15
+export default CardBody
16
+
17
+CardBody.PropTypes = {
18
+  children: PropTypes.element.isRequired,
19
+  formClass: PropTypes.string
20
+}
21
+
22
+CardBody.defaultProps = {
23
+  formClass: ''
24
+}

+ 22 - 0
src/component/common/Card/CardHeader.jsx View File

@@ -0,0 +1,22 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+
5
+const CardHeader = props => {
6
+  return (
7
+    <div className={classnames('card-header', props.customClass)}>
8
+      {props.children}
9
+    </div>
10
+  )
11
+}
12
+
13
+export default CardHeader
14
+
15
+CardHeader.PropTypes = {
16
+  children: PropTypes.element.isRequired,
17
+  customClass: PropTypes.string
18
+}
19
+
20
+CardHeader.defaultProps = {
21
+  customClass: ''
22
+}

+ 19 - 0
src/component/common/Input/BtnSwitch.jsx View File

@@ -0,0 +1,19 @@
1
+import React, { Component } from 'react'
2
+
3
+class BtnSwitch extends Component {
4
+  render () {
5
+    return (
6
+      <div className='btnswitch'>
7
+        <label className='switch nomarginlabel'>
8
+          <input type='checkbox' />
9
+          <span className='slider round' />
10
+        </label>
11
+        <div className='btnswitch__text'>
12
+          On
13
+        </div>
14
+      </div>
15
+    )
16
+  }
17
+}
18
+
19
+export default BtnSwitch

+ 33 - 0
src/component/common/Input/Button.jsx View File

@@ -0,0 +1,33 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+
5
+const Button = props => {
6
+  return (
7
+    <button
8
+      type={props.htmlType}
9
+      className={classnames(props.customClass, 'btn', `btn-${props.bootstrapType}`)}
10
+      onClick={props.onClick}
11
+    >
12
+      {props.label}
13
+    </button>
14
+  )
15
+}
16
+
17
+export default Button
18
+
19
+Button.PropTypes = {
20
+  htmlType: PropTypes.oneOf(['button', 'submit', 'reset']).isRequired,
21
+  bootstrapType: PropTypes.oneOf(
22
+    ['primary', 'default', 'default', 'success', 'danger', 'warning', 'info', 'light', 'dark']
23
+  ).isRequired,
24
+  customClass: PropTypes.string,
25
+  label: PropTypes.string,
26
+  onClick: PropTypes.func
27
+}
28
+
29
+Button.defaultProps = {
30
+  customClass: '',
31
+  label: '',
32
+  onClick: () => {}
33
+}

+ 46 - 0
src/component/common/Input/DropdownCreateButton.jsx View File

@@ -0,0 +1,46 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+
5
+const DropdownCreateButton = props => {
6
+  return (
7
+    <div className={classnames(props.parentClass, props.customClass, 'dropdownCreateBtn')}>
8
+      <button
9
+        className={classnames(`${props.parentClass}__label`, 'dropdownCreateBtn__label btn btn-succes dropdown-toggle')}
10
+        type='button'
11
+        id='dropdownCreateBtn'
12
+        data-toggle='dropdown'
13
+        aria-haspopup='true'
14
+        aria-expanded='false'
15
+      >
16
+        <div className={classnames(`${props.parentClass}__label__text`, 'dropdownCreateBtn__label__text')}>
17
+          Créer ...
18
+        </div>
19
+      </button>
20
+
21
+      <div
22
+        className={classnames(`${props.parentClass}__setting`, 'dropdownCreateBtn__setting dropdown-menu')}
23
+        aria-labelledby='dropdownCreateBtn'
24
+      >
25
+        <div className='setting__link dropdown-item'>
26
+          Créer un workspace
27
+        </div>
28
+        <div className='setting__link dropdown-item'>
29
+          Créer un fichiers
30
+        </div>
31
+      </div>
32
+    </div>
33
+  )
34
+}
35
+
36
+export default DropdownCreateButton
37
+
38
+DropdownCreateButton.propTypes = {
39
+  parentClass: PropTypes.string,
40
+  customClass: PropTypes.string
41
+}
42
+
43
+DropdownCreateButton.defaultProps = {
44
+  parentClass: '',
45
+  customClass: ''
46
+}

+ 35 - 0
src/component/common/Input/InputCheckbox.jsx View File

@@ -0,0 +1,35 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+
5
+const InputGroupText = props => {
6
+  return (
7
+    <label className={classnames(`${props.parentClassName}`, props.customClass, 'custom-control custom-checkbox')}>
8
+      <input
9
+        type='checkbox'
10
+        className='custom-control-input'
11
+        checked={props.checked}
12
+        onChange={props.onChange}
13
+      />
14
+      <span className={classnames(`${props.parentClassName}__checkbox`, 'custom-control-indicator')} />
15
+      <span className={classnames(`${props.parentClassName}__label`, 'custom-control-description')}>
16
+        {props.label}
17
+      </span>
18
+    </label>
19
+  )
20
+}
21
+
22
+export default InputGroupText
23
+
24
+InputGroupText.PropTypes = {
25
+  parentClassName: PropTypes.string.isRequired,
26
+  checked: PropTypes.bool.isRequired,
27
+  onChange: PropTypes.func.isRequired,
28
+  customClass: PropTypes.string,
29
+  label: PropTypes.string
30
+}
31
+
32
+InputGroupText.defaultProps = {
33
+  customClass: '',
34
+  label: ''
35
+}

+ 44 - 0
src/component/common/Input/InputGroupText.jsx View File

@@ -0,0 +1,44 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+
5
+const InputGroupText = props => {
6
+  return (
7
+    <div className={classnames(`${props.parentClassName}`, props.customClass, 'form-group')}>
8
+      <div className={classnames(`${props.parentClassName}__icon`)}>
9
+        <i className={classnames('fa fa-fw', props.icon)} />
10
+      </div>
11
+      <input
12
+        type={props.type}
13
+        className={classnames(`${props.parentClassName}__input`, 'form-control')}
14
+        placeholder={props.placeHolder}
15
+        value={props.value}
16
+        onChange={props.onChange}
17
+      />
18
+      <div className={classnames(`${props.parentClassName}__msgerror`, 'invalid-feedback')}>
19
+        {props.invalidMsg}
20
+      </div>
21
+    </div>
22
+  )
23
+}
24
+
25
+export default InputGroupText
26
+
27
+InputGroupText.PropTypes = {
28
+  parentClassName: PropTypes.string.isRequired,
29
+  value: PropTypes.string.isRequired,
30
+  type: PropTypes.oneOf(['text', 'email', 'password', 'tel']).isRequired,
31
+  customClass: PropTypes.string,
32
+  icon: PropTypes.string,
33
+  placeHolder: PropTypes.string,
34
+  invalidMsg: PropTypes.string,
35
+  onChange: PropTypes.func
36
+}
37
+
38
+InputGroupText.defaultProps = {
39
+  customClass: '',
40
+  icon: false,
41
+  placeHolder: '',
42
+  invalidMsg: false,
43
+  onChange: () => {}
44
+}

+ 42 - 0
src/component/common/PopinFixed/PopinFixed.jsx View File

@@ -0,0 +1,42 @@
1
+import React from 'react'
2
+import classnames from 'classnames'
3
+import PropTypes from 'prop-types'
4
+import PopinFixedHeader from './PopinFixedHeader.jsx'
5
+import PopinFixedOption from './PopinFixedOption.jsx'
6
+import PopinFixedContent from './PopinFixedContent.jsx'
7
+
8
+const PopinFixed = props => {
9
+  return (
10
+    <div className={classnames('wsFileGeneric', props.customClass, {'visible': props.visible})}>
11
+      {props.children}
12
+    </div>
13
+  )
14
+}
15
+
16
+export default PopinFixed
17
+
18
+PopinFixed.propTypes = {
19
+  customClass: PropTypes.string,
20
+  visible: PropTypes.bool
21
+}
22
+
23
+PopinFixed.propTypes = {
24
+  // from http://www.mattzabriskie.com/blog/react-validating-children
25
+  children: PropTypes.arrayOf((children, key, componentName /* , location, propFullName */) => {
26
+    if (
27
+      children.length > 3 ||
28
+      children[0].type !== PopinFixedHeader ||
29
+      children[1].type !== PopinFixedOption ||
30
+      children[2].type !== PopinFixedContent
31
+    ) {
32
+      return new Error(`PropType Error: childrens of ${componentName} must be: 1 PopinFixedHeader, 1 PopinFixedOption and 1 PopinFixedContent.`)
33
+    }
34
+  }).isRequired,
35
+  customClass: PropTypes.string,
36
+  visible: PropTypes.bool
37
+}
38
+
39
+PopinFixed.defaultProps = {
40
+  customClass: '',
41
+  visible: true
42
+}

+ 42 - 0
src/component/common/PopinFixed/PopinFixedContent.jsx View File

@@ -0,0 +1,42 @@
1
+import React from 'react'
2
+import classnames from 'classnames'
3
+import PropTypes from 'prop-types'
4
+import PageHtml from '../../Workspace/FileType/PageHtml.jsx'
5
+import Thread from '../../Workspace/FileType/Thread.jsx'
6
+import Timeline from '../../Timeline.jsx'
7
+
8
+const PopinFixedContent = props => {
9
+  return props.children.length === 2
10
+    ? (
11
+      <div className={classnames('wsFileGeneric__contentpage', `${props.customClass}`)}>
12
+        {props.children[0]}
13
+
14
+        <div className={classnames('wsFileGeneric__wrapper', `${props.customClass}__wrapper`)}>
15
+          {props.children[1]}
16
+        </div>
17
+      </div>
18
+    )
19
+    : (
20
+      <div className={classnames('wsFileGeneric__contentpage', `${props.customClass}`)}>
21
+        { props.children }
22
+      </div>
23
+    )
24
+}
25
+
26
+export default PopinFixedContent
27
+
28
+PopinFixedContent.propTypes = {
29
+  customClass: PropTypes.string,
30
+  // from http://www.mattzabriskie.com/blog/react-validating-children
31
+  children: PropTypes.arrayOf((children, key, componentName /* , location, propFullName */) => {
32
+    if (
33
+      (Array.isArray(children.length) && (
34
+        children.length > 2 ||
35
+        (children.length === 2 && children.some(c => ![PageHtml, Thread, Timeline].includes(c.type)))
36
+      )) ||
37
+      (children.type === Timeline)
38
+    ) {
39
+      return new Error(`PropType Error: childrens of ${componentName} must be one of [PageHtml, Thread, Timeline, undefined].`)
40
+    }
41
+  }).isRequired
42
+}

+ 42 - 0
src/component/common/PopinFixed/PopinFixedHeader.jsx View File

@@ -0,0 +1,42 @@
1
+import React from 'react'
2
+import classnames from 'classnames'
3
+import PropTypes from 'prop-types'
4
+
5
+const PopinFixedHeader = props => {
6
+  return (
7
+    <div className={classnames('wsFileGeneric__header', `${props.customClass}__header`)}>
8
+      <div className={classnames('wsFileGeneric__header__icon', `${props.customClass}__header__icon`)}>
9
+        <i className={props.icon} />
10
+      </div>
11
+
12
+      <div className={classnames('wsFileGeneric__header__title mr-auto', `${props.customClass}__header__title`)}>
13
+        {props.name}
14
+      </div>
15
+
16
+      <div className={classnames('wsFileGeneric__header__edittitle', `${props.customClass}__header__changetitle`)}>
17
+        <i className='fa fa-pencil' />
18
+      </div>
19
+
20
+      <div
21
+        className={classnames('wsFileGeneric__header__close', `${props.customClass}__header__close`)}
22
+        onClick={props.onClickCloseBtn}
23
+      >
24
+        <i className='fa fa-times' />
25
+      </div>
26
+    </div>
27
+  )
28
+}
29
+
30
+export default PopinFixedHeader
31
+
32
+PopinFixedHeader.propTypes = {
33
+  icon: PropTypes.string.isRequired,
34
+  onClickCloseBtn: PropTypes.func.isRequired,
35
+  customClass: PropTypes.string,
36
+  name: PropTypes.string
37
+}
38
+
39
+PopinFixedHeader.defaultProps = {
40
+  customClass: '',
41
+  name: ''
42
+}

+ 67 - 0
src/component/common/PopinFixed/PopinFixedOption.jsx View File

@@ -0,0 +1,67 @@
1
+import React from 'react'
2
+// import classnames from 'classnames'
3
+// import PropTypes from 'prop-types'
4
+
5
+const PopinFixedOption = props => {
6
+  return (
7
+    <div className='wsFileGeneric__option'>
8
+      <div className='wsFileGeneric__option__menu'>
9
+
10
+        <div className='wsFileFile__option__menu__addversion btn mr-auto'>
11
+          Nouvelle version
12
+          <i className='fa fa-plus-circle' />
13
+        </div>
14
+
15
+        <div className='wsFileGeneric__option__menu__status dropdown'>
16
+          <button className='wsFileGeneric__option__menu__status__dropdownbtn check btn dropdown-toggle' type='button' id='dropdownMenu2' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>
17
+            Validé
18
+            <div className='wsFileGeneric__option__menu__status__dropdownbtn__icon'>
19
+              <i className='fa fa-check' />
20
+            </div>
21
+          </button>
22
+
23
+          <div className='wsFileGeneric__option__menu__status__submenu dropdown-menu' aria-labelledby='dropdownMenu2'>
24
+            <h6 className='dropdown-header'>Statut du fichier</h6>
25
+            <div className='dropdown-divider' />
26
+            <button className='wsFileGeneric__option__menu__status__submenu__item current  dropdown-item' type='button'>
27
+              En cours
28
+              <div className='wsFileGeneric__option__menu__status__submenu__item__icon'>
29
+                <i className='fa fa-gears' />
30
+              </div>
31
+            </button>
32
+            <button className='wsFileGeneric__option__menu__status__submenu__item check dropdown-item' type='button'>
33
+              Validé
34
+              <div className='wsFileGeneric__option__menu__status__submenu__item__icon'>
35
+                <i className='fa fa-check' />
36
+              </div>
37
+            </button>
38
+            <button className='wsFileGeneric__option__menu__status__submenu__item invalid dropdown-item' type='button'>
39
+              Invalidé
40
+              <div className='wsFileGeneric__option__menu__status__submenu__item__icon'>
41
+                <i className='fa fa-times' />
42
+              </div>
43
+            </button>
44
+            <button className='wsFileGeneric__option__menu__status__submenu__item ban dropdown-item' type='button'>
45
+              Obsolète
46
+              <div className='wsFileGeneric__option__menu__status__submenu__item__icon'>
47
+                <i className='fa fa-ban' />
48
+              </div>
49
+            </button>
50
+          </div>
51
+        </div>
52
+        <div className='wsFileGeneric__option__menu__action'>
53
+          <i className='fa fa-archive' />
54
+        </div>
55
+        <div className='wsFileGeneric__option__menu__action'>
56
+          <i className='fa fa-trash' />
57
+        </div>
58
+      </div>
59
+    </div>
60
+  )
61
+}
62
+
63
+export default PopinFixedOption
64
+
65
+PopinFixedOption.propTypes = {
66
+
67
+}

+ 23 - 0
src/component/common/layout/PageContent.jsx View File

@@ -0,0 +1,23 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+
5
+const PageContent = props => {
6
+  return (
7
+    <div className={classnames(props.parentClass, props.customClass, 'pageContentGeneric')}>
8
+      {props.children}
9
+    </div>
10
+  )
11
+}
12
+
13
+PageContent.propTypes = {
14
+  parentClass: PropTypes.string,
15
+  customClass: PropTypes.string
16
+}
17
+
18
+PageContent.defaultProps = {
19
+  parentClass: '',
20
+  customClass: ''
21
+}
22
+
23
+export default PageContent

+ 27 - 0
src/component/common/layout/PageTitle.jsx View File

@@ -0,0 +1,27 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+
5
+const PageTitle = props => {
6
+  return (
7
+    <div className={classnames(props.parentClass, props.customClass, 'pageTitleGeneric')}>
8
+      <div className={classnames(`${props.parentClass}__title`, 'pageTitleGeneric__title')}>
9
+        {props.title}
10
+      </div>
11
+      {props.children}
12
+    </div>
13
+  )
14
+}
15
+
16
+PageTitle.propTypes = {
17
+  title: PropTypes.string.isRequired,
18
+  parentClass: PropTypes.string,
19
+  customClass: PropTypes.string
20
+}
21
+
22
+PageTitle.defaultProps = {
23
+  parentClass: '',
24
+  customClass: ''
25
+}
26
+
27
+export default PageTitle

+ 35 - 0
src/component/common/layout/PageWrapper.jsx View File

@@ -0,0 +1,35 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classnames from 'classnames'
4
+import PageTitle from './PageTitle.jsx'
5
+import PageContent from './PageContent.jsx'
6
+
7
+const PageWrapper = props => {
8
+  return (
9
+    <div className={classnames(props.customeClass, 'pageWrapperGeneric')}>
10
+      <div className='container-fluid'>
11
+        {props.children}
12
+      </div>
13
+    </div>
14
+  )
15
+}
16
+
17
+export default PageWrapper
18
+
19
+PageWrapper.propTypes = {
20
+  customClass: PropTypes.string,
21
+  children: PropTypes.arrayOf((children, key, componentName /* , location, propFullName */) => {
22
+    if (
23
+      children.length > 2 ||
24
+      children[0].type !== PageTitle ||
25
+      children[1].type !== PageContent
26
+      // children.some(p => p.type !== CardHeader && p.type !== CardBody)
27
+    ) {
28
+      return new Error(`PropType Error: childrens of ${componentName} must be: 1 PageTitle and 1 PageContent.`)
29
+    }
30
+  }).isRequired
31
+}
32
+
33
+PageWrapper.defaultProps = {
34
+  customClass: ''
35
+}

+ 327 - 0
src/container/AccountPage.jsx View File

@@ -0,0 +1,327 @@
1
+import React, { Component } from 'react'
2
+import imgProfil from '../img/imgProfil.png'
3
+import BtnSwitch from '../component/common/Input/BtnSwitch.jsx'
4
+
5
+class AccountPage extends Component {
6
+  render () {
7
+    return (
8
+      <div className='account'>
9
+        <div className='container-fluid nopadding'>
10
+          <div className='pageTitleGeneric'>
11
+            <div className='pageTitleGeneric__title'>
12
+              Mon Compte
13
+            </div>
14
+          </div>
15
+
16
+          <div className='account__userinformation mr-5 ml-5 mb-5'>
17
+            <div className='account__userinformation__avatar'>
18
+              <img src={imgProfil} alt='avatar' />
19
+            </div>
20
+            <div className='account__userinformation__wrapper'>
21
+              <div className='account__userinformation__name mb-3'>
22
+                Alexi Cauvin
23
+              </div>
24
+              <a href='mailto:contact@contact.fr' className='account__userinformation__email mb-3'>
25
+                alexi.cauvin@algoo.fr
26
+              </a>
27
+              <div className='account__userinformation__role mb-3'>
28
+                Utilisateur
29
+              </div>
30
+              <div className='account__userinformation__job mb-3'>
31
+                Integrateur | Webdesigner
32
+              </div>
33
+              <a href='www.algoo.fr' className='account__userinformation__company'>
34
+                Algoo
35
+              </a>
36
+            </div>
37
+          </div>
38
+
39
+          <div className='account__delimiter GenericDelimiter' />
40
+
41
+          <div className='account__userpreference'>
42
+
43
+            <nav className='account__userpreference__menu navbar d-flex align-items-start'>
44
+
45
+              <div className='account__userpreference__menu__responsive d-lg-none'>
46
+                <i className='fa fa-bars' />
47
+              </div>
48
+
49
+              <ul className='account__userpreference__menu__list nav flex-column'>
50
+
51
+                <li className='account__userpreference__menu__list__close nav-link'>
52
+                  <i className='fa fa-times' />
53
+                </li>
54
+
55
+                <li className='account__userpreference__menu__list__disabled'>Menu
56
+                </li>
57
+                <li className='account__userpreference__menu__list__item nav-item'>
58
+                  <div className='account__userpreference__menu__list__item__link nav-link'>Informations Compte</div>
59
+                </li>
60
+                <li className='account__userpreference__menu__list__item nav-item'>
61
+                  <div className='account__userpreference__menu__list__item__link nav-link'>Calendrier</div>
62
+                </li>
63
+                <li className='account__userpreference__menu__list__item nav-item'>
64
+                  <div className='account__userpreference__menu__list__item__link nav-link'>Notifications</div>
65
+                </li>
66
+              </ul>
67
+            </nav>
68
+
69
+            <div className='account__userpreference__setting'>
70
+
71
+              <div className='account__userpreference__setting__personaldata d-none'>
72
+                <div className='account__userpreference__setting__personaldata__title subTitle ml-2 ml-sm-0'>
73
+                  Mes informations personnelles
74
+                </div>
75
+
76
+                <div className='account__userpreference__setting__personaldata__text ml-2 ml-sm-0'>
77
+                  Ut consectetur dolor et sunt nisi officia ut magna. Ut consectetur dolor et sunt nisi officia ut magna.
78
+                  Ut consectetur dolor et sunt nisi officia ut magna.
79
+                </div>
80
+
81
+                <div className='account__userpreference__setting__personaldata__changeinfo'>
82
+                  <div className='account__userpreference__setting__personaldata__changeinfo__infotitle'>
83
+                    Changer le mot de passe :
84
+                  </div>
85
+                  <input className='account__userpreference__setting__personaldata__changeinfo__txtinput form-control' type='password' placeholder='Ancien mot de passe' />
86
+                  <input className='account__userpreference__setting__personaldata__changeinfo__txtinput form-control' type='password' placeholder='Nouveau mot de passe' />
87
+                  <div className='account__userpreference__setting__personaldata__changeinfo__button btn btn-primary'>
88
+                    Envoyer
89
+                  </div>
90
+                </div>
91
+
92
+                <div className='account__userpreference__setting__personaldata__changeinfo'>
93
+                  <div className='account__userpreference__setting__personaldata__changeinfo__infotitle'>
94
+                    Changer d'adresse mail :
95
+                  </div>
96
+                  <input className='account__userpreference__setting__personaldata__changeinfo__txtinput form-control' type='email' placeholder='Ancienne adresse mail' />
97
+                  <input className='account__userpreference__setting__personaldata__changeinfo__txtinput form-control' type='email' placeholder='Nouvelle adresse mail' />
98
+                  <div className='account__userpreference__setting__personaldata__changeinfo__button btn btn-primary'>
99
+                    Envoyer
100
+                  </div>
101
+                </div>
102
+              </div>
103
+
104
+              <div className='account__userpreference__setting__calendar d-none'>
105
+
106
+                <div className='account__userpreference__setting__calendar__title subTitle ml-2 ml-sm-0'>
107
+                  Calendrier
108
+                </div>
109
+
110
+                <div className='account__userpreference__setting__calendar__text ml-2 ml-sm-0'>
111
+                  Ut consectetur dolor et sunt nisi officia ut magna. Ut consectetur dolor et sunt nisi officia ut magna.
112
+                  Ut consectetur dolor et sunt nisi officia ut magna.
113
+                </div>
114
+
115
+                <div className='account__userpreference__setting__calendar__infotitle'>
116
+                  Accèder à votre Calendrier personnel
117
+                </div>
118
+                <div className='account__userpreference__setting__calendar__link'>
119
+                  http://algoo.trac.im/caldav/user/262.ics/
120
+                </div>
121
+
122
+                <div className='account__userpreference__setting__calendar__infotitle'>
123
+                  Changer de Fuseau Horaire :
124
+                </div>
125
+
126
+                <div className='account__userpreference__setting__calendar__timezone dropdown'>
127
+                  <button className='account__userpreference__setting__calendar__timezone__btn btn dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>
128
+                    Fuseau Horaire
129
+                  </button>
130
+                  <div className='account__userpreference__setting__calendar__timezone__submenu dropdown-menu'>
131
+                    <div className='account__userpreference__setting__calendar__timezone__submenu__item dropdown-item'> Paris GMT +1
132
+                    </div>
133
+                    <div className='account__userpreference__setting__calendar__timezone__submenu__item dropdown-item dropdown-item'> Londres GMT +0
134
+                    </div>
135
+                  </div>
136
+                </div>
137
+              </div>
138
+
139
+              <div className='account__userpreference__setting__notification'>
140
+
141
+                <div className='account__userpreference__setting__notification__title subTitle ml-2 ml-sm-0'>
142
+                  Mes Espaces de Travail
143
+                </div>
144
+
145
+                <div className='account__userpreference__setting__notification__text ml-2 ml-sm-0'>
146
+                  Ut consectetur dolor et sunt nisi officia ut magna. Ut consectetur dolor et sunt nisi officia ut magna.
147
+                  Ut consectetur dolor et sunt nisi officia ut magna.
148
+                </div>
149
+
150
+                <div className='account__userpreference__setting__notification__tableau'>
151
+                  <table className='table'>
152
+                    <thead>
153
+                      <tr>
154
+                        <th>Espace de travail</th>
155
+                        <th>Role</th>
156
+                        <th>Notification</th>
157
+                      </tr>
158
+                    </thead>
159
+                    <tbody>
160
+                      <tr>
161
+                        <td>
162
+                          <div className='account__userpreference__setting__notification__tableau__wksname'>
163
+                            Nouvelle ligne directrice du nouveau design de Tracim v2 en date du 10 Octobre 2017
164
+                          </div>
165
+                        </td>
166
+                        <td>
167
+                          <div className='account__userpreference__setting__notification__tableau__role'>
168
+                            <div className='account__userpreference__setting__notification__tableau__role__icon'>
169
+                              <i className='fa fa-graduation-cap' />
170
+                            </div>
171
+                            <div className='account__userpreference__setting__notification__tableau__role__text'>
172
+                              Gestionnaire de Contenu
173
+                            </div>
174
+                          </div>
175
+                        </td>
176
+                        <td>
177
+                          <div className='account__userpreference__setting__notification__tableau__btnswitch'>
178
+                            <BtnSwitch />
179
+                          </div>
180
+                        </td>
181
+                      </tr>
182
+                      <tr>
183
+                        <td>
184
+                          <div className='account__userpreference__setting__notification__tableau__wksname'>
185
+                            Nouvelle ligne directrice du nouveau design de Tracim v2 en date du 10 Octobre 2017
186
+                          </div>
187
+                        </td>
188
+                        <td>
189
+                          <div className='account__userpreference__setting__notification__tableau__role'>
190
+                            <div className='account__userpreference__setting__notification__tableau__role__icon'>
191
+                              <i className='fa fa-eye' />
192
+                            </div>
193
+                            <div className='account__userpreference__setting__notification__tableau__role__text'>
194
+                              Lecteur
195
+                            </div>
196
+                          </div>
197
+                        </td>
198
+                        <td>
199
+                          <div className='account__userpreference__setting__notification__tableau__btnswitch'>
200
+                            <BtnSwitch />
201
+                          </div>
202
+                        </td>
203
+                      </tr>
204
+                      <tr>
205
+                        <td>
206
+                          <div className='account__userpreference__setting__notification__tableau__wksname'>
207
+                            Nouvelle ligne directrice du nouveau design de Tracim v2 en date du 10 Octobre 2017
208
+                          </div>
209
+                        </td>
210
+                        <td>
211
+                          <div className='account__userpreference__setting__notification__tableau__role'>
212
+                            <div className='account__userpreference__setting__notification__tableau__role__icon'>
213
+                              <i className='fa fa-pencil' />
214
+                            </div>
215
+                            <div className='account__userpreference__setting__notification__tableau__role__text'>
216
+                              Contributeur
217
+                            </div>
218
+                          </div>
219
+                        </td>
220
+                        <td>
221
+                          <div className='account__userpreference__setting__notification__tableau__btnswitch'>
222
+                            <BtnSwitch />
223
+                          </div>
224
+                        </td>
225
+                      </tr>
226
+                      <tr>
227
+                        <td>
228
+                          <div className='account__userpreference__setting__notification__tableau__wksname'>
229
+                            Nouvelle ligne directrice du nouveau design de Tracim v2 en date du 10 Octobre 2017
230
+                          </div>
231
+                        </td>
232
+                        <td>
233
+                          <div className='account__userpreference__setting__notification__tableau__role'>
234
+                            <div className='account__userpreference__setting__notification__tableau__role__icon'>
235
+                              <i className='fa fa-gavel' />
236
+                            </div>
237
+                            <div className='account__userpreference__setting__notification__tableau__role__text'>
238
+                              Responsable
239
+                            </div>
240
+                          </div>
241
+                        </td>
242
+                        <td>
243
+                          <div className='account__userpreference__setting__notification__tableau__btnswitch'>
244
+                            <BtnSwitch />
245
+                          </div>
246
+                        </td>
247
+                      </tr>
248
+                      <tr>
249
+                        <td>
250
+                          <div className='account__userpreference__setting__notification__tableau__wksname'>
251
+                            Nouvelle ligne directrice du nouveau design de Tracim v2 en date du 10 Octobre 2017
252
+                          </div>
253
+                        </td>
254
+                        <td>
255
+                          <div className='account__userpreference__setting__notification__tableau__role'>
256
+                            <div className='account__userpreference__setting__notification__tableau__role__icon'>
257
+                              <i className='fa fa-graduation-cap' />
258
+                            </div>
259
+                            <div className='account__userpreference__setting__notification__tableau__role__text'>
260
+                              Gestionnaire de Contenu
261
+                            </div>
262
+                          </div>
263
+                        </td>
264
+                        <td>
265
+                          <div className='account__userpreference__setting__notification__tableau__btnswitch'>
266
+                            <BtnSwitch />
267
+                          </div>
268
+                        </td>
269
+                      </tr>
270
+                      <tr>
271
+                        <td>
272
+                          <div className='account__userpreference__setting__notification__tableau__wksname'>
273
+                            Nouvelle ligne directrice du nouveau design de Tracim v2 en date du 10 Octobre 2017
274
+                          </div>
275
+                        </td>
276
+                        <td>
277
+                          <div className='account__userpreference__setting__notification__tableau__role'>
278
+                            <div className='account__userpreference__setting__notification__tableau__role__icon'>
279
+                              <i className='fa fa-graduation-cap' />
280
+                            </div>
281
+                            <div className='account__userpreference__setting__notification__tableau__role__text'>
282
+                              Gestionnaire de Contenu
283
+                            </div>
284
+                          </div>
285
+                        </td>
286
+                        <td>
287
+                          <div className='account__userpreference__setting__notification__tableau__btnswitch'>
288
+                            <BtnSwitch />
289
+                          </div>
290
+                        </td>
291
+                      </tr>
292
+                      <tr>
293
+                        <td>
294
+                          <div className='account__userpreference__setting__notification__tableau__wksname'>
295
+                            Nouvelle ligne directrice du nouveau design de Tracim v2 en date du 10 Octobre 2017
296
+                          </div>
297
+                        </td>
298
+                        <td>
299
+                          <div className='account__userpreference__setting__notification__tableau__role'>
300
+                            <div className='account__userpreference__setting__notification__tableau__role__icon'>
301
+                              <i className='fa fa-graduation-cap' />
302
+                            </div>
303
+                            <div className='account__userpreference__setting__notification__tableau__role__text'>
304
+                              Gestionnaire de Contenu
305
+                            </div>
306
+                          </div>
307
+                        </td>
308
+                        <td>
309
+                          <div className='account__userpreference__setting__notification__tableau__btnswitch'>
310
+                            <BtnSwitch />
311
+                          </div>
312
+                        </td>
313
+                      </tr>
314
+                    </tbody>
315
+                  </table>
316
+                </div>
317
+              </div>
318
+
319
+            </div>
320
+          </div>
321
+        </div>
322
+      </div>
323
+    )
324
+  }
325
+}
326
+
327
+export default AccountPage

+ 372 - 0
src/container/Dashboard.jsx View File

@@ -0,0 +1,372 @@
1
+import React, { Component } from 'react'
2
+import listMemberBtn from '../img/listmemberbtn.png'
3
+import imgProfil from '../img/imgProfil.png'
4
+
5
+class Dashboard extends Component {
6
+  render () {
7
+    return (
8
+      <div className='dashboard'>
9
+        <div className='container-fluid nopadding'>
10
+          <div className='pageTitleGeneric'>
11
+            <div className='pageTitleGeneric__title dashboard__title'>
12
+              Dashboard
13
+            </div>
14
+          </div>
15
+
16
+          <div className='dashboard__wkswrapper'>
17
+            <div className='dashboard__workspace'>
18
+              <div className='dashboard__workspace__title'>
19
+                Nouvelle ligne directive sur le nouveau design de Tracim
20
+              </div>
21
+
22
+              <div className='dashboard__workspace__detail'>
23
+                Ut in et sit adipisicing mollit amet ut exercitation proident laborum duis occaecat eu aute qui ut.
24
+                Dolore veniam eu consectetur occaecat est elit dolor nulla est ut amet do reprehenderit eiusmod tempor.
25
+              </div>
26
+            </div>
27
+            <div className='dashboard__userstatut'>
28
+
29
+              <div className='dashboard__userstatut__role'>
30
+                <div className='dashboard__userstatut__role__text'>
31
+                  Hi ! Alexi, vous êtes actuellement
32
+                </div>
33
+                <div className='dashboard__userstatut__role__rank'>
34
+                  <div className='dashboard__userstatut__role__rank__icon'>
35
+                    <i className='fa fa-graduation-cap' />
36
+                  </div>
37
+                  <div className='dashboard__userstatut__role__rank__rolename'>
38
+                    Gestionnaire de projet
39
+                  </div>
40
+                </div>
41
+              </div>
42
+
43
+              <div className='dashboard__userstatut__notification'>
44
+                <div className='dashboard__userstatut__notification__text'>
45
+                  Vous êtes abonné(e) aux notifications de ce workspace
46
+                </div>
47
+                <div className='dashboard__userstatut__notification__btn btn btn-primary'>
48
+                  Changer de statut
49
+                </div>
50
+
51
+                <div className='dashboard__userstatut__notification__subscribe dropdown'>
52
+                  <button className='dashboard__userstatut__notification__subscribe__btn btn btn-secondary dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>
53
+                    Abonné(e)
54
+                  </button>
55
+                  <div className='dashboard__userstatut__notification__subscribe__submenu dropdown-menu'>
56
+                    <div className='dashboard__userstatut__notification__subscribe__submenu__item dropdown-item'>Abonné(e)
57
+                    </div>
58
+                    <div className='dashboard__userstatut__notification__subscribe__submenu__item dropdown-item dropdown-item'>Non Abonné(e)
59
+                    </div>
60
+                  </div>
61
+                </div>
62
+              </div>
63
+            </div>
64
+          </div>
65
+
66
+          <div className='dashboard__calltoaction'>
67
+            <div className='dashboard__calltoaction__button btnaction thread'>
68
+              <div className='dashboard__calltoaction__button__text'>
69
+                <div className='dashboard__calltoaction__button__text__icon'>
70
+                  <i className='fa fa-comments-o' />
71
+                </div>
72
+                <div className='dashboard__calltoaction__button__text__title'>
73
+                  Débuter une nouvelle discussion
74
+                </div>
75
+              </div>
76
+            </div>
77
+
78
+            <div className='dashboard__calltoaction__button btnaction writefile'>
79
+              <div className='dashboard__calltoaction__button__text'>
80
+                <div className='dashboard__calltoaction__button__text__icon'>
81
+                  <i className='fa fa-file-text-o' />
82
+                </div>
83
+                <div className='dashboard__calltoaction__button__text__title'>
84
+                  Rédiger un document
85
+                </div>
86
+              </div>
87
+            </div>
88
+
89
+            <div className='dashboard__calltoaction__button btnaction importfile'>
90
+              <div className='dashboard__calltoaction__button__text'>
91
+                <div className='dashboard__calltoaction__button__text__icon'>
92
+                  <i className='fa fa-paperclip' />
93
+                </div>
94
+                <div className='dashboard__calltoaction__button__text__title'>
95
+                  Importer un fichier
96
+                </div>
97
+              </div>
98
+            </div>
99
+
100
+            <div className='dashboard__calltoaction__button btnaction calendar'>
101
+              <div className='dashboard__calltoaction__button__text'>
102
+                <div className='dashboard__calltoaction__button__text__icon'>
103
+                  <i className='fa fa-calendar' />
104
+                </div>
105
+                <div className='dashboard__calltoaction__button__text__title'>
106
+                  Voir le Calendrier
107
+                </div>
108
+              </div>
109
+            </div>
110
+
111
+            <div className='dashboard__calltoaction__button btnaction explore'>
112
+              <div className='dashboard__calltoaction__button__text'>
113
+                <div className='dashboard__calltoaction__button__text__icon'>
114
+                  <i className='fa fa-folder-open-o' />
115
+                </div>
116
+                <div className='dashboard__calltoaction__button__text__title'>
117
+                  Explorer le Workspace
118
+                </div>
119
+              </div>
120
+            </div>
121
+          </div>
122
+
123
+          <div className='dashboard__wksinfo'>
124
+            <div className='dashboard__activity'>
125
+              <div className='dashboard__activity__header'>
126
+                <div className='dashboard__activity__header__title subTitle'>
127
+                  Activité récente
128
+                </div>
129
+
130
+                <div className='dashboard__activity__header__allread btn'>
131
+                  Tout marquer comme lu
132
+                </div>
133
+              </div>
134
+              <div className='dashboard__activity__wrapper'>
135
+                <div className='dashboard__activity__workspace'>
136
+                  <div className='dashboard__activity__workspace__icon'>
137
+                    <i className='fa fa-comments-o' />
138
+                  </div>
139
+                  <div className='dashboard__activity__workspace__name'>
140
+                    <span>Workspace 1</span>
141
+                  </div>
142
+                </div>
143
+
144
+                <div className='dashboard__activity__workspace'>
145
+                  <div className='dashboard__activity__workspace__icon'>
146
+                    <i className='fa fa-list-ul' />
147
+                  </div>
148
+                  <div className='dashboard__activity__workspace__name'>
149
+                    Workspace 2
150
+                  </div>
151
+                </div>
152
+
153
+                <div className='dashboard__activity__workspace'>
154
+                  <div className='dashboard__activity__workspace__icon'>
155
+                    <i className='fa fa-list-ul' />
156
+                  </div>
157
+                  <div className='dashboard__activity__workspace__name'>
158
+                    Workspace 3
159
+                  </div>
160
+                </div>
161
+
162
+                <div className='dashboard__activity__workspace'>
163
+                  <div className='dashboard__activity__workspace__icon'>
164
+                    <i className='fa fa-file-text-o' />
165
+                  </div>
166
+                  <div className='dashboard__activity__workspace__name'>
167
+                    <span>Workspace 4</span>
168
+                  </div>
169
+                </div>
170
+
171
+                <div className='dashboard__activity__workspace'>
172
+                  <div className='dashboard__activity__workspace__icon'>
173
+                    <i className='fa fa-comments-o' />
174
+                  </div>
175
+                  <div className='dashboard__activity__workspace__name'>
176
+                    <span>Workspace 5</span>
177
+                  </div>
178
+                </div>
179
+
180
+                <div className='dashboard__activity__workspace'>
181
+                  <div className='dashboard__activity__workspace__icon'>
182
+                    <i className='fa fa-file-text-o' />
183
+                  </div>
184
+                  <div className='dashboard__activity__workspace__name'>
185
+                    Workspace 6
186
+                  </div>
187
+                </div>
188
+
189
+                <div className='dashboard__activity__more d-flex flex-row-reverse'>
190
+                  <div className='dashboard__activity__more__btn btn'>
191
+                    Voir plus
192
+                  </div>
193
+                </div>
194
+              </div>
195
+            </div>
196
+
197
+            <div className='dashboard__memberlist'>
198
+
199
+              <div className='dashboard__memberlist__title subTitle'>
200
+                Liste des membres
201
+              </div>
202
+
203
+              <div className='dashboard__memberlist__wrapper'>
204
+                <ul className='dashboard__memberlist__list'>
205
+                  <li className='dashboard__memberlist__list__item'>
206
+                    <div className='dashboard__memberlist__list__item__avatar'>
207
+                      <img src={imgProfil} alt='avatar' />
208
+                    </div>
209
+                    <div className='dashboard__memberlist__list__item__info'>
210
+                      <div className='dashboard__memberlist__list__item__info__name'>
211
+                        Jean Dupont
212
+                      </div>
213
+                      <div className='dashboard__memberlist__list__item__info__role'>
214
+                        Responsable
215
+                      </div>
216
+                    </div>
217
+                  </li>
218
+
219
+                  <li className='dashboard__memberlist__list__item'>
220
+                    <div className='dashboard__memberlist__list__item__avatar'>
221
+                      <img src={imgProfil} alt='avatar' />
222
+                    </div>
223
+                    <div className='dashboard__memberlist__list__item__info'>
224
+                      <div className='dashboard__memberlist__list__item__info__name'>
225
+                        Aldwin Vinel
226
+                      </div>
227
+                      <div className='dashboard__memberlist__list__item__info__role'>
228
+                        lecteur
229
+                      </div>
230
+                    </div>
231
+                  </li>
232
+
233
+                  <li className='dashboard__memberlist__list__item'>
234
+                    <div className='dashboard__memberlist__list__item__avatar'>
235
+                      <img src={imgProfil} alt='avatar' />
236
+                    </div>
237
+                    <div className='dashboard__memberlist__list__item__info'>
238
+                      <div className='dashboard__memberlist__list__item__info__name'>
239
+                        William Himme
240
+                      </div>
241
+                      <div className='dashboard__memberlist__list__item__info__role'>
242
+                        contributeur
243
+                      </div>
244
+                    </div>
245
+                  </li>
246
+
247
+                  <li className='dashboard__memberlist__list__item'>
248
+                    <div className='dashboard__memberlist__list__item__avatar'>
249
+                      <img src={imgProfil} alt='avatar' />
250
+                    </div>
251
+                    <div className='dashboard__memberlist__list__item__info'>
252
+                      <div className='dashboard__memberlist__list__item__info__name'>
253
+                        Yacine Lite
254
+                      </div>
255
+                      <div className='dashboard__memberlist__list__item__info__role'>
256
+                        Gestionnaire de contenu
257
+                      </div>
258
+                    </div>
259
+                  </li>
260
+
261
+                  <li className='dashboard__memberlist__list__item'>
262
+                    <div className='dashboard__memberlist__list__item__avatar'>
263
+                      <img src={imgProfil} alt='avatar' />
264
+                    </div>
265
+                    <div className='dashboard__memberlist__list__item__info'>
266
+                      <div className='dashboard__memberlist__list__item__info__name'>
267
+                        Yacine Lite
268
+                      </div>
269
+                      <div className='dashboard__memberlist__list__item__info__role'>
270
+                        Gestionnaire de contenu
271
+                      </div>
272
+                    </div>
273
+                  </li>
274
+
275
+                  <li className='dashboard__memberlist__list__item'>
276
+                    <div className='dashboard__memberlist__list__item__avatar'>
277
+                      <img src={imgProfil} alt='avatar' />
278
+                    </div>
279
+                    <div className='dashboard__memberlist__list__item__info'>
280
+                      <div className='dashboard__memberlist__list__item__info__name'>
281
+                        Yacine Lite
282
+                      </div>
283
+                      <div className='dashboard__memberlist__list__item__info__role'>
284
+                        Gestionnaire de contenu
285
+                      </div>
286
+                    </div>
287
+                  </li>
288
+
289
+                </ul>
290
+                <div className='dashboard__memberlist__btnadd'>
291
+                  <div className='dashboard__memberlist__btnadd__button'>
292
+                    <div className='dashboard__memberlist__btnadd__button__avatar'>
293
+                      <img src={listMemberBtn} alt='avatar' />
294
+                    </div>
295
+                    <div className='dashboard__memberlist__btnadd__button__text'>
296
+                       Ajouter un membre
297
+                    </div>
298
+                  </div>
299
+                </div>
300
+
301
+                <form className='dashboard__memberlist__addmember'>
302
+                  <input type='text' className='dashboard__memberlist__addmember__name form-control' placeholder='Name' />
303
+                  <div className='dashboard__memberlist__addmember__role'>
304
+                    <div className='dashboard__memberlist__addmember__role__dropdown dropdown'>
305
+                      <button className='dashboard__memberlist__addmember__role__dropdown__button btn dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>
306
+                        Rôle du membre
307
+                      </button>
308
+                      <div className='dashboard__memberlist__addmember__role__dropdown__submenu dropdown-menu'>
309
+                        <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
310
+                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
311
+                            <i className='fa fa-eye' />
312
+                          </div>
313
+                          Lecteur
314
+                        </div>
315
+                        <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
316
+                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
317
+                            <i className='fa fa-pencil' />
318
+                          </div>
319
+                          contributeur
320
+                        </div>
321
+                        <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
322
+                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
323
+                            <i className='fa fa-graduation-cap' />
324
+                          </div>
325
+                          Gestionnaire de contenu
326
+                        </div>
327
+                        <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
328
+                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
329
+                            <i className='fa fa-gavel' />
330
+                          </div>
331
+                          Responsable
332
+                        </div>
333
+                      </div>
334
+                    </div>
335
+                  </div>
336
+                  <input type='submit' className='dashboard__memberlist__addmember__submitbtn' />
337
+                </form>
338
+
339
+              </div>
340
+            </div>
341
+          </div>
342
+
343
+          <div className='dashboard__webdav genericWebdav'>
344
+
345
+            <div className='dashboard__webdav__btn genericWebdav__btn'>
346
+              <div className='dashboard__webdav__btn__icon genericWebdav__btn__icon'>
347
+                <i className='fa fa-windows' />
348
+              </div>
349
+
350
+              <div className='dashboard__webdav__btn__text genericWebdav__btn__text'>
351
+                Implémenter Tracim dans votre explorateur
352
+              </div>
353
+            </div>
354
+
355
+            <div className='dashboard__webdav__information genericWebdav__info'>
356
+              <div className='dashboard__webdav__information__text genericWebdav__info__text'>
357
+                Lorem ipsum dolore dolore laborum exercitation et deserunt ad ullamco nostrud dolore magna in proident elit amet do eu ut officia anim magna dolore adipisicing aliqua qui reprehenderit laborum labore tempor consectetur ut pariatur deserunt nostrud.
358
+              </div>
359
+
360
+              <div className='dashboard__webdav__information__link genericWebdav__info__link'>
361
+                http://algoo.trac.im/webdav/
362
+              </div>
363
+            </div>
364
+
365
+          </div>
366
+        </div>
367
+      </div>
368
+    )
369
+  }
370
+}
371
+
372
+export default Dashboard

+ 3 - 12
src/container/Header.jsx View File

@@ -1,6 +1,5 @@
1 1
 import React from 'react'
2 2
 import { connect } from 'react-redux'
3
-// import HeaderTpl from '../component/HeaderTpl.jsx'
4 3
 import Logo from '../component/Header/Logo.jsx'
5 4
 import NavbarToggler from '../component/Header/NavbarToggler.jsx'
6 5
 import MenuLinkList from '../component/Header/MenuLinkList.jsx'
@@ -14,10 +13,6 @@ import flagFr from '../img/flagFr.png'
14 13
 import flagEn from '../img/flagEn.png'
15 14
 // import { updateUserLang } from '../action-creator.async.js'
16 15
 
17
-const HeaderWrapper = props => <header><nav className='header navbar navbar-expand-md navbar-light bg-light'>{props.children}</nav></header>
18
-const HeaderMenuRightWrapper = props => <div className='header__menu collapse navbar-collapse justify-content-end' id='navbarSupportedContent'>{props.children}</div>
19
-const MenuActionListWrapper = props => <ul className='header__menu__rightside'>{ props.children }</ul>
20
-
21 16
 class Header extends React.Component {
22 17
   // handleChangeLang = newLang => this.props.dispatch(updateUserLang(newLang))
23 18
   // handleSubmitSearch = search => console.log('search submited : ', search)
@@ -39,13 +34,6 @@ class Header extends React.Component {
39 34
   handleClickLogout = () => {}
40 35
 
41 36
   render () {
42
-    // return (
43
-    //   <HeaderTpl
44
-    //     user={this.props.user}
45
-    //     onChangeLang={this.handleChangeLang}
46
-    //     onSubmitSearch={this.handleSubmitSearch}
47
-    //   />
48
-    // )
49 37
     const { user } = this.props
50 38
     const langList = [{ // @TODO this should come from API
51 39
       id: 'fr',
@@ -65,6 +53,9 @@ class Header extends React.Component {
65 53
     //   'S_zkvxpAJO0g?size=800x600&size_mode=3'
66 54
     // }
67 55
 
56
+    const HeaderWrapper = props => <header><nav className='header navbar navbar-expand-md navbar-light bg-light'>{props.children}</nav></header>
57
+    const HeaderMenuRightWrapper = props => <div className='header__menu collapse navbar-collapse justify-content-end' id='navbarSupportedContent'>{props.children}</div>
58
+    const MenuActionListWrapper = props => <ul className='header__menu__rightside'>{ props.children }</ul>
68 59
     return (
69 60
       <HeaderWrapper>
70 61
         <Logo logoSrc={logoHeader} onClickImg={this.handleClickLogo} />

+ 86 - 85
src/container/Login.jsx View File

@@ -1,112 +1,113 @@
1 1
 import React from 'react'
2 2
 import { connect } from 'react-redux'
3
-// import { ConnectionForm } from '../component/ConnectionForm.jsx'
3
+import { Redirect } from 'react-router'
4
+import LoginLogo from '../component/Login/LoginLogo.jsx'
5
+import LoginLogoImg from '../img/logoTracimWhite.svg'
4 6
 import { userLogin } from '../action-creator.async.js'
7
+import Card from '../component/common/Card/Card.jsx'
8
+import CardHeader from '../component/common/Card/CardHeader.jsx'
9
+import CardBody from '../component/common/Card/CardBody.jsx'
10
+import InputGroupText from '../component/common/Input/InputGroupText.jsx'
11
+import InputCheckbox from '../component/common/Input/InputCheckbox.jsx'
12
+import Button from '../component/common/Input/Button.jsx'
13
+import LoginBtnForgotPw from '../component/Login/LoginBtnForgotPw.jsx'
5 14
 
6 15
 class Login extends React.Component {
7 16
   constructor (props) {
8 17
     super(props)
9 18
     this.state = {
10 19
       inputLogin: '',
11
-      inputPassword: ''
20
+      inputPassword: '',
21
+      inputRememberMe: false
12 22
     }
13 23
   }
14 24
 
15 25
   handleChangeLogin = e => this.setState({inputLogin: e.target.value})
16 26
   handleChangePassword = e => this.setState({inputPassword: e.target.value})
27
+  handleChangeRememberMe = () => this.setState(prev => ({inputRememberMe: !prev.inputRememberMe}))
17 28
 
18
-  handleClickSubmit = () => this.props.dispatch(userLogin(this.state.inputLogin, this.state.inputPassword))
29
+  handleClickSubmit = async () => {
30
+    const { history, dispatch } = this.props
31
+    const { inputLogin, inputPassword, inputRememberMe } = this.state
32
+
33
+    await dispatch(userLogin(inputLogin, inputPassword, inputRememberMe))
34
+    history.push('/')
35
+  }
19 36
 
20 37
   render () {
21
-    // const { user } = this.props
22
-    // return (
23
-    //   <div>
24
-    //     <ConnectionForm
25
-    //       user={user}
26
-    //       onChangeLogin={this.handleChangeLogin}
27
-    //       onChangePassword={this.handleChangePassword}
28
-    //       onClickSubmit={this.handleClickSubmit}
29
-    //     />
30
-    //   </div>
31
-    // )
32
-    return (
33
-      <div>{/*
34
-        <div className='loginpage'>
35
-
36
-          <section className='loginpage__content'>
37
-            <div className='sidebar'>
38
-              sidebar
39
-            </div>
40
-            <div className='container-fluid contentbody'>
41
-              <div className='loginpage__content__logo'>
42
-                <img src={logoAccueil} />
43
-              </div>
38
+    if (this.props.user.isLoggedIn) return <Redirect to={{pathname: '/'}} />
39
+    else {
40
+      return (
41
+        <section className='loginpage'>
42
+          <div className='container-fluid'>
44 43
 
45
-              <div className='row justify-content-center'>
46
-                <div className='col-12 col-sm-11 col-md-8 col-lg-6 col-xl-5'>
47
-                  <div className='loginpage__content__connection card'>
48
-                    <div className='connection__header card-header text-center'>
49
-                      Connexion
50
-                    </div>
44
+            <LoginLogo customClass='loginpage__logo' logoSrc={LoginLogoImg} />
45
+
46
+            <div className='row justify-content-center'>
47
+              <div className='col-12 col-sm-11 col-md-8 col-lg-6 col-xl-5'>
48
+
49
+                <Card customClass='loginpage__connection'>
50
+                  <CardHeader customClass='connection__header text-center'>{'Connexion'}</CardHeader>
51 51
 
52
-                    <div className='card-body'>
53
-                      <form className='connection__form'>
54
-                        <div className='connection__form__groupemail form-group mb-3 mt-4'>
55
-                          <div className='connection__form__groupemail__icon'>
56
-                            <i className='fa fa-fw fa-envelope-open-o' />
57
-                          </div>
58
-                          <input type='email' className='connection__form__groupemail__input form-control' placeholder='Adresse Email' />
59
-                          <div className='connection__form__groupemail__msgerror invalid-feedback'>
60
-                            Invalid email.
61
-                          </div>
62
-                        </div>
63
-
64
-                        <div className='connection__form__groupepw form-group'>
65
-                          <div className='connection__form__groupepw__icon'>
66
-                            <i className='fa fa-fw fa-lock' />
67
-                          </div>
68
-                          <input type='password' className='connection__form__groupepw__pw form-control' id='password-co' placeholder='Mot de passe' />
69
-                          <div className='connection__form__groupepw__msgerror invalid-feedback'>
70
-                            Invalid password.
71
-                          </div>
72
-                        </div>
73
-
74
-                        <div className='row mt-4 mb-4'>
75
-                          <div className='col-12 col-sm-6 col-md-6 col-lg-6 col-xl-6'>
76
-                            <div className='connection__form__rememberme form-check'>
77
-                              <label className='connection__form__rememberme__label form-check-label'>
78
-                                <input type='checkbox' className='connection__form__rememberme__label__checkbox form-check-input' />
79
-                                Se souvenir de moi
80
-                              </label>
81
-                            </div>
82
-                          </div>
83
-
84
-                          <div className='col-12 col-sm-6 col-md-6 col-lg-6 text-sm-right'>
85
-                            <div className='connection__form__pwforgot'>
86
-                              Mot de passe oublié ?
87
-                            </div>
88
-                          </div>
89
-                        </div>
90
-
91
-                        <button type='submit' className='connection__form__btnsubmit btn btn-primary'>Connexion</button>
92
-                      </form>
52
+                  <CardBody formClass='connection__form'>
53
+                    <InputGroupText
54
+                      parentClassName='connection__form__groupemail'
55
+                      customClass='mb-3 mt-4'
56
+                      icon='fa-envelope-open-o'
57
+                      type='email'
58
+                      placeHolder='Adresse Email'
59
+                      invalidMsg='Email invalide.'
60
+                      value={this.state.inputLogin}
61
+                      onChange={this.handleChangeLogin}
62
+                    />
93 63
 
64
+                    <InputGroupText
65
+                      parentClassName='connection__form__groupepw'
66
+                      customClass=''
67
+                      icon='fa-lock'
68
+                      type='password'
69
+                      placeHolder='Mot de passe'
70
+                      invalidMsg='Mot de passe invalide.'
71
+                      value={this.state.inputPassword}
72
+                      onChange={this.handleChangePassword}
73
+                    />
74
+
75
+                    <div className='row mt-4 mb-4'>
76
+                      <div className='col-12 col-sm-6 col-md-6 col-lg-6 col-xl-6'>
77
+                        <InputCheckbox
78
+                          parentClassName='connection__form__rememberme'
79
+                          customClass=''
80
+                          label='Se souvenir de moi'
81
+                          checked={this.state.inputRememberMe}
82
+                          onChange={this.handleChangeRememberMe}
83
+                        />
84
+                      </div>
85
+
86
+                      <div className='col-12 col-sm-6 col-md-6 col-lg-6 col-xl-6 text-sm-right'>
87
+                        <LoginBtnForgotPw
88
+                          customClass='connection__form__pwforgot'
89
+                          label='Mot de passe oublié ?'
90
+                        />
91
+                      </div>
94 92
                     </div>
95
-                  </div>
96
-                </div>
93
+
94
+                    <Button
95
+                      htmlType='button'
96
+                      bootstrapType='primary'
97
+                      customClass='connection__form__btnsubmit'
98
+                      label='Connexion'
99
+                      onClick={this.handleClickSubmit}
100
+                    />
101
+                  </CardBody>
102
+                </Card>
103
+
97 104
               </div>
98 105
             </div>
99
-          </section>
100 106
 
101
-          <footer className='footer text-right'>
102
-            <div className='footer__text'>
103
-              Créer votre propre espace de travail collaboratif sur trac.im - Copyright 2013 - 2017
104
-            </div>
105
-            <img className='footer__logo' src={logoFooter} />
106
-          </footer>
107
-        </div> */}
108
-      </div>
109
-    )
107
+          </div>
108
+        </section>
109
+      )
110
+    }
110 111
   }
111 112
 }
112 113
 

+ 0 - 16
src/container/Page.jsx View File

@@ -1,16 +0,0 @@
1
-import React from 'react'
2
-import { connect } from 'react-redux'
3
-
4
-class Page extends React.Component {
5
-  render () {
6
-    const { user } = this.props
7
-    return (
8
-      <div>
9
-        Page ! user Logged in : {user.isLoggedIn.toString()}
10
-      </div>
11
-    )
12
-  }
13
-}
14
-
15
-const mapStateToProps = ({ user }) => ({ user })
16
-export default connect(mapStateToProps)(Page)

+ 6 - 8
src/container/PrivateRoute.jsx View File

@@ -7,14 +7,12 @@ import { Route, Redirect, withRouter } from 'react-router-dom'
7 7
 
8 8
 // /!\ you shall destruct props.component otherwise you get a warning:
9 9
 // "You should not use <Route component> and <Route render> in the same route; <Route render> will be ignored
10
-const PrivateRoute = ({ component: Component, ...rest }) => {
11
-  return (
12
-    <Route {...rest} render={props => rest.user.isLoggedIn
13
-      ? <Component {...props} />
14
-      : <Redirect to={{pathname: '/login', state: {from: props.location}}} />
15
-    } />
16
-  )
17
-}
10
+const PrivateRoute = ({ component: Component, ...rest }) => (
11
+  <Route {...rest} render={props => rest.user.isLoggedIn
12
+    ? <Component {...props} />
13
+    : <Redirect to={{pathname: '/login', state: {from: props.location}}} />
14
+  } />
15
+)
18 16
 
19 17
 const mapStateToProps = ({ user }) => ({ user })
20 18
 export default withRouter(connect(mapStateToProps)(PrivateRoute))

+ 78 - 0
src/container/Sidebar.jsx View File

@@ -0,0 +1,78 @@
1
+import React from 'react'
2
+import {connect} from 'react-redux'
3
+import WorkspaceListItem from '../component/Sidebar/WorkspaceListItem.jsx'
4
+
5
+class Sidebar extends React.Component {
6
+  constructor (props) {
7
+    super(props)
8
+    this.state = {
9
+      firstWsOpen: false
10
+    }
11
+  }
12
+
13
+  handleClickWorkspace = wsId => {
14
+    // console.log('sidebar handleClickWs')
15
+    this.setState(prev => ({firstWsOpen: !prev.firstWsOpen})) // delete this, purpose is only to test transition on click
16
+    // console.log('sidebar firstwsOpen toggled')
17
+  }
18
+
19
+  render () {
20
+    // <div className='sidebar-expandbar'>
21
+    //   <i className='fa fa-minus-square-o sidebar-expandbar__icon' />
22
+    // </div>
23
+    return (
24
+      <div className='sidebar d-none d-lg-table-cell'>
25
+        <nav className='sidebar__navigation navbar navbar-light'>
26
+          <ul className='sidebar__navigation__workspace navbar-nav collapse navbar-collapse'>
27
+            <WorkspaceListItem
28
+              number={1}
29
+              name='workspace 1 sympa'
30
+              isOpen={this.state.firstWsOpen}
31
+              onClickTitle={() => this.handleClickWorkspace(1)}
32
+            />
33
+
34
+            <li className='sidebar__navigation__workspace__item nav-item dropdown'>
35
+              <div className='sidebar__navigation__workspace__item__wrapper'>
36
+                <div className='sidebar__navigation__workspace__item__number'>
37
+                  02
38
+                </div>
39
+                <div className='sidebar__navigation__workspace__item__name'>
40
+                  Workspace 2
41
+                </div>
42
+
43
+                <div className='sidebar__navigation__workspace__item__icon'>
44
+                  <i className='fa fa-chevron-down' />
45
+                </div>
46
+              </div>
47
+            </li>
48
+
49
+            <li className='sidebar__navigation__workspace__item nav-item dropdown'>
50
+              <div className='sidebar__navigation__workspace__item__wrapper'>
51
+                <div className='sidebar__navigation__workspace__item__number'>
52
+                  03
53
+                </div>
54
+                <div className='sidebar__navigation__workspace__item__name'>
55
+                  Workspace 3
56
+                </div>
57
+
58
+                <div className='sidebar__navigation__workspace__item__icon'>
59
+                  <i className='fa fa-chevron-down' />
60
+                </div>
61
+              </div>
62
+            </li>
63
+
64
+          </ul>
65
+        </nav>
66
+
67
+        <div className='sidebar__btnnewworkspace'>
68
+          <button className='sidebar__btnnewworkspace__btn btn btn-success'>
69
+            Créer un workspace
70
+          </button>
71
+        </div>
72
+      </div>
73
+    )
74
+  }
75
+}
76
+
77
+const mapStateToProps = ({user}) => ({user})
78
+export default connect(mapStateToProps)(Sidebar)

+ 37 - 6
src/container/Tracim.jsx View File

@@ -2,26 +2,57 @@ import React from 'react'
2 2
 import { connect } from 'react-redux'
3 3
 import Footer from '../component/Footer.jsx'
4 4
 import Header from './Header.jsx'
5
+import Sidebar from './Sidebar.jsx'
5 6
 import Login from './Login.jsx'
6
-import Page from './Page.jsx'
7
-import Home from './Home.jsx'
7
+import Dashboard from './Dashboard.jsx'
8
+import AccountPage from './AccountPage.jsx'
9
+import WorkspaceContent from './WorkspaceContent.jsx'
8 10
 import {
9 11
   Route,
10 12
   withRouter
11 13
 } from 'react-router-dom'
12 14
 import PrivateRoute from './PrivateRoute.jsx'
15
+import { getIsUserConnected } from '../action-creator.async.js'
13 16
 
14 17
 class Tracim extends React.Component {
18
+  componentDidMount = () => {
19
+    this.props.dispatch(getIsUserConnected())
20
+  }
21
+
15 22
   render () {
23
+    const { user, location } = this.props
24
+
25
+    const SidebarWrapper = props => {
26
+      if (props.locationPath !== '/login') {
27
+        return (
28
+          <div className='sidebarpagecontainer'>
29
+            <Sidebar />
30
+            {props.children}
31
+          </div>
32
+        )
33
+      } else return props.children
34
+    }
35
+
16 36
     return (
17 37
       <div>
18 38
         <Header />
19 39
 
20
-        <PrivateRoute exact path='/' component={Home} />
21
-        <Route path='/login' component={Login} />
22
-        <PrivateRoute path='/page' component={Page} />
40
+        { user.isLoggedIn === undefined
41
+          ? (<div />) // while we dont know if user is connected, display nothing but the header @TODO show loader
42
+          : (
43
+            <div>
44
+              <Route path='/login' component={Login} />
45
+
46
+              <SidebarWrapper locationPath={location.pathname}>
47
+
48
+                <PrivateRoute exact path='/' component={AccountPage} />
49
+
50
+              </SidebarWrapper>
23 51
 
24
-        <Footer />
52
+              <Footer />
53
+            </div>
54
+          )
55
+        }
25 56
       </div>
26 57
     )
27 58
   }

+ 82 - 0
src/container/WorkspaceContent.jsx View File

@@ -0,0 +1,82 @@
1
+import React from 'react'
2
+import { connect } from 'react-redux'
3
+import Folder from '../component/Workspace/Folder.jsx'
4
+import FileItem from '../component/Workspace/FileItem.jsx'
5
+import FileItemHeader from '../component/Workspace/FileItemHeader.jsx'
6
+import PageWrapper from '../component/common/layout/PageWrapper.jsx'
7
+import PageTitle from '../component/common/layout/PageTitle.jsx'
8
+import PageContent from '../component/common/layout/PageContent.jsx'
9
+import DropdownCreateButton from '../component/common/Input/DropdownCreateButton.jsx'
10
+import FileContentViewer from '../component/Workspace/FileContentViewer.jsx'
11
+import { getWorkspaceContent } from '../action-creator.async.js'
12
+import { setActiveFileContent, hideActiveFileContent } from '../action-creator.sync.js'
13
+
14
+class WorkspaceContent extends React.Component {
15
+  constructor (props) {
16
+    super(props)
17
+    this.state = {
18
+      activeFileType: ''
19
+    }
20
+  }
21
+
22
+  componentDidMount () {
23
+    this.props.dispatch(getWorkspaceContent(/* this.props.workspace.id */1))
24
+  }
25
+
26
+  handleClickFileItem = file => {
27
+    this.props.dispatch(setActiveFileContent(file))
28
+  }
29
+
30
+  handleClickCloseBtn = () => {
31
+    this.props.dispatch(hideActiveFileContent())
32
+  }
33
+
34
+  render () {
35
+    const { workspace, activeFileContent } = this.props
36
+
37
+    return (
38
+      <PageWrapper customeClass='workspace'>
39
+        <PageTitle
40
+          parentClass='workspace__header'
41
+          customClass='justify-content-between'
42
+          title={workspace.title}
43
+        >
44
+          <DropdownCreateButton parentClass='workspace__header__btnaddworkspace' />
45
+        </PageTitle>
46
+
47
+        <PageContent parentClass='workspace__content'>
48
+
49
+          <div className='workspace__content__fileandfolder folder__content active'>
50
+            <FileItemHeader />
51
+
52
+            { workspace.content.map(c => c.type === 'folder'
53
+              ? <Folder folderData={c} key={c.id} />
54
+              : (
55
+                <FileItem
56
+                  name={c.title}
57
+                  type={c.type}
58
+                  status={c.status}
59
+                  onClickItem={() => this.handleClickFileItem(c)}
60
+                  key={c.id}
61
+                />
62
+              )
63
+            )}
64
+          </div>
65
+
66
+          <DropdownCreateButton customClass='workspace__content__button mb-5' />
67
+
68
+          { activeFileContent.display &&
69
+            <FileContentViewer
70
+              file={activeFileContent}
71
+              onClose={this.handleClickCloseBtn}
72
+            />
73
+          }
74
+        </PageContent>
75
+
76
+      </PageWrapper>
77
+    )
78
+  }
79
+}
80
+
81
+const mapStateToProps = ({ workspace, activeFileContent }) => ({ workspace, activeFileContent })
82
+export default connect(mapStateToProps)(WorkspaceContent)

+ 302 - 0
src/css/AccountPage.styl View File

@@ -0,0 +1,302 @@
1
+.nomarginlabel
2
+  margin-bottom 0
3
+
4
+settingText()
5
+  margin 15px 0
6
+  font-size 18px
7
+
8
+.account
9
+  &__userinformation
10
+    display flex
11
+    justify-content center
12
+    align-items center
13
+    flex-wrap wrap
14
+    border 1px solid grey
15
+    padding 25px
16
+    font-size 18px
17
+    &__wrapper
18
+      flex-direction column
19
+    &__avatar
20
+      margin-right 50px
21
+      img
22
+        width 150px
23
+        height 150px
24
+    &__name
25
+      font-size 22px
26
+    &__email
27
+      color blue
28
+    &__company
29
+      font-size 20px
30
+      color blue
31
+  &__delimiter
32
+    position relative
33
+    top 3px
34
+    margin auto
35
+    z-index 3
36
+  &__userpreference
37
+    display flex
38
+    padding 25px
39
+    width 100%
40
+    background-color lightGrey
41
+    &__menu
42
+      margin-right 30px
43
+      border-radius 10px
44
+      padding 0
45
+      width 20%
46
+      background-color off-white
47
+      &__responsive
48
+        font-size 20px
49
+      &__list
50
+        width 100%
51
+        margin-bottom 20px
52
+        &__close
53
+          display none
54
+          justify-content flex-end
55
+          margin 10px 0 15px 0
56
+          font-size 20px
57
+          cursor pointer
58
+        &__disabled
59
+          padding 25px 20px 20px 20px
60
+          color grey
61
+          font-size 18px
62
+        &__item
63
+          margin-top 10px
64
+          padding-left 5px
65
+          font-weight 500
66
+          font-size 18px
67
+          cursor pointer
68
+          &:hover
69
+            background-color blue
70
+            color white
71
+    &__setting
72
+      border-radius 10px
73
+      padding 20px
74
+      width 80%
75
+      background-color off-white
76
+      &__personaldata
77
+        &__text
78
+          settingText()
79
+        &__changeinfo
80
+          margin 25px 0
81
+          &__infotitle
82
+            margin-bottom 15px
83
+            font-size 18px
84
+          &__txtinput
85
+            display inline-flex
86
+            display ms-inline-flex
87
+            width auto
88
+            margin 0 15px 15px 0
89
+            border 1px solid blue
90
+            border-radius 10px
91
+            padding 8px 15px
92
+          &__button
93
+            vertical-align top
94
+            border 1px solid blue
95
+            border-radius 10px
96
+            padding 8px 25px
97
+            background-color transparent
98
+            color blue
99
+            cursor pointer
100
+            &:hover, &:focus
101
+              background-color blue
102
+              color white
103
+      &__calendar
104
+        &__title
105
+          settingTitle()
106
+        &__text
107
+          settingText()
108
+        &__infotitle
109
+          margin 15px 0
110
+          font-size 18px
111
+        &__link
112
+          display inline-block
113
+          border 1px solid grey
114
+          border-radius 10px
115
+          padding 10px 25px
116
+        &__timezone
117
+          margin 15px 0 30px 0
118
+          &__btn
119
+            border 1px solid blue
120
+            border-radius 10px
121
+            padding 10px 35px
122
+            color blue
123
+            background-color transparent
124
+            &::after
125
+              margin-left 10px
126
+            &:hover, &:focus
127
+              background-color blue
128
+              color white
129
+          &__submenu
130
+            width 203px
131
+            max-height 300px
132
+            overflow-Y auto
133
+            &__item
134
+              &:hover, &:focus
135
+                background-color blue
136
+                color white
137
+      &__notification
138
+        &__title
139
+          settingTitle()
140
+        &__text
141
+          settingText()
142
+          margin-bottom 30px
143
+        &__tableau
144
+          border 1px solid lightGrey
145
+          &__role
146
+            display flex
147
+            align-items center
148
+            &__icon
149
+              margin-right 10px
150
+
151
+.account__userpreference__setting__notification__table__line:nth-last-child(1)
152
+  border-bottom 0
153
+
154
+
155
+/***** MEDIAQUERIES *****/
156
+
157
+
158
+/**** MEDIA 576px & 1199px ****/
159
+
160
+// Regroup the common rules
161
+
162
+@media (min-width: min-sm) and (max-width: max-md)
163
+
164
+  .account
165
+    &__userpreference
166
+      display block
167
+      position relative
168
+      &__menu
169
+        justify-content center
170
+        margin-bottom 25px
171
+        border-radius 30px
172
+        width 60px
173
+        min-height 60px
174
+        &__responsive
175
+          align-self center
176
+        &__list
177
+          display none
178
+      &__setting
179
+        padding 10px
180
+        width 100%
181
+
182
+  .activemenu
183
+    .account
184
+      &__userpreference
185
+        &__menu
186
+          justify-content start
187
+          position absolute
188
+          top 0
189
+          left 0
190
+          border-radius 10px
191
+          width 100%
192
+          height 100%
193
+          z-index 2
194
+          background-color rgbGrey
195
+          &__responsive
196
+            display none
197
+          &__list
198
+            display block
199
+            border-radius 10px
200
+            height 100%
201
+            background-color off-white
202
+            width 300px
203
+            &__close
204
+              display flex
205
+            &__disabled
206
+              padding 0 20px
207
+
208
+/***** MEDIA LG *****/
209
+
210
+@media (min-width: min-lg) and (max-width: max-lg)
211
+
212
+  .account
213
+    &__userpreference
214
+      padding 25px 10px
215
+      &__menu
216
+        margin-right 15px
217
+        width 25%
218
+
219
+/**** MEDIA SM ****/
220
+
221
+@media (min-width: min-sm) and (max-width: max-sm)
222
+
223
+  .account
224
+    &__userpreference
225
+      padding 25px 0
226
+      &__menu
227
+        margin-left 15px
228
+      &__setting
229
+        padding 30px 15px
230
+
231
+  .activemenu
232
+    .account__userpreference__menu
233
+      margin-left 0
234
+
235
+/***** MEDIA XS *****/
236
+
237
+@media (max-width: max-xs)
238
+
239
+  .account
240
+    &__userinformation
241
+      &__avatar
242
+        margin 0 0 20px 0
243
+      &__wrapper
244
+        text-align center
245
+    &__userpreference
246
+      display block
247
+      position relative
248
+      padding 25px 0
249
+      &__menu
250
+        justify-content center
251
+        margin 0 0 25px 15px
252
+        border-radius 30px
253
+        width 60px
254
+        min-height 60px
255
+        &__responsive
256
+          align-self center
257
+        &__list
258
+          display none
259
+      &__setting
260
+        border-radius 0
261
+        padding 10px 0
262
+        width 100%
263
+        &__calendar
264
+          &__link
265
+            padding 10px 15px
266
+        &__notification
267
+          &__tableau
268
+            &__wksname
269
+              text-overflow ellipsis
270
+              white-space nowrap
271
+              overflow hidden
272
+              width 100px
273
+              &:focus
274
+                overflow visible
275
+                width auto
276
+
277
+  .activemenu
278
+    .account
279
+      &__userpreference
280
+        &__menu
281
+          justify-content start
282
+          position absolute
283
+          top 0
284
+          left 0
285
+          margin-left 0
286
+          border-radius 10px
287
+          width 100%
288
+          height 100%
289
+          z-index 2
290
+          background-color rgbGrey
291
+          &__responsive
292
+            display none
293
+          &__list
294
+            display block
295
+            border-radius 10px
296
+            height 100%
297
+            background-color off-white
298
+            width 300px
299
+            &__close
300
+              display flex
301
+            &__disabled
302
+              padding 0 20px

+ 356 - 0
src/css/Dashboard.styl View File

@@ -0,0 +1,356 @@
1
+flexwrap()
2
+  display flex
3
+  flex-wrap wrap
4
+
5
+btnNotification()
6
+  margin 20px 0
7
+  border 1px solid blue
8
+  padding 10px 15px
9
+
10
+hoverfocus()
11
+  background-color blue
12
+  color white
13
+
14
+bgandcolor()
15
+  background-color transparent
16
+  color blue
17
+
18
+.dashboard
19
+  margin-left 20px
20
+  &__title
21
+    margin 0
22
+  &__wkswrapper
23
+    flexwrap()
24
+  &__workspace
25
+    margin-right 20px
26
+    width calc(65% - 20px) //20px => margin-right
27
+    &__title
28
+      margin-bottom 20px
29
+      font-size 40px
30
+      font-weight 500
31
+      color darkBlue
32
+    &__detail
33
+      margin-bottom 20px
34
+      font-size 18px
35
+  &__userstatut
36
+    width 35%
37
+    &__role
38
+      flexwrap()
39
+      margin 20px 0
40
+      font-size 18px
41
+      &__text
42
+        margin-right 15px
43
+      &__rank
44
+        display flex
45
+        &__icon
46
+          margin-right 15px
47
+          color gestionnaire
48
+    &__notification
49
+      font-size 18px
50
+      &__btn
51
+        btnNotification()
52
+        bgandcolor()
53
+        cursor pointer
54
+        &:hover , focus
55
+          hoverfocus()
56
+      &__subscribe
57
+        display none
58
+        &__btn
59
+          btnNotification()
60
+          bgandcolor()
61
+          &:hover,&:focus
62
+            hoverfocus()
63
+        &__submenu
64
+          padding 0
65
+          &__item
66
+            padding 10px
67
+            &:hover,&:focus
68
+              hoverfocus()
69
+  &__calltoaction
70
+    flexwrap()
71
+    margin 50px 0
72
+    &__button
73
+      &:active
74
+        box-shadow inset 0px 0px 5px 2px #656565
75
+      &__text
76
+        &__icon
77
+          font-size 30px
78
+          .fa-comments-o, .fa-paperclip, .fa-calendar, .fa-file-text-o, .fa-folder-open-o
79
+              color white
80
+        &__title
81
+          font-size 18px
82
+          color white
83
+    .thread
84
+      background-color blue
85
+    .writefile
86
+      background-color writefile
87
+    .importfile
88
+      background-color importfile
89
+    .calendar
90
+      background-color calendar
91
+    .explore
92
+      background-color explore
93
+  &__wksinfo
94
+    flexwrap()
95
+  &__activity
96
+    margin 0 35px 50px 0
97
+    width 60%
98
+    &__header
99
+      display flex
100
+      justify-content space-between
101
+      align-items center
102
+      margin-bottom 20px
103
+      height 44px
104
+      &__allread
105
+        border 1px solid blue
106
+        padding 10px 25px
107
+        color blue
108
+        font-size 18px
109
+        cursor pointer
110
+        &:hover, &:focus
111
+          hoverfocus()
112
+    &__wrapper
113
+      border 1px solid grey
114
+      height 480px
115
+    &__workspace
116
+      display flex
117
+      align-items center
118
+      border-bottom 1px solid grey
119
+      padding 15px
120
+      cursor pointer
121
+      &:hover
122
+        background-color folder-hover
123
+      &__icon
124
+        margin 0 25px
125
+        font-size 25px
126
+      &__name
127
+        font-size 18px
128
+        font-weight 500
129
+        span
130
+          font-weight 400
131
+    &__more
132
+      &__btn
133
+        margin 15px
134
+        border 1px solid blue
135
+        padding 10px 25px
136
+        color blue
137
+        cursor pointer
138
+        &:hover, &:focus
139
+          hoverfocus()
140
+  &__memberlist
141
+    margin 0 0 50px 0
142
+    width 35%
143
+    &__title
144
+      margin-bottom 20px
145
+      padding 6px
146
+      height 45px
147
+    &__wrapper
148
+      position relative
149
+      border 1px solid grey
150
+      height 480px
151
+    &__list
152
+      margin 0
153
+      padding 0
154
+      list-style none
155
+      height 400px
156
+      overflow-Y scroll
157
+      &__item
158
+        display flex
159
+        border-bottom 1px solid grey
160
+        padding 10px 15px
161
+        &:nth-last-child(1)
162
+          border-bottom 0
163
+        &__avatar
164
+          margin-right 20px
165
+          width 50px
166
+          height 50px
167
+        &__info
168
+          &__name
169
+            font-size 20px
170
+          &__role
171
+            font-size 18px
172
+    &__btnadd
173
+      border-top 1px solid grey
174
+      padding 15px
175
+      &__button
176
+        display flex
177
+        align-items center
178
+        &__avatar
179
+          margin-right 20px
180
+          cursor pointer
181
+          img
182
+            width 50px
183
+            height 50px
184
+        &__text
185
+          font-size 18px
186
+          color blue
187
+          cursor pointer
188
+    &__addmember
189
+      position absolute
190
+      top 0
191
+      display none
192
+      flex-direction column
193
+      justify-content center
194
+      align-items center
195
+      height 100%
196
+      width 100%
197
+      background-color off-white
198
+      &__name
199
+        margin-bottom 20px
200
+        border 1px solid grey
201
+        border-radius 10px
202
+        padding 10px 25px
203
+        width auto
204
+      &__role
205
+        margin-bottom 20px
206
+        &__dropdown
207
+          &__button
208
+            border 1px solid blue
209
+            border-radius 10px
210
+            padding 10px 25px
211
+            bgandcolor()
212
+            &::after
213
+              margin 10px 0 0 20px
214
+            &:hover,&:focus
215
+              hoverfocus()
216
+          &__submenu
217
+            padding 0
218
+            &__item
219
+              display flex
220
+              padding 10px
221
+              &:hover,&:focus
222
+                hoverfocus()
223
+              &__icon
224
+                margin-right 15px
225
+      &__submitbtn
226
+        border 1px solid blue
227
+        border-radius 5px
228
+        padding 5px 35px
229
+        bgandcolor()
230
+        cursor pointer
231
+        &:hover, &:focus
232
+          hoverfocus()
233
+  &__webdav
234
+    margin-bottom 100px
235
+    &__btn
236
+      width 300px
237
+    &__information
238
+      display none
239
+      width 600px
240
+
241
+/****** CLASS ACTIVE *******/
242
+
243
+/*** active dropdown subscribe ***/
244
+
245
+.activebtnsubs
246
+  .dashboard__userstatut__notification
247
+    &__btn
248
+      display none
249
+    &__subscribe
250
+      display flex
251
+
252
+/*** active form on list member ***/
253
+
254
+.activeform
255
+  .dashboard__memberlist__addmember
256
+    display flex
257
+
258
+/*** active webdav ***/
259
+
260
+.activewebdav
261
+  .dashboard__webdav__information
262
+    display block
263
+
264
+/**** MEDIAQUERIES *****/
265
+
266
+/**** MEDIA 576px & 1199px ****/
267
+
268
+// Regroup the common rules
269
+
270
+@media (min-width min-sm) and (max-width: max-lg)
271
+
272
+  .dashboard
273
+    &__workspace
274
+      width auto
275
+    &__userstatut
276
+      width auto
277
+    &__calltoaction
278
+      justify-content center
279
+    &__activity
280
+      width 100%
281
+    &__memberlist
282
+      width 50%
283
+
284
+/**** MEDIA 992px & 1199px ****/
285
+
286
+@media (min-width: min-lg) and (max-width: max-lg)
287
+
288
+  .dashboard
289
+    margin-left 15px
290
+
291
+/**** MEDIA 768px & 991px ****/
292
+
293
+@media (min-width: min-md) and (max-width: max-md)
294
+
295
+  .dashboard
296
+    &__activity
297
+      margin 25px 15px 25px 0
298
+
299
+/**** MEDIA 576px & 767px ****/
300
+
301
+@media (min-width: min-sm) and (max-width: max-sm)
302
+
303
+  .dashboard
304
+    &__activity
305
+      margin 25px 15px 25px 0
306
+    &__memberlist
307
+      margin 50px 0
308
+      width 90%
309
+    &__webdav__information
310
+      width 500px
311
+
312
+/**** MEDIA 575px ****/
313
+
314
+@media (max-width: max-xs)
315
+
316
+  position()
317
+    margin-left 10px
318
+    width auto
319
+
320
+  .dashboard
321
+    margin-left 0
322
+    &__title
323
+      margin-left 10px
324
+    &__workspace
325
+      position()
326
+    &__userstatut
327
+     position()
328
+    &__calltoaction
329
+      justify-content center
330
+      &__button
331
+        margin-right 0
332
+    &__activity
333
+      margin 25px 0
334
+      width 100%
335
+      &__header
336
+        display block
337
+        height auto
338
+        margin 0 15px 20px 15px
339
+        &__title
340
+          margin-bottom 20px
341
+    &__memberlist
342
+      margin 50px 0
343
+      width 100%
344
+      &__title
345
+        margin-left 10px
346
+      &__wrapper
347
+        height auto
348
+      &__list
349
+        height auto
350
+        overflow-Y visible
351
+      &__btnadd
352
+        border-top 0
353
+    &__webdav
354
+      margin-left 10px
355
+      &__information
356
+        width 350px

+ 275 - 0
src/css/File.styl View File

@@ -0,0 +1,275 @@
1
+.wsFileFile
2
+  width 1200px
3
+  height calc(100% - 85px)
4
+  &__header
5
+    background-color fileColor
6
+    &__editionmode
7
+      display none
8
+    .fa-file-image-o
9
+      color white
10
+  &__option
11
+    &__menu
12
+      display flex
13
+      &__addversion
14
+        padding 8px 15px
15
+        border 1px solid fileColor
16
+        border-radius 5px
17
+        background-color transparent
18
+        color fileColor
19
+        cursor pointer
20
+        & > i
21
+          margin-left 10px
22
+        &:hover
23
+          background-color fileColor
24
+          border none
25
+          color white
26
+  &__contentpage
27
+    display flex
28
+    height 100%
29
+    &__preview
30
+      position relative
31
+      margin 10px
32
+      border-radius 10px
33
+      width 60%
34
+      height calc(100% - 150px) // margin + height of header and option
35
+      background-color off-white
36
+      &__sidebar
37
+        display flex
38
+        position absolute
39
+        top 0
40
+        right 0
41
+        height 100%
42
+        &__button
43
+          display flex
44
+          flex-direction column
45
+          align-items center
46
+          width 50px
47
+          height 100%
48
+          background-color grey
49
+          cursor pointer
50
+          &:hover
51
+            background-color fileColor
52
+          &__icon
53
+            justify-content flex-start
54
+            font-size 30px
55
+            color white
56
+          &__title
57
+            margin-top 45px
58
+            color white
59
+            transform rotate(-90deg)
60
+        &__property
61
+          width 0
62
+          overflow-X hidden
63
+          background-color off-white
64
+          transition width 0.5s
65
+          &__detail
66
+            padding 20px
67
+            width 410px
68
+            &__size
69
+              margin-bottom 20px
70
+            &__description
71
+              &__editiondesc
72
+                display none
73
+                margin 20px 0
74
+                textarea
75
+                  width 100%
76
+                  height 250px
77
+                &__validate
78
+                  margin 30px auto
79
+                  width 150px
80
+            &__btndesc
81
+              display block
82
+              margin 15px 0
83
+              width 200px
84
+      &__dloption
85
+        display flex
86
+        justify-content center
87
+        padding-top 10px
88
+        &__icon
89
+          margin-right 20px
90
+          font-size 20px
91
+          cursor pointer
92
+          &:hover , &:focus
93
+            color fileColor
94
+      &__slider
95
+        display flex
96
+        align-items center
97
+        width calc(100% - 50px) // 50px => width of sidebar
98
+        height calc(100% - 40px) // 40px => height of dloption
99
+        &__fileimg
100
+          display flex
101
+          flex-direction column
102
+          justify-content center
103
+          padding 30px
104
+          width 100%
105
+          height 100%
106
+          & > img
107
+            max-height 100%
108
+            max-width 100%
109
+        &__icon
110
+          margin 0 5px
111
+          font-size 20px
112
+          cursor pointer
113
+    &__wrapper
114
+      width 40%
115
+      height calc(100% - 150px) // margin + height of header and option
116
+      overflow-Y auto
117
+      .timeline
118
+        &__messagelist
119
+          min-height 300px
120
+          &__version
121
+            &__btn
122
+              background-color fileColor
123
+              &:hover , &:focus
124
+                background-color lightFileColor
125
+        &__texteditor
126
+          &__simpletext
127
+            &__input
128
+              &:focus
129
+                color fileColor
130
+                border-color fileColor
131
+          &__submit
132
+            &__btn
133
+              border-color fileColor
134
+              background-color fileColor
135
+              color white
136
+              &:hover , &:focus
137
+                border-color fileColor
138
+                background-color fileColor
139
+
140
+/***** SENDER RECEIVER *****/
141
+
142
+.received
143
+  .wsFileFile__contentpage__messagelist__item__content
144
+      background-color fileColor
145
+
146
+/***** ACTIVE SIDEBAR *****/
147
+
148
+.activesidebar
149
+  .wsFileFile__contentpage__preview
150
+    &__sidebar
151
+      border-radius 0 10px 10px 0
152
+      &__button
153
+        background-color fileColor
154
+      &__property
155
+        width 450px
156
+        overflow-Y auto
157
+        color fileColor
158
+
159
+.activeEditionTitle
160
+  .wsFileFile__header
161
+    &__editionmode
162
+      display block
163
+    &__title
164
+      display none
165
+
166
+.activeEditionDesc
167
+  .wsFileFile__contentpage__preview__sidebar__property__detail
168
+    &__description
169
+      &__editiondesc
170
+        display block
171
+    &__btndesc
172
+      display none
173
+
174
+/****** MEDIA QUERIES ********/
175
+
176
+// Regroup the common css rules mediaqueries into a single media to lighten the code
177
+
178
+@media (min-width: max-xs) and (max-width: max-lg)
179
+
180
+  .wsFileFile
181
+    overflow-Y auto
182
+    &__contentpage
183
+      display block
184
+      &__preview
185
+        display flex
186
+        flex-direction column
187
+        width calc(100% - 30px) // 30px => margin
188
+      &__wrapper
189
+        width calc(100% - 30px) // 30px => margin
190
+        .timeline
191
+          &__texteditor
192
+            &__simpletext
193
+              display inline-flex
194
+              width 60%
195
+            &__submit
196
+              display inline-flex
197
+              margin 10px 0
198
+              &__btn
199
+                display flex
200
+                margin-left 35px
201
+                &__icon
202
+                  margin-left 15px
203
+
204
+/**** MEDIA 992px & 1199px ****/
205
+
206
+@media (min-width: min-lg) and (max-width: max-lg)
207
+
208
+  .wsFileFile
209
+    width 900px
210
+    overflow-Y auto
211
+
212
+/******************************/
213
+
214
+/**** MEDIA 768px & 991px ****/
215
+
216
+@media (min-width: min-md) and (max-width: max-md)
217
+
218
+  .wsFileFile
219
+    width 100%
220
+
221
+/******************************/
222
+
223
+/**** MEDIA 576px & 767px ****/
224
+
225
+@media (min-width: min-sm) and (max-width: max-sm)
226
+
227
+  .wsFileFile
228
+    top 69px
229
+    width 100%
230
+    height calc(100% - 69px) // 69px => top rules
231
+    overflow-Y scroll
232
+
233
+/******************************/
234
+
235
+/**** MEDIA 575px ****/
236
+
237
+@media (max-width: max-xs)
238
+
239
+  .activesidebar
240
+    .wsFileFile__contentpage__preview
241
+      &__sidebar
242
+        &__property
243
+          width 300px
244
+
245
+  .wsFileFile
246
+    top 69px
247
+    width 100%
248
+    height calc(100% - 69px) // 69px => top rules
249
+    overflow-Y scroll
250
+    &__option__menu__addversion
251
+        padding 8px 5px
252
+        & > i
253
+          display none
254
+    &__contentpage
255
+      display block
256
+      &__preview
257
+        display flex
258
+        flex-direction column
259
+        width calc(100% - 30px) // 30px => margin
260
+      &__wrapper
261
+        width calc(100% - 30px) // 30px => margin
262
+        .timeline
263
+          &__texteditor
264
+            &__simpletext
265
+              display inline-flex
266
+              width 60%
267
+              margin-right 0
268
+            &__submit
269
+              display inline-flex
270
+              margin 10px 0
271
+              &__btn
272
+                display flex
273
+                margin-left 10px
274
+                &__icon
275
+                  margin-left 15px

+ 34 - 0
src/css/FileItem.styl View File

@@ -0,0 +1,34 @@
1
+.file
2
+  display flex
3
+  border-bottom 0
4
+  &:hover
5
+    background-color files-hover
6
+  &__type
7
+    font-size 30px
8
+    text-align center
9
+  &__name
10
+    display flex
11
+    justify-content space-between
12
+    padding 15px 5px
13
+    cursor pointer
14
+    &__text
15
+      font-size 17px
16
+    &__icons
17
+      &__download
18
+        display inline-block
19
+        margin-right 10px
20
+      &__archive
21
+        display inline-block
22
+        margin-right 10px
23
+      &__delete
24
+        display inline-block
25
+        margin-right 10px
26
+  &__status
27
+    font-size 30px
28
+    text-align center
29
+
30
+@media (min-width: max-xs) and (max-width: max-lg)
31
+  .file
32
+    border-right 1px solid grey
33
+    &__name__icons
34
+        margin-top 5px

+ 13 - 0
src/css/FileItemHeader.styl View File

@@ -0,0 +1,13 @@
1
+.file__header
2
+  display flex
3
+  font-size 17px
4
+  &__type
5
+    padding 15px 0
6
+    text-align center
7
+  &__name
8
+    padding 15px 5px
9
+    width 100%
10
+  &__status
11
+    padding 15px 0
12
+    width 100%
13
+    text-align center

+ 120 - 0
src/css/Folder.styl View File

@@ -0,0 +1,120 @@
1
+// -----------------------------------------------------
2
+// border management for Workspace container
3
+border-style = 1px solid darkBlue
4
+.folder__header
5
+  border border-style
6
+.file
7
+  border border-style
8
+.folder + .file, .file + .file
9
+  border-bottom 0
10
+.folder__content > .file, .folder__content > .folder
11
+  border-bottom 0
12
+// @TODO the very last line of file or folder has to be added a border bottom in js
13
+// -----------------------------------------------------
14
+
15
+folderclose()
16
+  height 0
17
+  visibility hidden
18
+  opacity 0
19
+
20
+folderopen()
21
+  height 100%
22
+  opacity 1
23
+  visibility visible
24
+  transition opacity 1s
25
+
26
+.folder
27
+  padding-left 30px
28
+  & > .folder__header
29
+    folderopen()
30
+  & > .folder__content
31
+    folderclose()
32
+    & > .file, > .folder
33
+      folderclose()
34
+  &.active
35
+    & > .folder__header
36
+      .folder__header__triangleborder
37
+        display block
38
+        &__triangle
39
+          display block
40
+    & > .folder__content
41
+      folderopen()
42
+      & > .file, > .folder
43
+        folderopen()
44
+
45
+  &__header
46
+    position relative
47
+    display flex
48
+    justify-content space-between
49
+    margin-left -30px
50
+    border-bottom 0
51
+    background-color lightGrey
52
+    cursor pointer
53
+    &:hover
54
+      background-color folder-hover
55
+      .folder__header__triangleborder__triangle
56
+        border-color hover-folder transparent transparent transparent
57
+    &__triangleborder
58
+      display none
59
+      position absolute
60
+      top 62px
61
+      left -1px
62
+      border-style solid
63
+      border-width 25px 30px 0 30px
64
+      border-color darkBlue transparent transparent transparent
65
+      z-index 1
66
+      &__triangle
67
+        display none
68
+        position absolute
69
+        top -26px
70
+        left -30px
71
+        border-style solid
72
+        border-width 25px 30px 0 30px
73
+        border-color lightGrey transparent transparent transparent
74
+    &__name
75
+      display flex
76
+      padding-left 5px
77
+      &__icon
78
+        margin auto 15px
79
+        font-size 25px
80
+        color darkBlue
81
+      &__text
82
+        margin auto 15px
83
+        font-size 17px
84
+        color darkBlue
85
+      &__addbtn
86
+        margin auto 0
87
+        cursor pointer
88
+        &:hover > .folder__header__name__addbtn__text
89
+          color white
90
+        &__text
91
+          border 1px solid darkBlue
92
+          background-color transparent
93
+          color darkBlue
94
+          font-size 17px
95
+    &__contenttype
96
+      display flex
97
+      &__text
98
+        padding 18px 15px
99
+        font-size 17px
100
+        color darkBlue
101
+      &__icon
102
+        padding 18px 5px
103
+        font-size 17px
104
+        color darkBlue
105
+        & > i
106
+          margin-right 15px
107
+
108
+@media (max-width: max-xs)
109
+  .folder
110
+    &__header
111
+      &__triangleborder
112
+        top 59px
113
+      &__name
114
+        &__icon
115
+          padding 14px 15px
116
+          font-size 20px
117
+        &__text
118
+          font-size 15px
119
+      &__contenttype
120
+        display none

+ 1 - 1
src/css/Footer.styl View File

@@ -1,7 +1,7 @@
1 1
 .footer
2 2
   border-top 1px solid grey
3 3
   width 100%
4
-  background-color light-grey
4
+  background-color lightGrey
5 5
   &__text
6 6
     display none
7 7
     vertical-align middle

+ 265 - 0
src/css/Generic.styl View File

@@ -0,0 +1,265 @@
1
+/*** SIDEBAR ***/
2
+
3
+.sidebarpagecontainer
4
+  display flex
5
+  min-height calc(100% - 50px)
6
+  padding-top 85px
7
+
8
+/********************/
9
+
10
+/*** ELEMENTS ON ALL PAGE ***/
11
+
12
+.pageWrapperGeneric
13
+  width 100%
14
+  &__header
15
+    display flex
16
+  &__content
17
+    margin 10px 10px 120px 10px
18
+@media (min-width: min-md) and (max-width: max-md)
19
+  .pageWrapperGeneric
20
+    display block
21
+    padding-top 87px
22
+    &__header
23
+      margin 95px 0 5px 30px
24
+    &__content
25
+      margin 0
26
+@media (min-width: min-sm) and (max-width: max-sm)
27
+  .pageWrapperGeneric
28
+    display block
29
+    padding-top 87px
30
+    &__header
31
+      margin 95px 0 35px 0
32
+      &__title
33
+        display inline-block
34
+        margin-left 0
35
+    &__content
36
+      margin 0
37
+@media (max-width: max-xs)
38
+  .pageWrapperGeneric
39
+    display block
40
+    padding-top 87px
41
+    &__header
42
+      display block
43
+      margin-top 60px
44
+    &__content
45
+      margin 0
46
+
47
+.nopadding
48
+  padding 0
49
+
50
+.pageTitleGeneric
51
+  display flex
52
+  margin 45px 0
53
+  &__title
54
+    margin-left 10px
55
+    font-size 30px
56
+    color darkGrey
57
+@media (max-width: max-xs)
58
+  .pageTitleGeneric
59
+    display block
60
+
61
+
62
+.pageContentGeneric
63
+  margin 10px 10px 120px 10px
64
+
65
+.dropdownCreateBtn
66
+  &__label
67
+    padding 10px 65px
68
+    background-color green
69
+    cursor pointer
70
+    &__text
71
+      display inline-block
72
+      color white
73
+    &::after //bootstrap override
74
+      display inline-block
75
+      margin-left 30px
76
+      color white
77
+  &__setting
78
+    padding 0
79
+    cursor pointer
80
+    .setting__link
81
+      padding 5px 65px 5px 10px
82
+
83
+.fa-file-image-o
84
+  color previewColor
85
+
86
+.fa-comments-o
87
+  color threadColor
88
+
89
+.fa-list-ul
90
+  color taskColor
91
+
92
+.fa-file-code-o
93
+  color markdownColor
94
+
95
+.fa-file-word-o
96
+  color htmlColor
97
+
98
+.fa-ticket
99
+  color issueColor
100
+
101
+.fa-graduation-cap
102
+  color gestionnaire
103
+
104
+.fa-pencil
105
+  color contributeur
106
+
107
+.fa-gavel
108
+  color responsable
109
+
110
+.fa-eye
111
+  color lecteur
112
+
113
+.subTitle
114
+  font-size 20px
115
+  font-weight 500
116
+  color blue
117
+
118
+.GenericDelimiter
119
+  border-radius 10px
120
+  width 50%
121
+  height 5px
122
+  background-color blue
123
+
124
+.btnaction
125
+  display flex
126
+  flex-direction column
127
+  justify-content center
128
+  margin 20px 30px 20px 0
129
+  border-radius 10px
130
+  padding 15px
131
+  width 250px
132
+  height 200px
133
+  box-shadow shadow-all
134
+  text-align center
135
+  cursor pointer
136
+
137
+.genericWebdav
138
+  &__btn
139
+    display flex
140
+    margin-bottom 30px
141
+    border 1px solid blue
142
+    border-radius 10px
143
+    padding 15px 25px
144
+    color blue
145
+    cursor pointer
146
+    &:hover, &:focus
147
+      background-color blue
148
+      color white
149
+    &__icon
150
+      margin-right 20px
151
+      font-size 30px
152
+  &__info
153
+    border 1px solid grey
154
+    border-radius 10px
155
+    padding 15px 25px
156
+    &__text
157
+      margin-bottom 35px
158
+    &__link
159
+      display inline-block
160
+      margin-bottom 15px
161
+      border 1px solid grey
162
+      border-radius 10px
163
+      padding 15px 25px
164
+
165
+/********************/
166
+
167
+/*** PAGE FILE, THREAD, HTML, MARKDOWN, ISSUE ***/
168
+
169
+.wsFileGeneric
170
+  position fixed
171
+  top 85px
172
+  right 0
173
+  border 1px solid grey
174
+  height 100%
175
+  background-color lightGrey
176
+  box-shadow shadow-page
177
+  visibility hidden
178
+  z-index 1
179
+  &.visible
180
+    visibility visible
181
+  &__header
182
+    display flex
183
+    align-items center
184
+    padding 15px
185
+    height 64px
186
+    &__icon
187
+      margin-right 15px
188
+      font-size 22px
189
+      color white
190
+    &__title
191
+      margin-right 15px
192
+      color white
193
+      text-overflow ellipsis
194
+      overflow hidden
195
+      white-space nowrap
196
+    &__edittitle
197
+      margin 0 15px
198
+      color white
199
+      font-size 20px
200
+      cursor pointer
201
+      &:hover , &:focus
202
+        border 1px solid off-white
203
+        padding 0 10px
204
+        border-radius 5px
205
+    &__close
206
+      border 1px solid white
207
+      border-radius 5px
208
+      padding 2px 5px
209
+      cursor pointer
210
+      & > i
211
+        color white
212
+        font-size 20px
213
+  &__option
214
+    border-bottom 1px solid grey
215
+    padding 10px
216
+    height 58px
217
+    background-color off-white
218
+    & > i
219
+      vertical-align middle
220
+      margin-right 15px
221
+      font-size 25px
222
+      cursor pointer
223
+    &__menu
224
+      display flex
225
+      align-items center
226
+      &__status
227
+        margin-right 20px
228
+        .current
229
+          color blue
230
+        .check
231
+          color green
232
+        .invalid
233
+          color red
234
+        .ban
235
+          color grey
236
+        &__dropdownbtn
237
+          border 1px solid grey
238
+          width 150px
239
+          background-color transparent
240
+          cursor pointer
241
+          &::after
242
+            color fontColor
243
+          &:hover
244
+            background-color transparent
245
+          &__icon
246
+            display inline-block
247
+            margin 0 15px
248
+        &__submenu
249
+          &__item
250
+            display flex
251
+            justify-content space-between
252
+            margin 5px 0
253
+            cursor pointer
254
+            &:active
255
+              background-color transparent
256
+      &__action
257
+        margin 5px 10px 0 0
258
+        font-size 18px
259
+        cursor pointer
260
+        &:hover , &:focus
261
+          font-size 22px
262
+          color blue
263
+  &__wrapper
264
+    display flex
265
+    flex-direction column

+ 21 - 43
src/css/Header.styl View File

@@ -1,7 +1,9 @@
1 1
 .header
2
+  position fixed
2 3
   width 100%
3 4
   box-shadow shadow-bottom
4
-  background off-white
5
+  background mainColor
6
+  z-index 4
5 7
   &__logo
6 8
     &__img
7 9
       margin-left 40px
@@ -17,12 +19,10 @@
17 19
           color blue
18 20
           font-size 16px
19 21
           &:hover
20
-            color dark-blue
22
+            color darkBlue
21 23
     &__rightside
22 24
       display flex
23
-      justify-content flex-end
24 25
       margin-top 15px
25
-      width 60%
26 26
       list-style none
27 27
       &__itemsearch
28 28
         margin-right 8%
@@ -40,7 +40,7 @@
40 40
           .languagedropdown
41 41
             &__btnlanguage
42 42
               margin-right 25px
43
-              color dark-grey
43
+              color darkGrey
44 44
               &:focus
45 45
                 box-shadow shadow-all-side-blue
46 46
                 border-radius 5px
@@ -60,7 +60,7 @@
60 60
         &__btnquestion
61 61
           margin-right 30px
62 62
           .btnquestion__icon
63
-            color dark-grey
63
+            color darkGrey
64 64
       &__itemprofil
65 65
         &__profilgroup
66 66
           .profilgroup__name
@@ -68,13 +68,13 @@
68 68
             padding 0 5px
69 69
             background-color transparent
70 70
             &:hover
71
-              background-color light-grey
71
+              background-color lightGrey
72 72
             &:focus
73 73
               box-shadow shadow-all-side-blue
74
-              background-color light-grey
74
+              background-color lightGrey
75 75
             &::after //bootstrap overrides
76 76
               vertical-align middle
77
-              color dark-grey
77
+              color darkGrey
78 78
             &__imgprofil
79 79
               display inline-block
80 80
               margin-right 10px
@@ -84,7 +84,7 @@
84 84
               display inline-block
85 85
               vertical-align middle
86 86
               margin-right 10px
87
-              color dark-grey
87
+              color darkGrey
88 88
           .profilgroup__sub
89 89
             color dark-grey
90 90
             cursor pointer
@@ -96,62 +96,40 @@
96 96
               padding 10px 0
97 97
 
98 98
 @media (min-width: min-lg) and (max-width: max-lg)
99
-  .header__menu__rightside
100
-    width 100%
99
+  .header
100
+    &__menu
101
+      &__rightside
102
+        width 100%
101 103
 
102 104
 @media (min-width: min-md) and (max-width: max-md)
103 105
   .header
104 106
     &__logo__img
105
-        margin-left 0
107
+      margin-left 0
106 108
     &__menu
107
-      &__list
108
-        margin-left 0
109 109
       &__rightside
110
-        width 67%
110
+        width 100%
111 111
 
112 112
 @media (min-width: min-sm) and (max-width: max-sm)
113 113
   .header
114
-    position fixed
115
-    z-index 2
116 114
     &__logo__img
117 115
       margin-left 0
118 116
     &__menu
119
-      &__list
120
-        margin-left 0
121
-        .list__item
122
-          padding-right 0
123
-          padding-bottom 12px
124 117
       &__rightside
125
-        margin-top 12px
126 118
         padding-left 0
127
-        justify-content center
128 119
         width 100%
129
-        &__itemsearch
130
-          margin-right 45px
131 120
         &__itemquestion
132 121
           display none
133 122
 
134 123
 @media (max-width: max-xs)
135 124
   .header
136
-    position fixed
137
-    z-index 2
138 125
     &__logo__img
139 126
       margin-left 0
140
-    &__menu__list
141
-      margin-left 0
142
-      .list__item
143
-        padding-right 0
144
-        padding-bottom 12px
127
+    &__menu
145 128
       &__rightside
146
-        padding-top 12px
147
-        justify-content center
148
-        width 100%
129
+        flex-wrap wrap
149 130
         padding-left 0
150
-        &__itemsearch
151
-          margin-right 6%
152
-          width 100%
153
-        &__itemlanguage__languagedropdown
154
-          .languagedropdown__btnlanguage
155
-            margin-right 0
131
+        width 418px
156 132
         &__itemquestion
157 133
           display none
134
+        &__itemprofil__profilgroup
135
+          margin-top 20px

+ 97 - 0
src/css/Login.styl View File

@@ -0,0 +1,97 @@
1
+.loginpage
2
+  padding-top 85px // 85 = header height
3
+  min-height calc(100% - 50px)
4
+  background darkBlue url('../img/tracimLogoAsBg.png') no-repeat 25% 3px
5
+  background-size contain
6
+  width 100%
7
+  &__logo
8
+    margin 0 auto
9
+    padding 50px 0
10
+    width 170px
11
+  &__connection
12
+    border none
13
+    box-shadow shadow-right
14
+    margin-bottom 50px
15
+    .connection__header
16
+      background-color blue
17
+      color #FFF
18
+      font-size 25px
19
+  .connection__form
20
+    width 70%
21
+    margin 0 auto
22
+    &__rememberme
23
+      &__label
24
+        font-size 13px
25
+    &__groupemail
26
+      position relative
27
+      &__icon
28
+        position absolute
29
+        top 6px
30
+        left 10px
31
+        width 20px
32
+      &__input
33
+        padding-left 45px
34
+    &__groupepw
35
+      position relative
36
+      &__icon
37
+        font-size 20px
38
+        width 20px
39
+        position absolute
40
+        top 5px
41
+        left 8px
42
+      &__input
43
+        padding-left 45px
44
+    &__btnsubmit
45
+      width 150px
46
+      background-color green
47
+      border none
48
+      cursor pointer
49
+      display block
50
+      margin 0 auto
51
+      &:hover
52
+        background-color btnCallAction-hover
53
+      &:focus
54
+        box-shadow shadow-all-side-green
55
+    &__pwforgot
56
+      cursor pointer
57
+      font-size 13px
58
+      margin-top 3px
59
+      &:hover::after
60
+        content ' '
61
+        position absolute
62
+        top 20px
63
+        right 15px
64
+        width 130px
65
+        padding-bottom 2px
66
+        border-bottom 1px solid darkGrey
67
+
68
+@media (min-width: min-lg) and (max-width: max-lg)
69
+  .loginpage__content
70
+    .connection__form
71
+      width 100%
72
+
73
+@media (min-width: min-md) and (max-width: max-md)
74
+  .loginpage__content
75
+    .connection__form
76
+      width 95%
77
+
78
+@media (min-width: min-sm) and (max-width: max-sm)
79
+  .loginpage__content
80
+    padding-top 69px
81
+    display block
82
+    .connection__form
83
+      width 90%
84
+
85
+@media (max-width: max-xs)
86
+  .loginpage__content
87
+    padding-top 69px
88
+    background-size cover
89
+    display block
90
+    &__connection
91
+      margin-top 90px
92
+    &__logo
93
+      display none
94
+    .connection__form
95
+      width 95%
96
+    .connection__form__pwforgot:hover::after
97
+      content normal

+ 173 - 0
src/css/PageHtml.styl View File

@@ -0,0 +1,173 @@
1
+.wsFilePageHtml
2
+  width 1200px
3
+  height calc(100% - 85px)
4
+  overflow-Y auto
5
+  &__header
6
+    background-color htmlColor
7
+    &__icon
8
+      .fa-file-word-o
9
+        color white
10
+  &__contentpage
11
+    display flex
12
+    overflow-Y auto
13
+    &__textnote
14
+      margin 10px
15
+      border-radius 10px
16
+      padding 25px
17
+      width 55%
18
+      height 100%
19
+      background-color off-white
20
+      &__latestversion
21
+        text-align right
22
+        opacity 0.7
23
+      &__text
24
+        font-size 14px
25
+    &__wrapper
26
+      border-radius 10px
27
+      width 45%
28
+      height 100%
29
+    &__header
30
+      border-top-left-radius 10px
31
+      border-top-right-radius 10px
32
+      padding 10px 0
33
+      text-align center
34
+      font-size 20px
35
+      color dark-grey
36
+      background-color grey-hover
37
+    &__messagelist
38
+      min-height 300px
39
+      &__item
40
+        &__content
41
+          color dark-grey
42
+      &__version
43
+        margin-top 40px
44
+        background-color grey-hover
45
+        &__btn
46
+          padding 5px 25px
47
+          border-radius 5px
48
+          width 145px
49
+          color white
50
+          font-size 17px
51
+          background-color htmlColor
52
+          & > i
53
+            margin-right 10px
54
+            color dark-grey
55
+            font-size 22px
56
+          &:hover
57
+            background-color darkHtmlColor
58
+          &:focus
59
+            background-color darkHtmlColor
60
+        &__date
61
+          color fontColor
62
+          font-size 17px
63
+    &__texteditor
64
+      &__simpletext
65
+        &__input
66
+          &:focus
67
+            color htmlColor
68
+            border-color htmlColor
69
+      &__submit
70
+        &__btn
71
+          border-color htmlColor
72
+          background-color htmlColor
73
+          color white
74
+          &:hover
75
+            border-color htmlColor
76
+            background-color htmlColor
77
+          &:focus
78
+            border-color htmlColor
79
+            background-color htmlColor
80
+
81
+.messagelistOpen
82
+  .wsFilePageHtml__contentpage__messagelist
83
+    flex 0
84
+    min-height 0
85
+
86
+.received
87
+  .wsFilePageHtml__contentpage__messagelist__item__content
88
+      background-color htmlColor
89
+
90
+@media (min-width: max-xs) and (max-width: max-lg)
91
+  .wsFilePageHtml
92
+    &__contentpage
93
+      display block
94
+      overflow-Y scroll
95
+      &__textnote
96
+        margin-right 10px
97
+        padding 10px 20px
98
+        width auto
99
+        overflow-Y hidden
100
+        &__latestversion
101
+          padding-top 10px
102
+      &__wrapper
103
+        width auto
104
+      &__texteditor
105
+        &__simpletext
106
+          display inline-flex
107
+          width 60%
108
+        &__submit
109
+          display inline-flex
110
+          margin 10px 0
111
+          &__btn
112
+            display flex
113
+            margin-left 35px
114
+            &__icon
115
+              margin-left 15px
116
+
117
+@media (min-width: min-lg) and (max-width: max-lg)
118
+  .wsFilePageHtml
119
+    width 692px
120
+    &__contentpage__texteditor__simpletext
121
+      margin-left 15px
122
+
123
+@media (min-width: min-md) and (max-width: max-md)
124
+  .wsFilePageHtml
125
+    width 768px
126
+    &__contentpage__texteditor__simpletext
127
+      margin-left 25px
128
+
129
+@media (min-width: min-sm) and (max-width: max-sm)
130
+  .wsFilePageHtml
131
+      top 69px
132
+      width 576px
133
+      height calc(100% - 69px)
134
+      &__contentpage__texteditor__simpletext
135
+        margin-left 10px
136
+
137
+@media (max-width: max-xs)
138
+  .wsFilePageHtml
139
+    top 70px
140
+    height calc(100% - 70px)
141
+    width 100%
142
+    box-shadow none
143
+    &__contentpage
144
+      display block
145
+      overflow-Y scroll
146
+      &__textnote
147
+        margin-right 10px
148
+        width auto
149
+        overflow-Y hidden
150
+        font-size 15px
151
+      &__wrapper
152
+        width auto
153
+      &__messagelist
154
+        &__item
155
+          padding 0 35px 20px 30px
156
+        &__version
157
+          &__btn
158
+            font-size 17px
159
+            vertical-align middle
160
+          &__dateversion
161
+            font-size 15px
162
+      &__texteditor
163
+        &__simpletext
164
+          margin 10px 0
165
+          display flex
166
+          width 95%
167
+          margin-left 10px
168
+        &__submit
169
+          &__btn
170
+            display flex
171
+            margin 0 auto
172
+            &__icon
173
+              margin-left 10px

+ 277 - 0
src/css/PagePreview.styl View File

@@ -0,0 +1,277 @@
1
+.wsFilePreview
2
+  width 1200px
3
+  height calc(100% - 85px)
4
+  &__header
5
+    background-color previewColor
6
+    .fa-file-image-o
7
+      color white
8
+  &__option
9
+    &__menu
10
+      display flex
11
+      &__addversion
12
+        padding 8px 15px
13
+        border 1px solid previewColor
14
+        border-radius 5px
15
+        background-color transparent
16
+        color previewColor
17
+        cursor pointer
18
+        & > i
19
+          margin-left 10px
20
+        &:hover
21
+          background-color previewColor
22
+          border none
23
+          color white
24
+  &__contentpage
25
+    display flex
26
+    height 100%
27
+    &__visualizer
28
+      position relative
29
+      margin 10px
30
+      border-radius 10px
31
+      width 70%
32
+      height calc(100% - 150px)
33
+      background-color off-white
34
+      &__sidebar
35
+        position absolute
36
+        top 0
37
+        right 0
38
+        width 50px
39
+        height 100%
40
+        transition width 1s ease
41
+        &__visiblepart
42
+          display flex
43
+          flex-direction column
44
+          align-items center
45
+          border-top-right-radius 10px
46
+          border-bottom-right-radius 10px
47
+          width 50px
48
+          height 100%
49
+          background-color grey
50
+          cursor pointer
51
+          &:hover
52
+            background-color previewColor
53
+          &__icon
54
+            justify-content flex-start
55
+            font-size 30px
56
+            color white
57
+          &__title
58
+            margin-top 45px
59
+            color white
60
+            transform rotate(-90deg)
61
+        &__propertydetail
62
+          display none
63
+      &__dloption
64
+        display flex
65
+        margin-left calc(50% - 50px) // 50px => width/2 of the div
66
+        padding-top 10px
67
+        width 100px
68
+        &__icon
69
+          margin-right 20px
70
+          font-size 20px
71
+          cursor pointer
72
+      &__slidecontainer
73
+        display flex
74
+        align-items center
75
+        width calc(100% - 50px) // 50px => width of sidebar
76
+        height calc(100% - 40px) // 40px => height of dloption
77
+        &__fileimg
78
+          display flex
79
+          padding 30px
80
+          width 100%
81
+          height 100%
82
+          & > img
83
+            max-height 100%
84
+            max-width 100%
85
+        &__chevron
86
+          margin 0 5px
87
+          font-size 20px
88
+          cursor pointer
89
+    .timeline
90
+      margin 10px
91
+      border-radius 10px
92
+      width 45%
93
+      height calc(100% - 150px)
94
+      background-color off-white
95
+      overflow scroll
96
+      &__header
97
+        border-top-left-radius 10px
98
+        border-top-right-radius 10px
99
+        padding 10px 0
100
+        text-align center
101
+        font-size 20px
102
+        color dark-grey
103
+        background-color grey-hover
104
+      &__messagelist
105
+        min-height 300px
106
+        &__item
107
+          &__content
108
+            color dark-grey
109
+        &__version
110
+          margin-top 40px
111
+          background-color grey-hover
112
+          &__btn
113
+            padding 5px 25px
114
+            border-radius 5px
115
+            width 145px
116
+            color white
117
+            font-size 17px
118
+            background-color previewColor
119
+            & > i
120
+              margin-right 10px
121
+              color dark-grey
122
+              font-size 22px
123
+            &:hover
124
+              background-color lightPreviewColor
125
+            &:focus
126
+              background-color lightPreviewColor
127
+          &__date
128
+            color fontColor
129
+            font-size 17px
130
+      &__texteditor
131
+        &__simpletext
132
+          &__input
133
+            &:focus
134
+              color htmlColor
135
+              border-color htmlColor
136
+        &__submit
137
+          &__btn
138
+            border-color htmlColor
139
+            background-color htmlColor
140
+            color white
141
+            &:hover
142
+              border-color htmlColor
143
+              background-color htmlColor
144
+            &:focus
145
+              border-color htmlColor
146
+              background-color htmlColor
147
+
148
+/***** SENDER RECEIVER *****/
149
+
150
+.received
151
+  .wsFilePreview__contentpage__messagelist__item__content
152
+      background-color previewColor
153
+
154
+/***** ACTIVE SIDEBAR *****/
155
+
156
+.activesidebar
157
+  .wsFilePreview__contentpage__visualizer
158
+    &__sidebar
159
+      display flex
160
+      border-top-right-radius 10px
161
+      border-bottom-right-radius 10px
162
+      width 500px
163
+      background-color off-white
164
+      &__visiblepart
165
+        order 1
166
+        border-top-left-radius 10px
167
+        border-bottom-left-radius 10px
168
+        border-top-right-radius 0
169
+        border-bottom-right-radius 0
170
+        background-color previewColor
171
+      &__propertydetail
172
+        display flex
173
+        order 2
174
+        padding 20px
175
+        overflow-Y auto
176
+        color previewColor
177
+
178
+/****** MEDIA QUERIES ********/
179
+
180
+@media (min-width: max-xs) and (max-width: max-lg)
181
+
182
+  .wsFilePreview
183
+    overflow-Y auto
184
+    &__contentpage
185
+      display block
186
+      &__visualizer
187
+        display flex
188
+        flex-direction column
189
+        width calc(100% - 30px) // 20px => margin
190
+      .timeline
191
+        width calc(100% - 30px) // 20px => margin
192
+        &__texteditor
193
+          &__simpletext
194
+            display inline-flex
195
+            display ms-inline-flex
196
+            width 60%
197
+          &__submit
198
+            display inline-flex
199
+            display ms-inline-flex
200
+            margin 10px 0
201
+            &__btn
202
+              display flex
203
+              margin-left 35px
204
+              &__icon
205
+                margin-left 15px
206
+
207
+/**** MEDIA 992px & 1199px ****/
208
+
209
+@media (min-width: min-lg) and (max-width: max-lg)
210
+
211
+  .wsFilePreview
212
+    width 900px
213
+    overflow-Y auto
214
+
215
+/******************************/
216
+
217
+/**** MEDIA 768px & 991px ****/
218
+
219
+@media (min-width: min-md) and (max-width: max-md)
220
+
221
+  .wsFilePreview
222
+    width 100%
223
+
224
+/******************************/
225
+
226
+/**** MEDIA 576px & 767px ****/
227
+
228
+@media (min-width: min-sm) and (max-width: max-sm)
229
+
230
+  .wsFilePreview
231
+    top 69px
232
+    width 100%
233
+    height calc(100% - 69px)
234
+    overflow-Y scroll
235
+
236
+/******************************/
237
+
238
+/**** MEDIA 575px ****/
239
+
240
+@media (max-width: max-xs)
241
+
242
+  .activesidebar
243
+    .wsFilePreview__contentpage__visualizer
244
+      &__sidebar
245
+        width 350px
246
+
247
+  .wsFilePreview
248
+    top 69px
249
+    width 100%
250
+    height calc(100% - 69px)
251
+    overflow-Y scroll
252
+    &__option__menu__addversion
253
+        padding 8px 5px
254
+        & > i
255
+          display none
256
+    &__contentpage
257
+      display block
258
+      &__visualizer
259
+        display flex
260
+        flex-direction column
261
+        width calc(100% - 30px) // 20px => margin
262
+      .timeline
263
+        width calc(100% - 30px) // 20px => margin
264
+        &__texteditor
265
+          &__simpletext
266
+            display inline-flex
267
+            display ms-inline-flex
268
+            width 60%
269
+          &__submit
270
+            display inline-flex
271
+            display ms-inline-flex
272
+            margin 10px 0
273
+            &__btn
274
+              display flex
275
+              margin-left 35px
276
+              &__icon
277
+                margin-left 15px

+ 98 - 0
src/css/Sidebar.styl View File

@@ -0,0 +1,98 @@
1
+.sidebar-expandbar
2
+  position absolute
3
+  left 0
4
+  display none
5
+  border 1px solid darkBlue
6
+  border-top-width 2px
7
+  padding 11px 15px
8
+  background-color blue
9
+  z-index 2
10
+  &__icon
11
+    font-size 18px
12
+    text-align center
13
+    cursor pointer
14
+    &:hover
15
+      color white
16
+
17
+.sidebar
18
+  display none
19
+  min-height 100%
20
+  background-color secondColor
21
+  z-index 1
22
+
23
+sidebar-width = 300px
24
+.sidebar-visible
25
+  .sidebar-expandbar
26
+    left sidebar-width
27
+
28
+leftside()
29
+  flex-grow 0
30
+  height 100%
31
+  font-size 18px
32
+  background-color rgba(253,253,253,0.3)
33
+
34
+.sidebar
35
+  &__btnnewworkspace
36
+    margin-top 40px
37
+    padding 10px
38
+    width 100%
39
+    &__btn
40
+      display block
41
+      margin 0 auto
42
+      padding 15px 30px
43
+  &__navigation
44
+    padding 0
45
+    &__workspace
46
+      &__item
47
+        width sidebar-width
48
+        &__wrapper
49
+          display flex
50
+          align-items center
51
+          border-bottom 1px solid darkBlue
52
+          width 100%
53
+          height 100%
54
+          background-color blue
55
+          cursor pointer
56
+        &__number
57
+          leftside()
58
+          padding 12px
59
+          min-width 50px
60
+          letter-spacing 2px
61
+        &__name
62
+          flex-grow 2
63
+          padding 10px
64
+          font-size 20px
65
+          color off-white
66
+          white-space nowrap
67
+          overflow hidden
68
+          text-overflow ellipsis
69
+        &__icon
70
+          flex-grow 0
71
+          padding 10px
72
+          color white
73
+        &__submenu
74
+          margin 0
75
+          padding 0
76
+          width 100%
77
+          background-color fourthColor
78
+          height 0 // height is handled is js
79
+          overflow hidden
80
+          transition height 0.5s
81
+          &__dropdown
82
+            display flex
83
+            align-items center
84
+            border-top 1px solid darkBlue
85
+            &:nth-last-child(1)
86
+              border-bottom 1px solid darkBlue
87
+            &:hover
88
+              background-color lightBlue
89
+            &__showdropdown
90
+              display flex
91
+              justify-content space-between
92
+              align-items center
93
+              padding 0 10px
94
+              width 100%
95
+            .dropdown__icon
96
+              padding 10px 15px
97
+              min-width 50px
98
+              leftside()

+ 56 - 0
src/css/Thread.styl View File

@@ -0,0 +1,56 @@
1
+.wsFileThread
2
+  width 550px
3
+  &__header
4
+    color white
5
+    background-color threadColor
6
+  &__wrapper
7
+    height calc(100% - 209px) /* height of chat__header + height of option + top of chat */
8
+  &__messagelist
9
+    padding 15px 35px
10
+    &__item
11
+      &__content
12
+        color darkBlue
13
+  &__texteditor
14
+    &__simpletext
15
+      &__input
16
+        &:focus
17
+          color darkBlue
18
+          border-color darkBlue
19
+    &__submit
20
+      &__btn
21
+        color darkBlue
22
+
23
+.received
24
+  .wsFileThread__messagelist__item__content
25
+      background-color darkBlue
26
+      color white
27
+
28
+@media (min-width: max-xs) and (max-width: max-lg)
29
+  .wsFileThread
30
+    &__texteditor
31
+      padding 7px
32
+      &__simpletext
33
+        display inline-flex
34
+      &__submit
35
+        display inline-flex
36
+        width 80px
37
+
38
+@media (min-width: min-sm) and (max-width: max-sm)
39
+  .wsFileThread
40
+    top 69px
41
+
42
+@media (max-width: max-xs)
43
+  .wsFileThread
44
+    top 69px
45
+    width 100%
46
+    box-shadow none
47
+    z-index 1
48
+    &__texteditor
49
+      padding 7px
50
+      &__simpletext
51
+        display inline-flex
52
+        margin-right 15px
53
+        width 62%
54
+      &__submit
55
+        display inline-flex
56
+        width 80px

+ 141 - 0
src/css/Timeline.styl View File

@@ -0,0 +1,141 @@
1
+.timeline
2
+  display flex
3
+  flex-direction column
4
+  margin 10px
5
+  &__header
6
+    border-radius 10px 10px 0 0
7
+    padding 15px
8
+    text-align center
9
+    font-size 20px
10
+    color dark-grey
11
+    background-color grey-hover
12
+  &__messagelist
13
+    flex 1 1 0
14
+    margin-bottom 0
15
+    padding-left 0
16
+    border-bottom 1px solid grey
17
+    background-color off-white
18
+    overflow-Y auto
19
+    list-style none
20
+    &__item
21
+      padding 0 25px 20px 35px
22
+      &__avatar
23
+        position relative
24
+        top 43px
25
+        left -25px
26
+        width 45px
27
+        height 45px
28
+      &__createhour
29
+        margin-left 30px
30
+        opacity 0.7
31
+        font-size 14px
32
+      &__content
33
+        border 1px solid grey
34
+        border-radius 5px
35
+        padding 15px
36
+        background-color off-white
37
+        font-size 15px
38
+        z-index -1
39
+    &__version
40
+      display flex
41
+      justify-content space-between
42
+      margin-top 40px
43
+      padding 10px 15px
44
+      width 100%
45
+      background-color lightGrey
46
+      &__btn
47
+        padding 5px 25px
48
+        border-radius 5px
49
+        width 145px
50
+        color white
51
+        font-size 17px
52
+        & > i
53
+          margin-right 10px
54
+          color dark-grey
55
+          font-size 22px
56
+      &__date
57
+        color fontColor
58
+        font-size 17px
59
+        margin auto 0
60
+  &__texteditor
61
+    padding 2px
62
+    &__simpletext
63
+      display none
64
+      width 70%
65
+      margin-right 35px
66
+      &__icon
67
+        cursor pointer
68
+    &__wysiwyg
69
+      display block
70
+      & > textarea
71
+        width 100%
72
+        height 130px
73
+    &__submit
74
+      margin 10px 0
75
+      &__btn
76
+        display flex
77
+        cursor pointer
78
+        &:hover , &:focus
79
+          box-shadow shadow-all-btn
80
+        &__icon
81
+          margin-left 10px
82
+
83
+.sended
84
+  .timeline__messagelist__item__content
85
+    margin-right 25%
86
+
87
+.received
88
+  .timeline__messagelist__item
89
+    &__avatar
90
+      left 93%
91
+    &__createhour
92
+      text-align right
93
+      margin-right 50px
94
+    &__content
95
+      margin-left 25%
96
+      color white
97
+
98
+/**** MEDIA 992px & 1199px ****/
99
+
100
+@media (min-width: min-lg) and (max-width: max-lg)
101
+
102
+  .timeline__messagelist__item
103
+    margin-right 55px
104
+
105
+  .received
106
+    .timeline__messagelist__item
107
+      &__avatar
108
+        left 96%
109
+
110
+/**** MEDIA 768px & 991px ****/
111
+
112
+@media (min-width: min-md) and (max-width: max-md)
113
+
114
+  .timeline__messagelist__item
115
+    margin-right 55px
116
+
117
+  .received
118
+    .timeline__messagelist__item
119
+      &__avatar
120
+        left 96%
121
+
122
+/**** MEDIA 576px & 767px ****/
123
+
124
+@media (min-width: min-sm) and (max-width: max-sm)
125
+
126
+  .timeline__messagelist__item
127
+    margin-right 35px
128
+
129
+  .received
130
+    .timeline__messagelist__item
131
+      &__avatar
132
+        left 94%
133
+
134
+/**** MEDIA 575px ****/
135
+
136
+@media (max-width: max-xs)
137
+
138
+  .received
139
+    .timeline__messagelist__item
140
+      &__avatar
141
+        left 90%

+ 59 - 20
src/css/Variable.styl View File

@@ -1,30 +1,69 @@
1 1
 /**** VARIABLES ****/
2 2
 /*** COULEURS ****/
3
-dark-blue = #215E8E // #215E8E dark-blue
4
-hover-blue = #205AED // #205AED color blue use in hover rules
5
-blue = #2571FE // #2571FE blue
6
-light-blue = #569EDE // #569EDE light-blue
7
-opacity-blue = #82B2CC // #82B2CC  blue with light opacity
8
-off-white = #FDFDFD // #FDFDFD off-white
9
-dark-grey = #252525 // #252525 dark-grey
10
-hover = #9BC1EB // #9BC1EB hover on folder
11
-hover-files = rgba(155,193,235,0.2) // hover on files
12
-grey = #ABABAB // #ABABAB grey
13
-light-grey = #f0f0f0 // #f0f0f0 light grey
14
-hover-grey = #E0E0E0 // #E0E0E0 color for hover files
15
-green = #28a745 // #28a745 green
16
-dark-green = #65A833 // #65A833 dark-green
17
-purple = #7E36A0 // color icon on the sidebar menu workspace
18
-orange = #D95620 // color icon on the sidebar menu workspace
19
-red = #D9352B // color icon on the sidebar menu workspace
3
+
4
+mainColor = #fdfdfd // Bg header
5
+secondColor = #215e8e // bg sidebar
6
+thirdColor = #2571fe // bg workspace name
7
+fourthColor = #82b2cc // bg filter sidebar
8
+
9
+fontColor = #252525
10
+
11
+darkGrey = #252525
12
+rgbGrey = rgba(25,25,25,0.3)
13
+grey = #ababab
14
+lightGrey = #f0f0f0
15
+grey-hover = #e0e0e0
16
+
17
+folder-hover = #9BC1eb
18
+files-hover = rgba(155,193,235,0.2)
19
+
20
+off-white = #fdfdfd
21
+
22
+darkBlue = #215e8e
23
+blue = #2571fe
24
+lightBlue = #569EDE
25
+
26
+red = #f63434
27
+
28
+// c2a btn color in general context ; meaning every context but specific one related to file type (file, pageHtml, issues, threads ...)
29
+btnCallAction = #28a745
30
+btnCallAction-hover = darken(btnCallAction, 15%)
31
+
32
+threadColor = #2674d3
33
+
34
+htmlColor = #65c7f2
35
+darkHtmlColor = darken(htmlColor, 15%)
36
+
37
+markdownColor = #e0082b
38
+
39
+fileColor = #263462
40
+lightFileColor = lighten(fileColor, 15%)
41
+
42
+taskColor = #2d5a88
43
+
44
+issueColor = #a4835e
45
+
46
+/** Role Color  **/
47
+gestionnaire = #f2af2d
48
+lecteur = #15D948
49
+contributeur = #3145F7
50
+responsable = #ED0007
51
+
52
+/** Btn call to action dashboard **/
53
+writefile = #a738ed
54
+importfile = #ff8400
55
+calendar = red
56
+explore = #87d04c
57
+
20 58
 
21 59
 /*************************/
22 60
 /**** BOX SHADOW ****/
23 61
 shadow-bottom = 0px 0px 5px 1px #606060
24 62
 shadow-right = 2px 2px 5px 0px #404040
25
-shadow-all = 1px 1px 5px 2px #ABABAB
26
-shadow-all-side-blue = 0px 0px 1px 1px light-blue
63
+shadow-all = 1px 1px 5px 2px #ababab
64
+shadow-all-side-blue = 0px 0px 1px 1px lightBlue
27 65
 shadow-all-side-green = 0 0 1px 2px green
66
+shadow-all-btn = 0 0 3px 3px lightBlue
28 67
 
29 68
 /***********************/
30 69
 /**** MEDIA QUERIES ****/
@@ -41,4 +80,4 @@ min-lg = 992px
41 80
 max-lg = 1199px
42 81
 
43 82
 min-xl = 1200px
44
-/***********************/
83
+

+ 21 - 0
src/css/Workspace.styl View File

@@ -0,0 +1,21 @@
1
+.workspace
2
+  &__content
3
+    &__button
4
+      display flex
5
+      justify-content flex-end
6
+      margin 50px 10px 0 10px
7
+      &__btnaddworkspace
8
+        margin-bottom 50px
9
+        padding 10px 55px
10
+@media (min-width: min-sm) and (max-width: max-sm)
11
+  .workspace
12
+    &__header
13
+      &__btnaddworkspace
14
+        display inline-block
15
+        margin-right 0
16
+
17
+@media (max-width: max-xs)
18
+  .workspace
19
+    &__header
20
+      &__title
21
+        margin 0 0 20px 0

+ 55 - 0
src/css/btnSwtich.styl View File

@@ -0,0 +1,55 @@
1
+.btnswitch
2
+  display flex
3
+  align-items center
4
+  &__text
5
+    margin-left 10px
6
+
7
+.switch
8
+  position relative
9
+  display inline-block
10
+  width 60px
11
+  height 34px
12
+
13
+.switch input
14
+  display none
15
+
16
+.slider
17
+  position absolute
18
+  cursor pointer
19
+  top 0
20
+  left 0
21
+  right 0
22
+  bottom 0
23
+  background-color #ccc
24
+  -webkit-transition .4s
25
+  transition .4s
26
+
27
+.slider:before
28
+  position absolute
29
+  content ""
30
+  height 26px
31
+  width 26px
32
+  left 4px
33
+  bottom 4px
34
+  background-color white
35
+  -webkit-transition .4s
36
+  transition .4s
37
+
38
+input:checked + .slider
39
+  background-color blue
40
+
41
+input:focus + .slider
42
+  box-shadow 0 0 1px blue
43
+
44
+input:checked + .slider:before
45
+  -webkit-transform translateX(26px)
46
+  -ms-transform translateX(26px)
47
+  transform translateX(26px)
48
+
49
+/* Rounded sliders */
50
+.slider.round
51
+  border-radius 34px
52
+
53
+.slider.round:before
54
+  border-radius: 50%
55
+

+ 30 - 3
src/css/index.styl View File

@@ -1,3 +1,30 @@
1
-@import "Variable"
2
-@import "Header"
3
-@import "Footer"
1
+body
2
+  font-family 'Quicksand', sans-serif
3
+html, body, #content, #content > div
4
+  height 100%
5
+
6
+@import 'Variable'
7
+@import 'Generic'
8
+
9
+@import 'Sidebar'
10
+@import 'Header'
11
+@import 'Footer'
12
+
13
+@import 'Login'
14
+@import 'Workspace'
15
+
16
+@import 'FileItem'
17
+@import 'FileItemHeader'
18
+@import 'Folder'
19
+
20
+@import 'Thread'
21
+@import 'PageHtml'
22
+@import 'Timeline'
23
+@import 'File'
24
+
25
+@import 'Dashboard'
26
+@import 'AccountPage'
27
+@import 'btnSwtich'
28
+
29
+// @import 'UploadPopup'
30
+// @import 'ProgressBar'

+ 26 - 0
src/helper.js View File

@@ -4,3 +4,29 @@ export const FETCH_CONFIG = {
4 4
     'Content-Type': 'application/json'
5 5
   }
6 6
 }
7
+
8
+export const FILE_TYPE = [{
9
+  name: 'pageHtml',
10
+  customClass: 'wsFilePageHtml',
11
+  icon: 'fa fa-file-word-o'
12
+}, {
13
+  name: 'pageMarkdown',
14
+  customClass: 'wsFilePageMarkdown',
15
+  icon: 'fa fa-file-code-o'
16
+}, {
17
+  name: 'file',
18
+  customClass: 'wsFileFile',
19
+  icon: 'fa fa-file-image-o'
20
+}, {
21
+  name: 'thread',
22
+  customClass: 'wsFileThread',
23
+  icon: 'fa fa-comments-o'
24
+}, {
25
+  name: 'task',
26
+  customClass: 'wsFileTask',
27
+  icon: 'fa fa-list-ul'
28
+}, {
29
+  name: 'issue',
30
+  customClass: 'wsFileIssue',
31
+  icon: 'fa fa-ticket'
32
+}]

BIN
src/img/excel.png View File


BIN
src/img/imgProfil-reverse.png View File


BIN
src/img/imgProfil.png View File


BIN
src/img/listmemberbtn.png View File


+ 50 - 0
src/img/logoTracimWhite.svg View File

@@ -0,0 +1,50 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
3
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
5
+	 viewBox="0 0 457.5 133.5" enable-background="new 0 0 457.5 133.5" xml:space="preserve">
6
+<g id="Background">
7
+	<rect x="-149.6" y="-13.6" fill="transparent" width="800" height="600"/>
8
+</g>
9
+<g id="Logotype">
10
+	<g>
11
+		<g>
12
+			<path fill="#FFFFFF" d="M185.1,27.1v14.8h13.3v11.4h-13.3v24.3c0,3.2,0.6,5.3,1.8,6.4c1.2,1.1,2.9,1.7,5.3,1.7
13
+				c1.1,0,2.2-0.1,3.3-0.4c1.1-0.3,2.1-0.8,2.9-1.5l1.7,10.6c-1.7,1.5-3.4,2.7-5.2,3.4c-1.8,0.8-4.2,1.1-7.3,1.1
14
+				c-5.5,0-9.7-1.6-12.6-4.7c-2.8-3.1-4.3-8-4.3-14.6V53.3h-6.5V41.9h6.5v-9.1L185.1,27.1z"/>
15
+			<path fill="#FFFFFF" d="M239.2,52c-4.2,0-12,2.6-15.7,6.7v38.6h-14.3V41.9h14.3v6c3.7-4.8,10.8-7.3,15.7-7.3"/>
16
+			<path fill="#FFFFFF" d="M283.8,98.4c-4.4,0-8.9-1.5-10.8-4.6c-3.2,1.9-5.7,3.3-7.7,3.9c-1.9,0.7-3.8,1-5.6,1
17
+				c-4.4,0-8.1-1.5-11.1-4.6c-3-3-4.5-7.1-4.5-12.2c0-4.8,1.4-8.6,4.2-11.3c2.8-2.7,6.4-4.4,10.8-5.1l11.6-1.9V60
18
+				c0-2.8-0.8-4.6-2.4-5.5c-1.6-0.9-3.4-1.3-5.3-1.3c-2.4,0-4.7,0.4-7.2,1.2c-2.4,0.8-4.6,1.9-6.5,3.1l-2.3-12.2
19
+				c6.1-3.2,12.2-4.8,18.3-4.8c2.1,0,4.2,0.2,6.4,0.6c2.2,0.4,4.2,1.2,6,2.4c1.8,1.2,3.2,2.7,4.4,4.7c1.1,1.9,1.7,4.4,1.7,7.3
20
+				l0,26.1 M264.1,73c-1.9,0.3-3.5,1-4.7,2.3c-1.2,1.2-1.8,3-1.8,5.4c0,4.3,1.9,6.4,5.8,6.4c1.1,0,2.2-0.2,3.2-0.6
21
+				c1-0.4,2.4-1.1,4-2.1V71.8L264.1,73z"/>
22
+			<path fill="#FFFFFF" d="M330.4,54.6c-3.2-2.1-6.6-3.1-10.4-3.1c-4.6,0-7.8,1.5-9.8,4.5c-1.9,3-2.9,7-2.9,12.1
23
+				c0,4.8,0.9,9.1,2.7,12.7c1.8,3.6,5,5.4,9.8,5.4c1.9,0,4-0.3,6.3-0.9c2.3-0.6,4.3-1.6,5.9-3l1.9,10.2c-1.9,2.2-4.5,3.9-7.8,5.2
24
+				c-3.3,1.2-6.7,1.9-10.3,1.9c-7.1,0-12.6-2.6-16.5-7.7c-3.9-5.1-5.9-12.4-5.9-21.8c0-10,2.2-17.4,6.6-22.4
25
+				c4.4-5,10.7-7.5,18.7-7.5c5.5,0,10,1,13.5,2.9L330.4,54.6z"/>
26
+			<path fill="#FFFFFF" d="M349.5,18.9c2.5,0,4.5,0.7,5.9,2c1.5,1.3,2.2,3.4,2.2,6.1c0,2.6-0.7,4.7-2.2,6c-1.5,1.4-3.4,2.1-5.9,2.1
27
+				c-2.5,0-4.5-0.7-5.9-2.1c-1.5-1.4-2.2-3.4-2.2-6c0-2.8,0.7-4.8,2.2-6.1C345,19.5,347,18.9,349.5,18.9z M356.6,41.9v55.4h-14.3
28
+				V41.9H356.6z"/>
29
+			<path fill="#FFFFFF" d="M382.1,41.9v5.6c2.6-1.9,5.4-3.5,8.4-4.8c3-1.2,5.8-1.9,8.6-1.9c5.3,0,8.7,2.5,10.4,7.5
30
+				c2.8-1.9,5.7-3.7,8.8-5.2c3.1-1.5,6.2-2.3,9.2-2.3c3.6,0,6.4,1.1,8.3,3.4c1.9,2.3,2.9,6.1,2.9,11.3v41.7h-14.3V58.9
31
+				c0-4-1.4-6-4.2-6c-2.5,0-5.8,1.2-10,3.7v40.7h-14.1V58.9c0-4-1.5-6-4.4-6c-2.6,0-5.9,1.2-9.8,3.7v40.7h-14.3V41.9H382.1z"/>
32
+		</g>
33
+	</g>
34
+	<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M141.8,66.4c2.5,2.9,3.4,7,2,10.8c-1.4,3.9-4.7,6.6-8.6,7.4
35
+		c0,0-11.5,22.7-33.9,18.5c0,0,15.6-3.4,22.7-21.7c-3-3-4.2-7.4-2.7-11.6c1.5-4.1,5.2-6.9,9.4-7.5c-0.3-2.7-1.1-5.3-2.4-8
36
+		c-0.8-1.7-1-3.3-0.1-5c0,0,3.3-6,8.3-0.6S141.8,66.4,141.8,66.4z"/>
37
+	<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M102.7,122.6c-2.3,3.1-6.1,4.9-10.1,4.4c-4.1-0.5-7.4-3.2-9.1-6.8
38
+		c0,0-24.7-6.3-25.5-29c0,0,6.7,14.5,26.2,17.4c2.2-3.6,6.3-5.7,10.7-5.1c4.3,0.5,7.9,3.6,9.4,7.6c2.5-0.9,5-2.2,7.3-4
39
+		c1.5-1.2,3-1.7,4.8-1.2c0,0,6.6,1.9,2.4,8C114.5,119.9,102.7,122.6,102.7,122.6z"/>
40
+	<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M37.4,101.8c-3.5-1.7-5.9-5.1-6.2-9.1c-0.3-4.1,1.7-7.9,5-10.2
41
+		c0,0,1.6-25.4,23.8-30.4c0,0-13,9.3-12.3,29c3.9,1.5,6.7,5.1,7,9.6C55,95,52.7,99,49,101.2c1.3,2.3,3.1,4.5,5.3,6.4
42
+		c1.4,1.2,2.2,2.7,2,4.5c0,0-0.6,6.8-7.4,3.8C42.3,112.9,37.4,101.8,37.4,101.8z"/>
43
+	<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M37.5,38.3c0.1-3.8,2-7.5,5.6-9.5c3.6-2,7.9-1.8,11.3,0.1
44
+		c0,0,23.7-9.5,37.7,8.4c0,0-14-7.7-31.4,1.3c0.3,4.2-1.7,8.3-5.6,10.5c-3.8,2.1-8.5,1.7-12-0.6c-1.5,2.2-2.7,4.7-3.5,7.5
45
+		c-0.5,1.8-1.4,3.2-3.2,3.8c0,0-6.4,2.3-6.6-5C29.6,47.4,37.5,38.3,37.5,38.3z"/>
46
+	<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M97.6,14.3c3.5-1.6,7.7-1.4,11,1c3.3,2.4,5,6.4,4.7,10.3
47
+		c0,0,18.7,17.4,8.4,37.7c0,0,1-15.9-14.6-27.9c-3.7,2-8.2,2-11.9-0.6c-3.6-2.6-5.2-6.9-4.6-11.2c-2.6-0.4-5.4-0.4-8.3,0.1
48
+		c-1.8,0.3-3.5,0-4.8-1.3c0,0-4.9-4.8,1.8-8.1C85.9,11,97.6,14.3,97.6,14.3z"/>
49
+</g>
50
+</svg>

BIN
src/img/pdf.jpg View File


BIN
src/img/tracimLogoAsBg.png View File


+ 22 - 0
src/reducer/activeFileContent.js View File

@@ -0,0 +1,22 @@
1
+import { FILE_CONTENT } from '../action-creator.sync.js'
2
+
3
+export default function activeFileContent (state = {
4
+  display: false,
5
+  type: '',
6
+  title: '',
7
+  status: ''
8
+}, action) {
9
+  switch (action.type) {
10
+    case `Set/${FILE_CONTENT}/Active`:
11
+      return {
12
+        display: true,
13
+        ...action.file
14
+      }
15
+
16
+    case `Set/${FILE_CONTENT}/Hide`:
17
+      return {...state, display: false}
18
+
19
+    default:
20
+      return state
21
+  }
22
+}

+ 10 - 0
src/reducer/fileType/index.js View File

@@ -0,0 +1,10 @@
1
+import { combineReducers } from 'redux'
2
+
3
+// import color from './color.js'
4
+// import size from './size.js'
5
+// import price from './price.js'
6
+// import multicolor from './multicolor.js'
7
+
8
+export default combineReducers({
9
+
10
+})

+ 10 - 0
src/reducer/fileType/pageHtml.js View File

@@ -0,0 +1,10 @@
1
+export default function pageHtml (state = {
2
+  title: '',
3
+  version: 0,
4
+  text: ''
5
+}, action) {
6
+  switch (action.type) {
7
+    default:
8
+      return state
9
+  }
10
+}

+ 3 - 1
src/reducer/root.js View File

@@ -1,6 +1,8 @@
1 1
 import { combineReducers } from 'redux'
2 2
 import user from './user.js'
3
+import workspace from './workspace.js'
4
+import activeFileContent from './activeFileContent.js'
3 5
 
4
-const rootReducer = combineReducers({ user })
6
+const rootReducer = combineReducers({ user, workspace, activeFileContent })
5 7
 
6 8
 export default rootReducer

+ 14 - 2
src/reducer/user.js View File

@@ -3,14 +3,26 @@ import {
3 3
   USER_DATA
4 4
 } from '../action-creator.sync.js'
5 5
 
6
+const serializeUser = data => ({
7
+  id: data.user.id,
8
+  isLoggedIn: data.logged,
9
+  username: data.user.username,
10
+  firstname: data.user.firstname,
11
+  lastname: data.user.lastname,
12
+  email: data.user.email
13
+})
14
+
6 15
 export default function user (state = {
7
-  isLoggedIn: false,
16
+  id: 0,
17
+  isLoggedIn: undefined,
8 18
   username: '',
19
+  firstname: '',
20
+  lastname: '',
9 21
   email: ''
10 22
 }, action) {
11 23
   switch (action.type) {
12 24
     case `Update/${USER_CONNECTED}`:
13
-      return {...state, isLoggedIn: true, ...action.user}
25
+      return serializeUser(action.user)
14 26
 
15 27
     case `Update/${USER_DATA}`:
16 28
       return {...state, ...action.data}

+ 23 - 0
src/reducer/workspace.js View File

@@ -0,0 +1,23 @@
1
+import {
2
+  WORKSPACE
3
+} from '../action-creator.sync.js'
4
+
5
+const serializeWorkspace = data => ({
6
+  ...data,
7
+  ownerId: data.owner_id
8
+})
9
+
10
+export default function user (state = {
11
+  id: 0,
12
+  title: '',
13
+  ownerId: '',
14
+  content: []
15
+}, action) {
16
+  switch (action.type) {
17
+    case `Update/${WORKSPACE}`:
18
+      return serializeWorkspace(action.workspace)
19
+
20
+    default:
21
+      return state
22
+  }
23
+}

+ 3 - 1
webpack.config.js View File

@@ -1,6 +1,7 @@
1 1
 const webpack = require('webpack')
2 2
 const path = require('path')
3 3
 const isProduction = process.env.NODE_ENV === 'production'
4
+const dashboardPlugin = require('webpack-dashboard/plugin')
4 5
 
5 6
 module.exports = {
6 7
   entry: {
@@ -70,7 +71,7 @@ module.exports = {
70 71
       test: /\.(jpg|png|svg)$/,
71 72
       loader: 'url-loader',
72 73
       options: {
73
-        limit: 25000
74
+        limit: 2000
74 75
       }
75 76
     }]
76 77
   },
@@ -83,6 +84,7 @@ module.exports = {
83 84
         name: 'vendor',
84 85
         filename: 'tracim.vendor.bundle.js'
85 86
       })
87
+      // new dashboardPlugin()
86 88
     ],
87 89
     ...(isProduction
88 90
       ? [ // production specific plugins