Browse Source

first own code, user can login/logout

bach 1 year ago
parent
commit
38958d20dd

+ 1 - 1
index.html

@@ -4,7 +4,7 @@
     <meta charset="UTF-8" />
     <link rel="icon" href="/favicon.ico" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Vite App</title>
+    <title>Où atterrir</title>
   </head>
   <body>
     <div id="app"></div>

+ 186 - 0
package-lock.json

@@ -16,9 +16,11 @@
         "@rushstack/eslint-patch": "^1.1.4",
         "@vitejs/plugin-vue": "^3.0.3",
         "@vue/eslint-config-prettier": "^7.0.0",
+        "axios": "^1.0.0",
         "eslint": "^8.22.0",
         "eslint-plugin-vue": "^9.3.0",
         "prettier": "^2.7.1",
+        "querystring-es3": "^0.2.1",
         "vite": "^3.0.9"
       }
     },
@@ -366,6 +368,23 @@
         "node": ">=8"
       }
     },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "dev": true
+    },
+    "node_modules/axios": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.0.0.tgz",
+      "integrity": "sha512-SsHsGFN1qNPFT5QhSoSD37SHDfGyLSW5AESmyLk2JeCMHv5g0I9g0Hz/zQHx2KNe0jGXh2q2hAm7OdkXm360CA==",
+      "dev": true,
+      "dependencies": {
+        "follow-redirects": "^1.15.0",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -443,6 +462,18 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -503,6 +534,15 @@
       "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
       "dev": true
     },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/dir-glob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -1238,6 +1278,40 @@
       "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
       "dev": true
     },
+    "node_modules/follow-redirects": {
+      "version": "1.15.2",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "dev": true,
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -1568,6 +1642,27 @@
         "node": ">=8.6"
       }
     },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dev": true,
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/minimatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -1864,6 +1959,12 @@
         "node": ">=6.0.0"
       }
     },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+      "dev": true
+    },
     "node_modules/punycode": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@@ -1873,6 +1974,15 @@
         "node": ">=6"
       }
     },
+    "node_modules/querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.x"
+      }
+    },
     "node_modules/queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -2578,6 +2688,23 @@
       "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
       "dev": true
     },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "dev": true
+    },
+    "axios": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.0.0.tgz",
+      "integrity": "sha512-SsHsGFN1qNPFT5QhSoSD37SHDfGyLSW5AESmyLk2JeCMHv5g0I9g0Hz/zQHx2KNe0jGXh2q2hAm7OdkXm360CA==",
+      "dev": true,
+      "requires": {
+        "follow-redirects": "^1.15.0",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
     "balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -2640,6 +2767,15 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2683,6 +2819,12 @@
       "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
       "dev": true
     },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "dev": true
+    },
     "dir-glob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -3134,6 +3276,23 @@
       "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
       "dev": true
     },
+    "follow-redirects": {
+      "version": "1.15.2",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+      "dev": true
+    },
+    "form-data": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "dev": true,
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      }
+    },
     "fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -3385,6 +3544,21 @@
         "picomatch": "^2.3.1"
       }
     },
+    "mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.52.0"
+      }
+    },
     "minimatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -3569,12 +3743,24 @@
         "fast-diff": "^1.1.2"
       }
     },
+    "proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+      "dev": true
+    },
     "punycode": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
       "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
       "dev": true
     },
+    "querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==",
+      "dev": true
+    },
     "queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",

+ 2 - 0
package.json

@@ -16,9 +16,11 @@
     "@rushstack/eslint-patch": "^1.1.4",
     "@vitejs/plugin-vue": "^3.0.3",
     "@vue/eslint-config-prettier": "^7.0.0",
+    "axios": "^1.0.0",
     "eslint": "^8.22.0",
     "eslint-plugin-vue": "^9.3.0",
     "prettier": "^2.7.1",
+    "querystring-es3": "^0.2.1",
     "vite": "^3.0.9"
   }
 }

+ 18 - 73
src/App.vue

@@ -1,85 +1,30 @@
+
+
 <script setup>
