From 78516e5f8d68c24f789f363266d39f20151ea1a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timoth=C3=A9e=20Poussard?= <tpoussard@neogeo.fr>
Date: Mon, 26 Jul 2021 17:51:11 +0200
Subject: [PATCH] Get back previous page after login & add page project create
 an type list

---
 .env                                    |  26 ---
 src/App.vue                             |  23 +--
 src/router/index.js                     |  42 +++-
 src/store/index.js                      |  31 +--
 src/views/Index.vue                     |   5 +-
 src/views/My_account.vue                | 263 ++++++++++++++++++++++++
 src/views/project/Project_create.vue    |  13 +-
 src/views/project/Project_detail.vue    |   2 +-
 src/views/project/Project_type_list.vue |  69 +++++++
 9 files changed, 407 insertions(+), 67 deletions(-)
 delete mode 100644 .env
 create mode 100644 src/views/My_account.vue
 create mode 100644 src/views/project/Project_type_list.vue

diff --git a/.env b/.env
deleted file mode 100644
index 446e5e7e..00000000
--- a/.env
+++ /dev/null
@@ -1,26 +0,0 @@
-NODE_ENV=development
-VUE_APP_LOCALE=fr-FR
-
-DOMAIN=https://localhost:8000/api
-
-VUE_APP_ROOT_PATH=
-VUE_APP_NEXT_DEFAULT=/
-
-# API
-VUE_APP_LOGIN_API=${DOMAIN}/login
-
-# VUE_APP_ORGANISATION_API=${DOMAIN}/organisation/
-# VUE_APP_USERGROUP_API=${DOMAIN}/usergroup/
-
-
-# AUTH
-VUE_APP_LOGIN_API_USERNAME=admin
-VUE_APP_LOGIN_API_PASSWORD=admin
-
-
-VUE_APP_BASE_URL=http://localhost:8080/
-VUE_APP_APPLICATION_NAME=GéoContrib
-VUE_APP_APPLICATION_ABSTRACT=Application de saisie d'informations géographiques contributive
-VUE_APP_LOGO_PATH=@/assets/img/logo-neogeo-circle.png
-
-# VUE_APP_DJANGO_API_BASE=https://tim.geocontrib.dev.neogeo.fr/api/projects/
\ No newline at end of file
diff --git a/src/App.vue b/src/App.vue
index 25ea46cb..44f16ecb 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -67,16 +67,12 @@
 
           <div class="right menu">
             <!--  // todo : create my_account page + endpoint + router -->
-            <a
-              v-if="user"
-              class="item"
-              href="{% url 'geocontrib:my_account' %}"
-            >
-              {{ user.full_name || user.username
-              }}<!-- // ? full_name n'existe pas côté django... -->
-            </a>
-            <div v-if="project || user.is_administrator" class="item ui label">
-              <span v-if="project"> {{ USER_LEVEL_PROJECT }}</span
+            <router-link v-if="user" to="/my_account/" class="item">
+              {{ user.full_name || user.username }}
+              <!-- // ? full_name n'existe pas côté django... -->
+            </router-link>
+            <div v-if="project && user.is_administrator" class="item ui label">
+              <span v-if="project"> {{ USER_LEVEL_PROJECTS }}</span
               ><br />
               <span v-if="user.is_administrator"> Gestionnaire métier </span>
             </div>
@@ -149,14 +145,17 @@ export default {
     LOGO_PATH: () => process.env.VUE_APP_LOGO_PATH,
     APPLICATION_NAME: () => process.env.VUE_APP_APPLICATION_NAME,
     PACKAGE_VERSION: () => process.env.PACKAGE_VERSION || "0",
-    USER_LEVEL_PROJECT: () => this.USER_LEVEL_PROJECTS
+    /* USER_LEVEL_PROJECT: function() {
+      return this.USER_LEVEL_PROJECTS.filter(item => item)
+    } */
   },
   created() {
     this.$store.dispatch("GET_COOKIE", "csrftoken"); // * ne récupère plus le cookie arès avoir vidé le cache ?!
   },
   methods: {
     logout() {
-      this.$store.commit("SET_USER", false)
+      console.log("!")
+      this.$store.dispatch("LOGOUT");
     },
   },
 };
