浏览代码

footer + header improvement

tripeur 4 年之前
父节点
当前提交
fe9744ccc0
共有 10 个文件被更改,包括 182 次插入57 次删除
  1. 1 1
      .env.development
  2. 5 9
      src/PlannerApp.vue
  3. 1 1
      src/PlanningPage.vue
  4. 15 41
      src/assets/css/main.css
  5. 58 0
      src/components/Footer.vue
  6. 48 3
      src/components/Header.vue
  7. 1 1
      src/planner.ts
  8. 1 1
      src/planningPage.ts
  9. 47 0
      src/router/main.ts
  10. 5 0
      vue.config.js

+ 1 - 1
.env.development

@@ -1,2 +1,2 @@
 VUE_APP_TITLE=[test] BDLG Planner 
-VUE_APP_API_URL=https://bdlg-planner.jaquin.fr/
+VUE_APP_API_URL=http://localhost:8081/

+ 5 - 9
src/PlannerApp.vue

@@ -1,6 +1,6 @@
 <template>
-  <c-header title="BDLG Planner" to-title="/planner" :tabs="tabs" />
-  <div class="container">
+  <c-header title="BDLG Planner" title-to="/planner" :tabs="tabs" />
+  <div class="main-container">
     <router-view
       @export="exportStateToJson"
       @import="(e) => importJsonState(e, false)"
@@ -20,11 +20,11 @@
       <div class="modal-content" v-html="explanation" @click="(e) => e.stopPropagation()"></div>
     </div>
   </div>
+  <c-footer />
 </template>
 <script lang="ts">
 import { defineComponent } from "vue";
 import toast, { Toast } from "@/utils/Toast";
-import "@/assets/css/tabs.css";
 import ConstraintTranslation from "@/assets/ConstraintTranslation";
 import Evenement from "@/models/Evenement";
 import Creneau from "@/models/Creneau";
@@ -42,6 +42,7 @@ import { MutationTypes } from "@/store/Mutations";
 import dayjs from "dayjs";
 import { StateJSON } from "@/store/State";
 import Header, { HeaderLink } from "./components/Header.vue";
+import cFooter from "./components/Footer.vue";
 
 const API_URL = process.env.VUE_APP_API_URL;
 