-import { RouterLink, RouterView } from 'vue-router'
-import HelloWorld from './components/HelloWorld.vue'
+  import { onMounted } from 'vue';
+  import { RouterLink, RouterView } from 'vue-router'
+  import { UserStore } from '@/stores/user'
+  import UserBlock from '@components/block/UserBlock.vue'
+
+
+  const userStore = UserStore()
+
+  onMounted(() => {
+    console.log('APP onBeforeMount')
+    userStore.checkUser()
+  })
+
+
 </script>
 
 <template>
   <header>
-    <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />
-
-    <div class="wrapper">
-      <HelloWorld msg="You did it!" />
-
-      <nav>
-        <RouterLink to="/">Home</RouterLink>
-        <RouterLink to="/about">About</RouterLink>
-      </nav>
-    </div>
+    <h1>Où atterrir</h1>
+    <UserBlock/>
   </header>
 
   <RouterView />
 </template>
 
 <style scoped>
-header {
-  line-height: 1.5;
-  max-height: 100vh;
-}
-
-.logo {
-  display: block;
-  margin: 0 auto 2rem;
-}
-
-nav {
-  width: 100%;
-  font-size: 12px;
-  text-align: center;
-  margin-top: 2rem;
-}
-
-nav a.router-link-exact-active {
-  color: var(--color-text);
-}
-
-nav a.router-link-exact-active:hover {
-  background-color: transparent;
-}
-
-nav a {
-  display: inline-block;
-  padding: 0 1rem;
-  border-left: 1px solid var(--color-border);
-}
-
-nav a:first-of-type {
-  border: 0;
-}
-
-@media (min-width: 1024px) {
-  header {
-    display: flex;
-    place-items: center;
-    padding-right: calc(var(--section-gap) / 2);
-  }
-
-  .logo {
-    margin: 0 2rem 0 0;
-  }
-
-  header .wrapper {
-    display: flex;
-    place-items: flex-start;
-    flex-wrap: wrap;
-  }
-
-  nav {
-    text-align: left;
-    margin-left: -1rem;
-    font-size: 1rem;
-
-    padding: 1rem 0;
-    margin-top: 1rem;
-  }
-}
 </style>

+ 33 - 0
src/api/graphql-axios.js

@@ -0,0 +1,33 @@
+import axios from 'axios'
+
+// https://github.com/alvar0hurtad0/drupal-vuejs-todo/blob/master/frontend/src/api/axiosInterceptor.js
+
+// console.log('drupalSettings', drupalSettings)
+console.log(window.location)
+
+const MGQ = axios.create({
+  baseURL: `${window.location.origin}/api/mgq`,
+  withCredentials: true,
+  headers: {
+    Accept: 'application/json',
+    // Accept: 'application/vnd.api+json'
+    // Authorization: 'Basic {token}',
+    'Content-Type': 'application/json'
+  }
+})
+
+MGQ.interceptors.response.use(
+  response => {
+    return Promise.resolve(response)
+  },
+  error => {
+    const { status } = error.response
+    console.warn('error in graphql-axios', status)
+    // if (status === 403) {
+    //   window.location = '/'
+    // }
+    return Promise.reject(error)
+  }
+)
+
+export default MGQ

+ 32 - 0
src/api/json-axios.js

@@ -0,0 +1,32 @@
+import axios from 'axios'
+
+// https://github.com/alvar0hurtad0/drupal-vuejs-todo/blob/master/frontend/src/api/axiosInterceptor.js
+
+// console.log('drupalSettings', drupalSettings)
+console.log(window.location)
+
+const JSONAPI = axios.create({
+  baseURL: `${window.location.origin}/api/jsonapi`,
+  withCredentials: true,
+  headers: {
+    Accept: 'application/vnd.api+json'
+    // Authorization: 'Basic {token}',
+    // 'Content-Type': 'application/json'
+  }
+})
+
+JSONAPI.interceptors.response.use(
+  response => {
+    return Promise.resolve(response)
+  },
+  error => {
+    const { status } = error.response
+    console.warn('error in json-axios', status)
+    // if (status === 403) {
+    //   window.location = '/'
+    // }
+    return Promise.reject(error)
+  }
+)
+
+export default JSONAPI

+ 45 - 0
src/api/rest-axios.js

