28 Commits

Author SHA1 Message Date
2cc97c8de8 Ajout de la fonctionnalité de réduction de card lorsque l'on clique sur une des trois card dans le gamecontrol 2024-04-12 21:16:12 +02:00
3826a067e2 Décalage du boutton Debugger 2024-04-05 16:03:49 +02:00
76383c1a3d Ajustement du menu router pour cacher le debugger, il est désormais accessible depuis la page paramètre, onglet MQTT 2024-04-05 16:01:13 +02:00
8b012757f3 Ajustement de la section Son pourque les emplacements soient plus optimisés 2024-04-05 15:48:39 +02:00
0dea30e8a6 Modification du titre Brain Blast dans la barre de menu, désormais elle ne s'affiche que lorsque l'on ne se trouve pas sur la page d'accueil (sinon cela fait redondance avec le logo principal) 2024-04-05 15:14:28 +02:00
da4daae323 Suppression de la page About 2024-04-05 15:11:51 +02:00
ef4838bde1 Modification de l'écart de la carte solution par rapport aux autres 2024-04-05 15:03:58 +02:00
1edb73bf5f Création de la carte timer dans le GameStatus 2024-04-05 15:00:41 +02:00
5a983f2c7e Transformation des scores en card 2024-04-05 14:33:54 +02:00
96b7b1cbd7 Ajout de la card Timer pour créer un chronomètre de jeu 2024-04-05 14:29:08 +02:00
080601b792 Ajustement du placement des score, tout est bien aligné et centré 2024-04-05 14:12:22 +02:00
c3b86cb68b Modification des données affichée dans la gestion des scores, ajout de la notion Total et Manche (affichage de la manche courante et du score total) 2024-04-01 17:40:18 +02:00
44ce39bf3f Merge remote-tracking branch 'origin/soundboard-server' into DataWorking 2024-04-01 16:30:40 +02:00
068e24ba60 add mqtt soundplayer 2024-04-01 14:23:37 +00:00
995cca83ae Modification des données affichée dans la gestion des scores en vu d'une migration vers du dialog via WebSocket entre le serveur backend et le frontend 2024-04-01 15:03:27 +02:00
87bdf08b65 Ajout de l'affichage conditionnel pour le GameStatus, il ne s'affiche qu'en mode Présentateur pour que le GameMaster puisse avoir des infos sur la session courante 2024-04-01 14:00:52 +02:00
c9f82674de Merge branch 'AdaptationTablette' 2024-04-01 13:19:33 +02:00
ed78ffc158 Ajout des 4 emplacements de score dans le GameStatus, création du fichier de référence des variables pour le localstorage, désactivation du footer (pour l'instant) et arrangement pour le format de la tablette 2024-04-01 13:16:47 +02:00
83ce4b4fcc Modification du GameStatus avec ajout de la preview des buzzer connectés (juste l'UI Design pour l'instant) 2024-03-23 16:21:31 +01:00
3036190701 patch du margin bottom sous le statut du broker MQTT 2024-03-17 16:56:35 +01:00
e6a89c1561 Merge branch 'theme' 2024-03-17 16:50:41 +01:00
553b37654e Modification du thème et ajout de deux catégorie dans les paramètres 2024-03-17 16:49:50 +01:00
56bf47b91a Merge branch 'SettingsView' 2024-03-17 15:49:14 +01:00
745532c1b8 Remplacement des checkbox par des switch + création du thème 2024-03-17 15:47:42 +01:00
7e0687d3ca Merge branch 'SettingPage' 2024-03-17 12:39:51 +01:00
8a3185d694 V1 de la page avec une zone 'son' qui permet d'activer et régler le son intégré et d'activer le son MQTT 2024-03-17 12:36:05 +01:00
340fbd3812 V1 de la page avec une zone 'son' qui permet d'activer et régler le son intégré et d'activer le son MQTT 2024-03-17 12:34:59 +01:00
4c42f15dc6 Move brainblast vue app to ui repository 2024-03-16 21:17:43 +00:00
49 changed files with 1041 additions and 220 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>

Before

Width:  |  Height:  |  Size: 276 B

View File

@ -1,36 +0,0 @@
<template>
<v-card tile outlined class="card">
<v-card-title class="card__title primary">
<v-icon left class="white--text pr-5 pl-2" size="50">mdi-camera-control</v-icon>
Contrôles
</v-card-title>
<v-container class="text-center">
<v-row justify="center">
<v-col cols="12" sm="6" md="5" class="mt-4">
<mqtt-button width="240" height="130" class="btn xs12 sm6 md3" topic="/display/control" message="previous">
<v-icon left size="100">mdi-skip-previous</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="5" class="mt-4">
<mqtt-button width="240" height="130" class="btn card xs12 sm6 md3" topic="/display/control" message="next">
<v-icon left size="100">mdi-skip-next</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="5" class="mb-4">
<mqtt-button width="240" height="130" class="btn card xs12 sm6 md3" topic="/display/control" message="pause">
<v-icon left size="100">mdi-pause</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="5" class="mb-4">
<mqtt-button width="240" height="130" class="btn card xs12 sm6 md3 " topic="/display/control" message="play">
<v-icon left size="100">mdi-play</v-icon>
</mqtt-button>
</v-col>
</v-row>
</v-container>
</v-card>
</template>
<script setup>
import MqttButton from './MqttButton.vue';
</script>

View File

@ -1,43 +0,0 @@
<template>
<v-card tile outlined class="card" color="">
<v-card-title class="card__title primary">
<v-icon left class="white--text pr-5 pl-2" size="50">mdi-music-box-multiple</v-icon>
Soundboard
</v-card-title>
<v-container class="text-center">
<v-row justify="center">
<v-col cols="12" sm="6" md="4" class="mt-4">
<mqtt-button class="btn" width="200" height="130" topic="/sound/playsound" message="good-response" rounded>
<v-icon size="100">mdi-check-circle-outline</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="4" class="mt-4">
<mqtt-button class="btn" width="200" height="130" topic="/sound/playsound" message="bad-response" rounded>
<v-icon size="100">mdi-close-circle-outline</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="4" class="mt-4">
<mqtt-button class="btn" width="200" height="130" topic="/sound/playsound" message="timer" rounded>
<v-icon size="100">mdi-timer-outline</v-icon>
</mqtt-button>
</v-col>
</v-row>
<v-row justify="center">
<v-col cols="12" sm="6" md="4" class="mb-4">
<mqtt-button class="btn" width="220" height="130" topic="/sound/playsound" message="applause" rounded>
<v-icon size="100">mdi-human-handsup</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="s" class="mb-4">
<mqtt-button class="btn" width="220" height="130" topic="/sound/playsound" message="bell" rounded>
<v-icon size="100">mdi-bell-outline</v-icon>
</mqtt-button>
</v-col>
</v-row>
</v-container>
</v-card>
</template>
<script setup>
import MqttButton from './MqttButton.vue';
</script>

View File

@ -1,9 +0,0 @@
<template>
<v-navigation-drawer>
<v-list-item title="Brain Blast" subtitle="The cultural quizzzz"></v-list-item>
<v-divider></v-divider>
<v-list-item link title="List Item 1"></v-list-item>
<v-list-item link title="List Item 2"></v-list-item>
<v-list-item link title="List Item 3"></v-list-item>
</v-navigation-drawer>
</template>

View File

@ -1,24 +0,0 @@
<template>
<v-app-bar-nav-icon v-on:click="menu = !menu"></v-app-bar-nav-icon>
<v-menu v-model="menu" class="menu-below-bar">
<v-list>
<v-list-item v-for="route in routes" :key="route.name" :to="route.path">{{ route.name }}</v-list-item>
</v-list>
</v-menu>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const routes = router.options.routes
let menu = ref(false)
</script>
<style scoped>
.menu-below-bar {
margin-top: 48px; /* La hauteur de la barre d'application */
}
</style>

View File

@ -1 +0,0 @@
test

View File

@ -1,40 +0,0 @@
/**
* plugins/vuetify.js
*
* Framework documentation: https://vuetifyjs.com`
*/
// Styles
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/styles'
// Composables
import { createVuetify } from 'vuetify'
// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
export default createVuetify({
theme: {
themes: {
light: {
background: '#212121',
primary: '#cc0000',
controls: '#cc0000',
soundboard: '#9A2779',
secondary: '#b0bec5',
feedback: '#2E7D32',
accent: '#8c9eff',
error: '#b71c1c',
},
dark: {
background: '#121212',
primary: '#2979FF',
controls: '#AB47B',
secondary: '#90a4ae',
feedback: '#2E7D32',
accent: '#8c9eff',
error: '#b71c1c',
},
},
defaultTheme: 'dark',
}
})

View File

@ -1,24 +0,0 @@
<template>
<div class="about">
<h1>This is an about page</h1>
<hr/>
<p>
Exemple d'une page
</p><p>
Ou il y a un scroll
</p><p>
Pour mettre en valeur leu footer fixe en bas de page
</p><p>
Cette page n'a aucun interet et pourra etre supprimée
</p>
</div>
</template>
<style>
@media (min-width: 1024px) {
.about {
min-height: 100vh;
align-items: center;
}
}
</style>

View File

@ -1,11 +0,0 @@
<template>
<v-img width="1645" src="../assets/BrainBlast-For-HomeView-Alpha.png"></v-img>
</template>
<script>
export default {
name: 'VotreComposant', // Assurez-vous de donner un nom à votre composant
// Votre logique JavaScript ici, par exemple des méthodes, des données, etc.
};
</script>

View File

@ -10,19 +10,22 @@
"dependencies": {
"@mdi/font": "^7.4.47",
"mqtt": "^5.3.5",
"ping": "^0.4.4",
"roboto-fontface": "^0.10.0",
"vue": "^3.4.19",
"vue-router": "^4.2.5"
"vue-router": "^4.2.5",
"vuex": "^4.1.0"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.3.3",
"@vitejs/plugin-vue": "^5.0.3",
"@vue/eslint-config-prettier": "^8.0.0",
"concurrently": "^8.2.2",
"eslint": "^8.49.0",
"eslint-plugin-vue": "^9.17.0",
"prettier": "^3.0.3",
"unplugin-fonts": "^1.1.1",
"vite": "^5.1.4",
"vite": "^5.1.6",
"vite-plugin-vuetify": "^2.0.1"
}
},
@ -1171,6 +1174,20 @@
"node": ">= 6"
}
},
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@ -1227,6 +1244,48 @@
"node": ">= 6"
}
},
"node_modules/concurrently": {
"version": "8.2.2",
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz",
"integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==",
"dev": true,
"dependencies": {
"chalk": "^4.1.2",
"date-fns": "^2.30.0",
"lodash": "^4.17.21",
"rxjs": "^7.8.1",
"shell-quote": "^1.8.1",
"spawn-command": "0.0.2",
"supports-color": "^8.1.1",
"tree-kill": "^1.2.2",
"yargs": "^17.7.2"
},
"bin": {
"conc": "dist/bin/concurrently.js",
"concurrently": "dist/bin/concurrently.js"
},
"engines": {
"node": "^14.13.0 || >=16.0.0"
},
"funding": {
"url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
}
},
"node_modules/concurrently/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -1258,6 +1317,22 @@
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/date-fns": {
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
"integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
"dev": true,
"dependencies": {
"@babel/runtime": "^7.21.0"
},
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -1292,6 +1367,12 @@
"node": ">=6.0.0"
}
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@ -1341,6 +1422,15 @@
"@esbuild/win32-x64": "0.19.12"
}
},
"node_modules/escalade": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@ -1732,6 +1822,15 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@ -1888,6 +1987,15 @@
"node": ">=0.10.0"
}
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@ -2297,6 +2405,14 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/ping": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/ping/-/ping-0.4.4.tgz",
"integrity": "sha512-56ZMC0j7SCsMMLdOoUg12VZCfj/+ZO+yfOSjaNCRrmZZr6GLbN2X/Ui56T15dI8NhiHckaw5X2pvyfAomanwqQ==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/postcss": {
"version": "8.4.35",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
@ -2452,6 +2568,15 @@
"resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz",
"integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ=="
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@ -2551,6 +2676,15 @@
"queue-microtask": "^1.2.2"
}
},
"node_modules/rxjs": {
"version": "7.8.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
"dev": true,
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@ -2592,6 +2726,15 @@
"node": ">=8"
}
},
"node_modules/shell-quote": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
"integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
@ -2600,6 +2743,12 @@
"node": ">=0.10.0"
}
},
"node_modules/spawn-command": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz",
"integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==",
"dev": true
},
"node_modules/split2": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
@ -2635,6 +2784,20 @@
}
]
},
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@ -2705,6 +2868,15 @@
"node": ">=8.0"
}
},
"node_modules/tree-kill": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
"integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
"dev": true,
"bin": {
"tree-kill": "cli.js"
}
},
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
@ -2814,9 +2986,9 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/vite": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.4.tgz",
"integrity": "sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==",
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz",
"integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==",
"dev": true,
"dependencies": {
"esbuild": "^0.19.3",
@ -2980,6 +3152,17 @@
}
}
},
"node_modules/vuex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz",
"integrity": "sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==",
"dependencies": {
"@vue/devtools-api": "^6.0.0-beta.11"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/webpack-sources": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
@ -3041,6 +3224,23 @@
"tslib": "^2.6.2"
}
},
"node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@ -3076,12 +3276,48 @@
"node": ">=12"
}
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
"dependencies": {
"cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"y18n": "^5.0.5",
"yargs-parser": "^21.1.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/yargs-parser": {
"version": "21.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",

View File

@ -1,10 +1,11 @@
{
"name": "brain-blast",
"version": "0.0.0",
"private": true,
"private": false,
"type": "module",
"scripts": {
"dev": "vite",
"dev-complete": "concurrently \"vite\" \"node ./src/services/buzzerWatcher.js\"",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
@ -13,19 +14,22 @@
"dependencies": {
"@mdi/font": "^7.4.47",
"mqtt": "^5.3.5",
"ping": "^0.4.4",
"roboto-fontface": "^0.10.0",
"vue": "^3.4.19",
"vue-router": "^4.2.5"
"vue-router": "^4.2.5",
"vuex": "^4.1.0"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.3.3",
"@vitejs/plugin-vue": "^5.0.3",
"@vue/eslint-config-prettier": "^8.0.0",
"concurrently": "^8.2.2",
"eslint": "^8.49.0",
"eslint-plugin-vue": "^9.17.0",
"prettier": "^3.0.3",
"unplugin-fonts": "^1.1.1",
"vite": "^5.1.4",
"vite": "^5.1.6",
"vite-plugin-vuetify": "^2.0.1"
}
}

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,11 +1,11 @@
<template>
<v-app>
<BrainBlastBar />
<GameStatus />
<GameStatus v-if="$route.name === 'Game Control (Présentateur)'"></GameStatus>
<v-main>
<RouterView />
</v-main>
<v-footer class="footer" :elevation=12 border><v-row justify="center">© 2024 - ASCO section Fablab</v-row></v-footer>
<!-- <v-footer class="footer" :elevation=12 border><v-row justify="center">© 2024 - ASCO section Fablab</v-row></v-footer> -->
</v-app>
</template>

View File

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 MiB

View File

Before

Width:  |  Height:  |  Size: 768 KiB

After

Width:  |  Height:  |  Size: 768 KiB

BIN
ui/src/assets/design.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

View File

@ -1,7 +1,7 @@
<template>
<v-app-bar :elevation="5">
<v-app-bar :elevation="5" height="50">
<RouterMenu />
<v-app-bar-title>Brain Blast</v-app-bar-title>
<v-app-bar-title v-if="$route.name !== 'Accueil'">Brain Blast</v-app-bar-title>
<template v-slot:append>
<v-btn icon @click="toggleTheme">
@ -21,7 +21,7 @@
function toggleTheme() {
darkTheme.value = !darkTheme.value
theme.global.name.value = theme.global.current.value.dark ? 'light' : 'dark'
theme.global.name.value = theme.global.current.value.dark ? 'CustomThemeLight' : 'CustomThemeDark'
}
</script>

View File

@ -0,0 +1,54 @@
<template>
<v-card tile outlined :class="{ 'card--reduced': isCardReduced }">
<v-card-title class="card__title primary" @click="toggleCardSize">
<v-icon left class="white--text pr-5 pl-2" size="40">mdi-camera-control</v-icon>
Contrôles
</v-card-title>
<v-container class="text-center">
<v-row justify="center">
<v-col cols="12" sm="6" md="5" class="mt-4">
<mqtt-button width="220" height="110" class="btn xs12 sm6 md3" topic="/display/control" message="previous">
<v-icon left size="80">mdi-skip-previous</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="5" class="mt-4">
<mqtt-button width="240" height="110" class="btn card xs12 sm6 md3" topic="/display/control" message="next">
<v-icon left size="80">mdi-skip-next</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="5" class="mb-4">
<mqtt-button width="240" height="110" class="btn card xs12 sm6 md3" topic="/display/control" message="pause">
<v-icon left size="80">mdi-pause</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="5" class="mb-4">
<mqtt-button width="240" height="110" class="btn card xs12 sm6 md3 " topic="/display/control" message="play">
<v-icon left size="80">mdi-play</v-icon>
</mqtt-button>
</v-col>
</v-row>
</v-container>
</v-card>
</template>
<script setup>
import MqttButton from './MqttButton.vue';
import { ref } from 'vue';
// Variable pour contrôler l'état de la carte
const isCardReduced = ref(false);
// Méthode pour basculer l'état de la carte
function toggleCardSize() {
isCardReduced.value = !isCardReduced.value;
}
</script>
<style>
.card--reduced {
height: 56px; /* Réglez la hauteur réduite selon vos besoins */
width: 170px;
overflow: hidden;
transition: height 0.3s ease-in-out;
}
</style>

View File

@ -0,0 +1,161 @@
<template>
<div class="label-pos">
<v-label class="labelTitle-style pb-4">Scores</v-label>
</div>
<!-- Équipes Rouges et Bleues côte à côte -->
<v-row no-gutters class="scorebox-pos">
<!-- Équipe Rouge -->
<v-col cols="6"> <!-- Colonnes de taille 6 pour chaque équipe -->
<v-row no-gutters>
<v-col class="scorediv-style-red">
<div>
<v-label class="labelRoundScore-style pt-3">Manche</v-label>
<div>
<v-label class="labelRoundScore-style">{{ RedRoundScore }}</v-label>
</div>
</div>
<v-divider color="background"/>
<div>
<v-label class="labelTotalScore-style pt-3">Total</v-label>
<div>
<v-label class="labelTotalScore-style pb-3">{{ RedTotalScore }}</v-label>
</div>
</div>
</v-col>
</v-row>
</v-col>
<!-- Équipe Bleue -->
<v-col cols="6">
<v-row no-gutters>
<v-col class="scorediv-style-blue">
<div>
<v-label class="labelRoundScore-style pt-3">Manche</v-label>
<div>
<v-label class="labelRoundScore-style">{{ BlueRoundScore }}</v-label>
</div>
</div>
<v-divider color="background"/>
<div>
<v-label class="labelTotalScore-style pt-3">Total</v-label>
<div>
<v-label class="labelTotalScore-style pb-3">{{ BlueTotalScore }}</v-label>
</div>
</div>
</v-col>
</v-row>
</v-col>
</v-row>
<!-- Équipes Oranges et Vertes côte à côte -->
<v-row no-gutters class="scorebox-pos">
<!-- Équipe Orange -->
<v-col cols="6">
<v-row no-gutters>
<v-col class="scorediv-style-orange">
<div>
<v-label class="labelRoundScore-style pt-3">Manche</v-label>
<div>
<v-label class="labelRoundScore-style">{{ OrangeRoundScore }}</v-label>
</div>
</div>
<v-divider color="background"/>
<div>
<v-label class="labelTotalScore-style pt-3">Total</v-label>
<div>
<v-label class="labelTotalScore-style pb-3">{{ OrangeTotalScore }}</v-label>
</div>
</div>
</v-col>
</v-row>
</v-col>
<!-- Équipe Verte -->
<v-col cols="6">
<v-row no-gutters>
<v-col class="scorediv-style-green">
<div>
<v-label class="labelRoundScore-style pt-3">Manche</v-label>
<div>
<v-label class="labelRoundScore-style">{{ GreenRoundScore }}</v-label>
</div>
</div>
<v-divider color="background"/>
<div>
<v-label class="labelTotalScore-style pt-3">Total</v-label>
<div>
<v-label class="labelTotalScore-style pb-3">{{ GreenTotalScore }}</v-label>
</div>
</div>
</v-col>
</v-row>
</v-col>
</v-row>
</template>
<script setup>
import { ref } from 'vue'; // Import des fonctions de Vue 3
import variables from '@/variables.js';
// Déclaration des variables locales pour les scores
const RedTotalScore = ref(variables.RedTotalScore);
const BlueTotalScore = ref(variables.BlueTotalScore);
const OrangeTotalScore = ref(variables.OrangeTotalScore);
const GreenTotalScore = ref(variables.GreenTotalScore);
const RedRoundScore = ref(variables.RedRoundScore);
const BlueRoundScore = ref(variables.BlueRoundScore);
const OrangeRoundScore = ref(variables.OrangeRoundScore);
const GreenRoundScore = ref(variables.GreenRoundScore);
</script>
<style>
.label-pos {
padding-top: 15px;
text-align: center;
}
.labelTitle-style {
font-size: 20px !important;
font-weight: 500;
color: #e91e1e !important;
opacity: 90% !important;
}
.labelRoundScore-style {
opacity: 100% !important;
font-size: 25px !important;
font-weight: 500;
}
.labelTotalScore-style {
opacity: 100% !important;
font-size: 15px !important;
font-weight: 500;
}
.button-pos {
padding-top: 10px;
padding-bottom: 15px;
}
.scorebox-pos {
text-align: center;
}
.scorediv-style-red {
background-color: #d42828 !important;
padding: 15px;
border-top-left-radius: 10%;
}
.scorediv-style-orange {
background-color: #d48f28 !important;
padding: 15px;
border-bottom-left-radius: 10%;
}
.scorediv-style-blue {
background-color: #2867d4 !important;
padding: 15px;
border-top-right-radius: 10%;
}
.scorediv-style-green {
background-color: #28d42e !important;
padding: 15px;
border-bottom-right-radius: 10%;
}
</style>

View File

@ -1,14 +1,14 @@
<template>
<v-card tile outlined class="card">
<v-card-title class="card__title feedback">
<v-icon left class="white--text pr-5 pl-2" size="50">mdi-play-network-outline</v-icon>
<v-card tile outlined :class="{ 'card--reduced': isCardReduced }">
<v-card-title class="card__title feedback" @click="toggleCardSize">
<v-icon left class="white--text pr-5 pl-2" size="40">mdi-play-network-outline</v-icon>
Solution
</v-card-title>
<v-container class="text-center">
<v-row justify="center">
<v-container class="text-center">
<!-- Utilisation de styles CSS personnalisés pour centrer l'image -->
<v-img width="450" src="https://c4.wallpaperflare.com/wallpaper/908/893/291/funny-middle-finger-black-background-wallpaper-preview.jpg" style="margin: 0 auto;"></v-img>
<v-img width="400" src="https://c4.wallpaperflare.com/wallpaper/908/893/291/funny-middle-finger-black-background-wallpaper-preview.jpg" style="margin: 0 auto;"></v-img>
</v-container>
</v-row>
</v-container>
@ -27,4 +27,22 @@
display: block; /* Pour éviter l'espace réservé pour les images */
}
}
.card--reduced {
height: 56px; /* Réglez la hauteur réduite selon vos besoins */
width: 160px;
overflow: hidden;
transition: height 0.6s ease-in-out;
}
</style>
<script setup>
import { ref } from 'vue';
// Variable pour contrôler l'état de la carte
const isCardReduced = ref(false);
// Méthode pour basculer l'état de la carte
function toggleCardSize() {
isCardReduced.value = !isCardReduced.value;
}
</script>

View File

@ -0,0 +1,61 @@
<template>
<v-card tile outlined :class="{ 'card--reduced': isCardReduced }">
<v-card-title class="card__title primary" @click="toggleCardSize">
<v-icon left class="white--text pr-5 pl-2" size="40">mdi-music-box-multiple</v-icon>
Soundboard
</v-card-title>
<v-container class="text-center">
<v-row justify="center">
<v-col cols="12" sm="6" md="4" class="mt-4">
<mqtt-button class="btn" width="200" height="110" topic="/sound/playsound" message="good-response" rounded>
<v-icon size="70">mdi-check-circle-outline</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="4" class="mt-4">
<mqtt-button class="btn" width="200" height="110" topic="/sound/playsound" message="bad-response" rounded>
<v-icon size="70">mdi-close-circle-outline</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="4" class="mt-4">
<mqtt-button class="btn" width="200" height="110" topic="/sound/playsound" message="timer" rounded>
<v-icon size="70">mdi-timer-outline</v-icon>
</mqtt-button>
</v-col>
</v-row>
<v-row justify="center">
<v-col cols="12" sm="6" md="4" class="mb-4">
<mqtt-button class="btn" width="220" height="110" topic="/sound/playsound" message="applause" rounded>
<v-icon size="70">mdi-human-handsup</v-icon>
</mqtt-button>
</v-col>
<v-col cols="12" sm="6" md="4" class="mb-4">
<mqtt-button class="btn" width="220" height="110" topic="/sound/playsound" message="bell" rounded>
<v-icon size="70">mdi-bell-outline</v-icon>
</mqtt-button>
</v-col>
</v-row>
</v-container>
</v-card>
</template>
<script setup>
import MqttButton from './MqttButton.vue';
import { ref } from 'vue';
// Variable pour contrôler l'état de la carte
const isCardReduced = ref(false);
// Méthode pour basculer l'état de la carte
function toggleCardSize() {
isCardReduced.value = !isCardReduced.value;
}
</script>
<style scoped>
.card--reduced {
height: 56px; /* Réglez la hauteur réduite selon vos besoins */
width: 190px;
overflow: hidden;
transition: height 0.3s ease-in-out;
}
</style>

View File

@ -0,0 +1,118 @@
<template>
<div class="container">
<div class="timer">
<v-label color="primary" class="labelTime-style" >{{ formatTime }}</v-label>
</div>
<v-row no-gutters justify="space-around" >
<v-btn class="buttons" color="primary" icon="mdi-play" @click="startTimer"></v-btn>
<v-btn color="primary" icon="mdi-pause" @click="pauseTimer"></v-btn>
<v-btn color="primary" icon="mdi-restart" @click="resetTimer"></v-btn>
</v-row>
</div>
</template>
<script setup>
import { ref, computed, onBeforeUnmount } from 'vue';
const timerActive = ref(false);
const startTime = ref(null);
const currentTime = ref(null);
const elapsedTime = ref(0);
const formatTime = computed(() => {
let seconds = Math.floor(elapsedTime.value / 1000);
let minutes = Math.floor(seconds / 60);
let hours = Math.floor(minutes / 60);
seconds = seconds % 60;
minutes = minutes % 60;
return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
});
const pad = (number) => {
return (number < 10 ? "0" : "") + number;
};
const startTimer = () => {
if (!timerActive.value) {
timerActive.value = true;
startTime.value = Date.now() - elapsedTime.value;
updateTimer();
}
};
const pauseTimer = () => {
if (timerActive.value) {
timerActive.value = false;
clearInterval(currentTime.value);
}
};
const resetTimer = () => {
elapsedTime.value = 0;
timerActive.value = false;
clearInterval(currentTime.value);
};
const updateTimer = () => {
currentTime.value = setInterval(() => {
elapsedTime.value = Date.now() - startTime.value;
}, 1000);
};
onBeforeUnmount(() => {
clearInterval(currentTime.value);
});
</script>
<script>
const startTimer = () => {
if (!timerActive.value) {
timerActive.value = true;
startTime.value = Date.now() - elapsedTime.value;
updateTimer();
}
};
const pauseTimer = () => {
if (timerActive.value) {
timerActive.value = false;
clearInterval(currentTime.value);
}
};
const resetTimer = () => {
elapsedTime.value = 0;
timerActive.value = false;
clearInterval(currentTime.value);
};
export { startTimer, pauseTimer, resetTimer };
</script>
<style>
.container {
text-align: center;
margin-top: auto; /* Place le container en bas de son parent */
margin-bottom: 1px; /* Marge en bas pour un espacement */
position: fixed; /* Le positionne de manière fixe */
left: 0;
right: 0;
bottom: 0;
padding: 20px;
}
.timer {
margin-bottom: 15px;
}
.labelTime-style {
font-size: 30px !important;
font-weight: 500;
color: #e91e1e !important;
opacity: 90% !important;
}
.buttons{
background-color: rgb(255, 255, 255);
}
</style>

View File

@ -0,0 +1,45 @@
<template>
<v-navigation-drawer width="250"> <!-- Augmenter la largeur pour deux équipes côte à côte -->
<div class="label-pos">
<v-label class="labelTitle-style">Buzzer connectés</v-label>
</div>
<v-row no-gutters justify="space-around" class="button-pos">
<v-icon color="BuzzerRed">mdi-radiobox-marked</v-icon>
<v-icon color="BuzzerBlue">mdi-radiobox-marked</v-icon>
<v-icon color="BuzzerOrange">mdi-radiobox-marked</v-icon>
<v-icon color="BuzzerGreen">mdi-radiobox-marked</v-icon>
</v-row>
<v-divider :thickness="2" class="border-opacity-100" color="primary"/>
<CardScore/>
<CardTimer/>
</v-navigation-drawer>
</template>
<script setup>
import CardTimer from '@/components/CardTimer.vue'
import CardScore from '@/components/CardScore.vue'
import { ref } from 'vue'; // Import des fonctions de Vue 3
import variables from '@/variables.js';
</script>
<style>
.label-pos {
padding-top: 15px;
text-align: center;
}
.labelTitle-style {
font-size: 20px !important;
font-weight: 500;
color: #e91e1e !important;
opacity: 90% !important;
}
.button-pos {
padding-top: 10px;
padding-bottom: 15px;
}
</style>

View File

@ -0,0 +1,29 @@
<template>
<v-app-bar-nav-icon v-on:click="menu = !menu"></v-app-bar-nav-icon>
<v-menu v-model="menu" class="menu-below-bar">
<v-list>
<v-list-item v-for="route in filteredRoutes" :key="route.name" :to="route.path">{{ route.name }}</v-list-item>
</v-list>
</v-menu>
</template>
<script setup>
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const routes = router.options.routes;
let menu = ref(false);
// Filtrer les routes pour masquer une route spécifique (par exemple, 'RouteA')
const filteredRoutes = computed(() => {
return routes.filter(route => route.name !== 'Debugger MQTT');
});
</script>
<style scoped>
.menu-below-bar {
margin-top: 48px; /* La hauteur de la barre d'application */
}
</style>

16
ui/src/config.js Normal file
View File

@ -0,0 +1,16 @@
// Fichier vide, regarde config.js.example pour personaliser ce fichier.
// Note de dev : Normalement ce fichier ne devrait plus avoir de
// modifications
// config.js
export default {
mqttBrokerUrl: 'ws://192.168.1.78:9001',
// Buzzer
redBuzzerIP: '',
blueBuzzerIP: '',
orangeBuzzerIP: '',
greenBuzzerIP: ''
// Light
};

View File

@ -6,17 +6,9 @@ const router = createRouter({
routes: [
{
path: '/',
name: 'Home',
name: 'Accueil',
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: '/game/control',
name: 'Game Control (Présentateur)',
@ -31,6 +23,11 @@ const router = createRouter({
path: '/mqtt-debugger',
name: 'Debugger MQTT',
component: () => import('@/views/MQTTDebugView.vue')
},
{
path: '/settings',
name: 'Paramètres',
component: () => import('@/views/SettingsView.vue')
}
]
})

58
ui/src/plugins/vuetify.js Normal file
View File

@ -0,0 +1,58 @@
/**
* plugins/vuetify.js
*
* Framework documentation: https://vuetifyjs.com`
*/
// Styles
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/styles'
// Composables
import { createVuetify } from 'vuetify'
const CustomThemeDark = {
dark: true,
colors: {
background: '#121212',
primary: '#e91e1e',
secondary: '#F44336',
accent: '#FFC107',
error: '#e91e1e',
warning: '#FFC107',
info: '#607D8B',
success: '#e91e1e',
BuzzerBlue: '#2867d4',
BuzzerOrange: '#d48f28',
BuzzerRed: '#d42828',
BuzzerGreen: '#28d42e',
}
}
const CustomThemeLight = {
dark: false,
colors: {
background: '#ffffff',
primary: '#e91e1e',
secondary: '#F44336',
accent: '#FFC107',
error: '#e91e1e',
warning: '#FFC107',
info: '#607D8B',
success: '#4CAF50',
BuzzerBlue: '#2867d4',
BuzzerOrange: '#d48f28',
BuzzerRed: '#d42828',
BuzzerGreen: '#28d42e',
}
}
// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
export default createVuetify({
theme: {
defaultTheme: 'CustomThemeDark',
themes: {
CustomThemeDark,
CustomThemeLight,
},
},
})

View File

@ -0,0 +1,66 @@
// index.js
import Vue from 'vue';
import Vuex from 'vuex';
import ping from 'ping';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
buzzerRedState: '',
buzzerBlueState: '',
buzzerOrangeState: '',
buzzerGreenState: ''
},
mutations: {
setBuzzerRedState(state, newState) {
state.buzzerRedState = newState;
},
setBuzzerBlueState(state, newState) {
state.buzzerBlueState = newState;
},
setBuzzerOrangeState(state, newState) {
state.buzzerOrangeState = newState;
},
setBuzzerGreenState(state, newState) {
state.buzzerGreenState = newState;
}
},
actions: {
updateBuzzerStates({ commit }, { index, newState }) {
switch (index) {
case 0:
commit('setBuzzerRedState', newState);
break;
case 1:
commit('setBuzzerBlueState', newState);
break;
case 2:
commit('setBuzzerOrangeState', newState);
break;
case 3:
commit('setBuzzerGreenState', newState);
break;
default:
console.error('Index de buzzer invalide:', index);
}
}
}
});
const hosts = ['192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.4'];
async function pingHosts() {
hosts.forEach(async (host, index) => {
try {
const res = await ping.promise.probe(host);
store.dispatch('updateBuzzerStates', { index, newState: res.alive ? 'ON' : 'OFF' });
} catch (error) {
console.error(`Erreur lors du ping de ${host}:`, error.message);
}
});
}
pingHosts();
module.exports = store;

