Compare commits
	
		
			2 Commits
		
	
	
		
			ce697dc51f
			...
			3191fe5c04
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					3191fe5c04 | ||
| 
						 | 
					b1207d0b6f | 
							
								
								
									
										1
									
								
								.env
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								.env
									
									
									
									
									
								
							@@ -4,3 +4,4 @@ VITE_API_PATH_LIST=/list/today
 | 
				
			|||||||
VITE_API_PATH_WHITELIST=/whitelist
 | 
					VITE_API_PATH_WHITELIST=/whitelist
 | 
				
			||||||
VITE_API_PATH_NOW_SESSIONS=/ivao/sessions/now
 | 
					VITE_API_PATH_NOW_SESSIONS=/ivao/sessions/now
 | 
				
			||||||
VITE_API_PATH_NOW_FLIGHTPLANS=/ivao/flightplans/latest
 | 
					VITE_API_PATH_NOW_FLIGHTPLANS=/ivao/flightplans/latest
 | 
				
			||||||
 | 
					VITE_API_PATH_AUTHENTICATION=/admin/user/authenticate
 | 
				
			||||||
							
								
								
									
										68
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										68
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -15,6 +15,7 @@
 | 
				
			|||||||
        "bootstrap": "^5.2.3",
 | 
					        "bootstrap": "^5.2.3",
 | 
				
			||||||
        "lodash": "^4.17.21",
 | 
					        "lodash": "^4.17.21",
 | 
				
			||||||
        "moment": "^2.29.4",
 | 
					        "moment": "^2.29.4",
 | 
				
			||||||
 | 
					        "pinia": "^2.0.29",
 | 
				
			||||||
        "redis": "^4.5.1",
 | 
					        "redis": "^4.5.1",
 | 
				
			||||||
        "vue": "^3.2.45",
 | 
					        "vue": "^3.2.45",
 | 
				
			||||||
        "vue-loading-overlay": "^6.0.2",
 | 
					        "vue-loading-overlay": "^6.0.2",
 | 
				
			||||||