@@ -0,0 +1,45 @@
+import axios from 'axios'
+
+// https://github.com/alvar0hurtad0/drupal-vuejs-todo/blob/master/frontend/src/api/axiosInterceptor.js
+
+// console.log('drupalSettings', drupalSettings)
+// console.log('window.location.origin', window.location.origin)
+
+// axios.interceptors.response.use(
+//   response => {
+//     return Promise.resolve(response)
+//   },
+//   error => {
+//     const { status } = error.response
+//     console.warn('error in rest-axios', status)
+//     if (status === 403) {
+//       window.location = '/'
+//     }
+//     return Promise.reject(error)
+//   }
+// )
+
+const REST = axios.create({
+  baseURL: `${window.location.origin}/api`,
+  withCredentials: true,
+  headers: {
+    // Authorization: 'Bearer {token}',
+    'Content-Type': 'application/json'
+  }
+})
+
+REST.interceptors.response.use(
+  response => {
+    return Promise.resolve(response)
+  },
+  error => {
+    const { status } = error.response
+    console.warn('error in rest-axios', status)
+    // if (status === 403) {
+    //   window.location = '/'
+    // }
+    return Promise.reject(error)
+  }
+)
+
+export default REST

+ 3 - 74
src/assets/base.css

@@ -1,74 +1,3 @@
-/* color palette from <https://github.com/vuejs/theme> */
-:root {
-  --vt-c-white: #ffffff;
-  --vt-c-white-soft: #f8f8f8;
-  --vt-c-white-mute: #f2f2f2;
-
-  --vt-c-black: #181818;
-  --vt-c-black-soft: #222222;
-  --vt-c-black-mute: #282828;
-
-  --vt-c-indigo: #2c3e50;
-
-  --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
-  --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
-  --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
-  --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
-
-  --vt-c-text-light-1: var(--vt-c-indigo);
-  --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
-  --vt-c-text-dark-1: var(--vt-c-white);
-  --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
-}
-
-/* semantic color variables for this project */
-:root {
-  --color-background: var(--vt-c-white);
-  --color-background-soft: var(--vt-c-white-soft);
-  --color-background-mute: var(--vt-c-white-mute);
-
-  --color-border: var(--vt-c-divider-light-2);
-  --color-border-hover: var(--vt-c-divider-light-1);
-
-  --color-heading: var(--vt-c-text-light-1);
-  --color-text: var(--vt-c-text-light-1);
-
-  --section-gap: 160px;
-}
-
-@media (prefers-color-scheme: dark) {
-  :root {
-    --color-background: var(--vt-c-black);
-    --color-background-soft: var(--vt-c-black-soft);
-    --color-background-mute: var(--vt-c-black-mute);
-
-    --color-border: var(--vt-c-divider-dark-2);
-    --color-border-hover: var(--vt-c-divider-dark-1);
-
-    --color-heading: var(--vt-c-text-dark-1);
-    --color-text: var(--vt-c-text-dark-2);
-  }
-}
-
-*,
-*::before,
-*::after {
-  box-sizing: border-box;
-  margin: 0;
-  position: relative;
-  font-weight: normal;
-}
-
-body {
-  min-height: 100vh;
-  color: var(--color-text);
-  background: var(--color-background);
-  transition: color 0.5s, background-color 0.5s;
-  line-height: 1.6;
-  font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
-    Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-  font-size: 15px;
-  text-rendering: optimizeLegibility;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-}
+body{
+  font-size: 16px;
+}

+ 0 - 25
src/assets/main.css

@@ -8,28 +8,3 @@
   font-weight: normal;
 }
 
-a,
-.green {
-  text-decoration: none;
-  color: hsla(160, 100%, 37%, 1);
-  transition: 0.4s;
-}
-
-@media (hover: hover) {
-  a:hover {
-    background-color: hsla(160, 100%, 37%, 0.2);
-  }
-}
-
-@media (min-width: 1024px) {
-  body {
-    display: flex;
-    place-items: center;
-  }
-
-  #app {
-    display: grid;
-    grid-template-columns: 1fr 1fr;
-    padding: 0 2rem;
-  }
-}

+ 0 - 43
src/components/HelloWorld.vue