32
ui/src/variables.js Normal file
View File

@ -0,0 +1,32 @@
export default {
// Gestion des score et des Buzzers
// Scores totaux
RedTotalScore: 11,
BlueTotalScore: 22,
GreenTotalScore: 33,
OrangeTotalScore: 44,
// Score de la manche courante
RedRoundScore: 1,
BlueRoundScore: 2,
OrangeRoundScore: 3,
GreenRoundScore: 4,
//Etat des buzzer
BuzzerRed: false,
BuzzerBlue: false,
BuzzerOrange: false,
BuzzerGreen: false,
// Ajoutez d'autres variables globales ici
};
// Variables localStorage
export const localStorageVars = {
// Exemple de variable localStorage
RedScorelocal: localStorage.getItem('RedScore') || '',
BlueScorelocal: localStorage.getItem('BlueScore') || '',
OrangeScorelocal: localStorage.getItem('OrangeScore') || '',
GreenScorelocal: localStorage.getItem('GreenScore') || '',
};

View File

@ -9,13 +9,13 @@
</v-col>
</v-row>
</v-container>
<v-container>
<v-row no-gutters>
<v-row no-gutters class="pr-4 pl-4">
<v-col>
<card-solution />
</v-col>
</v-row>
</v-container>
</template>
<script setup>
@ -29,14 +29,14 @@ import CardSoundboard from '@/components/CardSoundboard.vue';
<style>
@media (min-width: 1024px) {
.card__title.primary {
background-color: #2979FF; /* Changez la couleur en fonction de votre thème */
background-color: #e91e1e; /* Changez la couleur en fonction de votre thème */
}
.card__title.feedback {
background-color: #2E7D32; /* Changez la couleur en fonction de votre thème */
}
.btn{
border-radius:30px!important;
background-color: #2979FF; /* Changez la couleur en fonction de votre thème */
background-color: #e91e1e; /* Changez la couleur en fonction de votre thème */
}
}
</style>