diff --git a/src/router/index.js b/src/router/index.js
index b285aa4e..918c21fe 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -11,23 +11,29 @@ const routes = [
     component: Index
   },
   {
-    path: '/mentions/',
-    name: 'Mentions',
+    path: '/connexion/',
+    name: 'Login',
     // route level code-splitting
     // this generates a separate chunk (login.[hash].js) for this route
     // which is lazy-loaded when the route is visited.
-    component: () => import(/* webpackChunkName: "login" */ '../views/flatpages/with_right_menu.vue')
+    component: () => import(/* webpackChunkName: "login" */'../views/registration/Login.vue')
+  },
+  {
+    path: '/my_account/',
+    name: 'My_account',
+    component: () => import('../views/My_account.vue')
+  },
+  {
+    path: '/mentions/',
+    name: 'Mentions',
+    component: () => import('../views/flatpages/with_right_menu.vue')
   },
   {
     path: '/aide/',
     name: 'Aide',
     component: () => import('../views/flatpages/Default.vue')
   },
-  {
-    path: '/connexion/',
-    name: 'Login',
-    component: () => import('../views/registration/Login.vue')
-  },
+  // * PROJECTS
   {
     path: '/projet/:slug',
     name: 'Project_detail',
@@ -40,12 +46,30 @@ const routes = [
     props: true,
     component: () => import('../views/project/Project_create.vue')
   },
+  {
+    path: '/Project_type_list/',
+    name: 'Project_type_list',
+    props: true,
+    component: () => import('../views/project/Project_type_list.vue')
+  },
 ]
+//let routerHistory = [];
 
 const router = new VueRouter({
   mode: 'history',
   base: process.env.BASE_URL,
-  routes
+  routes,
+  routerHistory: [],
+  scrollBehavior(to, from, savedPosition) {
+    const fromHistory = Boolean(savedPosition);
+
+    if (fromHistory && this.options.routerHistory.length > 0) {
+      this.options.routerHistory.splice(-1, 1);
+    } else {
+      this.options.routerHistory.push(from);
+    }
+    return savedPosition || { x: 0, y: 0 };
+  },
 })
 
 export default router
diff --git a/src/store/index.js b/src/store/index.js
index 18c26424..52b071ce 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -22,7 +22,7 @@ const SET_STATIC_PAGES = SET_STATIC_PAGES; */
 //  })('csrftoken');
 //}
 