@@ -1,43 +0,0 @@
-<script setup>
-defineProps({
-  msg: {
-    type: String,
-    required: true
-  }
-})
-</script>
-
-<template>
-  <div class="greetings">
-    <h1 class="green">{{ msg }}</h1>
-    <h3>
-      You’ve successfully created a project with
-      <a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> +
-      <a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>.
-    </h3>
-  </div>
-</template>
-
-<style scoped>
-h1 {
-  font-weight: 500;
-  font-size: 2.6rem;
-  top: -10px;
-}
-
-h3 {
-  font-size: 1.2rem;
-}
-
-.greetings h1,
-.greetings h3 {
-  text-align: center;
-}
-
-@media (min-width: 1024px) {
-  .greetings h1,
-  .greetings h3 {
-    text-align: left;
-  }
-}
-</style>

+ 0 - 86
src/components/TheWelcome.vue

@@ -1,86 +0,0 @@
-<script setup>
-import WelcomeItem from './WelcomeItem.vue'
-import DocumentationIcon from './icons/IconDocumentation.vue'
-import ToolingIcon from './icons/IconTooling.vue'
-import EcosystemIcon from './icons/IconEcosystem.vue'
-import CommunityIcon from './icons/IconCommunity.vue'
-import SupportIcon from './icons/IconSupport.vue'
-</script>
-
-<template>
-  <WelcomeItem>
-    <template #icon>
-      <DocumentationIcon />
-    </template>
-    <template #heading>Documentation</template>
-
-    Vue’s
-    <a href="https://vuejs.org/" target="_blank" rel="noopener">official documentation</a>
-    provides you with all information you need to get started.
-  </WelcomeItem>
-
-  <WelcomeItem>
-    <template #icon>
-      <ToolingIcon />
-    </template>
-    <template #heading>Tooling</template>
-
-    This project is served and bundled with
-    <a href="https://vitejs.dev/guide/features.html" target="_blank" rel="noopener">Vite</a>. The
-    recommended IDE setup is
-    <a href="https://code.visualstudio.com/" target="_blank" rel="noopener">VSCode</a> +
-    <a href="https://github.com/johnsoncodehk/volar" target="_blank" rel="noopener">Volar</a>. If
-    you need to test your components and web pages, check out
-    <a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a> and
-    <a href="https://on.cypress.io/component" target="_blank">Cypress Component Testing</a>.
-
-    <br />
-
-    More instructions are available in <code>README.md</code>.
-  </WelcomeItem>
-
-  <WelcomeItem>
-    <template #icon>
-      <EcosystemIcon />
-    </template>
-    <template #heading>Ecosystem</template>
-
-    Get official tools and libraries for your project:
-    <a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>,
-    <a href="https://router.vuejs.org/" target="_blank" rel="noopener">Vue Router</a>,
-    <a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener">Vue Test Utils</a>, and
-    <a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener">Vue Dev Tools</a>. If
-    you need more resources, we suggest paying
-    <a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">Awesome Vue</a>
-    a visit.
-  </WelcomeItem>
-
-  <WelcomeItem>
-    <template #icon>
-      <CommunityIcon />
-    </template>
-    <template #heading>Community</template>
-
-    Got stuck? Ask your question on
-    <a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a>, our official
-    Discord server, or
-    <a href="https://stackoverflow.com/questions/tagged/vue.js" target="_blank" rel="noopener"
-      >StackOverflow</a
-    >. You should also subscribe to
-    <a href="https://news.vuejs.org" target="_blank" rel="noopener">our mailing list</a> and follow
-    the official
-    <a href="https://twitter.com/vuejs" target="_blank" rel="noopener">@vuejs</a>
-    twitter account for latest news in the Vue world.
-  </WelcomeItem>
-
-  <WelcomeItem>
-    <template #icon>
-      <SupportIcon />
-    </template>
-    <template #heading>Support Vue</template>
-
-    As an independent project, Vue relies on community backing for its sustainability. You can help
-    us by
-    <a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener">becoming a sponsor</a>.
-  </WelcomeItem>
-</template>

+ 0 - 86
src/components/WelcomeItem.vue