View File

@ -0,0 +1,3 @@
<template>
</template>

View File

@ -0,0 +1,3 @@
<template>
<v-img src="../assets/BrainBlast-For-HomeView-Alpha.png" class="fill-height"></v-img>
</template>

View File

@ -0,0 +1,109 @@
<template>
<v-label class="title-style-1">Paramètres</v-label>
<v-divider :thickness="2" class="border-opacity-100" color="primary"/>
<v-label class="title-style-2">Son</v-label>
<div class="mutltiple-per-line">
<v-switch hide-details label="Activer le son intégré" v-model="EmbeddedSound" class="ml-15" color="primary"/>
<div>
<v-slider hide-details class="v-slider-style ml-15" :disabled="EmbeddedSound === false" v-model="EmbeddedSoundVolume" color="primary"/>
</div>
</div>
<v-switch label="Activer le son MQTT" v-model="MQTTSound" class="ml-15" color="primary"/>
<v-divider />
<v-label class="title-style-2">Affichage</v-label>
<v-switch label="Activer l'affichage des sattelites" v-model="SattelitesDisplay" class="ml-15" color="primary"/>
<v-divider />
<v-label class="title-style-2">MQTT</v-label>
<div class="mutltiple-per-line">
<v-icon v-model="MQTTBrokerState" class="ml-15 mb-5" color="error" icon="record">mdi-record</v-icon>
<v-label class="ml-2 mb-10 mt-5">Etat du serveur MQTT</v-label>
<v-btn class="ml-10 mb-5" color="primary" @click="goToDebugRoute">Debugger</v-btn>
</div>
<v-divider />
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useRouter } from 'vue-router';
const EmbeddedSound = ref(false); // Définition d'une référence pour la case à cocher. Initialement décochée.
const EmbeddedSoundVolume = ref(50); // Définition d'une référence pour la case à cocher. Initialement décochée.
const MQTTSound = ref(false); // Définition d'une référence pour la case à cocher. Initialement décochée.
const MQTTBrokerState = ref(false); // Définition d'une référence pour la case à cocher. Initialement décochée.
const SattelitesDisplay = ref(false);
const router = useRouter();
const goToDebugRoute = () => {
router.push({ name: 'Debugger MQTT' }); // Redirige vers la route nommée 'debugger'
};
onMounted(() => {
if (localStorage.getItem('EmbeddedSound')) {
EmbeddedSound.value = localStorage.getItem('EmbeddedSound') === 'true'; // Si l'état de la case à cocher est stocké, le mettre dans la référence
}
if (localStorage.getItem('MQTTSound')) {
MQTTSound.value = localStorage.getItem('MQTTSound') === 'true'; // Si l'état de la case à cocher est stocké, le mettre dans la référence
}
if (localStorage.getItem('EmbeddedSoundVolume')) {
EmbeddedSoundVolume.value = localStorage.getItem('EmbeddedSoundVolume'); // Si l'état de la case à cocher est stocké, le mettre dans la référence
}
if (localStorage.getItem('SattelitesDisplay')) {
SattelitesDisplay.value = localStorage.getItem('SattelitesDisplay') === 'true'; // Added a default value for this switch
}
});
watch(EmbeddedSound, (EmbeddedSoundNewValue) => {
if (EmbeddedSoundNewValue !== null) {
localStorage.setItem('EmbeddedSound', EmbeddedSoundNewValue); // Mettre à jour l'état de la case à cocher dans le LocalStorage chaque fois qu'il change.
}
});
watch(EmbeddedSoundVolume, (EmbeddedSoundVolumeNewValue) => {
if (EmbeddedSoundVolumeNewValue !== null) {
localStorage.setItem('EmbeddedSoundVolume', EmbeddedSoundVolumeNewValue); // Mettre à jour l'état de la case à cocher dans le LocalStorage chaque fois qu'il change.
}
});
watch(MQTTSound, (MQTTSoundNewValue) => {
if (MQTTSoundNewValue !== null) {
localStorage.setItem('MQTTSound', MQTTSoundNewValue); // Mettre à jour l'état de la case à cocher dans le LocalStorage chaque fois qu'il change.
}
});
watch(SattelitesDisplay, (SattelitesDisplaynewValue) => {
if (SattelitesDisplaynewValue !== null) {
localStorage.setItem('SattelitesDisplay', SattelitesDisplaynewValue); // Added a default value for this switch
}
});
</script>
<style>
.title-style-1{
margin-top: 20px;
margin-bottom: 16px;
margin-left: 20px;
font-size: 30px;
opacity: 100%;
font-weight: 500;
}
.title-style-2{
margin-top: 20px;
margin-bottom: 10px;
margin-left: 40px;
font-size: 25px;
opacity: 100%;
font-weight: 500;
}
.mutltiple-per-line{
display: flex;
align-items: center;
}
.v-slider-style{
width: 250px;
margin-left: 16px;
padding-top: px;
}
</style>