From 1a7c84ae5574df2eae4bc28fe153f36d62103dfa Mon Sep 17 00:00:00 2001
From: Florent Lavelle <flavelle@neogeo.fr>
Date: Thu, 30 Sep 2021 14:13:05 +0200
Subject: [PATCH] Initialize source code (beta version)

Co-authored-by: Florent <florent@Air-de-neogeo.neogeo.local>
Co-authored-by: m431m <mmeliani@neogeo.fr>
Co-authored-by: Kevin Rakotobe <krakotobe@neogeo.fr>
---
 .browserslistrc                               |   3 +
 .editorconfig                                 |   7 +
 .eslintrc.js                                  |  30 +
 .gitignore                                    |  31 +
 .gitlab-ci.yml                                |  69 ++
 README.md                                     |  65 +-
 babel.config.js                               |   5 +
 cypress.json                                  |   3 +
 jest.config.js                                |   3 +
 package.json                                  |  48 ++
 public/config/config.json.sample              |  13 +
 public/favicon.ico                            | Bin 0 -> 4286 bytes
 public/index.html                             |  18 +
 src/App.vue                                   |  11 +
 src/api/loginAPI.js                           | 165 ++++
 src/api/organisationsAPI.js                   |  63 ++
 src/api/usergroupsAPI.js                      |  45 ++
 src/api/usersAPI.js                           |  35 +
 src/app.less                                  | 125 ++++
 src/app.scss                                  |   4 +
 src/assets/icons/file_document_sheet.svg      |  10 +
 src/assets/logo_pigma.png                     | Bin 0 -> 69765 bytes
 src/components/ImportImage.vue                | 173 +++++
 src/components/OrganisationCreation.vue       | 353 +++++++++
 src/components/OrganisationSelector.vue       | 214 ++++++
 src/components/SearchUsergroups.vue           | 117 +++
 src/main.js                                   |  25 +
 src/router/index.js                           |  79 ++
 src/services/error-service.js                 |  55 ++
 src/store/index.js                            |  23 +
 src/store/modules/forgotten-pwd.store.js      | 105 +++
 src/store/modules/index.js                    |  16 +
 src/store/modules/organisations.store.js      |  97 +++
 src/store/modules/sign-in.store.js            |  78 ++
 src/store/modules/sign-out.store.js           |  57 ++
 src/store/modules/sign-up.store.js            | 115 +++
 src/store/modules/terms-of-use.store.js       |  77 ++
 src/store/modules/user.store.js               |  91 +++
 src/store/modules/usergroups.store.js         | 113 +++
 src/store/modules/validation-email.store.js   |  37 +
 .../modules/validation-registration.store.js  |  45 ++
 src/views/ForgottenPassword.vue               | 146 ++++
 src/views/NotFound.vue                        |  11 +
 src/views/ReinitPassword.vue                  | 292 ++++++++
 src/views/SignIn.vue                          | 251 +++++++
 src/views/SignOut.vue                         |  95 +++
 src/views/SignOutFailed.vue                   | 107 +++
 src/views/SignUp.vue                          | 598 +++++++++++++++
 src/views/SignUpSuccess.vue                   |  70 ++
 src/views/TermsOfUse.vue                      | 166 ++++
 src/views/UserProfile.vue                     | 708 ++++++++++++++++++
 src/views/ValidationEmail.vue                 |  98 +++
 src/views/ValidationRegistration.vue          | 126 ++++
 tests/e2e/.eslintrc.js                        |  12 +
 tests/e2e/plugins/index.js                    |  26 +
 tests/e2e/specs/test.js                       |   8 +
 tests/e2e/support/commands.js                 |  25 +
 tests/e2e/support/index.js                    |  20 +
 tests/unit/example.spec.js                    |  12 +
 vue.config.js                                 |  15 +
 60 files changed, 5408 insertions(+), 1 deletion(-)
 create mode 100644 .browserslistrc
 create mode 100644 .editorconfig
 create mode 100644 .eslintrc.js
 create mode 100644 .gitignore
 create mode 100644 .gitlab-ci.yml
 create mode 100644 babel.config.js
 create mode 100644 cypress.json
 create mode 100644 jest.config.js
 create mode 100644 package.json
 create mode 100644 public/config/config.json.sample
 create mode 100644 public/favicon.ico
 create mode 100644 public/index.html
 create mode 100644 src/App.vue
 create mode 100644 src/api/loginAPI.js
 create mode 100644 src/api/organisationsAPI.js
 create mode 100644 src/api/usergroupsAPI.js
 create mode 100644 src/api/usersAPI.js
 create mode 100644 src/app.less
 create mode 100644 src/app.scss
 create mode 100644 src/assets/icons/file_document_sheet.svg
 create mode 100644 src/assets/logo_pigma.png
 create mode 100644 src/components/ImportImage.vue
 create mode 100644 src/components/OrganisationCreation.vue
 create mode 100644 src/components/OrganisationSelector.vue
 create mode 100644 src/components/SearchUsergroups.vue
 create mode 100644 src/main.js
 create mode 100644 src/router/index.js
 create mode 100644 src/services/error-service.js
 create mode 100644 src/store/index.js
 create mode 100644 src/store/modules/forgotten-pwd.store.js
 create mode 100644 src/store/modules/index.js
 create mode 100644 src/store/modules/organisations.store.js
 create mode 100644 src/store/modules/sign-in.store.js
 create mode 100644 src/store/modules/sign-out.store.js
 create mode 100644 src/store/modules/sign-up.store.js
 create mode 100644 src/store/modules/terms-of-use.store.js
 create mode 100644 src/store/modules/user.store.js
 create mode 100644 src/store/modules/usergroups.store.js
 create mode 100644 src/store/modules/validation-email.store.js
 create mode 100644 src/store/modules/validation-registration.store.js
 create mode 100644 src/views/ForgottenPassword.vue
 create mode 100644 src/views/NotFound.vue
 create mode 100644 src/views/ReinitPassword.vue
 create mode 100644 src/views/SignIn.vue
 create mode 100644 src/views/SignOut.vue
 create mode 100644 src/views/SignOutFailed.vue
 create mode 100644 src/views/SignUp.vue
 create mode 100644 src/views/SignUpSuccess.vue
 create mode 100644 src/views/TermsOfUse.vue
 create mode 100644 src/views/UserProfile.vue
 create mode 100644 src/views/ValidationEmail.vue
 create mode 100644 src/views/ValidationRegistration.vue
 create mode 100644 tests/e2e/.eslintrc.js
 create mode 100644 tests/e2e/plugins/index.js
 create mode 100644 tests/e2e/specs/test.js
 create mode 100644 tests/e2e/support/commands.js
 create mode 100644 tests/e2e/support/index.js
 create mode 100644 tests/unit/example.spec.js
 create mode 100644 vue.config.js