-
+const DJANGO_API_BASE = process.env.VUE_APP_DJANGO_API_BASE
 
 export default new Vuex.Store({
   //  modules,
@@ -35,7 +35,7 @@ export default new Vuex.Store({
     projects: [],
     staticPages: null,
     SSO_SETTED: false,
-    USER_LEVEL_PROJECTS: "Administrateur projet"
+    USER_LEVEL_PROJECTS: null
   },
 
   mutations: {
@@ -75,7 +75,7 @@ export default new Vuex.Store({
         return new Date(dateArr[0], dateArr[1] - 1, dateArr[2])
       }
       await axios
-        .get("http://localhost:8000/api/projects/")
+        .get(`${DJANGO_API_BASE}projects/`)
         .then((response) => {
           const orderedProjects = response.data.sort((a, b) => parseDate(b.created_on) - parseDate(a.created_on));
           commit("SET_PROJECTS", orderedProjects)
@@ -86,7 +86,7 @@ export default new Vuex.Store({
     },
     async GET_STATIC_PAGES({ commit }) {
       await axios
-        .get("http://localhost:8000/api/aide/")
+        .get(`${DJANGO_API_BASE}aide/`)
         .then((response) => (commit("SET_STATIC_PAGES", response.data)))
         .catch((error) => {
           throw error;
@@ -95,12 +95,13 @@ export default new Vuex.Store({
     LOGIN({ commit, dispatch }, payload) {
       if (payload.username && payload.password) {
         axios
-          .post("http://localhost:8000/api/login/", {
+          .post(`${DJANGO_API_BASE}login/`, {
             username: payload.username,
             password: payload.password,
           })
           .then((response) => {
-            commit("SET_USER", response.data.user), router.push("/"); // todo: get back to last page
+            const routerHistory = router.options.routerHistory // * use store previous route to go back after login
+            commit("SET_USER", response.data.user), router.push(routerHistory[routerHistory.length - 1] || "/"); // todo: get back to original page
             dispatch("GET_USER_LEVEL_PROJECTS");
           })
           .catch((error) => {
@@ -110,17 +111,23 @@ export default new Vuex.Store({
       }
     },
 
+    LOGOUT({ commit }) {
+      commit("SET_USER", false) // ? better false or null
+      commit("SET_USER_LEVEL_PROJECTS", null)
+    },
+
     GET_USER_LEVEL_PROJECTS({ commit }) {
-      axios
-        .get(`http://localhost:8000/api/user_level_project/`)
-        .then((response) => (commit("SET_USER_LEVEL_PROJECTS", response)))
+      commit("SET_USER_LEVEL_PROJECTS", "Administrateur projet") // todo : use authentification)
+      /* axios
+        .get(`${DJANGO_API_BASE}user_level_project/`)
+        .then((response) => (commit("SET_USER_LEVEL_PROJECTS", response.data)))
         .catch((error) => {
           throw error;
-        });
+        }); */
     },
     GET_PROJECT({ commit }, project_slug) {
       axios
-        .get(`http://localhost:8000/api/projet/${project_slug}/project`)
+        .get(`${DJANGO_API_BASE}projet/${project_slug}/project`)
         .then((response) => commit("SET_PROJECT", response.data))
         .catch((error) => {
           throw error;
@@ -128,7 +135,7 @@ export default new Vuex.Store({
     },
     GET_PROJECT_USER({ commit }, project_slug) {
       axios
-        .get(`http://localhost:8000/api/projet/${project_slug}/utilisateurs`)
+        .get(`${DJANGO_API_BASE}projet/${project_slug}/utilisateurs`)
         .then((response) => (commit("SET_PROJECT_MEMBERS", response.data.members)))
         .catch((error) => {
           throw error;
diff --git a/src/views/Index.vue b/src/views/Index.vue
index 52b88c43..624f034d 100644
--- a/src/views/Index.vue
+++ b/src/views/Index.vue
@@ -20,9 +20,10 @@
       <i class="plus icon"></i> Créer un nouveau projet
     </router-link>
     <!-- //todo : get base url and add the rest -->
-    <a class="ui blue basic button right floated" href="#">
+    <router-link to="Project_type_list" class="ui blue basic button right floated">
+    <!-- <a class="ui blue basic button right floated" href="#"> -->
       <i class="copy icon"></i> Accéder à la liste des modèles de projets
-    </a>
+    </router-link>
     <!-- {% endif %} -->
     <div v-if="projects" class="ui divided items">
       <div v-for="project in projects" class="item" :key="project.slug">
diff --git a/src/views/My_account.vue b/src/views/My_account.vue
new file mode 100644
index 00000000..59e1d51b
--- /dev/null
+++ b/src/views/My_account.vue
@@ -0,0 +1,263 @@
+<template>
+  <div v-frag>
+    <div class="fourteen wide column">
+      <h1>Mon compte</h1>
+    </div>
+
+    <div class="row">
+      <div class="five wide column">
+        <h4 class="ui horizontal divider header">PROFIL</h4>
+        <div class="ui divided list">
+          <div class="item">
+            <div class="right floated content">
+              <div class="description">
+                <span v-if="user.username">{{ user.username }} </span>
+              </div>
+            </div>
+            <div class="content">Nom d'utilisateur</div>
+          </div>
+          <div class="item">
+            <div class="right floated content">
+              <div class="description">
+                {% if user.get_full_name %}{{ user.get_full_name }}{% endif %}
+              </div>
+            </div>
+            <div class="content">Nom complet</div>
+          </div>
+          <div class="item">
+            <div class="right floated content">
+              <div class="description">
+                {% if user.email %}{{ user.email }}{% endif %}
+              </div>
+            </div>
+            <div class="content">Adresse e-mail</div>
+          </div>
+          <div class="item">
+            <div class="right floated content">
+              <div class="description">
+                {% if user.is_superuser %}Oui{% else %}Non{% endif %}
+              </div>
+            </div>
+            <div class="content">Administrateur</div>
+          </div>
+        </div>
+      </div>
+
+      <div class="nine wide column">
+        <h4 class="ui horizontal divider header">MES PROJETS</h4>
+
+        <div class="ui divided items">
+          {% for project in projects %} {% if permissions|lookup:project.slug %}
+          <div v-for="project in projects" :key="project.slug" class="item">
+            <div class="ui tiny image">
+              {% if project.thumbnail %}
+              <img
+                class="ui small image"
+                :src="
+                  project.thumbnail.includes('default')
+                    ? require('@/assets/img/default.png')
+                    : project.thumbnail
+                "
+                height="200"
+              />
+              {% endif %}
+            </div>
+            <div class="middle aligned content">
+              <a class="header" href="'geocontrib:project' slug=project.slug">
+                {{ project.title }}
+              </a>
+              <div class="description">
+                <p>{{ project.description }}</p>
+              </div>
+              <div class="meta">
+                <span class="right floated"
+                  >{% if project.moderation%}Projet modéré {% else %} Projet non
+                  modéré {% endif %}</span
+                >
+                <span
+                  >Niveau d'autorisation requis :
+                  {{ project.access_level_pub_feature }}</span
+                ><br />
+                <span>
+                  Mon niveau d'autorisation :
+                  {{ USER_LEVEL_PROJECTS }}
+                  <!-- |lookup:project.slug -->
+                  {% if user.is_administrator == True %} + Gestionnaire métier{%
+                  endif %}
+                </span>
+              </div>
+              <div class="meta">
+                <span
+                  class="right floated"
+                  :data-tooltip="`Projet créé le ${project.created_on}`"
+                >
+                  <i class="calendar icon"></i>&nbsp;{{ project.created_on }}
+                </span>
+                <span data-tooltip="Membres">
+                  {{ project.nb_contributors }}&nbsp;<i class="user icon"></i>
+                </span>
+                <span data-tooltip="Signalements">
+                  {{ project.nb_published_features }}&nbsp;<i
+                    class="map marker icon"
+                  ></i>
+                </span>
+                <span data-tooltip="Commentaires">
+                  {{ project.nb_published_features_comments }}&nbsp;<i
+                    class="comment icon"
+                  ></i>
+                </span>
+              </div>
+            </div>
+          </div>
+          {% endif %} {% endfor %}
+        </div>
+      </div>
+    </div>
+
+    <div class="row">
+      <div class="fourteen wide column">
+        <div class="ui three stackable cards">
+          <div class="red card">
+            <div class="content">
+              <div class="center aligned header">
+                Mes dernières notifications reçues
+              </div>
+              <div class="center aligned description">
+                <div class="ui relaxed list">
+                  <div v-for="item in events" :key="item.id" class="item">
+                    <div class="content">
+                      <div>
+                        {% if item.event_type == 'create' %} {% if
+                        item.object_type == 'feature' %}
+                        <a :href="item.related_feature.feature_url">
+                          Signalement créé
+                        </a>
+                        {% elif item.object_type == 'comment' %}
+                        <a :href="item.related_feature.feature_url">
+                          Commentaire créé
+                        </a>
+                        {% elif item.object_type == 'attachment' %}
+                        <a :href="item.related_feature.feature_url">
+                          Pièce jointe ajoutée
+                        </a>
+                        {% elif item.object_type == 'project' %}
+                        <a :href="item.project_url"> Projet créé </a>
+                        {% endif %} {% elif item.event_type == 'update' %} {% if
+                        item.object_type == 'feature' %}
+                        <a :href="item.related_feature.project_url">
+                          Signalement mis à jour
+                        </a>
+                        {% elif item.object_type == 'project' %}
+                        <a :href="item.project_url"> Projet mis à jour </a>
+                        {% endif %} {% elif item.event_type == 'delete' %} {% if
+                        item.object_type == 'feature' %} Signalement supprimé
+                        ({{ item.data.feature_title }}) {% endif %} {% else %}
+                        <i>Événement inconnu</i>
+                        {% endif %}
+                      </div>
+                      <div class="description">
+                        <i
+                          >[ {{ item.created_on }}{% if user.is_authenticated
+                          %}, par {{ item.display_user }}{% endif %} ]</i
+                        >
+                      </div>
+                    </div>
+                  </div>
+                  {% empty %}
+                  <i>Aucune notification pour le moment.</i>
+                  {% endfor %}
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="orange card">
+            <div class="content">
+              <div class="center aligned header">Mes derniers signalements</div>
+              <div class="center aligned description">
+                <div class="ui relaxed list">
+                  <div v-for="item in features" :key="item.id" class="item">
+                    <div class="content">
+                      <div>
+                        {% if item.related_feature %}
+                        <a :href="item.related_feature.feature_url">{{
+                          item.related_feature.title
+                        }}</a>
+                        {% else %}
+                        {{ item.data.feature_title }} (supprimé) {% endif %}
+                      </div>
+                      <div class="description">
+                        <i
+                          >[ {{ item.created_on }}{% if user.is_authenticated
+                          %}, par {{ item.display_user }}{% endif %} ]</i
+                        >
+                      </div>
+                    </div>
+                  </div>
+                  {% empty %}
+                  <i>Aucun signalement pour le moment.</i>
+                  {% endfor %}
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="yellow card">
+            <div class="content">
+              <div class="center aligned header">Mes derniers commentaires</div>
+              <div class="center aligned description">
+                <div class="ui relaxed list">
+                  <div v-for="item in comments" :key="item.id" class="item">
+                    <div class="content">
+                      <div>
+                        <a :href="item.related_feature.feature_url"
+                          >"{{ item.related_comment.comment }}"</a
+                        >
+                      </div>
+                      <div class="description">
+                        <i
+                          >[ {{ item.created_on }}{% if user.is_authenticated
+                          %}, par {{ item.display_user }}{% endif %} ]</i
+                        >
+                      </div>
+                    </div>
+                  </div>
+                  {% empty %}
+                  <i>Aucun commentaire pour le moment.</i>
+                  {% endfor %}
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import frag from "vue-frag";
+import { mapState } from "vuex";
+
+export default {
+  name: "My_account",
+
+  directives: {
+    frag,
+  },
+
+  data() {
+    return {
+      events: [],
+      features: [],
+      comments: [],
+    };
+  },
+
+  computed: {
+    // todo : filter projects to user
+    ...mapState(["user", "projects", "USER_LEVEL_PROJECTS"]),
+  },
+  mounted() {
+    console.log(this.$router.history)
+  },
+};
+</script>
\ No newline at end of file
diff --git a/src/views/project/Project_create.vue b/src/views/project/Project_create.vue
index 3038a1d6..7e59ef7c 100644
--- a/src/views/project/Project_create.vue
+++ b/src/views/project/Project_create.vue
@@ -73,9 +73,11 @@
         <label :for="form.description.id_for_label">{{
           form.description.label
         }}</label>
-        <textarea :name="form.description.html_name" rows="5">
-{% if form.description.value %} form.description.value {% endif %}</textarea
-        >
+        <textarea
+          v-model="form.description.value"
+          :name="form.description.html_name"
+          rows="5"
+        ></textarea>
         {{ form.description.errors }}
       </div>
 
@@ -134,7 +136,8 @@
               <div
                 class="item"
                 :data-value="
-                  x + (form.access_level_pub_feature.value === x ? selected : '')
+                  x +
+                  (form.access_level_pub_feature.value === x ? selected : '')
                 "
               >
                 y
@@ -272,7 +275,7 @@ export default {
         },
       },
       errors: null,
-      x: null
+      x: null,
     };
   },
 };
diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue
index d39f5ee1..9bcdbc0d 100644
--- a/src/views/project/Project_detail.vue
+++ b/src/views/project/Project_detail.vue
@@ -2,7 +2,7 @@
   <div v-frag v-if="project">
     <div class="row">
       <div class="four wide middle aligned column">
-        <img class="ui small spaced image" :src="project.thumbnail" />
+        <img class="ui small spaced image" :src="project.thumbnail.includes('default') ? require('@/assets/img/default.png') : project.thumbnail" />
         <div class="ui hidden divider"></div>
         <div class="ui basic teal label" data-tooltip="Membres">
           <i class="user icon"></i>{{ project.nb_contributors }}
diff --git a/src/views/project/Project_type_list.vue b/src/views/project/Project_type_list.vue
new file mode 100644
index 00000000..c85d4038
--- /dev/null
+++ b/src/views/project/Project_type_list.vue
@@ -0,0 +1,69 @@
+<template>
+  <div class="row">
+    <div class="seven wide column">
+      <h3 class="ui header">
+        Créer un projet à partir d'un modèle disponible:
+      </h3>
+      <div class="ui divided items">
+        <div v-for="project in projects" :key="project.slug" class="item">
+          <div class="ui tiny image">
+            <img :src="project.thumbnail" />
+          </div>
+          <div class="middle aligned content">
+            <div class="description">
+              <a
+                :href="`project_create?create_from=${project.slug}`"
+                >{{ project.title }}</a
+              >
+              <p>{{ project.description }}</p>
+              <strong v-if="project.moderation">Projet modéré</strong>
+              <strong v-else>Projet non modéré</strong>
+            </div>
+            <div class="meta">
+              <span data-tooltip="Délai avant archivage">
+                {{ project.archive_feature }}&nbsp;<i class="box icon"></i>
+              </span>
+              <span data-tooltip="Délai avant suppression">
+                {{ project.archive_feature }}&nbsp;<i
+                  class="trash alternate icon"
+                ></i>
+              </span>
+              <span data-tooltip="Date de création">
+                {{ project.created_on }}&nbsp;<i class="calendar icon"></i>
+              </span>
+            </div>
+            <div class="meta">
+              <span data-tooltip="Visibilité des signalement publiés">
+                {{ project.access_level_pub_feature }}&nbsp;<i
+                  class="eye icon"
+                ></i>
+              </span>
+              <span data-tooltip="Visibilité des signalement archivés">
+                {{ project.access_level_arch_feature }}&nbsp;<i
+                  class="archive icon"
+                ></i>
+              </span>
+            </div>
+          </div>
+        </div>
+        <span v-if="!projects || projects.length === 0">Aucun projet type n'est défini.</span>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState } from "vuex"
+// todo : récupérer les projets type
+export default {
+  name: "Project_type_list",
+  /* data() {
+    return {
+      projects: []
+    }
+  }, */
+  computed: {
+    ...mapState(["projects"])
+  }
+}
+</script>
\ No newline at end of file
-- 
GitLab