@@ -2269,6 +2270,56 @@
 | 
				
			|||||||
        "url": "https://github.com/sponsors/jonschlinkert"
 | 
					        "url": "https://github.com/sponsors/jonschlinkert"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/pinia": {
 | 
				
			||||||
 | 
					      "version": "2.0.29",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.29.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-5z/KpFecq/cIgfeTnulJXldiLcTITRkTe3N58RKYSj0Pc1EdR6oyCdnf5A9jLoVwBqX5LtHhd0kGlpzWvk9oiQ==",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "@vue/devtools-api": "^6.4.5",
 | 
				
			||||||
 | 
					        "vue-demi": "*"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/sponsors/posva"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "peerDependencies": {
 | 
				
			||||||
 | 
					        "@vue/composition-api": "^1.4.0",
 | 
				
			||||||
 | 
					        "typescript": ">=4.4.4",
 | 
				
			||||||
 | 
					        "vue": "^2.6.14 || ^3.2.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "peerDependenciesMeta": {
 | 
				
			||||||
 | 
					        "@vue/composition-api": {
 | 
				
			||||||
 | 
					          "optional": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "typescript": {
 | 
				
			||||||
 | 
					          "optional": true
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/pinia/node_modules/vue-demi": {
 | 
				
			||||||
 | 
					      "version": "0.13.11",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
 | 
				
			||||||
 | 
					      "hasInstallScript": true,
 | 
				
			||||||
 | 
					      "bin": {
 | 
				
			||||||
 | 
					        "vue-demi-fix": "bin/vue-demi-fix.js",
 | 
				
			||||||
 | 
					        "vue-demi-switch": "bin/vue-demi-switch.js"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">=12"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/sponsors/antfu"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "peerDependencies": {
 | 
				
			||||||
 | 
					        "@vue/composition-api": "^1.0.0-rc.1",
 | 
				
			||||||
 | 
					        "vue": "^3.0.0-0 || ^2.6.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "peerDependenciesMeta": {
 | 
				
			||||||
 | 
					        "@vue/composition-api": {
 | 
				
			||||||
 | 
					          "optional": true
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/portfinder": {
 | 
					    "node_modules/portfinder": {
 | 
				
			||||||
      "version": "1.0.32",
 | 
					      "version": "1.0.32",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
 | 
				
			||||||
@@ -4559,6 +4610,23 @@
 | 
				
			|||||||
      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
 | 
					      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
 | 
				
			||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "pinia": {
 | 
				
			||||||
 | 
					      "version": "2.0.29",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.29.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-5z/KpFecq/cIgfeTnulJXldiLcTITRkTe3N58RKYSj0Pc1EdR6oyCdnf5A9jLoVwBqX5LtHhd0kGlpzWvk9oiQ==",
 | 
				
			||||||
 | 
					      "requires": {
 | 
				
			||||||
 | 
					        "@vue/devtools-api": "^6.4.5",
 | 
				
			||||||
 | 
					        "vue-demi": "*"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "vue-demi": {
 | 
				
			||||||
 | 
					          "version": "0.13.11",
 | 
				
			||||||
 | 
					          "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
 | 
				
			||||||
 | 
					          "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
 | 
				
			||||||
 | 
					          "requires": {}
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "portfinder": {
 | 
					    "portfinder": {
 | 
				
			||||||
      "version": "1.0.32",
 | 
					      "version": "1.0.32",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@
 | 
				
			|||||||
    "bootstrap": "^5.2.3",
 | 
					    "bootstrap": "^5.2.3",
 | 
				
			||||||
    "lodash": "^4.17.21",
 | 
					    "lodash": "^4.17.21",
 | 
				
			||||||
    "moment": "^2.29.4",
 | 
					    "moment": "^2.29.4",
 | 
				
			||||||
 | 
					    "pinia": "^2.0.29",
 | 
				
			||||||
    "redis": "^4.5.1",
 | 
					    "redis": "^4.5.1",
 | 
				
			||||||
    "vue": "^3.2.45",
 | 
					    "vue": "^3.2.45",
 | 
				
			||||||
    "vue-loading-overlay": "^6.0.2",
 | 
					    "vue-loading-overlay": "^6.0.2",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										164
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								src/App.vue
									
									
									
									
									
								
							@@ -1,18 +1,62 @@
 | 
				
			|||||||
<script>
 | 
					<script>
 | 
				
			||||||
// import { RouterLink, RouterView } from "vue-router";
 | 
					// import { RouterLink, RouterView } from "vue-router";
 | 
				
			||||||
 | 
					// import { useAuth0 } from '@auth0/auth0-vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { useSessionStore } from './stores/session-store';
 | 
				
			||||||
 | 
					import { authenticate, isAlive, logout } from './data/http/auth';
 | 
				
			||||||
 | 
					import { mapState } from 'pinia';
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
 | 
					  setup() {
 | 
				
			||||||
 | 
					    const store = useSessionStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const { setUser, logoutUser, hasRoles } = store;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      logoutUser,
 | 
				
			||||||
 | 
					      setUser,
 | 
				
			||||||
 | 
					      hasRoles
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  async mounted() {
 | 
				
			||||||
 | 
					    const user = await isAlive();
 | 
				
			||||||
 | 
					    if (user) {
 | 
				
			||||||
 | 
					      this.setUser(user);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },  
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
 | 
					      username: '',
 | 
				
			||||||
 | 
					      password: '',
 | 
				
			||||||
      loading: true,
 | 
					      loading: true,
 | 
				
			||||||
      list: [],
 | 
					      list: [],
 | 
				
			||||||
      whitelist: [],
 | 
					      whitelist: [],
 | 
				
			||||||
      isNavMobileOpen: false,
 | 
					      isNavMobileOpen: false,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  computed:{
 | 
				
			||||||
 | 
					    ...mapState(useSessionStore, ['user', 'isAuthenticated']),
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
    toggleNavMobile() {
 | 
					    toggleNavMobile() {
 | 
				
			||||||
      this.isNavMobileOpen = !this.isNavMobileOpen;
 | 
					      this.isNavMobileOpen = !this.isNavMobileOpen;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    async login() {
 | 
				
			||||||
 | 
					      if (!this.username.trim() || !this.password.trim()) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      const user = await authenticate(this.username, this.password);
 | 
				
			||||||
 | 
					      this.setUser(user);
 | 
				
			||||||
 | 
					      console.log('user :>> ', user);
 | 
				
			||||||
 | 
					      this.username = '';
 | 
				
			||||||
 | 
					      this.password = '';
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    async logout() {
 | 
				
			||||||
 | 
					      await logout();
 | 
				
			||||||
 | 
					      this.logoutUser();
 | 
				
			||||||
 | 
					      this.$router.push('/');
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    async check() {
 | 
				
			||||||
 | 
					      await isAlive();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -37,40 +81,45 @@ export default {
 | 
				
			|||||||
      <div class="navbar-start">
 | 
					      <div class="navbar-start">
 | 
				
			||||||
        <router-link class="navbar-item" to="/">ICAO</router-link>
 | 
					        <router-link class="navbar-item" to="/">ICAO</router-link>
 | 
				
			||||||
        <router-link class="navbar-item" to="/acars">Acars</router-link>
 | 
					        <router-link class="navbar-item" to="/acars">Acars</router-link>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <router-link v-if="hasRoles(['cabal'])" class="navbar-item" to="/cabal">Capt Cabal</router-link>
 | 
				
			||||||
 | 
					        <router-link v-if="hasRoles(['admin'])" class="navbar-item" to="/admin">Admin</router-link>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="navbar-end">
 | 
				
			||||||
 | 
					      <div class="navbar-item">
 | 
				
			||||||
 | 
					        <div class="field is-horizontal">
 | 
				
			||||||
 | 
					          <div v-if="!isAuthenticated" class="field-body">
 | 
				
			||||||
 | 
					            <div class="field">
 | 
				
			||||||
 | 
					              <p class="control is-expanded">
 | 
				
			||||||
 | 
					                <input class="input is-small input-login" @keyup.enter="login" v-model="username" type="text" placeholder="Username">
 | 
				
			||||||
 | 
					              </p>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="field is-grouped">
 | 
				
			||||||
 | 
					              <p class="control is-expanded">
 | 
				
			||||||
 | 
					                <input class="input is-small input-login" @keyup.enter="login" v-model="password" type="password" placeholder="Password">
 | 
				
			||||||
 | 
					              </p>
 | 
				
			||||||
 | 
					              <p class="control">
 | 
				
			||||||
 | 
					                <a class="button is-small is-light" @click="login">
 | 
				
			||||||
 | 
					                  Login
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
 | 
					              </p>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div v-if="isAuthenticated" class="field-body">
 | 
				
			||||||
 | 
					            <div class="is-6 mr-2 mt-1">{{ user.firstname }} {{ user.lastname }}</div>
 | 
				
			||||||
 | 
					            <p class="control">
 | 
				
			||||||
 | 
					              <a class="button is-small is-light" @click="logout">
 | 
				
			||||||
 | 
					                Logout
 | 
				
			||||||
 | 
					              </a>
 | 
				
			||||||
 | 
					            </p>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </nav>
 | 
					  </nav>
 | 
				
			||||||
  <div class="container">
 | 
					  <div class="container">
 | 
				
			||||||
    <div> <RouterView /> </div>
 | 
					    <div> <RouterView /> </div>
 | 
				
			||||||
    <!-- <section class="section">
 | 
					 | 
				
			||||||
      <h1 class="title">Pilotos activos con mas de 200 horas en ACARS</h1>      
 | 
					 | 
				
			||||||
        <table class="table is-striped is-hoverable is-fullwidth">
 | 
					 | 
				
			||||||
          <thead>
 | 
					 | 
				
			||||||
            <tr>
 | 
					 | 
				
			||||||
              <th class="has-text-centered">VID</th>
 | 
					 | 
				
			||||||
              <th class="">Nombre</th>
 | 
					 | 
				
			||||||
              <th class="has-text-centered">Total Vuelos</th>
 | 
					 | 
				
			||||||
              <th class="has-text-centered">Horas totales</th>
 | 
					 | 
				
			||||||
            </tr>
 | 
					 | 
				
			||||||
          </thead>
 | 
					 | 
				
			||||||
          <tbody>
 | 
					 | 
				
			||||||
            <tr v-for="item in whitelist" :key="item.vid">
 | 
					 | 
				
			||||||
              <td class="has-text-centered">
 | 
					 | 
				
			||||||
                {{ item.vid  }}
 | 
					 | 
				
			||||||
              </td>
 | 
					 | 
				
			||||||
              <td>
 | 
					 | 
				
			||||||
                {{ item.name  }}
 | 
					 | 
				
			||||||
              </td>
 | 
					 | 
				
			||||||
              <td class="has-text-centered">
 | 
					 | 
				
			||||||
                {{ item.flights  }}
 | 
					 | 
				
			||||||
              </td>
 | 
					 | 
				
			||||||
              <td class="has-text-centered">
 | 
					 | 
				
			||||||
                <FormatTime :value="item.flightTime" />
 | 
					 | 
				
			||||||
              </td>
 | 
					 | 
				
			||||||
            </tr>
 | 
					 | 
				
			||||||
          </tbody>
 | 
					 | 
				
			||||||
        </table>
 | 
					 | 
				
			||||||
      </section> -->
 | 
					 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
   
 | 
					   
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
@@ -83,60 +132,7 @@ export default {
 | 
				
			|||||||
.tag {
 | 
					.tag {
 | 
				
			||||||
  font-size: 60% !important;
 | 
					  font-size: 60% !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/* header {
 | 
					.input-login {
 | 
				
			||||||
  line-height: 1.5;
 | 
					  width: 100px;
 | 
				
			||||||
  max-height: 100vh;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
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>
 | 
					</style>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,7 @@
 | 
				
			|||||||
  export default {
 | 
					  export default {
 | 
				
			||||||
    data() { 
 | 
					    data() { 
 | 
				
			||||||
      return {
 | 
					      return {
 | 
				
			||||||
 | 
					        interval: undefined,
 | 
				
			||||||
        isLoading: true,
 | 
					        isLoading: true,
 | 
				
			||||||
        list: [],
 | 
					        list: [],
 | 
				
			||||||
        board: undefined,
 | 
					        board: undefined,
 | 
				
			||||||
@@ -45,8 +46,15 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    async mounted() {
 | 
					    async mounted() {
 | 
				
			||||||
      await this.loadData();
 | 
					      await this.loadData();
 | 
				
			||||||
 | 
					      this.startLoop();
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    unmounted() {
 | 
				
			||||||
 | 
					      clearInterval(this.interval);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    methods: {
 | 
					    methods: {
 | 
				
			||||||
 | 
					      startLoop() {
 | 
				
			||||||
 | 
					        this.interval = setInterval(this.loadData, 1000 * 30)
 | 
				
			||||||
 | 
					      },  
 | 
				
			||||||
      async loadData() {
 | 
					      async loadData() {
 | 
				
			||||||
        this.isLoading = true;
 | 
					        this.isLoading = true;
 | 
				
			||||||
        let data = await getFlightplansNow();
 | 
					        let data = await getFlightplansNow();
 | 
				
			||||||
@@ -58,8 +66,7 @@
 | 
				
			|||||||
          return acc;
 | 
					          return acc;
 | 
				
			||||||
        }, []);
 | 
					        }, []);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // this.list = rows;
 | 
					        this.list = rows;
 | 
				
			||||||
        this.list = this.test;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    components: {
 | 
					    components: {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,8 @@
 | 
				
			|||||||
<script>
 | 
					<script>
 | 
				
			||||||
import SolariBoardRow from './SolariBoardRow.vue';
 | 
					import SolariBoardRow from './SolariBoardRow.vue';
 | 
				
			||||||
import _isNil from 'lodash/isNil';
 | 
					import _isNil from 'lodash/isNil';
 | 
				
			||||||
import _fill from 'lodash/fill';
 | 
					import _times from 'lodash/times';
 | 
				
			||||||
 | 
					import _constant from 'lodash/constant';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  props: {
 | 
					  props: {
 | 
				
			||||||
@@ -62,9 +63,9 @@ export default {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  mounted() {
 | 
					  mounted() {
 | 
				
			||||||
   
 | 
					   
 | 
				
			||||||
    if (Array.isArray(this.data)) {
 | 
					    // if (Array.isArray(this.data)) {
 | 
				
			||||||
      this.setData(this.data);
 | 
					    //   this.setData(this.data);
 | 
				
			||||||
    }
 | 
					    // }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
@@ -87,18 +88,21 @@ export default {
 | 
				
			|||||||
      return this.cols * this.rows;
 | 
					      return this.cols * this.rows;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  watch: {
 | 
				
			||||||
 | 
					    data: {
 | 
				
			||||||
 | 
					      handler(newData) {
 | 
				
			||||||
 | 
					        this.setData(newData);
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      immediate: true,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
    setData(data) {
 | 
					    setData(data) {
 | 
				
			||||||
      const plainData = (data || []).reduce((acc, row) => {
 | 
					      const plainData = (data || []).reduce((acc, row) => {
 | 
				
			||||||
        console.log('row :>> ', row);
 | 
					 | 
				
			||||||
        acc = acc.concat(row);
 | 
					        acc = acc.concat(row);
 | 
				
			||||||
        return acc;
 | 
					        return acc;
 | 
				
			||||||
      }, []);
 | 
					      }, []);
 | 
				
			||||||
      console.log('plainData :>> ', plainData);
 | 
					      this.values = _times(this.total, _constant(' ')).map((d, i) => plainData[i] || d);
 | 
				
			||||||
      console.log('this.total :>> ', this.total);
 | 
					 | 
				
			||||||
      this.values =  _fill(Array(this.total), ' ').map((d, i) => plainData[i] || d);
 | 
					 | 
				
			||||||
      console.log('this.values :>> ', this.values);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    mapRow(r, i) {
 | 
					    mapRow(r, i) {
 | 
				
			||||||
      r.loops = (_isNil(r.loops)) ? this.loops : r.loops;
 | 
					      r.loops = (_isNil(r.loops)) ? this.loops : r.loops;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="board-line">
 | 
					  <div class="board-line">
 | 
				
			||||||
    <div class="board-letter" :ref="'letter' + $index" :class="{'animating': isAnimating[$index]}" v-for="(char, $index) in charsBack" :key="$index">{{ char }}</div>
 | 
					    <div class="board-letter" :ref="'letter' + $index" :class="{'animating': isAnimating[$index]}" v-for="(char, $index) in charsToShow" :key="$index">{{ char }}</div>
 | 
				
			||||||
  </div>  
 | 
					  </div>  
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -56,6 +56,7 @@
 | 
				
			|||||||
<script>
 | 
					<script>
 | 
				
			||||||
  import _isInteger from 'lodash/isInteger';
 | 
					  import _isInteger from 'lodash/isInteger';
 | 
				
			||||||
  import _delay from 'lodash/delay';
 | 
					  import _delay from 'lodash/delay';
 | 
				
			||||||
 | 
					  import _clone from 'lodash/clone';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export default {
 | 
					  export default {
 | 
				
			||||||
    props: {
 | 
					    props: {
 | 
				
			||||||
@@ -80,17 +81,19 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    data() {
 | 
					    data() {
 | 
				
			||||||
 | 
					      const newArray = Array.apply(null, Array(this.size)).map(() => ' ');
 | 
				
			||||||
 | 
					      const newArrayAnimating = Array.apply(null, Array(this.size)).map(() => false);
 | 
				
			||||||
      return {
 | 
					      return {
 | 
				
			||||||
        charsAll: ' ABCDEFGHIJKLMNÑOPQRSTUVWXYZ0123456789-:.>*',
 | 
					        charsAll: ' ABCDEFGHIJKLMNÑOPQRSTUVWXYZ0123456789-:.>*',
 | 
				
			||||||
        charsBack: [],
 | 
					        charsReference: _clone(newArray),
 | 
				
			||||||
        isAnimating: [],
 | 
					        charsToShow: _clone(newArray),
 | 
				
			||||||
 | 
					        isAnimating: newArrayAnimating,
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    computed: {
 | 
					    computed: {
 | 
				
			||||||
      chars() {
 | 
					      chars() {
 | 
				
			||||||
        const text =  this.getText(this.textToShow);
 | 
					        const text =  this.getText(this.textToShow);
 | 
				
			||||||
        const size = _isInteger(this.size) ? this.size : text.length;
 | 
					        const chars = Array.apply(null, Array(this.size)).map(() => ' ');
 | 
				
			||||||
        const chars = Array.apply(null, Array(size)).map(() => ' ');
 | 
					 | 
				
			||||||
        const offset = (this.align === 'left') ? 0 : chars.length - text.length;
 | 
					        const offset = (this.align === 'left') ? 0 : chars.length - text.length;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        for (let index = 0; index < text.length; index++) {
 | 
					        for (let index = 0; index < text.length; index++) {
 | 
				
			||||||
@@ -101,8 +104,7 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    watch: {
 | 
					    watch: {
 | 
				
			||||||
      chars: {
 | 
					      chars: {
 | 
				
			||||||
        handler(newValue) {
 | 
					        handler() {
 | 
				
			||||||
          this.charsBack = Array.apply(null, Array(newValue.length)).map(() => ' ');
 | 
					 | 
				
			||||||
          if (_isInteger(this.delay) && this.delay > 0) {
 | 
					          if (_isInteger(this.delay) && this.delay > 0) {
 | 
				
			||||||
            _delay(this.startAnimation, this.delay);
 | 
					            _delay(this.startAnimation, this.delay);
 | 
				
			||||||
          } else {
 | 
					          } else {
 | 
				
			||||||
@@ -123,24 +125,26 @@
 | 
				
			|||||||
        return (text.length > this.size) ? text.substring(0, this.size) : text;
 | 
					        return (text.length > this.size) ? text.substring(0, this.size) : text;
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      async startAnimation() {
 | 
					      async startAnimation() {
 | 
				
			||||||
        this.charsBack = this.charsBack.map(() => ' ');
 | 
					        const cts = _clone(this.charsReference);
 | 
				
			||||||
        this.isAnimating = [];
 | 
					 | 
				
			||||||
        for (let index = 0; index < this.chars.length; index++) {
 | 
					        for (let index = 0; index < this.chars.length; index++) {
 | 
				
			||||||
          const char = this.chars[index];
 | 
					          const char = this.chars[index];
 | 
				
			||||||
 | 
					          if (char !== cts[index]) {
 | 
				
			||||||
            this.animateLetter(index, char);
 | 
					            this.animateLetter(index, char);
 | 
				
			||||||
            await new Promise((resolve) => setTimeout(resolve, 100))
 | 
					            await new Promise((resolve) => setTimeout(resolve, 100))
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.charsReference = this.chars;
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      animateLetter(index, letter) {
 | 
					      animateLetter(index, letter) {
 | 
				
			||||||
        let showIndex = 0;
 | 
					        let showIndex = 0;
 | 
				
			||||||
        this.charsBack[index] = this.charsAll[showIndex];
 | 
					        this.charsToShow[index] = this.charsAll[showIndex];
 | 
				
			||||||
        this.isAnimating[index] = true;
 | 
					        this.isAnimating[index] = true;
 | 
				
			||||||
        let loop = 0;
 | 
					        let loop = 0;
 | 
				
			||||||
        const letterIndex = this.getLetterIndex(letter);
 | 
					        const letterIndex = this.getLetterIndex(letter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const interval = setInterval(() => {
 | 
					        const interval = setInterval(() => {
 | 
				
			||||||
          showIndex = this.getNextIndex(showIndex);
 | 
					          showIndex = this.getNextIndex(showIndex);
 | 
				
			||||||
          this.charsBack[index] = this.charsAll.charAt(showIndex);
 | 
					          this.charsToShow[index] = this.charsAll.charAt(showIndex);
 | 
				
			||||||
          if (showIndex === 0) {
 | 
					          if (showIndex === 0) {
 | 
				
			||||||
            loop++;
 | 
					            loop++;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								src/data/http/auth.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/data/http/auth.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					import {get, post } from './requests.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function isAlive() {
 | 
				
			||||||
 | 
					  const { VITE_API_BASE } =
 | 
				
			||||||
 | 
					  import.meta.env;
 | 
				
			||||||
 | 
					  const response = await get(`${VITE_API_BASE}/admin/user/alive`);
 | 
				
			||||||
 | 
					  return response;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function authenticate(username, password) {
 | 
				
			||||||
 | 
					  const { VITE_API_BASE, VITE_API_PATH_AUTHENTICATION } =
 | 
				
			||||||
 | 
					  import.meta.env;
 | 
				
			||||||
 | 
					  const response = await post(`${VITE_API_BASE}${VITE_API_PATH_AUTHENTICATION}`, { username, password });
 | 
				
			||||||
 | 
					  return response;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function logout() {
 | 
				
			||||||
 | 
					  const { VITE_API_BASE } =
 | 
				
			||||||
 | 
					  import.meta.env;
 | 
				
			||||||
 | 
					  const response = await get(`${VITE_API_BASE}/admin/user/logout`);
 | 
				
			||||||
 | 
					  return response;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,26 +1,26 @@
 | 
				
			|||||||
import { request } from './requests.js';
 | 
					import {get } from './requests.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function getMonthlyList() {
 | 
					export async function getMonthlyList() {
 | 
				
			||||||
  const { VITE_API_BASE, VITE_API_PATH_LIST } =
 | 
					  const { VITE_API_BASE, VITE_API_PATH_LIST } =
 | 
				
			||||||
  import.meta.env;
 | 
					  import.meta.env;
 | 
				
			||||||
  const response = await request(`${VITE_API_BASE}${VITE_API_PATH_LIST}`);
 | 
					  const response = await get(`${VITE_API_BASE}${VITE_API_PATH_LIST}`);
 | 
				
			||||||
  return response;
 | 
					  return response;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
export async function getWhitelist() {
 | 
					export async function getWhitelist() {
 | 
				
			||||||
  const { VITE_API_BASE, VITE_API_PATH_WHITELIST } =
 | 
					  const { VITE_API_BASE, VITE_API_PATH_WHITELIST } =
 | 
				
			||||||
  import.meta.env;
 | 
					  import.meta.env;
 | 
				
			||||||
  const response = await request(`${VITE_API_BASE}${VITE_API_PATH_WHITELIST}`);
 | 
					  const response = await get(`${VITE_API_BASE}${VITE_API_PATH_WHITELIST}`);
 | 
				
			||||||
  return response;
 | 
					  return response;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
export async function getInSessionNow() {
 | 
					export async function getInSessionNow() {
 | 
				
			||||||
  const { VITE_API_BASE, VITE_API_PATH_NOW_SESSIONS } =
 | 
					  const { VITE_API_BASE, VITE_API_PATH_NOW_SESSIONS } =
 | 
				
			||||||
  import.meta.env;
 | 
					  import.meta.env;
 | 
				
			||||||
  const response = await request(`${VITE_API_BASE}${VITE_API_PATH_NOW_SESSIONS}`);
 | 
					  const response = await get(`${VITE_API_BASE}${VITE_API_PATH_NOW_SESSIONS}`);
 | 
				
			||||||
  return response;
 | 
					  return response;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
export async function getFlightplansNow() {
 | 
					export async function getFlightplansNow() {
 | 
				
			||||||
  const { VITE_API_BASE, VITE_API_PATH_NOW_FLIGHTPLANS } =
 | 
					  const { VITE_API_BASE, VITE_API_PATH_NOW_FLIGHTPLANS } =
 | 
				
			||||||
  import.meta.env;
 | 
					  import.meta.env;
 | 
				
			||||||
  const response = await request(`${VITE_API_BASE}${VITE_API_PATH_NOW_FLIGHTPLANS}`);
 | 
					  const response = await get(`${VITE_API_BASE}${VITE_API_PATH_NOW_FLIGHTPLANS}`);
 | 
				
			||||||
  return response;
 | 
					  return response;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,6 +1,15 @@
 | 
				
			|||||||
import axios from 'axios';
 | 
					import axios from 'axios';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const request = async(url, options) => {
 | 
					export const get = async(url) => {
 | 
				
			||||||
  const response = await axios.get(url, options);
 | 
					  const response = await axios.get(url, { withCredentials: true });
 | 
				
			||||||
  return response.data;
 | 
					  return response.data;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const post = async(url, data) => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const response = await axios.post(url, data, { withCredentials: true });
 | 
				
			||||||
 | 
					    return response.data;
 | 
				
			||||||
 | 
					  } catch (err) {
 | 
				
			||||||
 | 
					    console.log('err :>> ', err.response);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -4,7 +4,7 @@ function format(num) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export function hoursFromSeconds(seconds) {
 | 
					export function hoursFromSeconds(seconds) {
 | 
				
			||||||
  const h = format(Math.floor(seconds / 3600));
 | 
					  const h = format(Math.floor(seconds / 3600));
 | 
				
			||||||
  const m = format(Math.round(seconds % 3600 * 60));
 | 
					  const m = format(Math.round(seconds % 3600 / 60));
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    h,
 | 
					    h,
 | 
				
			||||||
    m
 | 
					    m
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,17 @@
 | 
				
			|||||||
import { createApp } from 'vue';
 | 
					import { createApp } from 'vue';
 | 
				
			||||||
 | 
					import { createPinia } from 'pinia';
 | 
				
			||||||
import App from './App.vue';
 | 
					import App from './App.vue';
 | 
				
			||||||
import router from './router';
 | 
					import router from './router';
 | 
				
			||||||
import VueMobileDetection from 'vue-mobile-detection';
 | 
					import VueMobileDetection from 'vue-mobile-detection';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import './assets/css/main.css';
 | 
					import './assets/css/main.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const pinia = createPinia();
 | 
				
			||||||
const app = createApp(App);
 | 
					const app = createApp(App);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.use(pinia);
 | 
				
			||||||
app.use(router);
 | 
					app.use(router);
 | 
				
			||||||
app.use(VueMobileDetection);
 | 
					app.use(VueMobileDetection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.mount('#app');
 | 
					app.mount('#app');
 | 
				
			||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
import { createRouter, createWebHistory } from 'vue-router';
 | 
					import { createRouter, createWebHistory } from 'vue-router';
 | 
				
			||||||
import TableAcars from '../components/TableAcars.vue';
 | 
					import TableAcars from '../components/TableAcars.vue';
 | 
				
			||||||
import IvaoView from '../views/IvaoView.vue';
 | 
					import IvaoView from '../views/IvaoView.vue';
 | 
				
			||||||
 | 
					import CabalView from '../views/CabalView.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = createRouter({
 | 
					const router = createRouter({
 | 
				
			||||||
  history: createWebHistory(
 | 
					  history: createWebHistory(
 | 
				
			||||||
@@ -15,6 +16,11 @@ const router = createRouter({
 | 
				
			|||||||
      name: 'acars',
 | 
					      name: 'acars',
 | 
				
			||||||
      component: TableAcars,
 | 
					      component: TableAcars,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      path: '/cabal',
 | 
				
			||||||
 | 
					      name: 'cabal',
 | 
				
			||||||
 | 
					      component: CabalView,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    // {
 | 
					    // {
 | 
				
			||||||
    //   path: '/about',
 | 
					    //   path: '/about',
 | 
				
			||||||
    //   name: 'about',
 | 
					    //   name: 'about',
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								src/stores/session-store.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/stores/session-store.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					import { defineStore } from 'pinia';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const useSessionStore = defineStore('user', {
 | 
				
			||||||
 | 
					  state: () => ({ _user: {}, _isAuthenticated: false }),
 | 
				
			||||||
 | 
					  getters: {
 | 
				
			||||||
 | 
					    user: (state) => state._user,
 | 
				
			||||||
 | 
					    isAuthenticated: (state) => state._isAuthenticated,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  actions: {
 | 
				
			||||||
 | 
					    setUser(user) {
 | 
				
			||||||
 | 
					      this._isAuthenticated = !!user;
 | 
				
			||||||
 | 
					      this._user = user;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    logoutUser() {
 | 
				
			||||||
 | 
					      this._isAuthenticated = false;
 | 
				
			||||||
 | 
					      this._user = '';
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    hasRoles(roles = []) {
 | 
				
			||||||
 | 
					      let hasRole = false;
 | 
				
			||||||
 | 
					      roles.forEach(role => {
 | 
				
			||||||
 | 
					        hasRole = hasRole || (this._user.roles || []).indexOf(role) !== -1;
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      return hasRole;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										8
									
								
								src/views/CabalView.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/views/CabalView.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <main class="section">
 | 
				
			||||||
 | 
					    <h1 class="title is-2"> Capitán Cabal Hub</h1>
 | 
				
			||||||
 | 
					  </main>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
@@ -1,9 +0,0 @@
 | 
				
			|||||||
<script setup>
 | 
					 | 
				
			||||||
import TheWelcome from "../components/TheWelcome.vue";
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<template>
 | 
					 | 
				
			||||||
  <main>
 | 
					 | 
				
			||||||
    <TheWelcome />
 | 
					 | 
				
			||||||
  </main>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <main>
 | 
					  <main class="section">
 | 
				
			||||||
    <InSessionNow v-if="!$isMobile()" />
 | 
					    <InSessionNow v-if="!$isMobile()" />
 | 
				
			||||||
    <TableIvao />
 | 
					    <TableIvao />
 | 
				
			||||||
  </main>
 | 
					  </main>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user