@@ -54,7 +55,7 @@ const tabs: Array<HeaderLink> = [
   { to: "/planner/planningIndividuel", name: "Planning Individuel" },
 ];
 export default defineComponent({
-  components: { cHeader: Header },
+  components: { cHeader: Header, cFooter },
   mixins: [updatePlanningVersions, importJsonState],
   data() {
     return {
@@ -297,11 +298,6 @@ export default defineComponent({
 </script>
 
 <style>
-.container {
-  display: flex;
-  justify-content: center;
-  margin: 8px;
-}
 .toast.action > span {
   cursor: pointer;
   color: var(--color-primary-600);

+ 1 - 1
src/PlanningPage.vue

@@ -1,5 +1,5 @@
 <template>
-  <c-header title="BDLG Planner" />
+  <c-header title="BDLG Planner" titleTo="/planner" />
   <div class="container">
     <div v-if="isLoading" class="loading">Chargement en cours <br /><dots /></div>
     <template v-else-if="hasData">

+ 15 - 41
src/assets/css/main.css

@@ -28,43 +28,31 @@
   --color-neutral-600: hsl(37, 5%, 60%);
   --color-neutral-800: hsl(37, 5%, 80%);
 }
-
+html {
+  height: 100%;
+}
 body {
   color: #282e3a;
   margin: 0;
   font-size: 1rem;
   font-family: Roboto, Helvetica Neue, Helvetica, Arial, sans-serif;
   background-color: #ffffff;
+  min-height: 100vh;
+  flex-direction: column;
 }
-.header {
-  --bg-color: var(--color-neutral-100);
-  --color: var(--color-accent-600);
-  top: 0;
-  left: auto;
-  right: 0;
-  width: 100%;
-  display: -webkit-box;
+#app {
+  min-height: 100vh;
   display: flex;
-  padding: 0;
-  padding-right: 0px;
-  z-index: 1200;
-  position: -webkit-sticky;
-  position: sticky;
-  background-color: var(--bg-color);
-  color: var(--color);
-  box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.2);
-  box-sizing: border-box;
-  min-height: 3.5rem;
-  overflow-x: hidden;
-  -webkit-box-align: center;
-  align-items: center;
-  flex-shrink: 0;
-  font-family: Roboto, Helvetica Neue, Helvetica, Arial, sans-serif;
-  padding-right: 1rem;
+  flex-direction: column;
 }
-.header > :not(:first-child) {
-  margin-right: 0.5rem;
+.main-container {
+  display: flex;
+  justify-content: center;
+  align-items: flex-start;
+  flex-grow: 1;
+  margin: 8px;
 }
+
 .logo {
   width: 32px;
   height: 32px;
@@ -74,20 +62,6 @@ body {
   background-size: contain;
   background-repeat: no-repeat;
 }
-.appname {
-  -webkit-box-flex: 1;
-  flex: 1;
-  color: inherit;
-  font-size: 1rem;
-  text-align: left;
-  border-left: 1px solid var(--color);
-  font-weight: 400;
-  line-height: 1.5rem;
-  white-space: nowrap;
-  padding-left: 1rem;
-  padding-right: 1rem;
-  text-decoration: none;
-}
 
 @font-face {
   font-family: "Material Icons";

+ 58 - 0
src/components/Footer.vue

@@ -0,0 +1,58 @@
+<template>
+  <footer class="footer">
+    <a :href="logout" v-if="connected">Se déconnecter</a>
+    <a :href="adminPage" v-if="isAdmin">Admninistration</a>
+    <span>© 2021 - {{ year }} par Clovis Jaquin</span>
+  </footer>
+</template>
+
+<script lang="ts">
+import { defineComponent } from "vue";
+const API_URL = process.env.VUE_APP_API_URL;
+export default defineComponent({
+  data() {
+    return {
+      roles: ["ADMIN"] as Array<string>,
+      connected: true,
+      logout: API_URL + "logout",
+      adminPage: API_URL + "admin",
+      year: new Date().getFullYear() + "",
+    };
+  },
+  computed: {
+    isAdmin(): boolean {
+      return this.roles.includes("ADMIN");
+    },
+  },
+  mounted() {
+    fetch(API_URL + "roles/current")
+      .then((res) => {
+        if (res.status == 200) {
+          return res.json();
+        } else {
+          throw new Error(res.statusText);
+        }
+      })
+      .then((data: Array<string>) => {
+        this.roles = data;
+        this.connected = true;
+      });
+  },
+});
+</script>
+
+<style scoped>
+.footer {
+  display: flex;
+  justify-content: center;
+  gap: 16px;
+  border-top: 1px solid var(--color-neutral-800);
+  padding: 16px;
+  margin-top: 16px;
+  background: #fff;
+}
+.footer > a {
+  text-decoration: none;
+  color: var(--color-primary-400);
+}
+</style>

+ 48 - 3
src/components/Header.vue

@@ -1,7 +1,7 @@
 <template>
-  <div class="header">
+  <header class="header">
     <div class="logo" />
-    <router-link :to="titleTo" class="appname" v-if="titleTo">{{ title }}</router-link>
+    <a :href="titleTo" class="appname" v-if="titleTo">{{ title }}</a>
     <div class="appname" v-else>{{ title }}</div>
     <nav class="tabs floating show-lg">
       <router-link
@@ -17,7 +17,7 @@
     <div class="floating show-sm burger" @click="showMenu = true" v-if="tabs.length > 0">
       <i class="material-icons">menu</i>
     </div>
-  </div>
+  </header>
   <transition name="fade">
     <div class="modal" v-show="showMenu" @click="closeModal">
       <div class="sidenav" ref="sidenav" :class="{ in: showMenu }">
@@ -40,6 +40,8 @@
 
 <script lang="ts">
 import { defineComponent, PropType } from "vue";
+import "@/assets/css/main.css";
+import "@/assets/css/tabs.css";
 
 export type HeaderLink = {
   to: string;
@@ -65,6 +67,49 @@ export default defineComponent({
 </script>
 
 <style>
+.header {
+  --bg-color: var(--color-neutral-100);
+  --color: var(--color-accent-600);
+  top: 0;
+  left: auto;
+  right: 0;
+  width: 100%;
+  display: -webkit-box;
+  display: flex;
+  padding: 0;
+  padding-right: 0px;
+  z-index: 1200;
+  position: -webkit-sticky;
+  position: sticky;
+  background-color: var(--bg-color);
+  color: var(--color);
+  box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.2);
+  box-sizing: border-box;
+  min-height: 3.5rem;
+  overflow-x: hidden;
+  -webkit-box-align: center;
+  align-items: center;
+  flex-shrink: 0;
+  font-family: Roboto, Helvetica Neue, Helvetica, Arial, sans-serif;
+  padding-right: 1rem;
+}
+.header > :not(:first-child) {
+  margin-right: 0.5rem;
+}
+.appname {
+  -webkit-box-flex: 1;
+  flex: 1;
+  color: inherit;
+  font-size: 1rem;
+  text-align: left;
+  border-left: 1px solid var(--color);
+  font-weight: 400;
+  line-height: 1.5rem;
+  white-space: nowrap;
+  padding-left: 1rem;
+  padding-right: 1rem;
+  text-decoration: none;
+}
 @media (max-width: 600px) {
   .show-lg {
     display: none !important;

+ 1 - 1
src/planner.ts

@@ -1,6 +1,6 @@
 import { createApp } from "vue";
 import App from "./PlannerApp.vue";
-import router from "./router";
+import router from "./router/main";
 import { store } from "./store/Store";
 import "@/assets/css/main.css";
 import "@/assets/css/button.css";

+ 1 - 1
src/planningPage.ts

@@ -1,6 +1,6 @@
 import { createApp } from "vue";
 import App from "@/PlanningPage.vue";
-import router from "./router";
+import router from "./router/main";
 import { store } from "./store/Store";
 import "@/assets/css/main.css";
 import "@/assets/css/button.css";

+ 47 - 0
src/router/main.ts

@@ -0,0 +1,47 @@
+import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
+import Evenement from "../views/Evenement.vue";
+import Planning from "@/views/Planning.vue";
+import CompetenceManager from "@/views/CompetenceManager.vue";
+import BenevoleManager from "@/views/BenevoleManager.vue";
+import PlanningPersonnel from "@/views/PlanningPersonnel.vue";
+import Home from "@/views/Home.vue";
+
+const routes: Array<RouteRecordRaw> = [
+  {
+    path: "/planner/",
+    name: "Home",
+    component: Home,
+  },
+  {
+    path: "/planner/evenement",
+    name: "Evenement",
+    component: Evenement,
+  },
+  {
+    path: "/planner/planning",
+    name: "Planning",
+    component: Planning,
+  },
+  {
+    path: "/planner/competences",
+    name: "Competence",
+    component: CompetenceManager,
+  },
+  {
+    path: "/planner/benevoles",
+    name: "Benevoles",
+    component: BenevoleManager,
+  },
+  {
+    path: "/planner/planningIndividuel",
+    name: "planningIndividuel",
+    component: PlanningPersonnel,
+  },
+];
+
+const router = createRouter({
+  history: createWebHistory(process.env.BASE_URL),
+  routes,
+});
+
+export default router;

+ 5 - 0
vue.config.js

@@ -17,6 +17,11 @@ module.exports = {
       title: "BDLG planner - Visualisation",
       filename: "planning/display/index.html",
     },
+    admin: {
+      entry: "./src/admin.ts",
+      title: "BDLG planner - Admninistration",
+      filename: "admin/index.html",
+    },
   },
   outputDir:
     process.env.NODE_ENV === "production"