diff --git a/quasar.config.ts b/quasar.config.ts index 228e865..0da3e7a 100644 --- a/quasar.config.ts +++ b/quasar.config.ts @@ -112,7 +112,7 @@ export default defineConfig((/* ctx */) => { config: { dark: true, }, - // iconSet: 'material-icons', // Quasar icon set + iconSet: 'material-icons', // Quasar icon set // lang: 'en-US', // Quasar language pack // For special cases outside of where the auto-import strategy can have an impact diff --git a/src/boot/socket.ts b/src/boot/socket.ts index b460875..b848e8d 100644 --- a/src/boot/socket.ts +++ b/src/boot/socket.ts @@ -37,7 +37,7 @@ interface ClientToServerEvents { request_update: (callback: (response: { statusUpdate: StatusUpdate }) => void) => void; command: ( command: string, - callback: (response: { success: boolean; message?: string }) => void, + callback: (response: { status: boolean; message?: string }) => void, ) => void; shutdown: ( delay: number, diff --git a/src/components/ConfirmCommandDiaglog.vue b/src/components/ConfirmCommandDiaglog.vue new file mode 100644 index 0000000..c24639c --- /dev/null +++ b/src/components/ConfirmCommandDiaglog.vue @@ -0,0 +1,32 @@ + + + + + + + Are you sure you want to {{ name }} ? + + + + + + + + + + + diff --git a/src/components/MenuBar.vue b/src/components/MenuBar.vue index 3293d7a..03e993b 100644 --- a/src/components/MenuBar.vue +++ b/src/components/MenuBar.vue @@ -2,6 +2,13 @@ import { useLeafletStore } from 'stores/leaflet'; import type { coords } from 'src/types'; import { storeToRefs } from 'pinia'; +import { socket } from 'boot/socket'; +import ConfirmCommandDialog from 'components/ConfirmCommandDiaglog.vue'; +import { useQuasar } from 'quasar'; +import { useRoute } from 'vue-router'; + +const route = useRoute(); +const $q = useQuasar(); const leafletStore = useLeafletStore(); const { center, markerLatLng } = storeToRefs(leafletStore); @@ -15,6 +22,38 @@ const home = { icon: 'home', }; +interface Control { + id: number; + name: string; + cmd: string; + icon: string; + confirm: boolean; +} + +const controls: Control[] = [ + { + id: 1, + name: 'Start Location Sim', + cmd: 'start_location_simulation', + icon: 'play_arrow', + confirm: false, + }, + { + id: 3, + name: 'End Location Sim', + cmd: 'end_location_simulation', + icon: 'stop', + confirm: true, + }, + { + id: 3, + name: 'Shutdown', + cmd: 'shutdown', + icon: 'power_settings_new', + confirm: true, + }, +]; + const favorites = [ { id: 1, @@ -49,17 +88,47 @@ function handleFavClick(coords: coords) { center.value = [coords.lat, coords.lng]; markerLatLng.value = [coords.lat, coords.lng]; } + +function handleControlClick(ctrl: Control) { + if (ctrl.confirm) { + $q.dialog({ + component: ConfirmCommandDialog, + componentProps: { + name: ctrl.name, + }, + }) + .onOk(() => { + socket.emit('command', ctrl.cmd, (response) => { + console.log(response.status); + }); + }) + .onCancel(() => { + console.log('Dialog cancelled'); + }) + .onDismiss(() => { + console.log('Dialog dismissed'); + }); + } else { + socket.emit('command', ctrl.cmd, (response) => { + console.log(response.status); + }); + } +} - + - - - - + + + + + + + + + + {{ ctrl.name }} + + + + diff --git a/src/components/SocketTest.vue b/src/components/SocketTest.vue index bd7f8b0..6cd128c 100644 --- a/src/components/SocketTest.vue +++ b/src/components/SocketTest.vue @@ -5,7 +5,7 @@ import { computed } from 'vue'; const statusStore = useStatusStore(); -const socketStatus = computed(() => statusStore.socketConnected ? 'green' : 'red'); +const socketStatus = computed(() => statusStore.statusList.socketConnected ? 'green' : 'red'); socket.off(); statusStore.socketConnect(); diff --git a/src/components/StatusBar.vue b/src/components/StatusBar.vue index a3e553f..b16daf5 100644 --- a/src/components/StatusBar.vue +++ b/src/components/StatusBar.vue @@ -1,38 +1,35 @@ - {{ statusDev.deviceName }} + + Status: + + + WebSocket + + + + Device Connection + + + + tunneld + + + + Location Simulation + + diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss index 2605a0d..2e32ba3 100644 --- a/src/css/quasar.variables.scss +++ b/src/css/quasar.variables.scss @@ -12,12 +12,12 @@ // to match your app's branding. // Tip: Use the "Theme Builder" on Quasar's documentation website. -$primary: #1976d2; -$secondary: #26a69a; +$primary: #02006c; +$secondary: #010057; $accent: #9c27b0; $dark: #1d1d1d; -$dark-page: #121212; +$dark-page: #03002e; $positive: #21ba45; $negative: #c10015; diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 771901d..8caff60 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -1,12 +1,34 @@ - - - + + + - + - + + + + + + + + + + {{ menuItem.label }} + + + + + + + @@ -14,6 +36,69 @@ diff --git a/src/router/routes.ts b/src/router/routes.ts index 9b91a3f..7d15658 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -5,8 +5,23 @@ const routes: RouteRecordRaw[] = [ path: '/', component: () => import('layouts/MainLayout.vue'), children: [ - { path: '', component: () => import('pages/IndexPage.vue') }, - { path: 'test', component: () => import('pages/TestPage.vue') }, + { + path: '', + name: 'home', + redirect: { + name: 'Leaflet', + }, + }, + { + path: 'leaflet', + name: 'Leaflet', + component: () => import('pages/IndexPage.vue'), + }, + { + path: 'test', + name: 'Test', + component: () => import('pages/TestPage.vue') + }, ], }, @@ -14,6 +29,7 @@ const routes: RouteRecordRaw[] = [ // but you can also remove it { path: '/:catchAll(.*)*', + name: 'ErrorNotFound', component: () => import('pages/ErrorNotFound.vue'), }, ]; diff --git a/src/stores/status.ts b/src/stores/status.ts index 59a9339..76a3bbd 100644 --- a/src/stores/status.ts +++ b/src/stores/status.ts @@ -4,15 +4,20 @@ import { socket } from 'boot/socket'; export const useStatusStore = defineStore('status', { state: () => ({ device: {}, - socketConnected: false, + statusList: { + socketConnected: false, + deviceConnected: false, + tunnelConnected: false, + simulationRunning: false, + }, }), actions: { bindEvents() { socket.on('connect', () => { - this.socketConnected = true; + this.statusList.socketConnected = true; }); socket.on('disconnect', () => { - this.socketConnected = false; + this.statusList.socketConnected = false; }); socket.on('status_update', (data) => { this.$patch((state) => {