@@ -1,86 +0,0 @@
-<template>
-  <div class="item">
-    <i>
-      <slot name="icon"></slot>
-    </i>
-    <div class="details">
-      <h3>
-        <slot name="heading"></slot>
-      </h3>
-      <slot></slot>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-.item {
-  margin-top: 2rem;
-  display: flex;
-}
-
-.details {
-  flex: 1;
-  margin-left: 1rem;
-}
-
-i {
-  display: flex;
-  place-items: center;
-  place-content: center;
-  width: 32px;
-  height: 32px;
-
-  color: var(--color-text);
-}
-
-h3 {
-  font-size: 1.2rem;
-  font-weight: 500;
-  margin-bottom: 0.4rem;
-  color: var(--color-heading);
-}
-
-@media (min-width: 1024px) {
-  .item {
-    margin-top: 0;
-    padding: 0.4rem 0 1rem calc(var(--section-gap) / 2);
-  }
-
-  i {
-    top: calc(50% - 25px);
-    left: -26px;
-    position: absolute;
-    border: 1px solid var(--color-border);
-    background: var(--color-background);
-    border-radius: 8px;
-    width: 50px;
-    height: 50px;
-  }
-
-  .item:before {
-    content: ' ';
-    border-left: 1px solid var(--color-border);
-    position: absolute;
-    left: 0;
-    bottom: calc(50% + 25px);
-    height: calc(50% - 25px);
-  }
-
-  .item:after {
-    content: ' ';
-    border-left: 1px solid var(--color-border);
-    position: absolute;
-    left: 0;
-    top: calc(50% + 25px);
-    height: calc(50% - 25px);
-  }
-
-  .item:first-of-type:before {
-    display: none;
-  }
-
-  .item:last-of-type:after {
-    display: none;
-  }
-}
-</style>

+ 66 - 0
src/components/block/LoginBlock.vue

@@ -0,0 +1,66 @@
+<script>
+
+// import Vue from 'vue'
+import { mapState } from 'pinia'
+// import router from 'vuejs/route'
+import { UserStore } from '@/stores/user'
+
+export default {
+  setup() {
+    const userStore = UserStore()
+
+    return { userStore }
+  },
+  // router,
+  // props: ['title', 'block'],
+  data () {
+    return {
+      template: null,
+      mail: '',
+      passwd: ''
+    }
+  },
+  computed: {
+    ...mapState(UserStore,['loginMessage'])
+  },
+  methods: {
+    // ...mapActions({
+    //   userLogin: 'User/userLogin',
+    //   openCloseHamMenu: 'Common/openCloseHamMenu'
+    // }),
+    onSubmitLogin (event) {
+      console.log("onSubmitLogin", event, this.mail, this.passwd);
+      this.userStore.userLogin({
+        mail: this.mail,
+        pass: this.passwd
+      }).then(() => {
+        console.log('LoginBlock user logged-in then')
+      })
+      // this.userLogin({
+      //   mail: this.mail,
+      //   pass: this.password
+      // })
+      // moved to user.js store
+      // .then(() => {
+      //   console.log('LoginBlock user logged-in')
+      //   this.openCloseHamMenu(false)
+      //   this.$router.push({
+      //     name: 'base'
+      //   })
+      // })
+    }
+  }
+}
+</script>
+
+<template>
+  <form action="" @submit.prevent="onSubmitLogin">
+    <input type="email" placeholder="email" name="email" v-model="mail">
+    <input type="password" placeholder="mot de passe" name="passwd" v-model="passwd">
+    <input type="submit" value="login">
+    <p v-if="loginMessage">{{ loginMessage }}</p>
+  </form>
+</template>
+
+<style lang="css" scoped>
+</style>

+ 41 - 0
src/components/block/UserBlock.vue

@@ -0,0 +1,41 @@
+<script>
+
+import { mapState } from 'pinia'
+import { UserStore } from '@/stores/user'
+
+
+import LoginBlock from '@components/block/LoginBlock.vue'
+import UserTools from '@components/block/UserTools.vue'
+
+// import MA from '/api/ma-axios'
+
+export default {
+  props: ['title', 'loginblock'],
+  data(){
+    return {
+      block: null
+    }
+  },
+  computed: {
+    ...mapState(UserStore,['isloggedin'])
+  },
+  methods: {
+    
+  },
+  components: {
+    LoginBlock,
+    UserTools
+  }
+}
+
+</script>
+
+<template>
+  <h1>UserBlock</h1>
+  <UserTools v-if="isloggedin" />
+  <LoginBlock v-else/>
+</template>
+
+<style lang="css" scoped>
+
+</style>

+ 44 - 0
src/components/block/UserTools.vue