diff --git a/.browserslistrc b/.browserslistrc
new file mode 100644
index 0000000..214388f
--- /dev/null
+++ b/.browserslistrc
@@ -0,0 +1,3 @@
+> 1%
+last 2 versions
+not dead
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..c24743d
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,7 @@
+[*.{js,jsx,ts,tsx,vue}]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+trim_trailing_whitespace = true
+insert_final_newline = true
+max_line_length = 100
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..68aa83f
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,30 @@
+const config = require('./public/config/config.json');
+
+module.exports = {
+  root: true,
+  env: {
+    node: true,
+  },
+  extends: [
+    'plugin:vue/essential',
+    '@vue/airbnb',
+  ],
+  parserOptions: {
+    parser: 'babel-eslint',
+  },
+  rules: {
+    'no-console': config.NODE_ENV === 'production' ? 'warn' : 'off',
+    'no-debugger': config.NODE_ENV === 'production' ? 'warn' : 'off',
+  },
+  overrides: [
+    {
+      files: [
+        '**/__tests__/*.{j,t}s?(x)',
+        '**/tests/unit/**/*.spec.{j,t}s?(x)',
+      ],
+      env: {
+        jest: true,
+      },
+    },
+  ],
+};
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d451809
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,31 @@
+.DS_Store
+node_modules
+/dist
+
+/tests/e2e/videos/
+/tests/e2e/screenshots/
+
+# local env files
+.env
+.env.*
+.env.local
+.env.*.local
+dist
+package-lock.json
+jsconfig.json
+config.json
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..291f700
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,69 @@
+variables:
+  SONAR_TOKEN: "$SONAR_TOKEN"
+  SONAR_PROJECTKEY: "$CI_PROJECT_NAME"
+  SONAR_HOST_URL: "https://sonarqube.neogeo.fr"
+  GIT_DEPTH: 0
+
+cache:
+  paths:
+    - node_modules/
+
+stages:
+  - sonarqube
+  - build
+  - deploy
+
+sonarqube-check:
+  image:
+    name: sonarsource/sonar-scanner-cli:latest
+    entrypoint: [""]
+  stage: sonarqube
+  script:
+    - sonar-scanner -Dsonar.qualitygate.wait=true -Dsonar.projectKey=$CI_PROJECT_NAME -Dsonar.projectName=$CI_PROJECT_NAME -Dsonar.projectVersion=$CI_COMMIT_BRANCH
+  allow_failure: true
+  only:
+    - develop
+    - master
+    - draft
+
+build_development:
+  stage: build
+  tags:
+    - build
+  image: node:14.16.0
+  script:
+    - npm install --unsafe-perm
+    - echo -e "
+      NODE_ENV=development\n
+      VUE_APP_LOCALE=fr-FR\n
+      DOMAIN=https://dev.pigma.neogeo.fr/fr\n
+      VUE_APP_DOMAIN=https://dev.pigma.neogeo.fr/\n
+      BASE_PATH=/\n
+      VUE_APP_NEXT_DEFAULT=/\n
+      VUE_APP_BASE_PATH=${BASE_PATH}\n
+      VUE_APP_LOGIN_API_PATH=/fr/login/\n
+      VUE_APP_ORGANISATION_API_PATH=/fr/organisation/\n
+      VUE_APP_USERGROUP_API_PATH=/fr/usergroup/\n
+      VUE_APP_LOGIN_API_USERNAME=admin\n
+      VUE_APP_LOGIN_API_PASSWORD=Neogeo2020\n" > .env
+    - npm run build
+  artifacts:
+    paths:
+      - dist
+    expire_in: 1 week
+
+deploy-pigma-dev:
+  image: alpine
+  tags:
+    - deploy-dev
+  stage: deploy
+  when: manual
+  script:
+    - apk add --no-cache rsync openssh
+    - mkdir -p ~/.ssh
+    - echo "$SSH_PRIVATE_KEY" >> ~/.ssh/id_dsa
+    - chmod 600 ~/.ssh/id_dsa
+    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
+    - ls -lrth
+    - scp -o "ProxyCommand ssh debian@10.0.30.17 -W %h:%p" -r dist/* debian@10.9.10.13:/opt/neogeo/onegeo-login
+    - ssh -J debian@10.0.30.17 debian@10.9.10.13 "echo test"
diff --git a/README.md b/README.md
index 1075c60..85ab922 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,65 @@
-# Onegeo-Suite Site LogIn
+# login-site
 
+## Project setup
+
+```shell
+npm install
+```
+
+### Set environment variables
+
+```ìni
+NODE_ENV=development
+VUE_APP_LOCALE=fr-FR
+
+DOMAIN=https://dev.pigma.neogeo.fr/fr
+VUE_APP_DOMAIN=https://dev.pigma.neogeo.fr/
+
+BASE_PATH=/
+VUE_APP_NEXT_DEFAULT=/
+
+VUE_APP_BASE_PATH=${BASE_PATH}
+
+# API
+VUE_APP_LOGIN_API_PATH=/fr/login
+VUE_APP_ORGANISATION_API_PATH=/fr/organisation/
+VUE_APP_USERGROUP_API_PATH=/fr/usergroup/
+
+# AUTH
+VUE_APP_LOGIN_API_USERNAME=admin
+VUE_APP_LOGIN_API_PASSWORD=Neogeo2020
+```
+
+### Compiles and hot-reloads for development
+
+```shell
+npm run serve
+```
+
+### Compiles and minifies for production
+
+```shell
+npm run build
+```
+
+### Run your unit tests
+
+```shell
+npm run test:unit
+```
+
+### Run your end-to-end tests
+
+```shell
+npm run test:e2e
+```
+
+### Lints and fixes files
+
+```shell
+npm run lint
+```
+
+### Customize configuration
+
+See [Configuration Reference](https://cli.vuejs.org/config/).
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..757ff9b
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset',
+  ],
+};
diff --git a/cypress.json b/cypress.json
new file mode 100644
index 0000000..470c720
--- /dev/null
+++ b/cypress.json
@@ -0,0 +1,3 @@
+{
+  "pluginsFile": "tests/e2e/plugins/index.js"
+}
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..3ce878d
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+  preset: '@vue/cli-plugin-unit-jest',
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..54dc764
--- /dev/null
+++ b/package.json
@@ -0,0 +1,48 @@
+{
+  "name": "onegeo-suite-site-login-vuejs",
+  "version": "1.0.0dev0",
+  "private": true,
+  "scripts": {
+    "dev": "cross-env NODE_ENV=development vue-cli-service serve --open --host localhost",
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "test:unit": "vue-cli-service test:unit",
+    "test:e2e": "vue-cli-service test:e2e",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "axios": "^0.21.1",
+    "bootstrap-vue": "^2.21.2",
+    "core-js": "^3.6.5",
+    "corejs-typeahead": "^1.3.1",
+    "lodash": "^4.17.21",
+    "sweetalert2": "^11.0.18",
+    "vee-validate": "^3.4.9",
+    "vue": "^2.6.11",
+    "vue-multiselect": "^2.1.6",
+    "vue-recaptcha": "^1.3.0",
+    "vue-router": "^3.2.0",
+    "vuex": "^3.4.0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.0",
+    "@vue/cli-plugin-e2e-cypress": "~4.5.0",
+    "@vue/cli-plugin-eslint": "~4.5.0",
+    "@vue/cli-plugin-router": "~4.5.0",
+    "@vue/cli-plugin-unit-jest": "~4.5.0",
+    "@vue/cli-plugin-vuex": "~4.5.0",
+    "@vue/cli-service": "~4.5.0",
+    "@vue/eslint-config-airbnb": "^5.0.2",
+    "@vue/test-utils": "^1.0.3",
+    "babel-eslint": "^10.1.0",
+    "cross-env": "^7.0.3",
+    "eslint": "^6.7.2",
+    "eslint-plugin-import": "^2.20.2",
+    "eslint-plugin-vue": "^6.2.2",
+    "less": "^3.0.4",
+    "less-loader": "^5.0.0",
+    "sass": "^1.34.0",
+    "sass-loader": "^10.2.0",
+    "vue-template-compiler": "^2.6.11"
+  }
+}
diff --git a/public/config/config.json.sample b/public/config/config.json.sample
new file mode 100644
index 0000000..3f459af
--- /dev/null
+++ b/public/config/config.json.sample
@@ -0,0 +1,13 @@
+{
+  "NODE_ENV": "development",
+  "LOCALE": "fr-FR",
+  "DOMAIN": "http://127.0.0.1",
+  "BASE_PATH": "/",
+  "ROOT_PATH": "",
+  "NEXT_DEFAULT": "/",
+  "VUE_APP_LOGIN_API": "http://127.0.0.1/login",
+  "VUE_APP_ORGANISATION_API": "http://127.0.0.1/organisation/",
+  "VUE_APP_USERGROUP_API": "http://127.0.0.1/usergroup/",
+  "VUE_APP_LOGIN_API_USERNAME": "admin",
+  "VUE_APP_LOGIN_API_PASSWORD": "CHANGE_ME"
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..df36fcfb72584e00488330b560ebcf34a41c64c2
GIT binary patch
literal 4286
zcmds*O-Phc6o&64GDVCEQHxsW(p4>LW*W<827=Unuo8sGpRux(DN@jWP-e29Wl%wj
zY84_aq9}^Am9-cWTD5GGEo#+5Fi2wX_P*bo+xO!)p*7B;iKlbFd(U~_d(U?#hLj56
zPhFkj-|A6~Qk#@g^#D^U0XT1cu=c-vu1+SElX9NR;kzAUV(q0|dl0|%h|dI$%VICy
zJnu2^L*Te9JrJMGh%-P79CL0}dq92RGU6gI{v2~|)p}sG5x0U*z<8U;Ij*hB9z?ei
z@g6Xq-pDoPl=MANPiR7%172VA%r)kev<ISBgE$F{SFy+(=9Z)f)De0Se}ZDZW}Z3B
zElCeVrw;K0Fdl_Cg=gZOFXXc3pL)Q05CAuT+XucQ<8g~3dteP~|7s7c6QYP;fy;mF
zMN;>tV-_5H*QJKFmd;8yA$98zCxBZYXTNZ#QFk2(TX0;Y2dt&WitL#$96|gJY=3xX
zpCoi|YNzgO3R`f@IiEeSmKrPSf#h#Qd<$%Ej^RIeeYfsxhPMOG`S`Pz8q``=511zm
zAm)MX5AV^5xIWPyEu7u>qYs?pn$I4nL9J!=K=SGlKLXpE<5x+2cDTXq?brj?n6sp=
zphe9;_JHf40^9~}9i08r{XM$7HB!`{Ys~TK0kx<}ZQng`UPvH*11|q7&l9?@FQz;8
zx!=3<4seY*%=OlbCbcae?<QnEgvj4i?s}Yk=qA2z`-^*<eK3c)MS4JOdbsTQEOa0)
z0NWqlna2rzs>5^V_}*K>Uo6ZWV8mTyE^B=DKy7-sdLYkR5Z?paTgK-zyIkKjIcpyO
z{+uIt&YSa_$QnN_@t~L014dyK(fOOo+W*MIxbA6Ndgr=Y!f#Tokqv}n<7-9qfHkc3
z=>a|HWqcX8fzQCT=dqVbogRq!-S>H%yA{1w#2Pn;=e>JiEj7Hl;zdt-2f+j2%DeVD
zsW0Ab)ZK@0cIW%W7<X*Er!BfRbvU93$DH%#v6dRt^6HBxz1xBNHx=$&_Gv<&J}Ljk
zJN<Fzx(`Oe@KgQ0F$<14=XV#WK`o#6Ku>z}H{&~yGhn~D;aiP4=;m-HCo`BEI+Kd6
z={Xwx{T<?%b6i9IjI)Ls)S{-*mq<@~R{?$}ZKjf;^k75i_}(2MXt}^SEBVg7AI@28
zo_uPg2V)_e-`2Ois=PYoe%9u*n9({PFR)OnHJPi{dNx>Kx<YG`4QQ>D#iCLfl2<BD
h7L=-;Q>vQGDitKtN>z|-AdCN|$jTFDg0m3O`WLD4_s#$S

literal 0
HcmV?d00001

diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..f1a8b2b
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <link rel="stylesheet" href="https://unpkg.com/vue-multiselect@2.1.0/dist/vue-multiselect.min.css">
+    <title><%= htmlWebpackPlugin.options.title %></title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..2390341
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,11 @@
+<template>
+  <div id="app">
+    <router-view id="page"/>
+  </div>
+</template>
+
+<script>
+export default {
+
+};
+</script>
diff --git a/src/api/loginAPI.js b/src/api/loginAPI.js
new file mode 100644
index 0000000..69e982b
--- /dev/null
+++ b/src/api/loginAPI.js
@@ -0,0 +1,165 @@
+import axios from 'axios';
+
+const DEV_AUTH = process.env.NODE_ENV === 'development' ? true : false;
+
+const AUTH = {
+  username: process.env.VUE_APP_LOGIN_API_USERNAME,
+  password: process.env.VUE_APP_LOGIN_API_PASSWORD
+};
+
+if (!DEV_AUTH) {
+  axios.defaults.headers.common['X-CSRFToken'] = (name => {
+    var re = new RegExp(name + "=([^;]+)");
+    var value = re.exec(document.cookie);
+    return (value != null) ? unescape(value[1]) : null;
+  })('csrftoken');
+}
+
+const path = require('path');
+const DOMAIN = process.env.VUE_APP_DOMAIN;
+const LOGIN_API_PATH = process.env.VUE_APP_LOGIN_API_PATH;
+
+const loginAPI = {
+
+  async signUp(data) {
+    const url = new URL(path.join(LOGIN_API_PATH, `/signup/`), DOMAIN);
+    const response = await axios.post(url, data);
+    if (response.status === 201) {
+      return response.data;
+    } else {
+      console.error(response);
+      return false;
+    }
+  },
+
+  async signIn(data) {
+    const url = new URL(path.join(LOGIN_API_PATH, `/signin/`), DOMAIN);
+    const response = await axios.post(url, data);
+    if (response.status === 200) {
+      return response.data;
+    } else {
+      console.error(response);
+      return false;
+    }
+  },
+
+  async signOut(data) {
+    const url = new URL(path.join(LOGIN_API_PATH, `/signout/`), DOMAIN);
+    const response = await axios.get(url, data);
+    if (response.status === 200) {
+      return response.data;
+    } else {
+      console.error(response);
+      return false;
+    }
+  },
+
+  async validationRegistration(data) {
+    const url = new URL(path.join(LOGIN_API_PATH, `/signup-confirmation/`), DOMAIN);
+    const response = await axios.post(url, data);
+    if (response.status === 200) {
+      return true;
+    } else {
+      console.error(response);
+      return false;
+    }
+  },
+
+  async getOrganisationsList() {
+    const url = new URL(path.join(LOGIN_API_PATH, `/organisations/`), DOMAIN);
+    const response = await axios.get(url);
+    if (response.status === 200) {
+      return response.data;
+    } else {
+      console.error(response);
+      return false;
+    }
+  },
+
+  async getUserDetail() {
+    const url = new URL(path.join(LOGIN_API_PATH, `/user/`), DOMAIN);
+    const response = await axios.get(url, { ...DEV_AUTH && { auth: AUTH } });
+    if (response.status === 200) {
+      return response.data;
+    } else {
+      console.error(response);
+      return false;
+    }
+  },
+
+  async updateUserDetail(data) {
+    const url = new URL(path.join(LOGIN_API_PATH, `/user/`), DOMAIN);
+    const response = await axios.put(url, data, { ...DEV_AUTH && { auth: AUTH } });
+    if (response.status === 200) {
+      return response.data;
+    } else {
+      console.error(response);
+      return false;
+    }
+  },
+
+  async forgottenPasswordRequest(data) {
+    const url = new URL(path.join(LOGIN_API_PATH, `/forgotten-password-request/`), DOMAIN);
+    try {
+      const response = await axios.post(url, data);
+      if (response.status === 200) {
+        return response;
+      }
+    } catch (err) {
+      return err.response;
+    }
+  },
+
+  async forgottenPasswordConfirm(data) {
+    const url = new URL(path.join(LOGIN_API_PATH, `/forgotten-password-confirmation/`), DOMAIN);
+    try {
+      const response = await axios.post(url, data);
+      if (response.status === 200) {
+        return response;
+      }
+    } catch (err) {
+      return err.response;
+    }
+  },
+
+  async newEmailConfirm(data) {
+    const url = new URL(path.join(LOGIN_API_PATH, `/email-update-confirmation/`), DOMAIN);
+    try {
+      const response = await axios.post(url, data);
+      if (response.status === 200) {
+        return true;
+      } else {
+        return false;
+      }
+    } catch {
+      return false;
+    }
+  },
+
+  async getTermsOfUse() {
+    const url = new URL(path.join(LOGIN_API_PATH, `/term-of-use/`), DOMAIN);
+    try {
+      const response = await axios.get(url, { ...DEV_AUTH && { auth: AUTH } });
+      if (response.status === 200) {
+        return response;
+      }
+    } catch (err) {
+      return err.response;
+    }
+  },
+
+  async postTermsOfUseAgreement(data) {
+    const url = new URL(path.join(LOGIN_API_PATH, `/term-of-use/`), DOMAIN);
+    try {
+      const response = await axios.post(url, data, { ...DEV_AUTH && { auth: AUTH } });
+      if (response.status === 200) {
+        return response;
+      }
+    } catch (err) {
+      return err.response;
+    }
+  }
+
+};
+
+export default loginAPI;
diff --git a/src/api/organisationsAPI.js b/src/api/organisationsAPI.js
new file mode 100644
index 0000000..b41964a
--- /dev/null
+++ b/src/api/organisationsAPI.js
@@ -0,0 +1,63 @@
+import axios from 'axios';
+
+const DEV_AUTH = process.env.NODE_ENV === 'development' ? true : false;
+
+const AUTH = {
+  username: process.env.VUE_APP_LOGIN_API_USERNAME,
+  password: process.env.VUE_APP_LOGIN_API_PASSWORD
+};
+
+if (!DEV_AUTH) {
+  axios.defaults.headers.common['X-CSRFToken'] = (name => {
+    var re = new RegExp(name + "=([^;]+)");
+    var value = re.exec(document.cookie);
+    return (value != null) ? unescape(value[1]) : null;
+  })('csrftoken');
+}
+
+const path = require('path');
+const DOMAIN = process.env.VUE_APP_DOMAIN;
+const ORGANISATION_API_PATH = process.env.VUE_APP_ORGANISATION_API_PATH;
+const USERGROUP_API_PATH = process.env.VUE_APP_USERGROUP_API_PATH;
+
+const organisationsAPI = {
+
+  async getOrganisationsTypes() {
+    const url = new URL(path.join(ORGANISATION_API_PATH, `organisation-types/`), DOMAIN);
+    let response;
+    try {
+      response = await axios.get(url);
+      if (response.status === 200) {
+        return response.data;
+      }
+    } catch (err) {
+      console.error(err);
+      return false;
+    }
+  },
+
+  async getOrganisationsRoles() {
+    const url = new URL(path.join(USERGROUP_API_PATH, `user-group-roles/`), DOMAIN);
+    let response;
+    try {
+      response = await axios.get(url);
+      if (response.status === 200) {
+        return response.data;
+      }
+    } catch (err) {
+      console.error(err);
+      return false;
+    }
+  },
+
+  async setOrganisationThumbnail(id, data) {
+    const url = new URL(path.join(ORGANISATION_API_PATH, `organisations/${id}/thumbnail/`), DOMAIN);
+    const response = await axios.put(url, data, { ...DEV_AUTH && { auth: AUTH } });
+    if (response.status === 200) {
+      return response.data;
+    }
+    return false;
+  },
+};
+
+export default organisationsAPI;
diff --git a/src/api/usergroupsAPI.js b/src/api/usergroupsAPI.js
new file mode 100644
index 0000000..55cf151
--- /dev/null
+++ b/src/api/usergroupsAPI.js
@@ -0,0 +1,45 @@
+import axios from 'axios';
+
+const DEV_AUTH = process.env.NODE_ENV === 'development' ? true : false;
+
+const AUTH = {
+  username: process.env.VUE_APP_LOGIN_API_USERNAME,
+  password: process.env.VUE_APP_LOGIN_API_PASSWORD
+};
+
+
+const path = require('path');
+const DOMAIN = process.env.VUE_APP_DOMAIN;
+const USERGROUP_API_PATH = process.env.VUE_APP_USERGROUP_API_PATH;
+
+if (!DEV_AUTH) {
+  axios.defaults.headers.common['X-CSRFToken'] = (name => {
+    var re = new RegExp(name + "=([^;]+)");
+    var value = re.exec(document.cookie);
+    return (value != null) ? unescape(value[1]) : null;
+  })('csrftoken');
+}
+
+const usergroupsAPI = {
+
+  async getFilteredUsergroupsList(type = 'group-of-organisation', page = 1) {
+    const url = new URL(path.join(USERGROUP_API_PATH, `user-groups/?page=${page}&usergroup_types=${type}`), DOMAIN);
+    const response = await axios.get(url, { ...DEV_AUTH && { auth: AUTH } });
+    if (response.status === 200) {
+      return response.data;
+    }
+    return false;
+  },
+
+  async updateUsergroup(id, data) {
+    const url = new URL(path.join(USERGROUP_API_PATH, `user-groups/${id}/`), DOMAIN);
+    const response = await axios.put(url, data, { ...DEV_AUTH && { auth: AUTH } });
+    if (response.status === 200) {
+      return response.data;
+    }
+    return false;
+  },
+
+}
+
+export default usergroupsAPI;
diff --git a/src/api/usersAPI.js b/src/api/usersAPI.js
new file mode 100644
index 0000000..2363366
--- /dev/null
+++ b/src/api/usersAPI.js
@@ -0,0 +1,35 @@
+import axios from 'axios';
+
+const DEV_AUTH = process.env.NODE_ENV === 'development' ? true : false;
+
+const AUTH = {
+  username: process.env.VUE_APP_LOGIN_API_USERNAME,
+  password: process.env.VUE_APP_LOGIN_API_PASSWORD
+};
+
+if (!DEV_AUTH) {
+  axios.defaults.headers.common['X-CSRFToken'] = (name => {
+    var re = new RegExp(name + "=([^;]+)");
+    var value = re.exec(document.cookie);
+    return (value != null) ? unescape(value[1]) : null;
+  })('csrftoken');
+}
+
+const USERGROUP_API_URL = process.env.VUE_APP_USERGROUP_API;
+
+
+const usersAPI = {
+  async findUsername(username, page = 1) {
+    const url = `${USERGROUP_API_URL}users/?page=${page}&username=${username}`;
+    const response = await axios.get(
+      url,
+      { ...DEV_AUTH && { auth: AUTH } }
+    );
+    if (response.status === 200) {
+      return response.data;
+    }
+    return false;
+  }
+}
+
+export default usersAPI;
diff --git a/src/app.less b/src/app.less
new file mode 100644
index 0000000..6702c1a
--- /dev/null
+++ b/src/app.less
@@ -0,0 +1,125 @@
+html {
+  height: 100%;
+}
+
+body {
+  height: 100%;
+}
+
+#app {
+  height: 100%;
+}
+
+#page {
+  height: 100%;
+  overflow-y: auto;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+form {
+  margin: 1em 0 1em;
+  .form-row {
+    p {
+      width: 100%;
+      color: grey;
+      font-style: italic;
+      font-size: 0.7em;
+      margin-bottom: 0.2em;
+    }
+    .form-group {
+      input {
+        // font-size: 0.9em;
+        color: rgb(29, 29, 29);
+        font-weight: 400;
+      }
+      input::placeholder {
+        color: rgb(192, 192, 192);
+      }
+    }
+    .form-group.disabled {
+      opacity: 0.4;
+      pointer-events: none;
+    }
+  }
+  .form-row.disabled {
+    opacity: 0.4;
+    pointer-events: none;
+  }
+}
+
+label {
+  font-size: 0.8em;
+  font-weight: bold;
+  margin-bottom: 0.1em; 
+}
+
+label.required:after {
+	content: ' *';
+	color: rgb(209, 0, 0);
+}
+
+.form-control {
+  border-width: 2px;
+}
+
+.control {
+  width: 100%;
+  .form-errors {
+    display: block;
+    font-size: 0.8em;
+    font-style: italic;
+  }
+}
+.control.is-invalid {
+  .form-errors {
+    color: #EB0600 !important;
+    font-size: 0.75rem;
+    position: absolute;
+    padding-top: 1px;
+  }
+  input {
+    border: 1px #EB0600 solid;
+  }
+}
+.control.is-valid {
+  .form-errors {
+    color: #045929;
+  }
+  input {
+    border: 1px #045929 solid;
+  }
+}
+
+// Multiselect
+.multiselect__tags {
+  border: 2px solid #ced4da;
+}
+
+.multiselect__placeholder {
+  color: #838383;
+}
+
+.multiselect__option--highlight {
+  background-color: @blue;
+}
+
+.multiselect__option--selected.multiselect__option--highlight {
+  background-color: @blue;
+}
+
+.search-usergroups {
+  .multiselect__select {
+    display: none !important;
+  }
+  .multiselect__clear {
+    position: absolute;
+    right: 0;
+    top: 3px;
+    width: 40px;
+    display: block;
+    cursor: pointer;
+    z-index: 2;
+  }
+}
diff --git a/src/app.scss b/src/app.scss
new file mode 100644
index 0000000..4e2d6c4
--- /dev/null
+++ b/src/app.scss
@@ -0,0 +1,4 @@
+$primary: #187CC6;
+
+@import 'node_modules/bootstrap/scss/bootstrap.scss';
+@import 'node_modules/bootstrap-vue/src/index.scss';
diff --git a/src/assets/icons/file_document_sheet.svg b/src/assets/icons/file_document_sheet.svg
new file mode 100644
index 0000000..f755b4f
--- /dev/null
+++ b/src/assets/icons/file_document_sheet.svg
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill:#187CC6;}
+</style>
+<path class="st0" d="M59.85,0.77H20.46c-5.42,0-9.8,4.43-9.8,9.85l-0.05,78.77c0,5.42,4.38,9.85,9.8,9.85h59.13
+	c5.42,0,9.85-4.43,9.85-9.85V30.31L59.85,0.77z M20.46,89.39V10.61h34.46v24.62h24.62v54.16H20.46z"/>
+</svg>
diff --git a/src/assets/logo_pigma.png b/src/assets/logo_pigma.png
new file mode 100644
index 0000000000000000000000000000000000000000..d51900857e1fc949fbee7addfdd24309d481f1d9
GIT binary patch
literal 69765
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%0Dff})dp?&z_K$Wq8Sz`3PeU%cBB-*
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
JPDHLkV1k}W<M;po

literal 0
HcmV?d00001

diff --git a/src/components/ImportImage.vue b/src/components/ImportImage.vue
new file mode 100644
index 0000000..ac1b294
--- /dev/null
+++ b/src/components/ImportImage.vue
@@ -0,0 +1,173 @@
+<template>
+  <div :class="{disabled: disabled}">
+    <img
+      :id="previewId"
+      :hidden="!filePreview"
+      style="max-width: 400px; margin: 1em 1em 0.3em;"
+      alt="Image preview"
+    /><br v-if="filePreview">
+    <div v-if="fileExist || filePreview">
+      <div v-if="fileExist && !filePreview">
+        <img
+          :src="fileURL"
+          style="max-width: 400px; margin: 1em 1em 0.3em;"
+          alt="Image preview"
+        />
+        <p style="margin: 0 0 0.5em 1.3em">
+          {{ title.split('/').slice(-1)[0] }}
+        </p>
+      </div>
+    </div>
+    <div
+      v-else
+      id="import-file"
+      @click="uploadFile"
+    >
+      <img
+        src="@/assets/icons/file_document_sheet.svg"
+        alt="Icône fichier"
+      />
+      <div v-if="type === 'logo'"><b-icon-plus />Ajouter un logo</div>
+      <div v-if="type === 'image'"><b-icon-plus />Ajouter une image</div>
+    </div>
+    <div>
+      <input
+        :id="`upload-file-${this.name}`"
+        :hidden="!(fileExist || filePreview)"
+        type="file"
+        accept="image/*"
+        placeholder="Importer un fichier"
+        @change="previewFile"
+      >
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex';
+
+export default {
+  name: 'ImportImage',
+
+  props: {
+    name: {
+      type: String,
+      default: ''
+    },
+    title: {
+      type: String,
+      default: ''
+    },
+    type: {
+      type: String,
+      default: 'logo'
+    },
+    file: {
+      type: String,
+      default: null
+    },
+    disabled: {
+      type: Boolean,
+      default: false
+    }
+  },
+
+  data() {
+    return {
+      fileExist: false,
+      filePreview: false
+    }
+  },
+
+  computed: {
+    previewId() {
+      return `preview-file-${this.name}`;
+    },
+    fileURL() {
+      if (this.file) {
+        return `${process.env.VUE_APP_DOMAIN}${this.file}`;
+      } else {
+        return ''
+      }
+    }
+  },
+
+  watch: {
+    accept(newValue, oldValue) {
+      if (newValue || (!newValue && oldValue)) {
+        this.filePreview = false;
+      }
+    }
+  },
+
+  created() {
+    if (this.file) {
+      this.fileExist = true;
+    }
+  },
+
+  methods: {
+    uploadFile() {
+      const elem = document.getElementById(`upload-file-${this.name}`);
+      elem.click();
+    },
+    previewFile(e) {
+      const previewEl = document.getElementById(this.previewId);
+      if (e.target.files && e.target.files[0]) {
+        this.fileExist = false;
+        this.filePreview = true;
+        previewEl.src = URL.createObjectURL(e.target.files[0]);
+        previewEl.onload = function() {
+          URL.revokeObjectURL(previewEl.src) // free memory
+        }
+        this.$emit('update', e.target.files[0]);
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+
+#import-file {
+  cursor: pointer;
+  margin-top: 0.5em;
+  border: 1px dashed @blue;
+  border-radius: 3px;
+  width: 240px;
+  height: 130px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-evenly;
+  img {
+    height: 2.5em;
+  }
+  div {
+    color: @blue;
+    font-size: 1.1em;
+    font-weight: bold;
+    font-style: normal;
+  }
+}
+#import-file:hover {
+  border: 2px dashed @blue;
+  img {
+    height: 2.7em;
+  }
+  div {
+    font-size: 1.3em;
+
+  }
+}
+
+#preview-file {
+  max-width: 15em;
+}
+
+.disabled {
+  pointer-events: none;
+  opacity: 0.6;
+}
+
+</style>
diff --git a/src/components/OrganisationCreation.vue b/src/components/OrganisationCreation.vue
new file mode 100644
index 0000000..9706792
--- /dev/null
+++ b/src/components/OrganisationCreation.vue
@@ -0,0 +1,353 @@
+<template>
+  <div>
+    <b-button-close @click="$emit('cancel')" class="close"/>
+    <h6>Créer une nouvelle organisation</h6>
+    <br>
+    <form>
+      <div class="form-row">
+        <div class="form-group col-11">
+          <ValidationProvider rules="required" v-slot="{ classes, errors }">
+            <div class="control" :class="classes">
+              <label class="required">Nom de l'organisation</label>
+              <p>Inscrivez le nom complet et en toutes lettres ; par ex. « Communauté des Communes Rurales de l'Entre-Deux-Mers »</p>
+              <input
+                v-model="formData.name"
+                class="form-control"
+                type="text"
+                placeholder=""
+              >
+              <span class="form-errors">{{ errors[0] }}</span>
+            </div>
+          </ValidationProvider>
+        </div>
+      </div>
+      <div class="form-row">
+        <div class="form-group col-6">
+          <div class="control">
+            <label>Sigle</label>
+            <input
+              v-model="formData.sigle"
+              class="form-control"
+              type="text"
+              placeholder=""
+            >
+          </div>
+        </div>
+      </div>
+      <div class="form-row">
+        <div class="form-group col-6">
+          <label>Numéro SIRET</label>
+          <input
+            v-model="formData.siret"
+            class="form-control"
+            type="text"
+            placeholder="xxx xxx xxx xxxxx"
+          >
+        </div>
+      </div>
+      <div class="form-row">
+        <div class="form-group col-6">
+          <ValidationProvider rules="required" v-slot="{ classes, errors }">
+            <div class="control" :class="classes">
+              <label class="required">Type d'organisation</label>
+              <Multiselect
+                v-model="formData.type"
+                :options="organisationsTypes"
+                track-by="codename"
+                label="display_name"
+                selectLabel=""
+                selectedLabel=""
+                deselectLabel=""
+                :searchable="false"
+                placeholder="Sélectionnez un type"
+              />
+              <span class="form-errors">{{ errors[0] }}</span>
+            </div>
+          </ValidationProvider>
+        </div>
+      </div>
+      <div class="form-row">
+        <div class="form-group col-6">
+          <label>Logo de l'organisation</label>
+          <p>Importez un logo au format JPG ou PNG (taille maximale : 2 Mo)</p>
+          <ValidationProvider ref="thumbnail" v-slot="{ classes, errors }">
+            <div class="control" :class="classes">
+              <ImportImage
+                name="logo"
+                :title="null"
+                :file="null"
+                @update="setThumbnail"
+              />
+              <span class="form-errors">{{ errors[0] }}</span>
+            </div>
+          </ValidationProvider>
+        </div>
+      </div>
+      <div class="form-row">
+        <div class="form-group col-9">
+          <label>Site internet</label>
+          <input
+            v-model="formData.web"
+            class="form-control"
+            type="text"
+            placeholder="https://"
+            @focus="formData.web === null ? formData.web = 'https://' : null"
+            @blur="formData.web === 'https://' ? formData.web = null : null"
+          >
+        </div>
+      </div>
+      <div class="form-row">
+        <div class="form-group col-6">
+          <label>Numéro de téléphone</label>
+          <input
+            v-model="formData.tel"
+            class="form-control"
+            type="text"
+            placeholder=""
+          >
+        </div>
+      </div>
+      <div class="form-row">
+        <div class="form-group col-11">
+          <label>Adresse postale</label>
+          <textarea
+            v-model="formData.postalAddress"
+            class="form-control"
+          />
+        </div>
+      </div>
+      <div class="form-row">
+        <div class="form-group col-11">
+          <label>Description de l'organisation</label>
+          <textarea
+            v-model="formData.description"
+            class="form-control"
+          />
+        </div>
+      </div>
+      <!-- <div class="form-row">
+        <div class="form-group col-11">
+          <label>
+            Ajouter cette organisation à des groupe d'organisations
+          </label>
+          <p>
+            L'ajout de cette organisation à un groupe d'organisation donnera accès aux données et collections de données associées à ce groupe d'organisation.
+          </p>
+          <SearchUsergroups
+            :type="'group-of-organisation'"
+            @select="addOrgToSphere"
+          />
+          <div
+            v-if="spheres.length > 0"
+            id="orga-spheres-container"
+          >
+            <div
+              v-for="sphere of spheres"
+              :key="sphere.id"
+              class="orga-sphere"
+            >
+              {{ sphere.display_name }}
+              <b-icon-x
+                font-scale="1.5"
+                @click="removeOrgFromSphere"
+              />
+            </div>
+          </div>
+        </div>
+      </div> -->
+    </form>
+    <hr class="divider" />
+  </div>
+</template>
+
+<script>
+import {
+  mapState,
+  mapActions
+} from 'vuex';
+
+import ImportImage from '@/components/ImportImage';
+// import SearchUsergroups from '@/components/SearchUsergroups';
+
+import {
+  ValidationObserver,
+  ValidationProvider,
+  extend,
+  configure
+} from 'vee-validate';
+import {
+  required
+} from 'vee-validate/dist/rules';
+
+
+extend('required', {
+  ...required,
+  message: 'Ce champ est requis'
+});
+
+configure({
+  classes: {
+    valid: 'is-valid',
+    invalid: 'is-invalid'
+  }
+});
+
+export default {
+  name: 'OrganisationCreation',
+
+  components: {
+    ValidationObserver,
+    ValidationProvider,
+    ImportImage,
+    // SearchUsergroups
+  },
+
+  data() {
+    return {
+      formData: {
+        name: null,
+        sigle: null,
+        siret: null,
+        type: null,
+        web: null,
+        postalAddress: null,
+        tel: null,
+        description: null
+      },
+      thumbnail: null,
+      spheres: []
+    };
+  },
+
+  computed: {
+    ...mapState('organisations', [
+      'organisationsTypes'
+    ]),
+    ...mapState('sign-up', [
+      'error'
+    ])
+  },
+
+  watch: {
+    formData: {
+      deep: true,
+      handler(newValue) {
+        this.$emit('update', {
+          form: newValue,
+          thumbnail: this.thumbnail,
+          spheres: this.spheres
+        });
+      }
+    },
+    thumbnail(newValue) {
+      this.$emit('update', {
+        form: this.formData,
+        thumbnail: newValue,
+        spheres: this.spheres
+      });
+    },
+    spheres: {
+      deep: true,
+      handler(newValue) {
+        this.$emit('update', {
+          form: this.formData,
+          thumbnail: this.thumbnail,
+          spheres: newValue
+        });
+      }
+    },
+    error(newValue) {
+      if (newValue) {
+        for (const [key, value] of Object.entries(newValue)) {
+          this.$refs[key].applyResult({
+            errors: value,
+            valid: false,
+            failedRules: {},
+          });
+        }
+      }
+    }
+  },
+
+  created() {
+    if (this.organisationsTypes.length === 0) {
+      this.GET_ORGANISATIONS_TYPES();
+    }
+    this.$emit('update', {
+      form: this.formData,
+      thumbnail: this.thumbnail,
+      spheres: this.spheres
+    });
+  },
+
+  methods: {
+    ...mapActions('organisations', ['GET_ORGANISATIONS_TYPES']),
+
+    setThumbnail(e) {
+      const formData = new FormData();
+      formData.append('file', e);
+      this.thumbnail = formData;
+    },
+
+    addOrgToSphere(e) {
+      this.spheres.push(e);
+    },
+    removeOrgFromSphere(e) {
+      const index = this.spheres.findIndex(el => el.id === e.id);
+      this.spheres.splice(index, 1);
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+form {
+  min-width: 800px;
+  margin-bottom: 3em;
+}
+
+h2 {
+  color: @blue;
+  margin-top: 0.5em;
+  margin-left: 0.5em;
+}
+
+h4 {
+  color: @blue;
+  margin-top: 0.8em;
+}
+
+button {
+  margin: 1em 2em 0 0;
+  font-size: 1em;
+}
+
+.close {
+  font-size: 2rem;
+  position: relative;
+  display: block;
+  float: right;
+  top: -2.5rem;
+  right: -2.5rem;
+}
+
+#orga-spheres-container {
+  display: flex;
+  flex-flow: row wrap;
+  padding: 0.1em;
+  margin: 0.5em 0;
+  .orga-sphere {
+    display: flex;
+    margin: 0.2em 1em 0.2em 0;
+    padding: 0.5em;
+    border-radius: 10px;
+    font-size: 0.9em;
+    background-color: @blue;
+    color: white;
+    .b-icon {
+      cursor: pointer;
+    }
+  }
+}
+
+</style>
diff --git a/src/components/OrganisationSelector.vue b/src/components/OrganisationSelector.vue
new file mode 100644
index 0000000..717679c
--- /dev/null
+++ b/src/components/OrganisationSelector.vue
@@ -0,0 +1,214 @@
+<template>
+  <div>
+    <h5>Organisation</h5>
+    <hr class="divider" />
+    <div v-if="!showCreationForm">
+      <label>Sélectionnez votre organisation dans la liste ci-dessous.</label>
+      <Multiselect
+        v-model="organisation"
+        style="margin-top: 0.5em;"
+        class="search-usergroups"
+        :options="suggestions.local"
+        :optionsLimit="10"
+        :allow-empty="false"
+        track-by="id"
+        label="display_name"
+        :resetAfter="false"
+        selectLabel=""
+        selectedLabel=""
+        deselectLabel=""
+        :searchable="true"
+        placeholder="Recherchez une organisation ..."
+        :showNoResults="true"
+        :loading="loading"
+        :clearOnSelect="false"
+        :preserveSearch="false"
+        @search-change="search"
+      >
+        <template slot="clear">
+          <div
+            v-if="organisation"
+            class="multiselect__clear"
+            @click.prevent.stop="organisation = null"
+          >
+            <b-icon-x font-scale="2"/>
+          </div>
+        </template>
+        <span slot="noResult">
+          Aucun résultat.
+        </span>
+        <span slot="noOptions">
+          Saississez les premiers caractères d'une organisation pour lancer la recherche
+        </span>
+      </Multiselect>
+      <label>
+        Si celle-ci n'est pas dans la liste, vous pouvez
+        <b-link @click="showCreationForm = true">
+          indiquer une nouvelle organisation.
+        </b-link>
+      </label>
+    </div>
+    <OrganisationCreation
+      v-if="showCreationForm"
+      @update="updateOrganisationToCreate"
+      @cancel="showCreationForm = false"
+    />
+  </div>
+</template>
+
+<script>
+import { mapState, mapActions } from 'vuex';
+import Bloodhound from 'corejs-typeahead/dist/bloodhound';
+
+import OrganisationCreation from '@/components/OrganisationCreation.vue';
+
+export default {
+  name: 'OrganisationSelector',
+  components: {
+    OrganisationCreation
+  },
+  data() {
+    return {
+      loading: false,
+      text: null,
+      suggestions: {
+        local: []
+      },
+      results: [],
+      organisation: null,
+      role: null,
+      showCreationForm: false,
+      organisationToCreate: {
+        codename: null,
+        display_name: null,
+        description: null,
+        organisation_type: null,
+        registration_number: null,
+        phone_number: null,
+        website_url: null,
+        postal_address: null,
+      },
+      organisationThumbnail: null,
+      organisationSpheres: null,
+      selectedOrganisation: null,
+    };
+  },
+  computed: {
+    ...mapState('organisations', [
+      'organisationsList',
+      'organisationsRoles'
+    ])
+  },
+  watch: {
+    text(newValue) {
+      this.suggestions.search(newValue, data => {
+        this.results = data.map(function(item) {
+          return item.id;
+        });
+      });
+    },
+
+    organisationsList: {
+      deep: true,
+      handler(newValue) {
+        const SuggestionsEngine = Bloodhound.noConflict();
+        let local = [];
+        newValue.map(function(item) {
+          local.push({
+            id: item.id,
+            display_name: item.display_name
+          });
+        });
+        this.suggestions = new SuggestionsEngine({
+          local: local,
+          initialize: true,
+          datumTokenizer: Bloodhound.tokenizers.obj.nonword('title'),
+          queryTokenizer: Bloodhound.tokenizers.nonword
+        });
+      }
+    },
+
+    organisation(newValue) {
+      if (newValue) {
+        this.selectedOrganisation = newValue;
+      }
+    },
+    organisationToCreate: {
+      deep: true,
+      handler(newValue) {
+        if (newValue) {
+          this.selectedOrganisation = newValue;
+        }
+      }
+    },
+    organisationThumbnail(newValue) {
+      if (newValue) {
+        this.$emit('select', {
+          selected: true,
+          orga: this.selectedOrganisation,
+          thumbnail: newValue,
+          spheres: this.organisationSpheres
+        });
+      }
+    },
+    organisationSpheres(newValue) {
+      if (newValue) {
+        this.$emit('select', {
+          selected: true,
+          orga: this.selectedOrganisation,
+          thumbnail: this.organisationThumbnail,
+          spheres: newValue
+        });
+      }
+    },
+    selectedOrganisation(newValue) {
+      if (newValue) {
+        this.$emit('select', {
+          selected: true,
+          orga: newValue,
+          thumbnail: this.organisationThumbnail,
+          spheres: this.organisationSpheres
+        });
+      }
+    },
+  },
+
+  created() {
+    this.GET_ORGANISATIONS_LIST();
+  },
+
+  methods: {
+    ...mapActions('organisations', [
+      'GET_ORGANISATIONS_LIST',
+      'GET_ORGANISATIONS_ROLES',
+      'SEARCH_ORGANISATIONS_LIST'
+    ]),
+
+    search(text) {
+      this.text = text;
+    },
+
+    updateOrganisationToCreate(e) {
+      this.organisationToCreate.codename = e.form.name ? e.form.name.replace(/[^A-Z0-9]/ig, "_") : null;
+      this.organisationToCreate.acronym = e.form.sigle;
+      this.organisationToCreate.display_name = e.form.name;
+      this.organisationToCreate.description = e.form.description;
+      this.organisationToCreate.organisation_type = e.form.type;
+      this.organisationToCreate.registration_number = e.form.siret;
+      this.organisationToCreate.phone_number = e.form.tel;
+      this.organisationToCreate.website_url = e.form.web;
+      this.organisationToCreate.postal_address = e.form.postalAddress;
+
+      this.organisationSpheres = e.spheres;
+      this.organisationThumbnail = e.thumbnail;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+label {
+  font-size: 1rem;
+  font-weight: normal;
+}
+</style>
diff --git a/src/components/SearchUsergroups.vue b/src/components/SearchUsergroups.vue
new file mode 100644
index 0000000..58a4164
--- /dev/null
+++ b/src/components/SearchUsergroups.vue
@@ -0,0 +1,117 @@
+<template>
+  <div>
+    <Multiselect
+      v-model="selection"
+      style="margin-top: 0.5em;"
+      class="search-usergroups"
+      :options="results"
+      :optionsLimit="10"
+      :allow-empty="false"
+      track-by="id"
+      label="display_name"
+      :resetAfter="true"
+      selectLabel=""
+      selectedLabel=""
+      deselectLabel=""
+      :searchable="true"
+      :placeholder="placeholder"
+      :showNoResults="true"
+      :loading="loading"
+      :clearOnSelect="false"
+      :preserveSearch="true"
+      @search-change="search"
+      @select="select"
+    >
+      <template slot="clear">
+        <div
+          v-if="selection"
+          class="multiselect__clear"
+          @click.prevent.stop="selection = null"
+        >
+          <b-icon-x font-scale="2"/>
+        </div>
+      </template>
+      <span slot="noResult">
+        Aucun résultat.
+      </span>
+      <span slot="noOptions">
+        Saisissez les premiers caractères ...
+      </span>
+    </Multiselect>
+  </div>
+</template>
+
+<script>
+import Multiselect from 'vue-multiselect';
+
+import { mapState, mapActions } from 'vuex';
+
+export default {
+  name: 'SearchUsergroups',
+
+  components: {
+    Multiselect
+  },
+
+  props: {
+    placeholder: {
+      type: String,
+      default: 'Ajouter cette organisation à des groupes d\'organisations'
+    }
+  },
+
+  data() {
+    return {
+      selection: null,
+      loading: false,
+      text: null,
+      results: []
+    };
+  },
+
+  computed: {
+    ...mapState('usergroups', [
+      'spheres'
+    ])
+  },
+
+  watch: {
+    text: function(newValue) {
+      this.loading = true;
+      this.SEARCH_SPHERES(newValue)
+      .then(() => {
+        if (newValue) {
+          this.results = this.spheres;
+        } else {
+          // this.results.splice(0);
+          this.results = this.spheres;
+        }
+        this.loading = false;
+      });
+    }
+  },
+
+  created() {
+    this.GET_SPHERES_LIST()
+    .then(() => {
+      this.results = this.spheres;
+    })
+  },
+
+  methods: {
+    ...mapActions('usergroups', [
+      'GET_SPHERES_LIST',
+      'SEARCH_SPHERES'
+    ]),
+
+    search(text) {
+      this.text = text;
+    },
+
+    select(e) {
+      this.$emit('select', e);
+      this.selection = null;
+    }
+  }
+}
+</script>
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..2a6a249
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,25 @@
+import Vue from 'vue';
+
+import { BootstrapVue, BootstrapVueIcons } from 'bootstrap-vue';
+import 'bootstrap-vue/dist/bootstrap-vue-icons.min.css';
+import Multiselect from 'vue-multiselect';
+
+// Custom css
+import '@/app.scss';
+import '@/app.less';
+
+Vue.use(BootstrapVue);
+Vue.use(BootstrapVueIcons);
+Vue.component('Multiselect', Multiselect);
+
+import App from '@/App.vue';
+import router from '@/router';
+import store from '@/store';
+
+Vue.config.productionTip = false;
+
+new Vue({
+  router,
+  store,
+  render: (h) => h(App),
+}).$mount('#app')
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 0000000..9e6e3ec
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,79 @@
+import Vue from 'vue';
+import VueRouter from 'vue-router';
+
+Vue.use(VueRouter);
+
+const routes = [
+  {
+    path: '/',
+    redirect: { name: 'SignIn' },
+  },
+  {
+    path: '/signin',
+    name: 'SignIn',
+    component: () => import('@/views/SignIn.vue'),
+  },
+  {
+    path: '/signup',
+    name: 'SignUp',
+    component: () => import('@/views/SignUp.vue'),
+  },
+  {
+    path: '/terms-of-use',
+    name: 'TermsOfUse',
+    component: () => import('@/views/TermsOfUse.vue'),
+  },
+  {
+    path: '/signout',
+    name: 'SignOut',
+    component: () => import('@/views/SignOut.vue'),
+  },
+  {
+    path: '/signout-failed',
+    name: 'SignOutFailed',
+    component: () => import('@/views/SignOutFailed.vue'),
+  },
+  {
+    path: '/signupsuccess',
+    name: 'SignUpSuccess',
+    component: () => import('@/views/SignUpSuccess.vue'),
+  },
+  {
+    path: '/validateregistration',
+    name: 'ValidationRegistration',
+    component: () => import('@/views/ValidationRegistration.vue'),
+  },
+  {
+    path: '/validate-email',
+    name: 'ValidationEmail',
+    component: () => import('@/views/ValidationEmail.vue'),
+  },
+  {
+    path: '/forgottenpwd',
+    name: 'ForgottenPassword',
+    component: () => import('@/views/ForgottenPassword.vue'),
+  },
+  {
+    path: '/reinitpwd',
+    name: 'ReinitPassword',
+    component: () => import('@/views/ReinitPassword.vue'),
+  },
+  {
+    path: '/profile',
+    name: 'UserProfile',
+    component: () => import('@/views/UserProfile.vue'),
+  },
+  {
+    path: '/*',
+    name: 'NotFound',
+    component: () => import('@/views/NotFound.vue'),
+  },
+];
+
+const router = new VueRouter({
+  routes,
+  mode: 'history',
+  base: process.env.VUE_APP_BASE_PATH || '',
+});
+
+export default router;
diff --git a/src/services/error-service.js b/src/services/error-service.js
new file mode 100644
index 0000000..4a1d29e
--- /dev/null
+++ b/src/services/error-service.js
@@ -0,0 +1,55 @@
+import Swal from "sweetalert2";
+import "sweetalert2/dist/sweetalert2.min.css";
+
+import router from '@/router';
+
+export class ErrorService {
+
+  static onError(error) {
+    const response = error;
+    if (response && response.status === 403) {
+      router.push({ name: '403Page'});
+    }
+    if (response && response.status >= 400 && response.status < 405) {
+
+      const errorObj = response.data.detail ? response.data.detail : response.data;
+      const messages = [];
+      function recurse(obj) {
+        for (const [key, value] of Object.entries(obj)) {
+          if (typeof key === 'string' && typeof value === 'string') {
+            messages.push(`<b>${key}:</b> ${value}`);
+          } else if (typeof value === 'string') {
+            messages.push(`${value}`);
+          } else {
+            recurse(value);
+          }
+        }
+      }
+      recurse(errorObj);
+
+      Swal.fire({
+        position: 'top-end',
+        icon: 'error',
+        title: `Erreur ${response.status}`,
+        html: messages.join('\n'),
+        showConfirmButton: false,
+        timer: 3000
+      });
+    }
+    return false;
+  }
+
+  static onSuccess(response, message) {
+    if (response) {
+      Swal.fire({
+        position: 'top-end',
+        heightAuto: false,
+        icon: 'success',
+        title: `${message}`,
+        showConfirmButton: false,
+        timer: 3000
+      });
+    }
+    return false;
+  }
+}
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 0000000..e844d05
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,23 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import modules from './modules';
+
+Vue.use(Vuex);
+
+const state = {
+  cancellableSearchRequest: null
+};
+
+export const SET_CANCELLABLE_SEARCH_REQUEST = 'SET_CANCELLABLE_SEARCH_REQUEST';
+
+const mutations = {
+  [SET_CANCELLABLE_SEARCH_REQUEST]: (state, payload) => {
+    state.cancellableSearchRequest = payload;
+  }
+};
+
+export default new Vuex.Store({
+  modules,
+  state,
+  mutations
+});
diff --git a/src/store/modules/forgotten-pwd.store.js b/src/store/modules/forgotten-pwd.store.js
new file mode 100644
index 0000000..bb39585
--- /dev/null
+++ b/src/store/modules/forgotten-pwd.store.js
@@ -0,0 +1,105 @@
+import client from '@/api/loginAPI.js';
+import { ErrorService } from '@/services/error-service.js';
+import Swal from "sweetalert2";
+import "sweetalert2/dist/sweetalert2.min.css";
+import router from '@/router';
+
+const state = {
+  error: null,
+  success: null
+};
+
+const getters = {
+};
+
+export const REQUEST_FORGOTTEN_PASSWORD = 'REQUEST_FORGOTTEN_PASSWORD';
+export const CONFIRM_NEW_PASSWORD = 'CONFIRM_NEW_PASSWORD';
+
+const actions = {
+  [REQUEST_FORGOTTEN_PASSWORD]: async ({ commit }, data) => {
+    const response = await client.forgottenPasswordRequest(data);
+    if (response.status === 200) {
+      Swal.fire({
+        position: 'center',
+        heightAuto: false,
+        icon: 'success',
+        text: `
+          Un e-mail vous a été envoyé sur votre messagerie pour réinitialiser votre mot de passe.
+        `,
+        showConfirmButton: true,
+        confirmButtonText: 'OK',
+        confirmButtonColor: '#187CC6'
+      }).then((result) => {
+        if (result.isConfirmed) {
+          router.push({ name: 'SignIn' });
+        }
+      });
+    }
+    if (response.status === 404) {
+      commit('SET_ERROR', {
+        response: response,
+        message: 'Aucun compte trouvé pour cette adresse e-mail.'
+      });
+    }
+  },
+
+  [CONFIRM_NEW_PASSWORD]: async ({ commit }, data) => {
+    const response = await client.forgottenPasswordConfirm(data);
+    if (response.status === 200) {
+      Swal.fire({
+        position: 'center',
+        heightAuto: false,
+        icon: 'success',
+        text: `Votre mot de passe a bien été réinitialisé.
+          Vous allez être redirigé vers la page de connexion.
+        `,
+        showConfirmButton: true,
+        confirmButtonText: 'OK',
+        confirmButtonColor: '#187CC6'
+      }).then((result) => {
+        if (result.isConfirmed) {
+          router.push({ name: 'SignIn' });
+        }
+      });
+    } else if (response.status === 400) {
+      Swal.fire({
+        position: 'center',
+        heightAuto: false,
+        icon: 'error',
+        text: `Votre token a expiré. Vous devez en demander un nouveau 
+          pour changer votre mot de passe.
+        `,
+        showConfirmButton: true,
+        confirmButtonText: 'OK',
+        confirmButtonColor: '#187CC6'
+      }).then((result) => {
+        if (result.isConfirmed) {
+          router.push({ name: 'SignIn' });
+        }
+      });
+    }
+  }
+};
+
+export const SET_ERROR = 'SET_ERROR';
+export const SET_SUCCESS = 'SET_SUCCESS';
+
+const mutations = {
+  [SET_ERROR]: (state, payload) => {
+    state.success = null;
+    ErrorService.onError(payload.response);
+    state.error = payload.message;
+  },
+  [SET_SUCCESS]: (state, payload) => {
+    state.error = null;
+    state.success = payload.message;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  getters,
+  actions,
+  mutations,
+};
diff --git a/src/store/modules/index.js b/src/store/modules/index.js
new file mode 100644
index 0000000..2bbb9be
--- /dev/null
+++ b/src/store/modules/index.js
@@ -0,0 +1,16 @@
+/**
+ * Automatically imports all the modules and exports as a single module object
+*/
+
+const requireModule = require.context('.', false, /\.store\.js$/);
+const modules = {};
+
+requireModule.keys().forEach((filename) => {
+  // create the module name from fileName
+  // remove the store.js extension
+  const moduleName = filename.replace(/(\.\/|\.store\.js)/g, '');
+
+  modules[moduleName] = requireModule(filename).default || requireModule(filename);
+});
+
+export default modules;
diff --git a/src/store/modules/organisations.store.js b/src/store/modules/organisations.store.js
new file mode 100644
index 0000000..1d165e1
--- /dev/null
+++ b/src/store/modules/organisations.store.js
@@ -0,0 +1,97 @@
+import client from '@/api/loginAPI.js';
+import organisationAPI from '@/api/organisationsAPI.js';
+import axios from 'axios';
+
+const state = {
+  organisationsList: [],
+  organisationsTypes: [],
+  organisationsRoles: [],
+};
+
+const getters = { };
+
+export const GET_ORGANISATIONS_LIST = 'GET_ORGANISATIONS_LIST';
+export const GET_ORGANISATIONS_TYPES = 'GET_ORGANISATIONS_TYPES';
+export const GET_ORGANISATIONS_ROLES = 'GET_ORGANISATIONS_ROLES';
+export const SEARCH_ORGANISATIONS_LIST = 'SEARCH_ORGANISATIONS_LIST';
+
+const actions = {
+  [GET_ORGANISATIONS_LIST]: async ({ commit }) => {
+    const organisations = await client.getOrganisationsList();
+    commit('SET_ORGANISATIONS_LIST', organisations);
+  },
+  [SEARCH_ORGANISATIONS_LIST]: async ({ rootState, commit, dispatch }, text) => {
+
+    if (text) {
+      if (rootState.cancellableSearchRequest) {
+        rootState.cancellableSearchRequest.cancel();
+        commit('SET_CANCELLABLE_SEARCH_REQUEST', null, { root: true });
+      }
+
+      const cancelToken = axios.CancelToken.source();
+      commit('SET_CANCELLABLE_SEARCH_REQUEST', cancelToken, { root: true });
+      const url = `${process.env.VUE_APP_LOGIN_API}/organisations/?page=1&search=${text}`;
+
+      try {
+        const response = await axios.get(
+          url,
+          {
+            cancelToken: cancelToken.token,
+            ...process.env.NODE_ENV === 'development' && {
+              auth: {
+                username: process.env.VUE_APP_LOGIN_API_USERNAME,
+                password: process.env.VUE_APP_LOGIN_API_PASSWORD
+              }
+            }
+          }
+        );
+        if (response.status === 200) {
+          commit('SET_CANCELLABLE_SEARCH_REQUEST', null, { root: true });
+          const organisations = response.data;
+          if (organisations) {
+            commit('SET_ORGANISATIONS_LIST', organisations);
+          }
+        }
+      } catch(err) {
+        commit('SET_CANCELLABLE_SEARCH_REQUEST', null, { root: true });
+      }
+    } else {
+      dispatch('GET_ORGANISATIONS_LIST', {
+        direction: null,
+        field: null
+      });
+    }
+  },
+  [GET_ORGANISATIONS_TYPES]: async ({ commit }) => {
+    const types = await organisationAPI.getOrganisationsTypes();
+    commit('SET_ORGANISATIONS_TYPES', types);
+  },
+  [GET_ORGANISATIONS_ROLES]: async ({ commit }) => {
+    const roles = await organisationAPI.getOrganisationsRoles();
+    commit('SET_ORGANISATIONS_ROLES', roles);
+  }
+};
+
+export const SET_ORGANISATIONS_LIST = 'SET_ORGANISATIONS_LIST';
+export const SET_ORGANISATIONS_TYPES = 'SET_ORGANISATIONS_TYPES';
+export const SET_ORGANISATIONS_ROLES = 'SET_ORGANISATIONS_ROLES';
+
+const mutations = {
+  [SET_ORGANISATIONS_LIST]: (state, payload) => {
+    state.organisationsList = payload ? payload.results ? payload.results : payload : [];
+  },
+  [SET_ORGANISATIONS_TYPES]: (state, payload) => {
+    state.organisationsTypes = payload;
+  },
+  [SET_ORGANISATIONS_ROLES]: (state, payload) => {
+    state.organisationsRoles = payload;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  getters,
+  actions,
+  mutations,
+};
diff --git a/src/store/modules/sign-in.store.js b/src/store/modules/sign-in.store.js
new file mode 100644
index 0000000..fb3bd4c
--- /dev/null
+++ b/src/store/modules/sign-in.store.js
@@ -0,0 +1,78 @@
+import client from '@/api/loginAPI.js';
+
+const state = {
+  username: null,
+  password: null,
+  logged: false,
+  error: null,
+  next: null,
+};
+
+const getters = {
+};
+
+export const POST_SIGNIN = 'POST_SIGNIN';
+
+const actions = {
+  [POST_SIGNIN]: async ({ commit }) => {
+    const data = {
+      username: state.username,
+      password: state.password,
+    };
+    await client.signIn(data)
+      .then(
+        () => {
+          commit('SET_ERROR', null);
+          commit('SET_LOGGED', true);
+        },
+      )
+      .catch(
+        (error) => {
+          if (error.response.status === 403) {
+            commit(
+              'SET_ERROR',
+              error.response.data.detail
+              || 'Nom d\'utilisateur et/ou mot de passe incorrect(s)',
+            );
+            commit('SET_LOGGED', false);
+          }
+        },
+      );
+  },
+};
+
+export const SET_LOGGED = 'SET_LOGGED';
+export const SET_USERNAME = 'SET_USERNAME';
+export const SET_PASSWORD = 'SET_PASSWORD';
+export const SET_ERROR = 'SET_ERROR';
+export const SET_NEXT = 'SET_NEXT';
+
+const mutations = {
+  [SET_LOGGED]: (state, value) => {
+    if (value === true) {
+      state.logged = true;
+    } else {
+      state.logged = false;
+    }
+  },
+  [SET_USERNAME]: (state, value) => {
+    state.username = value;
+  },
+  [SET_PASSWORD]: (state, value) => {
+    state.password = value;
+  },
+  [SET_ERROR]: (state, value) => {
+    state.error = value;
+  },
+  [SET_NEXT]: (state, value) => {
+    state.next = value;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  getters,
+  actions,
+  mutations,
+};
diff --git a/src/store/modules/sign-out.store.js b/src/store/modules/sign-out.store.js
new file mode 100644
index 0000000..f9377c8
--- /dev/null
+++ b/src/store/modules/sign-out.store.js
@@ -0,0 +1,57 @@
+import client from '@/api/loginAPI.js';
+
+const state = {
+  logged: null,
+  error: null
+};
+
+const getters = {
+};
+
+export const GET_SIGNOUT = 'GET_SIGNOUT';
+
+const actions = {
+  [GET_SIGNOUT]: async ({ commit }) => {
+    await client.signOut()
+      .then(
+        () => {
+          commit('SET_ERROR', undefined);
+          commit('SET_LOGGED', false);
+        },
+      )
+      .catch(
+        (error) => {
+          commit(
+            'SET_ERROR',
+            error.response.data
+            || 'Une erreur est survenue',
+          );
+          commit('SET_LOGGED', true);
+        },
+      );
+  },
+};
+
+export const SET_ERROR = 'SET_ERROR';
+export const SET_LOGGED = 'SET_LOGGED';
+
+const mutations = {
+  [SET_LOGGED]: (state, value) => {
+    if (value === true) {
+      state.logged = true;
+    } else {
+      state.logged = false;
+    }
+  },
+  [SET_ERROR]: (state, payload) => {
+    state.error = payload;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  getters,
+  actions,
+  mutations,
+};
diff --git a/src/store/modules/sign-up.store.js b/src/store/modules/sign-up.store.js
new file mode 100644
index 0000000..98e999b
--- /dev/null
+++ b/src/store/modules/sign-up.store.js
@@ -0,0 +1,115 @@
+import client from '@/api/loginAPI.js';
+import organisationAPI from '@/api/organisationsAPI.js';
+import usergroupsAPI from '@/api/usergroupsAPI.js';
+
+import { ErrorService } from '@/services/error-service.js';
+
+const state = {
+  form: {
+    first_name: null,
+    last_name: null,
+    email: null,
+    phone_number: null,
+    comments: null,
+    username: null,
+    password1: null,
+    password2: null
+  },
+  organisationThumbnail: null,
+  organisationSpheres: [],
+  signed: false,
+  error: null,
+};
+
+const getters = {
+  getForm: state => state.form,
+  getSigned: state => state.signed,
+  getError: state => state.error,
+};
+
+export const POST_SIGNUP = 'POST_SIGNUP';
+
+const actions = {
+  [POST_SIGNUP]: async ({ state, commit }) => {
+    await client.signUp(state.form)
+      .then(
+        async (resp) => {
+          if (state.organisationThumbnail) {
+            await organisationAPI.setOrganisationThumbnail(resp.usergroup_roles[0].organisation.id, state.organisationThumbnail)
+            .then(() => {
+              commit('SET_ERROR', undefined);
+            })
+            .catch((error) => {
+              commit(
+                'SET_ERROR',
+                error.response
+                || 'Une erreur est survenue',
+              );
+              commit('SET_SIGNED', false);
+            });
+          }
+          if (state.organisationSpheres.length > 0) {
+            const data = {
+              ...resp.usergroup_roles[0].organisation,
+              parents: state.organisationSpheres.map((el) => { return el.id; })
+            };
+            await usergroupsAPI.updateUsergroup(resp.usergroup_roles[0].organisation.id, data)
+            .then(() => {
+              commit('SET_ERROR', undefined);
+            })
+            .catch((error) => {
+              commit(
+                'SET_ERROR',
+                error.response
+                || 'Une erreur est survenue',
+              );
+              commit('SET_SIGNED', false);
+            });
+          }
+          commit('SET_ERROR', undefined);
+          commit('SET_SIGNED', true);
+        },
+      )
+      .catch(
+        (error) => {
+          commit(
+            'SET_ERROR',
+            error.response
+            || 'Une erreur est survenue',
+          );
+          commit('SET_SIGNED', false);
+        },
+      );
+  },
+};
+
+export const SET_FORM = 'SET_FORM';
+export const SET_SIGNED = 'SET_SIGNED';
+export const SET_ERROR = 'SET_ERROR';
+
+const mutations = {
+  [SET_FORM]: (state, data) => {
+    state.form = data.form;
+    state.organisationThumbnail = data.thumbnail;
+    state.organisationSpheres = data.spheres;
+  },
+  [SET_SIGNED]: (state, value) => {
+    if (value === true) {
+      state.signed = true;
+    } else {
+      state.signed = false;
+    }
+  },
+  [SET_ERROR]: (state, value) => {
+    ErrorService.onError(value);
+    state.error = value && value.data ? value.data : value;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  getters,
+  actions,
+  mutations,
+};
diff --git a/src/store/modules/terms-of-use.store.js b/src/store/modules/terms-of-use.store.js
new file mode 100644
index 0000000..076d29f
--- /dev/null
+++ b/src/store/modules/terms-of-use.store.js
@@ -0,0 +1,77 @@
+import client from '@/api/loginAPI.js';
+import { ErrorService } from '@/services/error-service.js';
+import router from '@/router';
+
+const state = {
+  terms: null,
+  error: null,
+  success: null
+};
+
+const getters = {
+};
+
+export const GET_TERMS_OF_USE = 'GET_TERMS_OF_USE';
+export const AGREE_TO_TERMS_OF_USE = 'AGREE_TO_TERMS_OF_USE';
+
+const actions = {
+  [GET_TERMS_OF_USE]: async ({ commit }) => {
+    const response = await client.getTermsOfUse();
+    if (response.status === 200) {
+      commit('SET_TERMS', response.data);
+      commit('SET_SUCCESS', {
+        response: response,
+        message: ''
+      });
+    }
+    if (response.status === 404) {
+      commit('SET_ERROR', {
+        response: response,
+        message: 'Une erreur est survenue.'
+      });
+    }
+  },
+  [AGREE_TO_TERMS_OF_USE]: async ({ commit }, data) => {
+    const response = await client.postTermsOfUseAgreement(data);
+    if (response.status === 200) {
+      commit('SET_SUCCESS', {
+        response: response,
+        message: ''
+      });
+      window.location.href = router.currentRoute.query.next;
+    }
+    if (response.status === 404) {
+      commit('SET_ERROR', {
+        response: response,
+        message: 'Une erreur est survenue.'
+      });
+    }
+  }
+};
+
+export const SET_TERMS = 'SET_TERMS';
+export const SET_ERROR = 'SET_ERROR';
+export const SET_SUCCESS = 'SET_SUCCESS';
+
+const mutations = {
+  [SET_TERMS]: (state, payload) => {
+    state.terms = payload;
+  },
+  [SET_ERROR]: (state, payload) => {
+    state.success = null;
+    ErrorService.onError(payload.response);
+    state.error = payload.message;
+  },
+  [SET_SUCCESS]: (state, payload) => {
+    state.error = null;
+    state.success = payload.message;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  getters,
+  actions,
+  mutations,
+};
diff --git a/src/store/modules/user.store.js b/src/store/modules/user.store.js
new file mode 100644
index 0000000..e5b7ea6
--- /dev/null
+++ b/src/store/modules/user.store.js
@@ -0,0 +1,91 @@
+import loginAPI from '@/api/loginAPI.js';
+
+import { ErrorService } from '@/services/error-service.js';
+
+// MUTATIONS
+export const SET_ERROR = 'SET_ERROR';
+export const SET_SUCCESS = 'SET_SUCCESS';
+export const SET_USER_DETAIL = 'SET_USER_DETAIL';
+
+// ACTIONS
+export const GET_USER_DETAIL = 'GET_USER_DETAIL';
+export const UPDATE_USER_DETAIL = 'UPDATE_USER_DETAIL';
+
+/**************** STATE *******************/
+const state = {
+  userData: null,
+  userError: null,
+  error: null,
+  success: null
+};
+
+/**************** GETTERS *****************/
+const getters = {
+
+};
+
+/*************** MUTATIONS ****************/
+const mutations = {
+  [SET_USER_DETAIL]: (state, payload) => {
+    state.userData = payload;
+  },
+
+  [SET_ERROR]: (state, error) => {
+    if (error) {
+      ErrorService.onError(error);
+      state.userError = error.response.data.detail;
+    } else {
+      state.userError = error;
+    }
+  },
+
+  [SET_SUCCESS]: (state, payload) => {
+    state.error = null;
+    state.success = payload.message;
+  },
+};
+/**************** ACTIONS *****************/
+const actions = {
+
+
+  [GET_USER_DETAIL]: async ({ commit }) => {
+    await loginAPI.getUserDetail()
+    .then((resp) => {
+      if (resp) {
+        commit('SET_ERROR', null);
+        commit('SET_USER_DETAIL', resp);
+      }
+    })
+    .catch((error) => {
+      commit('SET_ERROR', error);
+    });
+  },
+
+  [UPDATE_USER_DETAIL]: async ({ commit }, data) => {
+    await loginAPI.updateUserDetail(data)
+    .then((resp) => {
+      if (resp) {
+        commit('SET_ERROR', null);
+        commit('SET_SUCCESS', {
+          response: resp,
+          message: 'Votre mot de passe a bien été modifié.'
+        });
+      }
+    })
+    .catch((error) => {
+      commit('SET_SUCCESS', {
+        response: null,
+        message: null
+      });
+      commit('SET_ERROR', error);
+    });
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  getters,
+  actions,
+  mutations,
+};
\ No newline at end of file
diff --git a/src/store/modules/usergroups.store.js b/src/store/modules/usergroups.store.js
new file mode 100644
index 0000000..f5ae420
--- /dev/null
+++ b/src/store/modules/usergroups.store.js
@@ -0,0 +1,113 @@
+import { ErrorService } from '@/services/error-service.js';
+import usergroupsAPI from '@/api/usergroupsAPI';
+import axios from 'axios';
+
+const DEV_AUTH = process.env.NODE_ENV === 'development' ? true : false;
+const AUTH = {
+  username: process.env.VUE_APP_LOGIN_API_USERNAME,
+  password: process.env.VUE_APP_LOGIN_API_PASSWORD
+};
+const path = require('path');
+const DOMAIN = process.env.VUE_APP_DOMAIN;
+const USERGROUP_API_PATH = process.env.VUE_APP_USERGROUP_API_PATH;
+
+// MUTATIONS
+export const SET_USERGROUPS_SPHERES_LIST = 'SET_USERGROUPS_SPHERES_LIST';
+export const SET_ERROR = 'SET_ERROR';
+export const SET_IS_SPHERES_SEARCHED = 'SET_IS_SPHERES_SEARCHED';
+
+// ACTIONS
+export const GET_SPHERES_LIST = 'GET_SPHERES_LIST';
+export const SEARCH_SPHERES = 'SEARCH_SPHERES';
+
+/**************** STATE *******************/
+const state = {
+  spheresCount: 0,
+  spheres: [],
+  usergroupsError: null,
+  isSpheresSearched: false
+};
+
+/**************** GETTERS *****************/
+const getters = {
+};
+
+/*************** MUTATIONS ****************/
+const mutations = {
+
+  [SET_USERGROUPS_SPHERES_LIST]: (state, payload) => {
+    if (payload) {
+      state.spheresCount = payload.count;
+      state.spheres = payload.results;
+    }
+  },
+
+  [SET_ERROR]: (state, error) => {
+    if (error) {
+      ErrorService.onError(error);
+      state.usergroupsError = error;
+    } else {
+      state.usergroupsError = error;
+    }
+  },
+
+  [SET_IS_SPHERES_SEARCHED]: (state, payload) => {
+    state.isSpheresSearched = payload;
+  }
+
+};
+/**************** ACTIONS *****************/
+const actions = {
+
+  [GET_SPHERES_LIST]: async ({ commit }) => {
+    try {
+      const spheres = await usergroupsAPI.getFilteredUsergroupsList()
+      if (spheres) {
+        commit('SET_ERROR', null);
+        commit('SET_USERGROUPS_SPHERES_LIST', spheres);
+      }
+    } catch (error) {
+      commit('SET_ERROR', error);
+    }
+  },
+
+  [SEARCH_SPHERES]: async ({ rootState, commit }, text) => {
+    if (rootState.cancellableSearchRequest) {
+      rootState.cancellableSearchRequest.cancel();
+      commit('SET_CANCELLABLE_SEARCH_REQUEST', null, { root: true });
+    }
+
+    const cancelToken = axios.CancelToken.source();
+    commit('SET_CANCELLABLE_SEARCH_REQUEST', cancelToken, { root: true });
+    const url = new URL(path.join(USERGROUP_API_PATH, `user-groups/?page=1&search=${text}&usergroup_types=group-of-organisation`), DOMAIN);
+
+    try {
+      const response = await axios.get(
+        url,
+        {
+          cancelToken: cancelToken.token,
+          ...DEV_AUTH && { auth: AUTH }
+        }
+      );
+      if (response.status === 200) {
+        commit('SET_CANCELLABLE_SEARCH_REQUEST', null, { root: true });
+        const usergroups = response.data;
+        if (usergroups) {
+          commit('SET_ERROR', null);
+          commit('SET_USERGROUPS_SPHERES_LIST', usergroups);
+          commit('SET_IS_SPHERES_SEARCHED', true);
+        }
+      }
+    } catch(err) {
+      commit('SET_CANCELLABLE_SEARCH_REQUEST', null, { root: true });
+    }
+  }
+};
+
+export default {
+  namespaced: true,
+  state,
+  getters,
+  actions,
+  mutations,
+};
diff --git a/src/store/modules/validation-email.store.js b/src/store/modules/validation-email.store.js
new file mode 100644
index 0000000..e17831b
--- /dev/null
+++ b/src/store/modules/validation-email.store.js
@@ -0,0 +1,37 @@
+import client from '@/api/loginAPI.js';
+
+const state = {
+  status: undefined,
+};
+
+export const POST_TOKEN = 'POST_TOKEN';
+
+const actions = {
+  [POST_TOKEN]: async ({ commit }, token) => {
+    const data = {
+      token: token
+    };
+    await client.newEmailConfirm(data).then(response => {
+      commit('SET_STATUS', response);
+    });
+  },
+};
+
+export const SET_STATUS = 'SET_STATUS';
+
+const mutations = {
+  [SET_STATUS]: (state, response) => {
+    if (response === true) {
+      state.status = true;
+    } else {
+      state.status = false;
+    }
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  actions,
+  mutations,
+};
diff --git a/src/store/modules/validation-registration.store.js b/src/store/modules/validation-registration.store.js
new file mode 100644
index 0000000..ff4b6d9
--- /dev/null
+++ b/src/store/modules/validation-registration.store.js
@@ -0,0 +1,45 @@
+import client from '@/api/loginAPI.js';
+
+const state = {
+  token: null,
+  status: undefined,
+};
+
+const getters = {
+  getStatus: state => state.status,
+};
+
+export const POST_TOKEN = 'POST_TOKEN';
+
+const actions = {
+  [POST_TOKEN]: async ({ state, commit }) => {
+    const data = { token: state.token };
+    await client.validationRegistration(data).then(response => {
+      commit('SET_STATUS', response);
+    });
+  },
+};
+
+export const SET_STATUS = 'SET_STATUS';
+export const SET_TOKEN = 'SET_TOKEN';
+
+const mutations = {
+  [SET_TOKEN]: (state, value) => {
+    state.token = value;
+  },
+  [SET_STATUS]: (state, response) => {
+    if (response === true) {
+      state.status = true;
+    } else {
+      state.status = false;
+    }
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  getters,
+  actions,
+  mutations,
+};
diff --git a/src/views/ForgottenPassword.vue b/src/views/ForgottenPassword.vue
new file mode 100644
index 0000000..069e878
--- /dev/null
+++ b/src/views/ForgottenPassword.vue
@@ -0,0 +1,146 @@
+<template>
+  <div>
+    <div class="container">
+      <div class="header">
+        <img alt="logo" src="@/assets/logo_pigma.png"/>
+      </div>
+      <div class="form">
+        <h5 class="title">Réinitialisez votre mot de passe</h5>
+        <form>
+          <div class="form-row">
+            <label>
+              Veuillez indiquer l'adresse e-mail de votre compte
+            </label>
+            <input
+              v-model="email"
+              class="form-control"
+              type="text"
+              placeholder="Adresse e-mail"
+            >
+          </div>
+          <button
+            type="submit"
+            class="btn btn-primary"
+            @click.prevent="reinitPassword"
+          >
+            Envoyer un e-mail de réinitialisation
+          </button>
+          <button
+            class="btn btn-outline-secondary"
+            @click="$router.push({ name: 'SignIn' })">
+            Annuler
+          </button>
+        </form>
+      </div>
+      <div class="messages">
+        <div v-if="error">
+          <p class="form-errors">{{ error }}</p>
+        </div>
+      </div>
+    </div>
+    <small class="footer">
+      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+    </small>
+  </div>
+</template>
+
+<script>
+import { mapState, mapActions } from 'vuex';
+
+export default {
+  name: 'ForgottenPassword',
+  data() {
+    return {
+      email: null,
+    };
+  },
+
+  computed: {
+    ...mapState('forgotten-pwd', [
+      'error',
+      'success'
+    ])
+  },
+
+  methods: {
+    ...mapActions('forgotten-pwd', [
+      'REQUEST_FORGOTTEN_PASSWORD'
+    ]),
+    reinitPassword() {
+      this.REQUEST_FORGOTTEN_PASSWORD({
+        email: this.email
+      })
+    }
+  }
+};
+</script>
+
+<style lang="less" scoped>
+
+.container {
+  margin: auto;
+  width: 480px;
+  height: fit-content;
+
+  .header {
+    margin: 0 0 5rem 0;
+    img {
+      width: 440px;
+    }
+  }
+
+  .form {
+
+    .form-row {
+      margin: 0 0 40px 0;
+    }
+
+    button.btn {
+      float: right;
+      position: relative;
+      margin-left: 7px;
+      margin-right: 0;
+    }
+
+    button.btn-primary {
+      border: 2px solid #9BD0FF;
+      border-radius: 8px;
+    }
+    button.btn-outline-secondary {
+      background-color: #F7F8FA;
+      border: 2px solid #A9B2B9;
+      border-radius: 8px;
+      color: #2F3234;
+    }
+    button.btn-outline-secondary:hover {
+      color: white;
+      background-color: #4b4b4b;
+    }
+
+  }
+  .messages {
+    display: inline-block;
+    position: relative;
+    top: 1.5em;
+  }
+}
+
+.form-errors {
+  color: #EB0600 !important;
+}
+
+.form-success {
+  color: #11ac45 !important;
+}
+
+.footer {
+  position: absolute;
+  bottom: 0;
+  font-size: small;
+}
+
+.footer a {
+  text-decoration: none;
+}
+
+</style>
diff --git a/src/views/NotFound.vue b/src/views/NotFound.vue
new file mode 100644
index 0000000..1388ee9
--- /dev/null
+++ b/src/views/NotFound.vue
@@ -0,0 +1,11 @@
+<template>
+  <div>
+
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'NotFound',
+};
+</script>
diff --git a/src/views/ReinitPassword.vue b/src/views/ReinitPassword.vue
new file mode 100644
index 0000000..0505791
--- /dev/null
+++ b/src/views/ReinitPassword.vue
@@ -0,0 +1,292 @@
+<template>
+  <div>
+    <div class="container">
+      <div class="header">
+        <img alt="logo" src="@/assets/logo_pigma.png"/>
+      </div>
+      <b-overlay
+        id="overlay-background"
+        :show="loading"
+        :variant="'white'"
+        :opacity="0.7"
+        :blur="'2px'"
+        rounded="sm"
+        no-wrap
+      >
+      </b-overlay>
+      <div class="form">
+        <h5 class="title">Choississez un nouveau mot de passe</h5>
+        <ValidationObserver v-slot="{ handleSubmit }">
+          <form>
+            <div class="form-row">
+              <ValidationProvider
+                ref="password"
+                :rules="{ required: true, regex: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/ }"
+                v-slot="{ classes, errors }"
+                vid="confirmation"
+              >
+                <div class="control" :class="classes">
+                  <label class="required">
+                    Nouveau de mot de passe
+                  </label>
+                  <div class="input-group flex-nowrap">
+                    <input
+                      v-model="password1"
+                      class="form-control"
+                      :type="showPassword ? 'text' : 'password'"
+                      placeholder="Mot de passe"
+                    >
+                    <span
+                      v-if="!showPassword"
+                      class="input-group-text"
+                    >
+                      <b-icon
+                        icon="eye-fill"
+                        @click="showPassword = !showPassword"
+                      />
+                    </span>
+                    <span
+                      v-else
+                      class="input-group-text"
+                    >
+                      <b-icon
+                        icon="eye-slash-fill"
+                        @click="showPassword = !showPassword"
+                      />
+                    </span>
+                  </div>
+                  <span class="form-errors">{{ errors[0] }}</span>
+                </div>
+              </ValidationProvider>
+            </div>
+            <div class="form-row">
+              <ValidationProvider ref="password" rules="required|confirmed:confirmation" v-slot="{ classes, errors }">
+                <div class="control" :class="classes">
+                  <label class="required">
+                    Confirmez le mot de passe
+                  </label>
+                  <div class="input-group flex-nowrap">
+                    <input
+                      v-model="password2"
+                      class="form-control"
+                      :type="showPassword ? 'text' : 'password'"
+                      placeholder="Mot de passe"
+                    >
+                    <span
+                      v-if="!showPassword"
+                      class="input-group-text"
+                    >
+                      <b-icon
+                        icon="eye-fill"
+                        @click="showPassword = !showPassword"
+                      />
+                    </span>
+                    <span
+                      v-else
+                      class="input-group-text"
+                    >
+                      <b-icon
+                        icon="eye-slash-fill"
+                        @click="showPassword = !showPassword"
+                      />
+                    </span>
+                  </div>
+                  <span class="form-errors">{{ errors[0] }}</span>
+                </div>
+              </ValidationProvider>
+            </div>
+            <div class="infos">
+              <ul>
+                <li>Votre mot de passe ne peut pas trop ressembler à vos autres informations personnelles.</li>
+                <li>Votre mot de passe doit contenir au minimum 8 caractères.</li>
+                <li>Votre mot de passe ne peut pas être un mot de passe couramment utilisé.</li>
+                <li>Votre mot de passe ne peut pas être entièrement numérique.</li>
+              </ul>
+            </div>
+            <button
+              type="button"
+              class="btn btn-primary"
+              @click.prevent="handleSubmit(sendNewPassword)"
+            >
+              Sauvegarder
+            </button>
+            <button
+              type="button"
+              class="btn btn-outline-secondary"
+              @click="$router.push({ name: 'SignIn' })"
+            >
+              Annuler
+            </button>
+          </form>
+        </ValidationObserver>
+      </div>
+      <div class="messages">
+        <div v-if="error">
+          <p class="form-errors">{{ error }}</p>
+        </div>
+        <div v-if="success">
+          <p class="form-success">{{ success }}</p>
+        </div>
+      </div>
+    </div>
+    <small class="footer">
+      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+    </small>
+  </div>
+</template>
+
+<script>
+import { mapState, mapActions } from 'vuex';
+
+import {
+  ValidationObserver,
+  ValidationProvider,
+  extend,
+  configure,
+} from 'vee-validate';
+
+import { required, confirmed, regex } from 'vee-validate/dist/rules';
+
+extend('required', {
+  ...required,
+  message: 'Ce champ est requis',
+});
+
+extend('confirmed', {
+  ...confirmed,
+  message: 'Les mots de passe doivent être identiques',
+});
+
+configure({
+  classes: {
+    valid: 'is-valid',
+    invalid: 'is-invalid',
+  },
+});
+
+extend('regex', {
+  ...regex,
+  message: 'Votre mot de passe doit comporter au moins 8 caractères, dont au moins une majuscule, une minuscule et 1 chiffre.',
+});
+
+export default {
+  name: 'ReinitPassword',
+
+  components: {
+    ValidationObserver,
+    ValidationProvider
+  },
+
+  data() {
+    return {
+      loading: false,
+      password1: null,
+      password2: null,
+      showPassword: false
+    }
+  },
+
+  computed: {
+    ...mapState('forgotten-pwd', [
+      'error',
+      'success'
+    ])
+  },
+
+  methods: {
+    ...mapActions('forgotten-pwd', [
+      'CONFIRM_NEW_PASSWORD'
+    ]),
+
+    sendNewPassword() {
+      this.loading = true;
+      this.CONFIRM_NEW_PASSWORD({
+        token: this.$route.query.token,
+        password: this.password1
+      }).then(() => {
+        this.loading = false;
+      })
+    }
+  }
+};
+</script>
+
+<style lang="less" scoped>
+
+.container {
+  margin: auto;
+  width: 480px;
+  height: fit-content;
+
+  .header {
+    margin: 0 0 5rem 0;
+    img {
+      width: 440px;
+    }
+  }
+
+  .form {
+
+    .form-row {
+      margin: 0 0 40px 0;
+      display: block;
+    }
+
+    button.btn {
+      float: right;
+      position: relative;
+      margin-left: 7px;
+      margin-right: 0;
+      margin-top: 1rem;
+    }
+
+    button.btn-primary {
+      border: 2px solid #9BD0FF;
+      border-radius: 8px;
+    }
+    button.btn-outline-secondary {
+      background-color: #F7F8FA;
+      border: 2px solid #A9B2B9;
+      border-radius: 8px;
+      color: #2F3234;
+    }
+    button.btn-outline-secondary:hover {
+      color: white;
+      background-color: #4b4b4b;
+    }
+
+  }
+  .infos {
+    font-size: 0.75em;
+    text-align: justify;
+    ul {
+      padding-left: 1rem;
+    }
+  }
+  .messages {
+    display: inline-block;
+    position: relative;
+    top: 1.5em;
+  }
+}
+
+.form-errors {
+  color: #EB0600 !important;
+  max-width: 40em;
+}
+
+.form-success {
+  color: #11ac45 !important;
+}
+
+.footer {
+  position: absolute;
+  bottom: 0;
+  font-size: small;
+}
+
+.footer a {
+  text-decoration: none;
+}
+
+</style>
diff --git a/src/views/SignIn.vue b/src/views/SignIn.vue
new file mode 100644
index 0000000..6f68b47
--- /dev/null
+++ b/src/views/SignIn.vue
@@ -0,0 +1,251 @@
+<template>
+  <div>
+    <div class="sign-in-container">
+      <div class="sign-in-header">
+        <img alt="logo" src="@/assets/logo_pigma.png"/>
+      </div>
+      <div class="sign-in-form">
+        <h5 class="title">Saississez vos identifiants PIGMA</h5>
+        <form>
+          <div class="form-row">
+            <input
+              v-model="form.username"
+              class="form-control"
+              type="text"
+              placeholder="Nom d'utilisateur"
+              v-on:keydown.enter.prevent="submit"
+            >
+          </div>
+          <div class="form-row">
+            <div class="input-group flex-nowrap">
+              <input
+                v-model="form.password"
+                class="form-control"
+                :type="showPassword ? 'text' : 'password'"
+                placeholder="Mot de passe"
+                v-on:keydown.enter.prevent="submit"
+              >
+              <span
+                v-if="!showPassword"
+                class="input-group-text"
+              >
+                <b-icon
+                  icon="eye-fill"
+                  @click="showPassword = !showPassword"
+                />
+              </span>
+              <span
+                v-else
+                class="input-group-text"
+              >
+                <b-icon
+                  icon="eye-slash-fill"
+                  @click="showPassword = !showPassword"
+                />
+              </span>
+            </div>
+          </div>
+          <div class="form-row">
+            <div v-if="error" class="form-row">
+              <span class="form-errors">{{ error }}</span>
+            </div>
+          </div>
+          <div class="form-row">
+            <b-button
+              :pressed="btnPressed"
+              :disabled="(!username || !password)"
+              @click.prevent="submit"
+              variant="primary"
+              block
+            >
+              Se connecter
+            </b-button>
+          </div>
+          <div class="form-row">
+            <div class="btn-group-vertical">
+              <router-link
+                to="/signup"
+                custom
+              >
+                Pas encore de compte ?
+              </router-link>
+              <router-link
+                to="/forgottenpwd"
+                custom
+              >
+                Mot de passe oublié ?
+              </router-link>
+            </div>
+          </div>
+        </form>
+      </div>
+    </div>
+    <small class="footer">
+      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+    </small>
+  </div>
+</template>
+
+<script>
+
+import {
+  mapState,
+  mapActions,
+  mapMutations,
+} from 'vuex';
+
+const signInActions = [
+  'POST_SIGNIN'
+];
+const signInMutations = [
+  'SET_LOGGED',
+  'SET_NEXT',
+  'SET_USERNAME',
+  'SET_PASSWORD',
+];
+
+export default {
+  name: 'SignIn',
+
+  data() {
+    return {
+      showPassword: false,
+      btnPressed: false,
+      form: {
+        username: null,
+        password: null
+      }
+    };
+  },
+
+  computed: {
+    ...mapState('sign-in', [
+      'username',
+      'password',
+      'logged',
+      'error',
+      'next',
+    ])
+  },
+
+  watch: {
+    form: {
+      deep: true,
+      handler(newValue) {
+        this.SET_USERNAME(newValue.username);
+        this.SET_PASSWORD(newValue.password);
+      }
+    },
+
+    logged() {
+      if (this.logged && this.next) {
+        window.location.href = this.next;
+      }
+    }
+  },
+
+  created() {
+    this.SET_NEXT(this.$route.query.next || process.env.VUE_APP_NEXT_DEFAULT);
+  },
+
+  methods: {
+    ...mapActions('sign-in', signInActions),
+    ...mapMutations('sign-in', signInMutations),
+    async submit() {
+      this.btnPressed = true;
+      await this.POST_SIGNIN();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.sign-in-container {
+  margin: auto;
+  width: 480px;
+  height: fit-content;
+
+  .sign-in-header {
+    margin: 0 1rem 1rem 1rem;
+    img {
+      width: 440px;
+    }
+  }
+
+  .sign-in-form {
+    margin: 5rem 1rem;
+
+    h5.title {
+      color: #373b3d;
+    }
+
+    form {
+      margin: 2rem 0.25rem;
+
+      .form-row {
+        margin-bottom: 1.25em;
+
+        .input-group {
+          span {
+            cursor: pointer;
+            border-bottom-left-radius: 0;
+            border-top-left-radius: 0;
+            border-left: none
+          }
+        }
+      }
+
+      .row {
+        .col-7 {
+          display: flex;
+          flex-direction: column;
+          justify-content: flex-end;
+
+          .checkbox {
+            label {
+              small {
+                cursor: pointer !important;
+                input {
+                  cursor: pointer !important;
+                }
+              }
+            }
+          }
+        }
+
+        .col-5 {
+          button {
+            float: right;
+          }
+        }
+      }
+
+      .btn-group-vertical {
+        margin-top: 2rem;
+
+        a {
+          text-decoration: none;
+        }
+      }
+    }
+  }
+}
+
+.form-errors {
+  color: #EB0600 !important;
+}
+
+.form-success {
+  color: #30C963 !important;
+}
+
+.footer {
+  position: absolute;
+  bottom: 0;
+  font-size: small;
+}
+
+.footer a {
+  text-decoration: none;
+}
+</style>
diff --git a/src/views/SignOut.vue b/src/views/SignOut.vue
new file mode 100644
index 0000000..47ccac3
--- /dev/null
+++ b/src/views/SignOut.vue
@@ -0,0 +1,95 @@
+<template>
+  <div>
+    <div class="header">
+      <img alt="logo" src="@/assets/logo_pigma.png"/>
+    </div>
+    <div class="center">
+      <b-container class="msg">
+        <p>
+          Vous êtes maintenant déconnecté.<br>
+        </p>
+        <b-button type="button" variant="outline-primary" @click.prevent="$router.push({ name: 'SignIn' })">
+          Ouvrir la page de connexion
+        </b-button>
+      </b-container>
+    </div>
+    <small class="footer">
+      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+    </small>
+  </div>
+</template>
+
+<script>
+import { mapState, mapActions } from 'vuex';
+
+export default {
+  name: 'SignOut',
+
+  data: () => {
+    return { };
+  },
+
+  computed: {
+    ...mapState('sign-out', [
+      'logged',
+      'error'
+    ])
+  },
+
+  beforeRouteEnter(to, from, next) {
+    next((vm) => {
+        vm.GET_SIGNOUT().then(() => {
+          if (vm.logged) {
+            vm.$router.push({ name: 'SignOutFailed' })
+          }
+        })
+    });
+  },
+
+  methods: {
+    ...mapActions('sign-out', [
+      'GET_SIGNOUT'
+    ])
+  }
+};
+</script>
+
+<style lang="less" scoped>
+.header {
+  position: absolute;
+  top: 0;
+  left: 0;
+}
+
+.header > img {
+  width: 440px;
+}
+
+.center {
+  position: initial;
+}
+
+.center .msg.container {
+  margin: 0;
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  text-align: center;
+}
+
+.center .msg.container,
+.center .msg.container button {
+  font-size: large;
+}
+
+.footer {
+  position: absolute;
+  bottom: 0;
+  font-size: small;
+}
+
+.footer a {
+  text-decoration: none;
+}
+</style>
diff --git a/src/views/SignOutFailed.vue b/src/views/SignOutFailed.vue
new file mode 100644
index 0000000..febef67
--- /dev/null
+++ b/src/views/SignOutFailed.vue
@@ -0,0 +1,107 @@
+<template>
+  <div>
+    <div class="header">
+      <img alt="logo" src="@/assets/logo_pigma.png"/>
+    </div>
+    <b-overlay
+      id="overlay-background"
+      :show="loading"
+      :variant="'white'"
+      :opacity="0.7"
+      :blur="'2px'"
+      rounded="sm"
+      no-wrap
+    >
+    </b-overlay>
+    <div class="center">
+      <b-container class="msg">
+        <p>
+          Une erreur est survenue lors de la déconnexion.<br>
+        </p>
+        <b-button type="button" variant="outline-primary" @click.prevent="retrySignout">
+          Réessayer
+        </b-button>
+      </b-container>
+    </div>
+    <small class="footer">
+      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+    </small>
+  </div>
+</template>
+
+<script>
+import { mapState, mapActions } from 'vuex';
+
+export default {
+  name: 'SignOutFailed',
+
+  data: () => {
+    return {
+      loading: false
+    };
+  },
+
+  computed: {
+    ...mapState('sign-out', [
+      'logged',
+      'error'
+    ])
+  },
+
+  methods: {
+    ...mapActions('sign-out', [
+      'GET_SIGNOUT'
+    ]),
+
+    retrySignout() {
+      this.loading = false;
+      this.GET_SIGNOUT().then(() => {
+        this.loading = false;
+        if (!this.logged) {
+          this.$router.push({ name: 'SignOut' });
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style lang="less" scoped>
+.header {
+  position: absolute;
+  top: 0;
+  left: 0;
+}
+
+.header > img {
+  width: 440px;
+}
+
+.center {
+  position: initial;
+}
+
+.center .msg.container {
+  margin: 0;
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  text-align: center;
+}
+
+.center .msg.container,
+.center .msg.container button {
+  font-size: large;
+}
+
+.footer {
+  position: absolute;
+  bottom: 0;
+  font-size: small;
+}
+
+.footer a {
+  text-decoration: none;
+}
+</style>
diff --git a/src/views/SignUp.vue b/src/views/SignUp.vue
new file mode 100644
index 0000000..2900747
--- /dev/null
+++ b/src/views/SignUp.vue
@@ -0,0 +1,598 @@
+<template>
+  <div>
+    <div class="signup-container">
+      <div class="signup-header">
+        <img alt="logo" src="@/assets/logo_pigma.png"/>
+      </div>
+      <b-overlay
+        id="overlay-background"
+        :show="loading"
+        :variant="'white'"
+        :opacity="0.7"
+        :blur="'2px'"
+        rounded="sm"
+        no-wrap
+      >
+      </b-overlay>
+      <div class="signup-form">
+        <h4 class="title">
+          Nouveau compte
+          <span class="sub-title">Sollicitez la création d'un compte</span>
+        </h4>
+        <hr class="divider">
+        <h5>Un e-mail de confirmation sera envoyé à l'adresse indiquée</h5>
+        <ValidationObserver v-slot="{ handleSubmit }">
+        <form>
+          <h5>Vos informations personnelles</h5>
+          <hr class="divider">
+          <div class="row g-2 align-items-center">
+            <div class="col-3">
+              <label class="col-form-label required">Prénom</label>
+            </div>
+            <div class="col">
+              <ValidationProvider ref="first_name" rules="required" v-slot="{ classes, errors }">
+                <div class="control" :class="classes">
+                  <input
+                    v-model="form.first_name"
+                    type="text"
+                    class="form-control"
+                    placeholder="Prénom"
+                  >
+                  <span class="form-errors">{{ errors[0] }}</span>
+                </div>
+              </ValidationProvider>
+            </div>
+          </div>
+          <div class="row g-2 align-items-center">
+            <div class="col-3">
+              <label class="col-form-label required">Nom</label>
+            </div>
+            <div class="col">
+              <ValidationProvider ref="last_name" rules="required" v-slot="{ classes, errors }">
+                <div class="control" :class="classes">
+                  <input
+                    v-model="form.last_name"
+                    type="text"
+                    class="form-control"
+                    placeholder="Nom"
+                  >
+                  <span class="form-errors">{{ errors[0] }}</span>
+                </div>
+              </ValidationProvider>
+            </div>
+          </div>
+          <div class="row g-2 align-items-center">
+            <div class="col-3">
+              <label class="col-form-label required">Adresse e-mail</label>
+            </div>
+            <div class="col">
+              <ValidationProvider ref="email" rules="required|email" v-slot="{ classes, errors }">
+                <div class="control" :class="classes">
+                  <input
+                    v-model="form.email"
+                    type="mail"
+                    class="form-control"
+                    placeholder="Adresse e-mail"
+                  >
+                  <span class="form-errors">{{ errors[0] }}</span>
+                </div>
+              </ValidationProvider>
+            </div>
+          </div>
+          <div class="row g-2 align-items-center">
+            <div class="col-3">
+              <label class="col-form-label">Numéro de téléphone</label>
+            </div>
+            <div class="col">
+              <ValidationProvider ref="phone_number" v-slot="{ classes, errors }">
+                <div class="control" :class="classes">
+                  <input
+                    v-model="form.phone_number"
+                    type="text"
+                    class="form-control"
+                    placeholder=""
+                  >
+                  <span class="form-errors">{{ errors[0] }}</span>
+                </div>
+              </ValidationProvider>
+            </div>
+          </div>
+          <div class="row g-2 align-items-center">
+            <div class="col-3">
+              <label class="col-form-label">Motif de l'inscription</label>
+            </div>
+            <div class="col">
+              <textarea
+                v-model="form.comments"
+                class="form-control"
+              />
+            </div>
+          </div>
+          <h5>Vos identifiants</h5>
+          <hr class="divider">
+          <div class="row g-2 align-items-center">
+            <div class="col-3">
+              <label class="col-form-label">Nom d'utilisateur</label>
+            </div>
+            <div class="col">
+              <ValidationProvider ref="username" rules="required" v-slot="{ classes, errors }">
+                <div class="control" :class="classes">
+                  <div class="input-group flex-nowrap">
+                    <input
+                      v-model="form.username"
+                      type="text"
+                      class="form-control"
+                      disabled
+                    >
+                    <span class="input-group-text">
+                      <b-icon icon="person-fill" />
+                    </span>
+                  </div>
+                  <span class="form-errors">{{ errors[0] }}</span>
+                </div>
+              </ValidationProvider>
+            </div>
+          </div>
+          <div class="row g-2 align-items-center" style="margin-bottom">
+            <div class="col-3">
+            </div>
+            <div class="col">
+              <p class="infos">
+                Le nom d'utilisateur est généré automatiquement à partir de la 
+                première lettre de votre prénom et de votre nom.
+                Il n'est pas modifiable.
+              </p>
+            </div>
+          </div>
+          <div class="row g-2 align-items-center">
+            <div class="col-3">
+              <label
+                class="col-form-label required"
+                style="padding: 0;"
+              >Mot de passe
+              </label>
+            </div>
+            <div class="col">
+              <ValidationProvider
+                ref="password"
+                :rules="{ required: true, regex: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/ }"
+                v-slot="{ classes, errors }"
+                vid="confirmation"
+              >
+                <div class="control" :class="classes">
+                  <div class="input-group flex-nowrap">
+                    <input
+                      v-model="form.password1"
+                      class="form-control"
+                      :type="showPassword ? 'text' : 'password'"
+                      placeholder="Mot de passe"
+                    >
+                    <span
+                      v-if="!showPassword"
+                      class="input-group-text"
+                    >
+                      <b-icon
+                        icon="eye-fill"
+                        @click="showPassword = !showPassword"
+                      />
+                    </span>
+                    <span
+                      v-else
+                      class="input-group-text"
+                    >
+                      <b-icon
+                        icon="eye-slash-fill"
+                        @click="showPassword = !showPassword"
+                      />
+                    </span>
+                  </div>
+                  <span class="form-errors">{{ errors[0] }}</span>
+                </div>
+              </ValidationProvider>
+            </div>
+          </div>
+          <div class="row g-2 align-items-center">
+            <div class="col-3"></div>
+            <div class="col">
+              <ValidationProvider ref="password" rules="required|confirmed:confirmation" v-slot="{ classes, errors }">
+                <div class="control" :class="classes">
+                  <div class="input-group flex-nowrap">
+                    <input
+                      v-model="form.password2"
+                      class="form-control"
+                      :type="showPassword ? 'text' : 'password'"
+                      placeholder="Mot de passe"
+                    >
+                    <span
+                      v-if="!showPassword"
+                      class="input-group-text"
+                    >
+                      <b-icon
+                        icon="eye-fill"
+                        @click="showPassword = !showPassword"
+                      />
+                    </span>
+                    <span
+                      v-else
+                      class="input-group-text"
+                    >
+                      <b-icon
+                        icon="eye-slash-fill"
+                        @click="showPassword = !showPassword"
+                      />
+                    </span>
+                  </div>
+                  <span class="form-errors">{{ errors[0] }}</span>
+                </div>
+              </ValidationProvider>
+            </div>
+          </div>
+          <div class="row g-2 align-items-center">
+            <div class="col-3">
+            </div>
+            <div class="col">
+              <div class="infos">
+                <ul>
+                  <li>Votre mot de passe ne peut pas ressembler à vos informations personnelles.</li>
+                  <li>Votre mot de passe doit contenir au minimum 8 caractères.</li>
+                  <li>Votre mot de passe ne peut pas être un mot de passe couramment utilisé.</li>
+                  <li>Votre mot de passe ne peut pas être entièrement numérique.</li>
+                </ul>
+              </div>
+            </div>
+          </div>
+          <OrganisationSelector @select="handleOrganisationSelection"/>
+          <b-button
+            :disabled="(!form.username || !form.password1 || !form.password2 || !form.first_name || !form.last_name || !form.email)"
+            :pressed="btnPressed"
+            @click.prevent="handleSubmit(submit)"
+            variant="primary"
+          >
+            Valider
+          </b-button>
+          <b-button type="button" variant="outline-primary" @click.prevent="$router.push({ name: 'SignIn' })">
+            Annuler
+          </b-button>
+        </form>
+        </ValidationObserver>
+      </div>
+    </div>
+    <small class="footer">
+      <p>
+        Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a>
+      </p>
+    </small>
+  </div>
+</template>
+
+<script>
+
+import {
+  mapState,
+  mapActions,
+  mapMutations,
+} from 'vuex';
+
+const signUpActions = [
+  'POST_SIGNUP',
+];
+
+const signOutActions = [
+  'GET_SIGNOUT',
+];
+
+import OrganisationSelector from '@/components/OrganisationSelector';
+
+// import usersAPI from '@/api/usersAPI.js';
+
+// import Swal from "sweetalert2";
+// import "sweetalert2/dist/sweetalert2.min.css";
+
+import { deburr } from 'lodash';
+
+import {
+  ValidationObserver,
+  ValidationProvider,
+  extend,
+  configure,
+} from 'vee-validate';
+
+import { required, email, confirmed, regex } from 'vee-validate/dist/rules';
+
+extend('required', {
+  ...required,
+  message: 'Ce champ est requis',
+});
+
+extend('email', {
+  ...email,
+  message: 'Veuillez entrer une adresse e-mail valide',
+});
+
+extend('confirmed', {
+  ...confirmed,
+  message: 'Les mots de passe doivent être identiques',
+});
+
+extend('regex', {
+  ...regex,
+  message: 'Votre mot de passe doit comporter au moins 8 caractères, dont au moins une majuscule, une minuscule et 1 chiffre.',
+});
+
+configure({
+  classes: {
+    valid: 'is-valid',
+    invalid: 'is-invalid',
+  },
+});
+
+export default {
+  name: 'SignUp',
+  components: {
+    ValidationObserver,
+    ValidationProvider,
+    OrganisationSelector,
+  },
+  data() {
+    return {
+      loading: false,
+      form: {
+        first_name: null,
+        last_name: null,
+        email: null,
+        phone_number: null,
+        comments: null,
+        username: null,
+        password1: null,
+        password2: null
+      },
+      isOrganisationSelected: false,
+      organisation: null,
+      organisationThumbnail: null,
+      organisationSpheres: [],
+      btnPressed: false,
+      showPassword: false,
+    };
+  },
+  computed: {
+    ...mapState('sign-up', [
+      'error',
+      'signed'
+    ]),
+    ...mapState('sign-out', [
+      'logged'
+    ])
+  },
+  watch: {
+    'form.first_name': {
+      deep: true,
+      handler(newValue) {
+        if (newValue !== null && this.form.last_name !== null) {
+          this.form.username =
+            deburr(
+              newValue
+                .replace(/\s/g, '')
+                .charAt(0)
+                .toLowerCase()
+                .concat('', this.form.last_name.replace(/\s/g, '').toLowerCase())
+            ).replace(/[^a-z0-9]/g,'');
+        }
+      }
+    },
+    'form.last_name': {
+      deep: true,
+      handler(newValue) {
+        if (this.form.first_name !== null && newValue !== null) {
+          this.form.username =
+          deburr(
+            this.form.first_name
+              .replace(/\s/g, '')
+              .charAt(0)
+              .toLowerCase()
+              .concat('', newValue.replace(/\s/g, '').toLowerCase())
+          ).replace(/[^a-z0-9]/g,'');
+        }
+      }
+    },
+    signed() {
+      this.$router.push({ name: 'SignUpSuccess' });
+    },
+    error(newValue) {
+      if (newValue) {
+        for (const [key, value] of Object.entries(newValue)) {
+          if (this.$refs[key]) {
+            this.$refs[key].applyResult({
+              errors: value,
+              valid: false,
+              failedRules: {},
+            });
+          }
+        }
+      }
+    },
+  },
+  created() {
+    if (this.logged) {
+      this.GET_SIGNOUT();
+    }
+    if (this.signed) {
+      this.SET_SIGNED(true);
+    }
+  },
+  methods: {
+    ...mapActions('sign-out', signOutActions),
+    ...mapActions('sign-up', signUpActions),
+    ...mapMutations('sign-up', [
+      'SET_FORM',
+      'SET_SIGNED'
+    ]),
+    handleOrganisationSelection(e) {
+      this.isOrganisationSelected = e.selected;
+      this.organisation = e.orga;
+      this.organisationThumbnail = e.thumbnail;
+      this.organisationSpheres = e.spheres;
+    },
+    submit() {
+      this.loading = true;
+      this.btnPressed = true;
+      // const isUsernameAvailable = await usersAPI.findUsername(this.form.username);
+      // if (isUsernameAvailable.results.length > 0) {
+      //   const currentUsername = this.form.username;
+      //   let newUsername;
+      //   let suffix = '1';
+      //   // Check if username last character is a number already
+      //   // and apply suffix accordingly
+      //   if (!isNaN(parseInt(currentUsername.slice(-1)))) {
+      //     suffix = (parseInt(currentUsername.slice(-1)) + 1).toString();
+      //     newUsername = currentUsername.replace(/.$/, suffix);
+      //   } else {
+      //     newUsername = currentUsername.concat(suffix);
+      //   }
+      //   Swal.fire({
+      //     position: 'center',
+      //     heightAuto: false,
+      //     icon: 'warning',
+      //     html: `Le nom d'utilisateur <b>${currentUsername}</b> est déjà pris.
+      //     Le compte sera créé avec le nom d'utilisateur suivant: <b>${newUsername}</b>`,
+      //     showCancelButton: true,
+      //     cancelButtonText: 'Annuler',
+      //     showConfirmButton: true,
+      //     confirmButtonText: 'Confirmer',
+      //     confirmButtonColor: '#187CC6'
+      //   }).then((result) => {
+      //     if (result.isConfirmed) {
+      //       this.form.username = newUsername;
+      //       this.submit();
+      //     }
+      //   });
+      // } else {
+        this.signUp();
+      // }
+      // this.loading = false;
+    },
+    async signUp() {
+      // this.loading = true;
+      this.SET_FORM({
+        form: {
+          first_name: this.form.first_name,
+          last_name: this.form.last_name,
+          email: this.form.email,
+          username: this.form.username,
+          password: this.form.password1,
+          phone_number: this.form.phone_number ? this.form.phone_number : '',
+          comments: this.form.comments ? this.form.comments : '',
+          ...this.isOrganisationSelected && {
+            usergroup_roles: [
+              {
+                organisation: this.organisation,
+              },
+            ],
+          }
+        },
+        thumbnail: this.organisationThumbnail,
+        spheres: this.organisationSpheres
+      });
+      await this.POST_SIGNUP();
+      this.loading = false;
+    }
+  }
+};
+</script>
+
+<style lang="less" scoped>
+.signup-container {
+  margin: auto;
+  width: 800px;
+  height: fit-content;
+
+  .signup-header {
+    margin: 0 1rem 1rem 1rem;
+    img {
+      width: 440px;
+    }
+  }
+
+  .signup-form {
+    margin: 5rem 1rem;
+
+    h4.title {
+      color: #373b3d;
+
+      .sub-title {
+        font-size: 75%;
+        color: #6b7479;
+      }
+    }
+
+    hr.solid {
+      border-top: 2px solid #373b3d;
+    }
+
+    h5 {
+      color: #6b7479;
+    }
+
+    form {
+      margin-top: 32px;
+
+      h5 {
+        margin-bottom: 20px;
+        margin-top: 40px;
+        color: #373b3d;
+      }
+
+      .row {
+        margin-bottom: 1.6rem;
+      }
+
+      .input-group {
+        span {
+          cursor: pointer;
+          border-bottom-left-radius: 0;
+          border-top-left-radius: 0;
+          border-left: none
+        }
+      }
+
+      button {
+        float: right;
+        position: relative;
+        margin-left: 7px;
+        margin-top: 30px;
+      }
+
+      .infos {
+        font-size: 0.8em;
+        font-style: italic;
+        margin-right: 1em;
+        ul {
+          padding-left: 1rem;
+        }
+      }
+
+    }
+  }
+}
+
+.form-errors {
+  color: #EB0600 !important;
+  margin-right: 2em;
+  line-height: 1;
+}
+
+.form-success {
+  color: #30C963 !important;
+}
+
+.footer {
+  position: relative;
+  bottom: 0;
+  font-size: small;
+  margin-top: 2rem;
+}
+
+.footer a {
+  text-decoration: none;
+}
+
+</style>
diff --git a/src/views/SignUpSuccess.vue b/src/views/SignUpSuccess.vue
new file mode 100644
index 0000000..7e15394
--- /dev/null
+++ b/src/views/SignUpSuccess.vue
@@ -0,0 +1,70 @@
+<template>
+  <div>
+    <div class="header">
+      <img alt="logo" src="@/assets/logo_pigma.png"/>
+    </div>
+    <div class="center">
+      <b-container class="msg">
+        <p>
+          Un e-mail de confirmation vient d'être envoyé à l'adresse indiquée.<br>
+          Merci de bien vouloir suivre les instructions données afin de finaliser la création de votre compte.
+        </p>
+        <!-- <b-button type="button" variant="outline-primary" @click.prevent="$router.push({ name: 'SignIn' })">
+          Ouvrir la page de connexion
+        </b-button> -->
+      </b-container>
+    </div>
+    <small class="footer">
+      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+    </small>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'SignUpSuccess',
+  data: () => {
+    return { };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.header {
+  position: absolute;
+  top: 0;
+  left: 0;
+}
+
+.header > img {
+  width: 440px;
+}
+
+.center {
+  position: initial;
+}
+
+.center .msg.container {
+  margin: 0;
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  text-align: center;
+}
+
+.center .msg.container,
+.center .msg.container button {
+  font-size: large;
+}
+
+.footer {
+  position: absolute;
+  bottom: 0;
+  font-size: small;
+}
+
+.footer a {
+  text-decoration: none;
+}
+</style>
diff --git a/src/views/TermsOfUse.vue b/src/views/TermsOfUse.vue
new file mode 100644
index 0000000..40e475d
--- /dev/null
+++ b/src/views/TermsOfUse.vue
@@ -0,0 +1,166 @@
+<template>
+  <div>
+    <div class="terms-container">
+      <div class="terms-header">
+        <img alt="logo" src="@/assets/logo_pigma.png"/>
+      </div>
+      <div v-if="!error">
+        <b-overlay
+          :show="loading"
+          :variant="'white'"
+          rounded="lg"
+          opacity="0.9"
+        >
+          <template #overlay>
+            <div class="d-flex align-items-center">
+              <b-spinner variant="secondary"></b-spinner>
+            </div>
+          </template>
+          <div class="terms-title">
+            {{ terms ? terms.title : '' }}
+          </div>
+          <div class="terms-content">
+            <div class="terms-date">
+              {{ terms ? new Date(terms.issue_date.slice(0, 10)).toLocaleString('fr-FR', {
+                year: "numeric",
+                month: "long",
+                day: "numeric"
+              }) : '' }}<br>
+            </div>
+            <div v-html="terms ? terms.body : ''"></div>
+            <a v-if="terms && terms.file" :href="terms.file" target="_blank">Télécharger les conditions d'utilisation</a>
+          </div>
+          <div class="terms-footer">
+            <button
+              type="button"
+              class="btn btn-primary"
+              @click.prevent="acceptTermsOfUse"
+            >
+              Accepter
+            </button>
+            <button
+              type="button"
+              class="btn btn-outline-secondary"
+              @click="$router.push({ name: 'SignIn' })"
+            >
+              Refuser
+            </button>
+          </div>
+        </b-overlay>
+      </div>
+      <div v-else class="terms-container">
+        <b-container class="msg">
+          <p>
+            Une erreur est survenue. Veuillez contacter l'administrateur du site.
+          </p>
+        </b-container>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState, mapMutations, mapActions } from 'vuex';
+
+export default {
+  name: 'TermsOfUse',
+
+  data() {
+    return {
+      loading: false
+    }
+  },
+
+  computed: {
+    ...mapState('terms-of-use', [
+      'error',
+      'terms'
+    ])
+  },
+
+  created() {
+    this.loading = true;
+    this.GET_TERMS_OF_USE().then(() => {
+      this.loading = false;
+    });
+  },
+
+  methods: {
+    ...mapMutations('terms-of-use', [
+      'SET_ERROR'
+    ]),
+    ...mapActions('terms-of-use', [
+      'GET_TERMS_OF_USE',
+      'AGREE_TO_TERMS_OF_USE'
+    ]),
+
+    acceptTermsOfUse() {
+      this.AGREE_TO_TERMS_OF_USE({
+        has_agreed: true
+      });
+    },
+
+    retry() {
+      this.SET_ERROR({
+        message: null
+      });
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.terms-container {
+  margin: auto;
+  width: 600px;
+  height: fit-content;
+  max-height: 80vh;
+
+  .terms-header {
+    margin: 0 1rem 1rem 1rem;
+    img {
+      width: 560px;
+    }
+  }
+
+  .terms-title {
+    text-align: center;
+    font-size: 2rem;
+    font-weight: 600;
+  }
+  .terms-content {
+    text-align: justify;
+    margin: 1em 20px;
+    min-height: 10rem;
+    .terms-date {
+      text-align: right;
+      margin-bottom: 1rem;
+    }
+  }
+  .terms-footer {
+    height: 7rem;
+    margin: 2em 40px;
+    button.btn {
+      float: right;
+      position: relative;
+      margin-left: 7px;
+      margin-right: 0;
+    }
+
+    button.btn-primary {
+      border: 2px solid #9BD0FF;
+      border-radius: 8px;
+    }
+    button.btn-outline-secondary {
+      background-color: #F7F8FA;
+      border: 2px solid #A9B2B9;
+      border-radius: 8px;
+      color: #2F3234;
+    }
+    button.btn-outline-secondary:hover {
+      color: white;
+      background-color: #4b4b4b;
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/UserProfile.vue b/src/views/UserProfile.vue
new file mode 100644
index 0000000..7d94510
--- /dev/null
+++ b/src/views/UserProfile.vue
@@ -0,0 +1,708 @@
+<template>
+   <div>
+    <b-button
+      id="back-button"
+      variant="primary"
+      @click="goBackToNext"
+    >
+      <b-icon-arrow-bar-left/>
+      Revenir
+    </b-button>
+    <div class="signup-container">
+      <div class="signup-header">
+        <img alt="logo" src="@/assets/logo_pigma.png"/>
+      </div>
+      <div class="signup-form">
+        <h4 class="title">
+          Compte existant
+          <span class="sub-title">Modifiez les informations relatives à votre compte</span>
+        </h4>
+        <hr class="divider">
+        <ValidationObserver v-slot="{ handleSubmit }">
+          <b-overlay
+            :show="loadingUserInformation"
+            rounded="lg"
+            :style="'padding: 5px;'"
+            variant="white"
+          >
+            <form>
+              <h5>Vos informations personnelles</h5>
+              <hr class="divider">
+              <div class="row g-2 align-items-center">
+                <div class="col-3">
+                  <label class="col-form-label">Nom d'utilisateur</label>
+                </div>
+                <div class="col">
+                  <div class="input-group flex-nowrap">
+                    <input
+                      v-model="formUser.username"
+                      type="text"
+                      class="form-control"
+                      placeholder="Nom d'utilisateur"
+                      disabled
+                    >
+                  </div>
+                </div>
+              </div>
+              <div class="row g-2 align-items-center">
+                <div class="col-3">
+                  <label class="col-form-label required">Prénom</label>
+                </div>
+                <div class="col">
+                  <ValidationProvider ref="first_name" rules="required" v-slot="{ classes, errors }">
+                    <div class="control" :class="classes">
+                      <input
+                        v-model="formUser.first_name"
+                        type="text"
+                        class="form-control"
+                        placeholder="Prénom"
+                      >
+                      <span class="form-errors">{{ errors[0] }}</span>
+                    </div>
+                  </ValidationProvider>
+                </div>
+              </div>
+              <div class="row g-2 align-items-center">
+                <div class="col-3">
+                  <label class="col-form-label required">Nom</label>
+                </div>
+                <div class="col">
+                  <ValidationProvider ref="last_name" rules="required" v-slot="{ classes, errors }">
+                    <div class="control" :class="classes">
+                      <input
+                        v-model="formUser.last_name"
+                        type="text"
+                        class="form-control"
+                        placeholder="Nom"
+                      >
+                      <span class="form-errors">{{ errors[0] }}</span>
+                    </div>
+                  </ValidationProvider>
+                </div>
+              </div>
+              <div class="row g-2 align-items-center">
+                <div class="col-3">
+                  <label class="col-form-label">
+                    Adresse e-mail
+                  </label>
+                </div>
+                <div class="col">
+                  <ValidationProvider ref="email" rules="required|email" v-slot="{ classes, errors }">
+                    <div class="control" :class="classes">
+                      <input
+                        v-model="formUser.email"
+                        type="mail"
+                        class="form-control"
+                        placeholder="Adresse e-mail"
+                        disabled
+                      >
+                      <span class="form-errors">{{ errors[0] }}</span>
+                    </div>
+                  </ValidationProvider>
+                </div>
+              </div>
+              <div class="row g-2 align-items-center">
+                <div class="col-3">
+                  <label class="col-form-label">Numéro de téléphone</label>
+                </div>
+                <div class="col">
+                  <ValidationProvider ref="phone_number" v-slot="{ classes, errors }">
+                    <div class="control" :class="classes">
+                      <input
+                        v-model="formUser.phone_number"
+                        type="text"
+                        class="form-control"
+                        placeholder=""
+                      >
+                      <span class="form-errors">{{ errors[0] }}</span>
+                    </div>
+                  </ValidationProvider>
+                </div>
+              </div>
+              <div class="row g-2 align-items-center">
+                <div class="col-3">
+                  <label class="col-form-label">Motif de l'inscription</label>
+                </div>
+                <div class="col">
+                  <textarea
+                    v-model="formUser.comments"
+                    class="form-control"
+                  />
+                </div>
+              </div>
+              <div class="row g-2 align-items-center" style="margin-bottom: 0.5em;">
+                <div class="col-3">
+                  <label class="col-form-label">Organisation(s)</label>
+                </div>
+                <div v-if="userData" class="col">
+                  <div v-if="userData.usergroup_roles.length === 0">
+                    Vous n'êtes rattaché à aucune organisation.
+                  </div>
+                  <b-list-group
+                    v-else
+                  >
+                    <b-list-group-item
+                      v-for="usergroup of userData.usergroup_roles"
+                      :key="usergroup.organisation.id"
+                      disabled
+                    >
+                      {{ usergroup.organisation.display_name }} <em>en tant que</em> {{ organisationsRoles.find(el => el.choice === usergroup.role).label }}
+                    </b-list-group-item>
+                  </b-list-group>
+                </div>
+              </div>
+              <div class="row g-2 align-items-center">
+                <div class="col-3">
+                </div>
+                <div v-if="userData" class="col">
+                  <div
+                    style="margin: 0 0.5em 0.5em 0.1em; font-size: 0.9em; font-style: italic;"
+                  >
+                    Pour toute demande de modification, merci de contacter <a href="mailto:admin@example.com">admin@example.com</a>.
+                  </div>
+                </div>
+              </div>
+            </form>
+            <div class="form-footer">
+              <b-button
+                :disabled="(!formUser.first_name || !formUser.last_name || !formUser.email)"
+                @click.prevent="handleSubmit(submitUserInformations)"
+                variant="primary"
+              >
+                Valider
+              </b-button>
+            </div>
+          </b-overlay>
+        </ValidationObserver>
+
+        <ValidationObserver v-slot="{ handleSubmit }">
+          <b-overlay
+            :show="loadingUserEmail"
+            rounded="lg"
+            variant="white"
+            :style="'padding: 5px;'"
+          >
+            <form>
+              <h5>Changer votre adresse e-mail</h5>
+              <hr class="divider">
+              <div class="row g-2 align-items-center">
+                <div class="col-3" style="padding-right: 0;">
+                  <label class="col-form-label required" style="font-size: 0.9em;">Nouvelle adresse e-mail</label>
+                </div>
+                <div class="col">
+                 <ValidationProvider ref="email" rules="email" v-slot="{ classes, errors }">
+                    <div class="control" :class="classes">
+                      <input
+                        v-model="formEmail.new_email"
+                        type="mail"
+                        class="form-control"
+                        placeholder="Adresse e-mail"
+                      >
+                      <span class="form-errors">{{ errors[0] }}</span>
+                    </div>
+                  </ValidationProvider>
+                </div>
+              </div>
+              <div class="row g-2 align-items-center">
+                <div class="col-3">
+                </div>
+                <div class="col">
+                  <div
+                    style="margin: 0 0.5em 0.5em 0.5em; font-size: 0.8em; font-style: italic;"
+                  >
+                    Vous pouvez demander le changement de votre adresse mail en renseignant une nouvelle adresse. 
+                    Un lien de confirmation vous sera envoyé sur la nouvelle adresse.
+                  </div>
+                </div>
+              </div>
+            </form>
+            <div class="form-footer">
+              <b-button
+                :disabled="!formEmail.new_email"
+                :pressed="btnPressed"
+                @click.prevent="handleSubmit(submitNewEmail)"
+                variant="primary"
+              >
+                Valider
+              </b-button>
+            </div>
+          </b-overlay>
+        </ValidationObserver>
+
+        <ValidationObserver v-slot="{ handleSubmit }">
+          <b-overlay
+            :show="loadingUserPassword"
+            rounded="lg"
+            variant="white"
+            :style="'padding: 5px;'"
+          >
+            <form>
+              <h5>Changer votre mot de passe</h5>
+              <hr class="divider">
+              <div class="row g-2 align-items-center">
+                <div class="col-3" style="padding-right: 0;">
+                  <label class="col-form-label required" style="font-size: 0.9em;">Ancien mot de passe</label>
+                </div>
+                <div class="col">
+                  <ValidationProvider ref="password" rules="required" v-slot="{ classes, errors }">
+                    <div class="control" :class="classes">
+                      <div class="input-group flex-nowrap">
+                        <input
+                          v-model="formPassword.password"
+                          class="form-control"
+                          :type="showPassword ? 'text' : 'password'"
+                          placeholder="Ancien mot de passe"
+                        >
+                        <span
+                          v-if="!showPassword"
+                          class="input-group-text"
+                        >
+                          <b-icon
+                            icon="eye-fill"
+                            @click="showPassword = !showPassword"
+                          />
+                        </span>
+                        <span
+                          v-else
+                          class="input-group-text"
+                        >
+                          <b-icon
+                            icon="eye-slash-fill"
+                            @click="showPassword = !showPassword"
+                          />
+                        </span>
+                      </div>
+                      <span class="form-errors">{{ errors[0] }}</span>
+                    </div>
+                  </ValidationProvider>
+                </div>
+              </div>
+              <div class="row g-2 align-items-center">
+                <div class="col-3" style="padding-right: 0;">
+                  <label
+                    class="col-form-label required"
+                    style="font-size: 0.9em;">Nouveau mot de passe</label>
+                </div>
+                <div class="col">
+                  <ValidationProvider ref="newPassword1" v-slot="{ classes, errors }" vid="confirmation">
+                    <div class="control" :class="classes">
+                      <div class="input-group flex-nowrap">
+                        <input
+                          v-model="formPassword.newPassword1"
+                          :type="showNewPassword2 ? 'text' : 'password'"
+                          class="form-control"
+                          placeholder="Nouveau mot de passe"
+                        >
+                        <span
+                          v-if="!showNewPassword2"
+                          class="input-group-text"
+                        >
+                          <b-icon
+                            icon="eye-fill"
+                            @click="showNewPassword2 = !showNewPassword2"
+                          />
+                        </span>
+                        <span
+                          v-else
+                          class="input-group-text"
+                        >
+                          <b-icon
+                            icon="eye-slash-fill"
+                            @click="showNewPassword2 = !showNewPassword2"
+                          />
+                        </span>
+                      </div>
+                      <span class="form-errors">{{ errors[0] }}</span>
+                    </div>
+                  </ValidationProvider>
+                </div>
+              </div>
+              <div class="row g-2 align-items-center">
+                <div class="col-3" style="padding-right: 0;">
+                  <label
+                    class="col-form-label"
+                    style="font-size: 0.9em;"></label>
+                </div>
+                <div class="col">
+                  <ValidationProvider ref="newPassword2" rules="confirmed:confirmation" v-slot="{ classes, errors }">
+                    <div class="control" :class="classes">
+                      <div class="input-group flex-nowrap">
+                        <input
+                          v-model="formPassword.newPassword2"
+                          class="form-control"
+                          :type="showNewPassword2 ? 'text' : 'password'"
+                          placeholder="Confirmez le mot de passe"
+                        >
+                        <span
+                          v-if="!showNewPassword2"
+                          class="input-group-text"
+                        >
+                          <b-icon
+                            icon="eye-fill"
+                            @click="showNewPassword2 = !showNewPassword2"
+                          />
+                        </span>
+                        <span
+                          v-else
+                          class="input-group-text"
+                        >
+                          <b-icon
+                            icon="eye-slash-fill"
+                            @click="showNewPassword2 = !showNewPassword2"
+                          />
+                        </span>
+                      </div>
+                      <span class="form-errors">{{ errors[0] }}</span>
+                    </div>
+                  </ValidationProvider>
+                </div>
+              </div>
+              <div class="row g-2 align-items-center">
+                <div class="col-3">
+                </div>
+                <div class="col">
+                  <div class="infos">
+                    <ul>
+                      <li>Votre mot de passe ne peut pas trop ressembler à vos autres informations personnelles.</li>
+                      <li>Votre mot de passe doit contenir au minimum 8 caractères.</li>
+                      <li>Votre mot de passe ne peut pas être un mot de passe couramment utilisé.</li>
+                      <li>Votre mot de passe ne peut pas être entièrement numérique.</li>
+                    </ul>
+                  </div>
+                </div>
+              </div>
+            </form>
+            <div class="form-footer">
+              <b-button
+                :disabled="(!formPassword.password || !formPassword.newPassword1 || !formPassword.newPassword2)"
+                :pressed="btnPressed"
+                @click.prevent="handleSubmit(submitNewPassword)"
+                variant="primary"
+              >
+                Valider
+              </b-button>
+            </div>
+          </b-overlay>
+        </ValidationObserver>
+      </div>
+    </div>
+    <small class="footer">
+      <p>
+        Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a>
+      </p>
+    </small>
+  </div>
+</template>
+
+<script>
+import { mapState, mapMutations, mapActions } from 'vuex';
+
+import Swal from "sweetalert2";
+import "sweetalert2/dist/sweetalert2.min.css";
+
+import {
+  ValidationObserver,
+  ValidationProvider,
+  extend,
+  configure,
+} from 'vee-validate';
+
+import { required, email, confirmed } from 'vee-validate/dist/rules';
+
+extend('required', {
+  ...required,
+  message: 'Ce champ est requis',
+});
+
+extend('email', {
+  ...email,
+  message: 'Veuillez entrer une adresse e-mail valide',
+});
+
+extend('confirmed', {
+  ...confirmed,
+  message: 'Les mots de passe doivent être identiques',
+});
+
+configure({
+  classes: {
+    valid: 'is-valid',
+    invalid: 'is-invalid',
+  },
+});
+
+export default {
+  name: 'UserProfile',
+
+  components: {
+    ValidationObserver,
+    ValidationProvider,
+  },
+
+  data() {
+    return {
+      loadingUserInformation: false,
+      loadingUserPassword: false,
+      loadingUserEmail: false,
+      formUser: {
+        first_name: null,
+        last_name: null,
+        email: null,
+        phone_number: null,
+        comments: null,
+        username: null
+      },
+      formEmail: {
+        new_email: null
+      },
+      formPassword: {
+        password: null,
+        newPassword1: null,
+        newPassword2: null
+      },
+      isOrganisationSelected: false,
+      organisation: null,
+      btnPressed: false,
+      showPassword: false,
+      showNewPassword2: false,
+    };
+  },
+
+  computed: {
+    ...mapState('user', ['userData', 'success']),
+    ...mapState('organisations', ['organisationsRoles']),
+    ...mapState('sign-in', [
+      'next'
+    ])
+  },
+
+  created() {
+    this.SET_NEXT(this.$route.query.next || process.env.VUE_APP_NEXT_DEFAULT);
+    if (!this.userData) {
+      this.loadingUserInformation = true;
+      this.GET_USER_DETAIL()
+      .then(() => {
+        this.formUser = {
+          ...this.formUser,
+          ...this.userData
+        };
+        this.loadingUserInformation = false;
+      });
+    }
+    if (this.organisationsRoles.length === 0) {
+      this.GET_ORGANISATIONS_ROLES();
+    }
+  },
+
+  methods: {
+    ...mapMutations('sign-in', [
+      'SET_NEXT'
+    ]),
+    ...mapActions('user', [
+      'GET_USER_DETAIL',
+      'UPDATE_USER_DETAIL'
+    ]),
+    ...mapActions('organisations', [
+      'GET_ORGANISATIONS_ROLES'
+    ]),
+
+    goBackToNext() {
+      this.$router.push(this.$route.path);
+      window.location.pathname = this.next;
+    },
+
+    submitUserInformations() {
+      this.loadingUserInformation = true
+      this.UPDATE_USER_DETAIL(this.formUser)
+      .then(() => {
+        this.GET_USER_DETAIL()
+        .then(() => {
+          this.formUser = {
+            ...this.formUser,
+            ...this.userData
+          };
+          this.loadingUserInformation = false;
+        });
+      })
+      .catch(() => {
+        this.loadingUserInformation = false;
+      });
+    },
+
+    submitNewEmail() {
+      const data = {
+        new_email: this.formEmail.new_email,
+      };
+      this.loadingUserEmail = true;
+      this.UPDATE_USER_DETAIL(data)
+      .then(() => {
+        this.loadingUserEmail = false;
+        Swal.fire({
+          position: 'center',
+          heightAuto: false,
+          icon: 'success',
+          text: `Un e-mail est envoyé à votre nouvelle adresse. 
+            Il contient un lien de validation sur lequel vous devez 
+            cliquer pour confirmer le changement. 
+          `,
+          showConfirmButton: true,
+          confirmButtonText: 'OK',
+          confirmButtonColor: '#187CC6'
+        });
+      });
+    },
+
+    submitNewPassword() {
+      const data = {
+        password: this.formPassword.password,
+        new_password: this.formPassword.newPassword2
+      };
+      this.loadingUserPassword = true;
+      this.UPDATE_USER_DETAIL(data)
+      .then(() => {
+        this.loadingUserPassword = false;
+        if (this.success && this.success.length) {
+          Swal.fire({
+            position: 'center',
+            heightAuto: false,
+            icon: 'success',
+            text: `Votre mot de passe a bien été modifié.
+              Vous allez être redirigé vers la page de connexion.
+            `,
+            showConfirmButton: true,
+            confirmButtonText: 'OK',
+            confirmButtonColor: '#187CC6'
+          }).then((result) => {
+            if (result.isConfirmed) {
+              this.$router.push({ name: 'SignIn' });
+            }
+          });
+        }
+      });
+    }
+  }
+
+}
+</script>
+
+<style lang="less" scoped>
+
+#back-button {
+  font-size: 1.5em;
+  position: -webkit-sticky; /* Safari */
+  position: sticky;
+  top: 5%;
+  left: 40px;
+  align-self: flex-start;
+  border: 2px solid #9BD0FF;
+  border-radius: 8px;
+  letter-spacing: 1px;
+}
+
+.signup-container {
+  margin: auto;
+  width: 800px;
+  height: fit-content;
+
+  .signup-header {
+    margin: 0 1rem 1rem 1rem;
+    img {
+      width: 440px;
+    }
+  }
+
+  .signup-form {
+    margin: 5rem 1rem;
+
+    h4.title {
+      color: #373b3d;
+
+      .sub-title {
+        font-size: 75%;
+        color: #6b7479;
+      }
+    }
+
+    hr.solid {
+      border-top: 2px solid #373b3d;
+    }
+
+    h5 {
+      color: #6b7479;
+    }
+
+    form {
+      margin-top: 32px;
+
+      h5 {
+        margin-bottom: 20px;
+        margin-top: 40px;
+        color: #373b3d;
+      }
+
+      .row {
+        margin-bottom: 1.6rem;
+      }
+
+      .input-group {
+        span {
+          cursor: pointer;
+          border-bottom-left-radius: 0;
+          border-top-left-radius: 0;
+          border-left: none
+        }
+      }
+    }
+    .infos {
+      font-size: 0.7em;
+      font-style: italic;
+      margin-right: 1em;
+      ul {
+        padding-left: 1rem;
+      }
+    }
+    .form-footer {
+      display: flex;
+      justify-content: flex-end;
+      margin-left: 7px;
+      margin-top: 30px;
+      button {
+        margin-left: 2em;
+      }
+      button.btn-primary {
+        border: 2px solid #9BD0FF;
+        border-radius: 8px;
+      }
+      button.btn-outline-secondary {
+        background-color: #F7F8FA;
+        border: 2px solid #A9B2B9;
+        border-radius: 8px;
+        color: #2F3234;
+      }
+      button.btn-outline-secondary:hover {
+        color: white;
+        background-color: #4b4b4b;
+      }
+    }
+  }
+}
+
+.form-errors {
+  color: #EB0600 !important;
+}
+
+.form-success {
+  color: #30C963 !important;
+}
+
+.footer {
+  position: relative;
+  bottom: 0;
+  font-size: small;
+  margin-top: 2rem;
+}
+
+.footer a {
+  text-decoration: none;
+}
+</style>
diff --git a/src/views/ValidationEmail.vue b/src/views/ValidationEmail.vue
new file mode 100644
index 0000000..b73a7b1
--- /dev/null
+++ b/src/views/ValidationEmail.vue
@@ -0,0 +1,98 @@
+<template>
+  <div>
+    <div class="header">
+      <img alt="logo" src="@/assets/logo_pigma.png"/>
+    </div>
+    <div class="center">
+      <b-container class="msg" v-if="status">
+        <p>
+          Votre nouvelle adresse e-mail est validée.
+        </p>
+        <b-button
+          type="button"
+          variant="outline-primary"
+          @click.prevent="$router.push({ name: 'SignIn' })"
+        >
+          Ouvrir la page de connexion
+        </b-button>
+      </b-container>
+      <b-container class="msg" v-else>
+        <p>
+          Une erreur est survenue. Veuillez contacter l'administrateur du site.
+        </p>
+      </b-container>
+    </div>
+    <small class="footer">
+      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+    </small>
+  </div>
+</template>
+
+<script>
+
+import {
+  mapState,
+  mapActions,
+} from 'vuex';
+
+export default {
+  name: 'ValidationEmail',
+  data: () => {
+    return {
+    };
+  },
+  computed: {
+    ...mapState('validation-email', [
+      'status'
+    ])
+  },
+  created() {
+    this.POST_TOKEN(this.$route.query.token);
+  },
+  methods: {
+    ...mapActions('validation-email', [
+      'POST_TOKEN'
+    ])
+  }
+};
+</script>
+
+<style lang="less" scoped>
+.header {
+  position: absolute;
+  top: 0;
+  left: 0;
+}
+
+.header > img {
+  width: 440px;
+}
+
+.center {
+  position: initial;
+}
+
+.center .msg.container {
+  margin: 0;
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  text-align: center;
+}
+
+.center .msg.container,
+.center .msg.container button {
+  font-size: large;
+}
+
+.footer {
+  position: absolute;
+  bottom: 0;
+  font-size: small;
+}
+
+.footer a {
+  text-decoration: none;
+}
+</style>
diff --git a/src/views/ValidationRegistration.vue b/src/views/ValidationRegistration.vue
new file mode 100644
index 0000000..53dbcee
--- /dev/null
+++ b/src/views/ValidationRegistration.vue
@@ -0,0 +1,126 @@
+<template>
+  <div>
+    <div class="header">
+      <img alt="logo" src="@/assets/logo_pigma.png"/>
+    </div>
+    <div class="center">
+      <b-container class="msg" v-if="btnVariant=='success'">
+        <p>
+          Merci pour votre inscription.
+        </p>
+        <p>
+          Vous recevrez une notification lors de l'activation de votre compte par l'administrateur de la plateforme.
+        </p>
+        <!-- <b-button type="button" variant="outline-primary" @click.prevent="$router.push({ name: 'SignIn' })">
+          Ouvrir la page de connexion
+        </b-button> -->
+      </b-container>
+      <b-container class="msg" v-else-if="btnVariant=='danger'">
+        <p>
+          Une erreur est survenue. Veuillez contacter l'administrateur du site.
+        </p>
+      </b-container>
+      <b-container class="msg" v-else>
+        <p>
+          Pour confirmer votre inscription <b-button :pressed="btnPressed" :variant="btnVariant" @click.prevent="submit">Cliquez ici</b-button>
+        </p>
+      </b-container>
+    </div>
+    <small class="footer">
+      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+    </small>
+  </div>
+</template>
+
+<script>
+
+import {
+  mapGetters,
+  mapState,
+  mapActions,
+  mapMutations
+} from 'vuex';
+
+const validationRegistrationStoreName = 'validation-registration';
+
+const validationRegistrationGetters = {
+  status: 'getStatus',
+};
+
+const validationRegistrationState = ['accountStatus'];
+const validationRegistrationMutations = ['SET_TOKEN'];
+const validationRegistrationActions = ['POST_TOKEN'];
+
+export default {
+  name: 'ValidationRegistration',
+  data: () => {
+    return {
+      btnPressed: false,
+    };
+  },
+  computed: {
+    ...mapState(validationRegistrationStoreName, validationRegistrationState),
+    ...mapGetters(validationRegistrationStoreName, validationRegistrationGetters),
+    btnVariant() {
+      if (this.status === true) {
+        return 'success';
+      } else if (this.status === false) {
+        return 'danger';
+      } else {
+        return '';
+      }
+    },
+  },
+  created() {
+    this.$store.commit('validation-registration/SET_TOKEN', this.$route.query.token);
+  },
+  methods: {
+    ...mapActions(validationRegistrationStoreName, validationRegistrationActions),
+    ...mapMutations(validationRegistrationStoreName, validationRegistrationMutations),
+    async submit() {
+      this.btnPressed = true;
+      await this.$store.dispatch('validation-registration/POST_TOKEN');
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.header {
+  position: absolute;
+  top: 0;
+  left: 0;
+}
+
+.header > img {
+  width: 440px;
+}
+
+.center {
+  position: initial;
+}
+
+.center .msg.container {
+  margin: 0;
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  text-align: center;
+}
+
+.center .msg.container,
+.center .msg.container button {
+  font-size: large;
+}
+
+.footer {
+  position: absolute;
+  bottom: 0;
+  font-size: small;
+}
+
+.footer a {
+  text-decoration: none;
+}
+</style>
diff --git a/tests/e2e/.eslintrc.js b/tests/e2e/.eslintrc.js
new file mode 100644
index 0000000..25e20e8
--- /dev/null
+++ b/tests/e2e/.eslintrc.js
@@ -0,0 +1,12 @@
+module.exports = {
+  plugins: [
+    'cypress',
+  ],
+  env: {
+    mocha: true,
+    'cypress/globals': true,
+  },
+  rules: {
+    strict: 'off',
+  },
+};
diff --git a/tests/e2e/plugins/index.js b/tests/e2e/plugins/index.js
new file mode 100644
index 0000000..8be9bc3
--- /dev/null
+++ b/tests/e2e/plugins/index.js
@@ -0,0 +1,26 @@
+/* eslint-disable arrow-body-style */
+// https://docs.cypress.io/guides/guides/plugins-guide.html
+
+// if you need a custom webpack configuration you can uncomment the following import
+// and then use the `file:preprocessor` event
+// as explained in the cypress docs
+// https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples
+
+// /* eslint-disable import/no-extraneous-dependencies, global-require */
+// const webpack = require('@cypress/webpack-preprocessor')
+
+module.exports = (on, config) => {
+  // on('file:preprocessor', webpack({
+  //  webpackOptions: require('@vue/cli-service/webpack.config'),
+  //  watchOptions: {}
+  // }))
+
+  return {
+    ...config,
+    fixturesFolder: 'tests/e2e/fixtures',
+    integrationFolder: 'tests/e2e/specs',
+    screenshotsFolder: 'tests/e2e/screenshots',
+    videosFolder: 'tests/e2e/videos',
+    supportFile: 'tests/e2e/support/index.js',
+  };
+};
diff --git a/tests/e2e/specs/test.js b/tests/e2e/specs/test.js
new file mode 100644
index 0000000..e6c9471
--- /dev/null
+++ b/tests/e2e/specs/test.js
@@ -0,0 +1,8 @@
+// https://docs.cypress.io/api/introduction/api.html
+
+describe('My First Test', () => {
+  it('Visits the app root url', () => {
+    cy.visit('/');
+    cy.contains('h1', 'Welcome to Your Vue.js App');
+  });
+});
diff --git a/tests/e2e/support/commands.js b/tests/e2e/support/commands.js
new file mode 100644
index 0000000..c1f5a77
--- /dev/null
+++ b/tests/e2e/support/commands.js
@@ -0,0 +1,25 @@
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add("login", (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This is will overwrite an existing command --
+// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
diff --git a/tests/e2e/support/index.js b/tests/e2e/support/index.js
new file mode 100644
index 0000000..37a498f
--- /dev/null
+++ b/tests/e2e/support/index.js
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands';
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/tests/unit/example.spec.js b/tests/unit/example.spec.js
new file mode 100644
index 0000000..6fa693d
--- /dev/null
+++ b/tests/unit/example.spec.js
@@ -0,0 +1,12 @@
+import { shallowMount } from '@vue/test-utils';
+import HelloWorld from '@/components/HelloWorld.vue';
+
+describe('HelloWorld.vue', () => {
+  it('renders props.msg when passed', () => {
+    const msg = 'new message';
+    const wrapper = shallowMount(HelloWorld, {
+      propsData: { msg },
+    });
+    expect(wrapper.text()).toMatch(msg);
+  });
+});
diff --git a/vue.config.js b/vue.config.js
new file mode 100644
index 0000000..0aeb41b
--- /dev/null
+++ b/vue.config.js
@@ -0,0 +1,15 @@
+module.exports = {
+  publicPath: process.env.VUE_APP_BASE_PATH || '/',
+  transpileDependencies: ['vuetify'],
+  lintOnSave: false,
+  css: {
+    loaderOptions: {
+      less: {
+        globalVars: {
+          blue: '#187CC6',
+          lightBlue: '#9BD0FF',
+        },
+      },
+    },
+  },
+};
-- 
GitLab