@@ -0,0 +1,44 @@
+<template>
+  <div id="user-tools">
+    <a class="mdi mdi-account" href="/user">
+      <span>{{ name }}</span>
+      <!-- <span v-else>{{ mail }}</span> -->
+    </a><br/>
+    <a href="/user/logout"
+      @click.prevent="onLogout()"
+      class="mdi mdi-logout"
+      title="logout"
+    >logout</a>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'pinia'
+import { UserStore } from '@/stores/user'
+
+
+export default {
+  setup() {
+    const userStore = UserStore()
+
+    return { userStore }
+  },
+  computed: {
+    ...mapState(UserStore,['isloggedin', 'mail', 'name'])
+  },
+  methods: {
+    // ...mapActions({
+    //   userLogout: 'User/userLogout'
+    // }),
+    onLogout () {
+      console.log('UserTools onLogout')
+      this.userStore.userLogout().then(() => {
+        console.log('UserTools user logged-out then')
+      })
+    }
+  }
+}
+</script>
+
+<style lang="css" scoped>
+</style>

File diff suppressed because it is too large
+ 0 - 3
src/components/icons/IconCommunity.vue


File diff suppressed because it is too large
+ 0 - 3
src/components/icons/IconDocumentation.vue


File diff suppressed because it is too large
+ 0 - 3
src/components/icons/IconEcosystem.vue


+ 0 - 7
src/components/icons/IconSupport.vue

@@ -1,7 +0,0 @@
-<template>
-  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
-    <path
-      d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
-    />
-  </svg>
-</template>

+ 0 - 19
src/components/icons/IconTooling.vue

@@ -1,19 +0,0 @@
-<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license-->
-<template>
-  <svg
-    xmlns="http://www.w3.org/2000/svg"
-    xmlns:xlink="http://www.w3.org/1999/xlink"
-    aria-hidden="true"
-    role="img"
-    class="iconify iconify--mdi"
-    width="24"
-    height="24"
-    preserveAspectRatio="xMidYMid meet"
-    viewBox="0 0 24 24"
-  >
-    <path
-      d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z"
-      fill="currentColor"
-    ></path>
-  </svg>
-</template>

+ 13 - 14
src/router/index.js

@@ -1,22 +1,21 @@
 import { createRouter, createWebHistory } from 'vue-router'
-import HomeView from '../views/HomeView.vue'
 
 const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
   routes: [
-    {
-      path: '/',
-      name: 'home',
-      component: HomeView
-    },
-    {
-      path: '/about',
-      name: 'about',
-      // route level code-splitting
-      // this generates a separate chunk (About.[hash].js) for this route
-      // which is lazy-loaded when the route is visited.
-      component: () => import('../views/AboutView.vue')
-    }
+    // {
+    //   path: '/',
+    //   name: 'home',
+    //   component: HomeView
+    // },
+    // {
+    //   path: '/about',
+    //   name: 'about',
+    //   // route level code-splitting
+    //   // this generates a separate chunk (About.[hash].js) for this route
+    //   // which is lazy-loaded when the route is visited.
+    //   component: () => import('../views/AboutView.vue')
+    // }
   ]
 })
 

+ 135 - 0
src/stores/user.js

@@ -0,0 +1,135 @@
+import { defineStore } from 'pinia'
+import REST from '@api/rest-axios'
+import JSONAPI from '@api/json-axios'
+import qs from 'querystring-es3'
+
+export const UserStore = defineStore({
+  id: 'user',
+  state: () => ({
+    isloggedin: false,
+    csrf_token: null,
+    logout_token: null,
+    uid: 0,
+    uuid: 0,
+    mail: '',
+    name: null,
+    roles: null,
+    logginMessage: null
+  }),
+  getters: {
+    
+  },
+  actions: {
+    checkUser () {
+      JSONAPI.get('').then(({ data }) => {
+        console.log('checkuser jsonapi', data)
+        if (data.meta && data.meta.links.me) {
+          JSONAPI.get(data.meta.links.me.href).then(({ data : { data } }) => {
+            console.log('checkuser jsonapi get user', data)
+            this.uid = data.attributes.drupal_internal__uid
+            this.mail = data.attributes.mail
+            this.name = data.attributes.name
+            this.isloggedin = data.attributes.status
+            console.log('user store checkuser isloggedin', this.isloggedin);
+          })
+        }
+      })
+    },
+    userLogin (credentials) {
+      console.log('user store userLogin', credentials);
+      return new Promise((resolve, reject) => {
+        this.getToken(credentials)
+          .then((response) => {
+            console.log('userLogin getToken response', response)
+
+            if (response.status === 200) {
+              this.uid = response.data.current_user.uid
+              // state.username = data.username;
+              this.mail = response.data.current_user.mail
+              this.csrf_token = response.data.csrf_token
+              // this.isloggedin = true
+              this.logout_token = response.data.logout_token
+              this.getUser().then(userdata => {
+                console.log('User Loggedin')
+                resolve()
+              })
+            } else {
+              this.loginMessage = response.data.message
+              console.warn('Issue with getToken', response)
+              console.log('user loggein failed', this.loginMessage)
+              Promise.reject(new Error('user loggin failed'))
+            }
+          })
+          .catch(error => {
+            console.warn('Issue with Dispatch getToken', error)
+            Promise.reject(error)
+          })
+      })
+    },
+    getToken (credentials) {
+      console.log('userStore getToken', credentials)
+      return REST.post('/user/login?_format=json',
+        credentials,
+        {
+          validateStatus: function (status) {
+            return status >= 200 && status < 500
+          }
+        })
+    },
+    getUser () {
+      console.log('user store getUser');
+      return new Promise((resolve, reject) => {
+        REST.get('/session/token').then(({ data }) => {
+          console.log('csrf_token', data)
+          this.csrf_token = data
+          console.log('state csrf_token', this.csrf_token)
+          const params = {
+            token: this.csrf_token
+          }
+          REST.get(`/user/${this.uid}?_format=json`, params)
+            .then(({ data }) => {
+              console.log('user REST getUser data', data)
+              console.log('roles', data.roles)
+              // with session_limit, only here we are certain that the user is logged
+              // this.user = data
+              // this.mail = data.mail[0].value
+              this.uuid = data.uuid[0].value
+              this.name = data.name[0].value
+              // with session_limit, only here we are certain that the user is logged
+              this.isloggedin = true
+              if (data.roles) {
+                this.roles = data.roles
+              }
+              // console.log('customer_profiles', data.customer_profiles.length)
+              // if (data.customer_profiles.length) {
+              //   dispatch('getUserProfiles', data.customer_profiles[data.customer_profiles.length - 1].target_id)
+              // }
+              resolve()
+            })
+            .catch(error => {
+              console.warn('Issue with getUser', error)
+              Promise.reject(error)
+            })
+        })
+      })
+    },
+    userLogout () {
+      const credentials = qs.stringify({
+        token: this.csrf_token
+      })
+      return new Promise((resolve, reject) => {
+        REST.post('/user/logout', credentials)
+          .then(resp => {
+            console.log('userStore userLogout resp', resp)
+            this.isloggedin = false
+            // window.location.reload(true) ???
+            resolve()
+          })
+          .catch(error => {
+            console.warn('Issue with logout', error)
+            Promise.reject(error)
+          })
+      })
+    }
+  }
+})

+ 0 - 15
src/views/AboutView.vue

@@ -1,15 +0,0 @@
-<template>
-  <div class="about">
-    <h1>This is an about page</h1>
-  </div>
-</template>
-
-<style>
-@media (min-width: 1024px) {
-  .about {
-    min-height: 100vh;
-    display: flex;
-    align-items: center;
-  }
-}
-</style>

+ 0 - 9
src/views/HomeView.vue

@@ -1,9 +0,0 @@
-<script setup>
-import TheWelcome from '../components/TheWelcome.vue'
-</script>
-
-<template>
-  <main>
-    <TheWelcome />
-  </main>
-</template>

+ 3 - 1
vite.config.js

@@ -8,7 +8,9 @@ export default defineConfig({
   plugins: [vue()],
   resolve: {
     alias: {
-      '@': fileURLToPath(new URL('./src', import.meta.url))
+      '@': fileURLToPath(new URL('./src', import.meta.url)),
+      '@components': fileURLToPath(new URL('./src/components', import.meta.url)),
+      '@api': fileURLToPath(new URL('./src/api', import.meta.url))
     }
   }
 })

Some files were not shown because too many files changed in this diff