aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateja Marić <mail@matejamaric.com>2021-03-22 15:21:40 +0100
committerGitHub <noreply@github.com>2021-03-22 15:21:40 +0100
commit6ab102bc4be617255d5eab77faebb1cada65b370 (patch)
tree09fcff5953cc6ca3702335e717ca72f865124d1c
parent21e9e94e76a21516edc3d1e4d0462a0ba75aafa4 (diff)
parentdb976a9fb0434df0095ea9f1b8858213d57e7535 (diff)
downloadyota-laravel-6ab102bc4be617255d5eab77faebb1cada65b370.tar.gz
yota-laravel-6ab102bc4be617255d5eab77faebb1cada65b370.zip
Merge pull request #4 from MatejaMaric/use-vueHEADv2.0.0master
Use Vue.js and Vuex.
-rw-r--r--app/Http/Controllers/SpecialCallsController.php7
-rw-r--r--package-lock.json6
-rw-r--r--package.json3
-rw-r--r--public/js/activities.js49
-rw-r--r--public/js/reservations.js119
-rw-r--r--public/js/reserve.js9
-rw-r--r--resources/js/app.js19
-rw-r--r--resources/js/bootstrap.js8
-rw-r--r--resources/js/components/activities.vue53
-rw-r--r--resources/js/components/call-sign-description.vue56
-rw-r--r--resources/js/components/call-sign-filter.vue44
-rw-r--r--resources/js/components/reservation.vue59
-rw-r--r--resources/js/components/reservations.vue62
-rw-r--r--resources/js/store.js96
-rw-r--r--resources/views/layouts/app.blade.php3
-rw-r--r--resources/views/pages/activities.blade.php25
-rw-r--r--resources/views/pages/reservations.blade.php94
-rw-r--r--resources/views/pages/reserve.blade.php17
-rw-r--r--routes/web.php1
19 files changed, 419 insertions, 311 deletions
diff --git a/app/Http/Controllers/SpecialCallsController.php b/app/Http/Controllers/SpecialCallsController.php
index 025d955..a26af78 100644
--- a/app/Http/Controllers/SpecialCallsController.php
+++ b/app/Http/Controllers/SpecialCallsController.php
@@ -13,6 +13,13 @@ use App\Models\SpecialCall;
class SpecialCallsController extends Controller
{
+ public function index(Request $request)
+ {
+ //$data = SpecialCall::select('sign')->get()->toArray();
+ $data = SpecialCall::all()->toArray();
+ return $data;
+ }
+
public function create(Request $request)
{
$data = SpecialCall::all();
diff --git a/package-lock.json b/package-lock.json
index 9c0ccea..5f8bfbe 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9198,6 +9198,12 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true
},
+ "vuex": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
+ "integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==",
+ "dev": true
+ },
"watchpack": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
diff --git a/package.json b/package.json
index 3556d45..5c158cb 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"sass": "^1.32.8",
"sass-loader": "^8.0.2",
"vue": "^2.6.12",
- "vue-template-compiler": "^2.6.12"
+ "vue-template-compiler": "^2.6.12",
+ "vuex": "^3.6.2"
}
}
diff --git a/public/js/activities.js b/public/js/activities.js
deleted file mode 100644
index eacf4d3..0000000
--- a/public/js/activities.js
+++ /dev/null
@@ -1,49 +0,0 @@
-$.ajaxSetup({
- headers: {
- 'X-CSRF-TOKEN': $('input[name="csrf-token"]').attr('content')
- }
-});
-
-jQuery('select#call-sign').change(fillTable);
-jQuery(document).ready(fillTable);
-
-function fillTable() {
- tableData = jQuery('table#ajax-table>tbody').first();
- tableData.html('<tr><td class="font-weight-bold text-center" colspan="7">Loading...</td></tr>');
-
- sign = jQuery('select#call-sign').first().val();
-
- descDiv = jQuery('div#sign-desc-div');
- if (sign === 'all') {
- descDiv.empty();
- } else {
- jQuery.get('/special-calls/show/' + sign, function (data, status) {
- descDiv.html('<div class="card mt-1"><div class="card-body pb-1">' + data + '</div></div>');
- console.log(data);
- });
- }
-
- jQuery.post('/api/activities', {'call-sign': sign}, function (data, status) {
- if (status === 'success') {
- if (data.data.length > 0) {
- tableData.empty();
- for (i = 0, len = data.data.length; i < len; i++) {
- tr = '<tr><td>' + data.data[i].operatorCall + '</td>' +
- '<td>' + data.data[i].fromTime + '</td>' +
- '<td>' + data.data[i].toTime + '</td>' +
- '<td>' + data.data[i].specialCall + '</td>' +
- '<td>' + data.data[i].frequencies + '</td>' +
- '<td>' + data.data[i].modes + '</td>' +
- '<td>' + data.data[i].qso + '</td></tr>';
- tableData.append(tr);
- }
- }
- else {
- tableData.html('<tr><td class="font-weight-bold text-center" colspan="6">No data...</td></tr>');
- }
- }
- else {
- tableData.html('<tr><td class="font-weight-bold text-center" colspan="6">Error!</td></tr>');
- }
- });
-}
diff --git a/public/js/reservations.js b/public/js/reservations.js
deleted file mode 100644
index bc9c6de..0000000
--- a/public/js/reservations.js
+++ /dev/null
@@ -1,119 +0,0 @@
-$.ajaxSetup({
- headers: {
- 'X-CSRF-TOKEN': $('input[name="csrf-token"]').attr('content')
- }
-});
-
-jQuery('select#call-sign').change(fillTable);
-jQuery(document).ready(fillTable);
-
-function fillTable() {
- tableData = jQuery('table#ajax-table>tbody').first();
- tableData.html('<tr><td class="font-weight-bold text-center" colspan="13">Loading...</td></tr>');
-
- sign = jQuery('select#call-sign').first().val();
-
- jQuery.post('/special-calls/reservations', {'call-sign': sign}, function (data, status) {
- if (status === 'success') {
- if (data.data.length > 0) {
- tableData.empty();
- for (i = 0, len = data.data.length; i < len; i++) {
- tr = '<tr>';
- tr += '<td>' + data.data[i].id + '</td>';
- if (data.data[i].approved === 1)
- tr += '<td class="text-center"><input type="checkbox" checked></td>';
- else
- tr += '<td class="text-center"><input type="checkbox"></td>';
-
- tr +=
- '<td contenteditable="true">' + data.data[i].operatorCall + '</td>' +
- '<td contenteditable="true">' + data.data[i].qso + '</td>' +
- '<td contenteditable="true">' + data.data[i].fromTime + '</td>' +
- '<td contenteditable="true">' + data.data[i].toTime + '</td>' +
- '<td contenteditable="true">' + data.data[i].specialCall + '</td>' +
- '<td contenteditable="true">' + data.data[i].frequencies + '</td>' +
- '<td contenteditable="true">' + data.data[i].modes + '</td>' +
- '<td contenteditable="true">' + data.data[i].operatorName + '</td>' +
- '<td contenteditable="true">' + data.data[i].operatorEmail + '</td>' +
- '<td contenteditable="true">' + data.data[i].operatorPhone + '</td>';
- tr += '<td>';
- tr += "<button class=\"btn btn-primary mr-2\" onclick=\"btnAction('update', this)\">Update</button>";
- tr += "<button class=\"btn btn-warning mr-2\" onclick=\"btnAction('restore', this)\">Restore</button>";
- tr += "<button class=\"btn btn-danger\" onclick=\"btnAction('delete', this)\">Delete</button>";
- tr += '</td>';
- tr += '</tr>';
- tableData.append(tr);
- }
- }
- else {
- tableData.html('<tr><td class="font-weight-bold text-center" colspan="13">No data...</td></tr>');
- }
- }
- else {
- tableData.html('<tr><td class="font-weight-bold text-center" colspan="13">Error!</td></tr>');
- }
- });
-}
-
-function btnAction(action, btn) {
- trDom = btn.parentElement.parentElement;
- trData = trDom.children;
-
- actionData = {
- action: action,
- id: trData[0].innerText,
- approved: trData[1].firstElementChild.checked,
- operatorCall: trData[2].innerText,
- qso: trData[3].innerText,
- fromTime: trData[4].innerText,
- toTime: trData[5].innerText,
- specialCall: trData[6].innerText,
- frequencies: trData[7].innerText,
- modes: trData[8].innerText,
- operatorName: trData[9].innerText,
- operatorEmail: trData[10].innerText,
- operatorPhone: trData[11].innerText
- };
-
- if (actionData.action == 'delete') {
- if (confirm("Are you sure you want to delete reservation #" + actionData.id + " made by " + actionData.operatorCall + "?") === true)
- trDom.remove();
- else return;
- }
-
- jQuery.post('/api/reservations', actionData, function (response, status) {
- if (status === 'success') {
- try {
- // Handle various actions
- if (response.action == "update") {
- jQuery('#notice').html("Record #" + actionData.id + " updated.");
- } else if (response.action == "restore") {
- trData[1].firstElementChild.checked = response.approved == 1;
- trData[2].innerText = response.operatorCall;
- trData[3].innerText = response.qso;
- trData[4].innerText = response.fromTime;
- trData[5].innerText = response.toTime;
- trData[6].innerText = response.specialCall;
- trData[7].innerText = response.frequencies;
- trData[8].innerText = response.modes;
- trData[9].innerText = response.operatorName;
- trData[10].innerText = response.operatorEmail;
- trData[11].innerText = response.operatorPhone;
- jQuery('#notice').html("Record's #" + actionData.id + " data restored.");
- } else if (response.action == "delete") {
- jQuery('#notice').html("Record #" + actionData.id + " deleted.");
- } else {
- console.log("No action?");
- //console.log(data);
- }
- } catch {
- //console.log(data);
- alert("Bad input data!");
- }
- }
- else {
- console.log('AJAX error');
- alert("Bad input data!");
- }
- });
-}
diff --git a/public/js/reserve.js b/public/js/reserve.js
deleted file mode 100644
index 7a20c37..0000000
--- a/public/js/reserve.js
+++ /dev/null
@@ -1,9 +0,0 @@
-jQuery('select#special-call').change(setCallDesc);
-jQuery(document).ready(setCallDesc);
-
-function setCallDesc() {
- sign = jQuery('select#special-call').first().val();
- jQuery.get('/special-calls/show/' + sign, function (data, status) {
- jQuery('div#call-desc').html(data);
- });
-}
diff --git a/resources/js/app.js b/resources/js/app.js
index 40c55f6..b5fbbbf 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -1 +1,20 @@
require('./bootstrap');
+
+import Vue from 'vue';
+
+import store from './store.js';
+
+import callSignDescription from './components/call-sign-description.vue';
+
+import activitiesView from './components/activities.vue';
+import reservationsView from './components/reservations.vue';
+
+new Vue({
+ el: '#vue',
+ store,
+ components: {
+ callSignDescription,
+ activitiesView,
+ reservationsView
+ }
+});
diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js
index ffc0a2b..e5e0ab6 100644
--- a/resources/js/bootstrap.js
+++ b/resources/js/bootstrap.js
@@ -3,7 +3,13 @@ window._ = require('lodash');
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
-window.Vue = require('vue');
+let token = document.querySelector('meta[name="csrf-token"]');
+
+if (token) {
+ window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
+} else {
+ console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
+}
window.$ = window.jQuery = require('jquery');
window.Popper = require('popper.js');
diff --git a/resources/js/components/activities.vue b/resources/js/components/activities.vue
new file mode 100644
index 0000000..1b1057c
--- /dev/null
+++ b/resources/js/components/activities.vue
@@ -0,0 +1,53 @@
+<template>
+ <div>
+ <call-sign-filter :showDescriptions="true" @sign-changed="filterChanged()"></call-sign-filter>
+
+ <div class="table-responsive mt-2">
+ <table class="table table-striped table-bordered" style="white-space:nowrap;">
+ <thead class="thead-dark">
+ <tr>
+ <th>Operator</th>
+ <th>From</th>
+ <th>To</th>
+ <th>Special Callsign</th>
+ <th>Frequencies</th>
+ <th>Modes</th>
+ <th>QSO</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr v-for="(activity, index) in activities" :key="index">
+ <td>{{ activity.operatorCall }}</td>
+ <td>{{ activity.fromTime }}</td>
+ <td>{{ activity.toTime }}</td>
+ <td>{{ activity.specialCall }}</td>
+ <td>{{ activity.frequencies }}</td>
+ <td>{{ activity.modes }}</td>
+ <td>{{ activity.qso }}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</template>
+
+<script>
+import callSignFilter from './call-sign-filter.vue';
+
+export default {
+ components: { callSignFilter },
+ mounted() {
+ this.$store.dispatch('pullActivities');
+ },
+ computed: {
+ activities() {
+ return this.$store.getters.getData;
+ }
+ },
+ methods: {
+ filterChanged() {
+ this.$store.dispatch('pullActivities');
+ }
+ }
+}
+</script>
diff --git a/resources/js/components/call-sign-description.vue b/resources/js/components/call-sign-description.vue
new file mode 100644
index 0000000..7ab8b64
--- /dev/null
+++ b/resources/js/components/call-sign-description.vue
@@ -0,0 +1,56 @@
+<template>
+ <div>
+ <div class="form-group">
+ <label for="special-call">Special Callsign:</label>
+ <select class="form-control" :class="{ 'is-invalid': isInvalid }" id="special-call" v-model="selected" :name="name" required>
+ <option v-for="option in options" :key="option.id" :value="option.sign" v-text="option.sign"></option>
+ </select>
+ </div>
+
+ <div class="card mb-3">
+ <div class="card-body pb-1">
+ <div class="card-text" v-html="description"></div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ props: [ 'name', 'old', 'isInvalid' ],
+ mounted() {
+ this.$store.dispatch('pullSigns').then(() => {
+ try {
+ if (this.old) {
+ this.$store.dispatch('setSelectedSign', this.old);
+ }
+ else {
+ this.$store.dispatch('setSelectedSign', this.$store.getters.getSigns[0].sign);
+ }
+ }
+ catch {
+ console.log('No call signs!');
+ }
+ });
+ },
+ computed: {
+ options() {
+ return this.$store.getters.getSigns;
+ },
+ selected: {
+ get() {
+ return this.$store.getters.getSelectedSign;
+ },
+ set(value) {
+ this.$store.dispatch('setSelectedSign', value);
+ }
+ },
+ description() {
+ for (let i = 0; i < this.options.length; i++)
+ if (this.options[i].sign === this.selected)
+ return this.options[i].description;
+ return '';
+ }
+ }
+}
+</script>
diff --git a/resources/js/components/call-sign-filter.vue b/resources/js/components/call-sign-filter.vue
new file mode 100644
index 0000000..0ba8b4d
--- /dev/null
+++ b/resources/js/components/call-sign-filter.vue
@@ -0,0 +1,44 @@
+<template>
+ <div>
+ <label for="call-sign">Filter by special callsign: </label>
+ <select id="call-sign" v-model="selected">
+ <option value="all">All</option>
+ <option v-for="option in options" :key="option.id" :value="option.sign" v-text="option.sign"></option>
+ </select>
+
+ <div class="card mb-3" v-if="showDescriptions && (selected !== 'all')">
+ <div class="card-body pb-1">
+ <div class="card-text" v-html="description"></div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ props: ['showDescriptions'],
+ mounted() {
+ this.$store.dispatch('pullSigns');
+ },
+ computed: {
+ selected: {
+ get() {
+ return this.$store.getters.getSelectedSign;
+ },
+ set(value) {
+ this.$store.dispatch('setSelectedSign', value);
+ this.$emit('sign-changed');
+ }
+ },
+ options() {
+ return this.$store.getters.getSigns;
+ },
+ description() {
+ for (let i = 0; i < this.options.length; i++)
+ if (this.options[i].sign === this.selected)
+ return this.options[i].description;
+ return '';
+ }
+ }
+}
+</script>
diff --git a/resources/js/components/reservation.vue b/resources/js/components/reservation.vue
new file mode 100644
index 0000000..ec430ab
--- /dev/null
+++ b/resources/js/components/reservation.vue
@@ -0,0 +1,59 @@
+<template>
+ <tr>
+ <td v-text="reservation.id"></td>
+ <td><input type="checkbox" v-model="reservation.approved"/></td>
+ <td><input type="text" v-model="reservation.operatorCall"></td>
+ <td><input type="text" v-model="reservation.qso"></td>
+ <td><input type="text" v-model="reservation.fromTime"></td>
+ <td><input type="text" v-model="reservation.toTime"></td>
+ <td><input type="text" v-model="reservation.specialCall"></td>
+ <td><input type="text" v-model="reservation.frequencies"></td>
+ <td><input type="text" v-model="reservation.modes"></td>
+ <td><input type="text" v-model="reservation.operatorName"></td>
+ <td><input type="text" v-model="reservation.operatorEmail"></td>
+ <td><input type="text" v-model="reservation.operatorPhone"></td>
+ <td>
+ <button class="btn btn-primary mr-2" @click="updateRow">Update</button>
+ <button class="btn btn-warning mr-2" @click="restoreRow">Restore</button>
+ <button class="btn btn-danger" @click="deleteRow">Delete</button>
+ </td>
+ </tr>
+</template>
+
+<script>
+export default {
+ props: [ 'reservationIndex' ],
+ data() {
+ return {
+ reservation: this.$store.getters.getDataRow(this.reservationIndex)
+ }
+ },
+ methods: {
+ updateRow() {
+ this.$store.dispatch('pushReservation', {
+ index: this.reservationIndex,
+ reservation: this.reservation
+ });
+ },
+ restoreRow() {
+ this.reservation = this.$store.getters.getDataRow(this.reservationIndex);
+ },
+ deleteRow() {
+ this.$store.dispatch('removeReservation', this.reservationIndex);
+ }
+ }
+}
+</script>
+
+<style scoped>
+td {
+ text-align: center;
+ vertical-align: middle;
+}
+input {
+ background-color: white;
+ border: 1px solid lightgray;
+ border-radius: 3px;
+ padding: 0.2em;
+}
+</style>
diff --git a/resources/js/components/reservations.vue b/resources/js/components/reservations.vue
new file mode 100644
index 0000000..0c420b8
--- /dev/null
+++ b/resources/js/components/reservations.vue
@@ -0,0 +1,62 @@
+<template>
+ <div>
+ <call-sign-filter @sign-changed="filterChanged()"></call-sign-filter>
+
+ <div class="table-responsive mt-2">
+ <table id="ajax-table" class="table table-striped table-bordered" style="white-space:nowrap;"><!-- table-hover -->
+ <thead class="thead-dark">
+ <tr>
+ <th>ID</th>
+ <th>Approved</th>
+ <th>Operator Callsign</th>
+ <th>QSO</th>
+ <th>From</th>
+ <th>To</th>
+ <th>Special Callsign</th>
+ <th>Frequencies</th>
+ <th>Modes</th>
+ <th>Operator Name</th>
+ <th>Operator Email</th>
+ <th>Operator Phone</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ <reservation-view v-for="(reservation, index) in reservations"
+ :key="reservation.id" :reservation-index="index">
+ </reservation-view>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</template>
+
+<script>
+import callSignFilter from './call-sign-filter.vue';
+import reservationView from './reservation.vue';
+
+export default {
+ components: { callSignFilter, reservationView },
+ mounted() {
+ this.$store.dispatch('pullReservations');
+ },
+ computed: {
+ reservations() {
+ return this.$store.getters.getData;
+ }
+ },
+ methods: {
+ filterChanged() {
+ this.$store.dispatch('pullReservations');
+ }
+ }
+}
+</script>
+
+<style scoped>
+@media only screen and (min-width:961px) {
+ .table-responsive {
+ max-height: 80vh;
+ }
+}
+</style>
diff --git a/resources/js/store.js b/resources/js/store.js
new file mode 100644
index 0000000..117db93
--- /dev/null
+++ b/resources/js/store.js
@@ -0,0 +1,96 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+Vue.use(Vuex);
+
+export default new Vuex.Store({
+ state: {
+ selectedSign: "all",
+ callSigns: [],
+ data: []
+ },
+ getters: {
+ getSelectedSign(state) {
+ return state.selectedSign;
+ },
+ getSigns(state) {
+ return state.callSigns;
+ },
+ getData(state) {
+ return state.data;
+ },
+ getDataRow(state) {
+ return (index) => _.cloneDeep(state.data[index]);
+ }
+ },
+ mutations: {
+ setSelectedSign(state, sign) {
+ state.selectedSign = sign;
+ },
+ setSigns(state, signs) {
+ state.callSigns = signs;
+ },
+ setData(state, data) {
+ state.data = data;
+ },
+ setDataRow(state, row) {
+ state.data[row.index] = _.cloneDeep(row.data);
+ },
+ removeDataRow(state, index) {
+ state.data.splice(index, 1);
+ }
+ },
+ actions: {
+ setSelectedSign(context, sign) {
+ context.commit('setSelectedSign', sign);
+ },
+ async pullSigns(context) {
+ await axios.get('/special-calls/show').then(response => {
+ context.commit('setSigns', response.data);
+ }).catch(error => {
+ console.log(error);
+ });
+ },
+ async pullActivities(context) {
+ await axios.post('/api/activities', {'call-sign': this.state.selectedSign}).then(response => {
+ context.commit('setData', response.data.data);
+ }).catch(error => {
+ console.log(error);
+ });
+ },
+ async pullReservations(context) {
+ await axios.post('/special-calls/reservations', {'call-sign': this.state.selectedSign}).then(response => {
+ context.commit('setData', response.data.data);
+ }).catch(error => {
+ console.log(error);
+ });
+ },
+ async pushReservation(context, data) {
+ await axios.post('/api/reservations', {
+ action: 'update',
+ ...data.reservation
+ }).then(() => {
+ context.commit('setDataRow', {
+ index: data.index,
+ data: data.reservation
+ });
+ }).catch(error => {
+ console.log(error);
+ alert("Couldn't update reservation! Bad data!");
+ });
+ },
+ async removeReservation(context, index) {
+ let data = {
+ action: 'delete',
+ ...this.state.data[index]
+ };
+ if (confirm(`Are you sure you want to delete reservation #${data.id} made by ${data.operatorCall}?`) === true) {
+ await axios.post('/api/reservations', data).then(() => {
+ context.commit('removeDataRow', index);
+ }).catch(error => {
+ console.log(error);
+ alert('Unable to remove reservation!');
+ });
+ }
+ }
+ }
+});
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php
index 79235ac..0a8bbda 100644
--- a/resources/views/layouts/app.blade.php
+++ b/resources/views/layouts/app.blade.php
@@ -3,6 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" href="{{ mix('css/app.css') }}" type="text/css">
@yield('styles')
<title>YOTA - @yield('title')</title>
@@ -10,7 +11,7 @@
<body>
@yield('navbar', View::make('inc.navbar'))
@yield('jumbotron')
- <div class="container pt-3">
+ <div id="vue" class="container pt-3">
@yield('content')
</div>
<script src="{{ mix('js/manifest.js') }}"></script>
diff --git a/resources/views/pages/activities.blade.php b/resources/views/pages/activities.blade.php
index 7e7a0ed..275431a 100644
--- a/resources/views/pages/activities.blade.php
+++ b/resources/views/pages/activities.blade.php
@@ -5,30 +5,7 @@
@section('navbar', View::make('inc.navbar'))
@section('content')
-<input type="hidden" name="csrf-token" content="{{ csrf_token() }}">
-<label for="call-sign">Filter by special callsign: </label>
-<select id="call-sign">
- <option value="all">All</option>
- @if (count($signs) > 0)
- @foreach ($signs as $sign)
- <option value="{{ $sign->sign }}">{{ $sign->sign }}</option>
- @endforeach
- @endif
-</select>
-<div id="sign-desc-div"></div>
+<activities-view></activities-view>
-<div class="table-responsive mt-2">
- <table id="ajax-table" class="table table-striped table-bordered" style="white-space:nowrap;">
- <thead class="thead-dark">
- <tr><th>Operator</th><th>From</th><th>To</th><th>Special Callsign</th><th>Frequencies</th><th>Modes</th><th>QSO</th></tr>
- </thead>
- <tbody>
- </tbody>
- </table>
-</div>
@endsection()
-
-@section('scripts')
- <script src="{{ asset('js/activities.js') }}"></script>
-@endsection
diff --git a/resources/views/pages/reservations.blade.php b/resources/views/pages/reservations.blade.php
index addc9a9..475e5d7 100644
--- a/resources/views/pages/reservations.blade.php
+++ b/resources/views/pages/reservations.blade.php
@@ -4,98 +4,6 @@
@section('navbar', View::make('inc.navbar'))
-@section('scripts')
- <script src="{{ asset('js/reservations.js') }}"></script>
-@endsection
-
@section('content')
-<input type="hidden" name="csrf-token" content="{{ csrf_token() }}">
-<label for="call-sign">Filter by special callsign: </label>
-<select id="call-sign">
- <option value="all">All</option>
- @if (count($signs) > 0)
- @foreach ($signs as $sign)
- <option value="{{ $sign->sign }}">{{ $sign->sign }}</option>
- @endforeach
- @endif
-</select>
-<div id="notice" class="float-right font-weight-bold"></div>
-
-<div class="table-responsive mt-2">
- <table id="ajax-table" class="table table-striped table-bordered" style="white-space:nowrap;"><!-- table-hover -->
- <thead class="thead-dark">
- <tr>
- <th>ID</th>
- <th>Approved</th>
- <th>Operator Callsign</th>
- <th>QSO</th>
- <th>From</th>
- <th>To</th>
- <th>Special Callsign</th>
- <th>Frequencies</th>
- <th>Modes</th>
- <th>Operator Name</th>
- <th>Operator Email</th>
- <th>Operator Phone</th>
- <th>Actions</th>
- </tr>
- </thead>
- <tbody>
- </tbody>
- </table>
-</div>
-{{--@if (count($data) > 0)--}}
-{{--<div class="table-responsive">--}}
- {{--<table class="table table-striped table-bordered" style="white-space:nowrap;"><!-- table-hover -->--}}
- {{--<thead class="thead-dark">--}}
- {{--<tr>--}}
- {{--<th>ID</th>--}}
- {{--<th>Approved</th>--}}
- {{--<th>Operator Callsign</th>--}}
- {{--<th>QSO</th>--}}
- {{--<th>From</th>--}}
- {{--<th>To</th>--}}
- {{--<th>Frequencies</th>--}}
- {{--<th>Modes</th>--}}
- {{--<th>Special Callsign</th>--}}
- {{--<th>Operator Name</th>--}}
- {{--<th>Operator Email</th>--}}
- {{--<th>Operator Phone</th>--}}
- {{--<th>Actions</th>--}}
- {{--</tr>--}}
- {{--</thead>--}}
- {{--<tbody>--}}
- {{--@foreach ($data as $row)--}}
- {{--<tr>--}}
- {{--<td class="align-middle">{{ $row->id }}</td>--}}
- {{--@if ($row->approved)--}}
- {{--<td class="align-middle"><input type="checkbox" checked></td> --}}
- {{--@else--}}
- {{--<td class="align-middle"><input type="checkbox"></td> --}}
- {{--@endif--}}
- {{--<td class="align-middle">{{ $row->operatorCall }}</td>--}}
- {{--<td class="align-middle">{{ $row->qso }}</td>--}}
- {{--<td class="align-middle">{{ $row->fromTime }}</td>--}}
- {{--<td class="align-middle">{{ $row->toTime }}</td>--}}
- {{--<td class="align-middle">{{ $row->frequencies }}</td>--}}
- {{--<td class="align-middle">{{ $row->modes }}</td>--}}
- {{--<td class="align-middle">{{ $row->specialCall }}</td>--}}
- {{--<td class="align-middle">{{ $row->operatorName }}</td>--}}
- {{--<td class="align-middle">{{ $row->operatorEmail }}</td>--}}
- {{--<td class="align-middle">{{ $row->operatorPhone }}</td>--}}
- {{--<td>--}}
- {{--<button class="btn btn-primary">Update</button>--}}
- {{--<button class="btn btn-warning">Restore</button>--}}
- {{--<button class="btn btn-danger">Delete</button>--}}
- {{--</td>--}}
- {{--</tr>--}}
- {{--@endforeach--}}
- {{--</tbody>--}}
- {{--</table>--}}
-{{--</div>--}}
-{{--@else--}}
-{{--<div class="text-center">--}}
- {{--<strong>There are currently no reservations.</strong>--}}
-{{--</div>--}}
-{{--@endif--}}
+ <reservations-view></reservations-view>
@endsection()
diff --git a/resources/views/pages/reserve.blade.php b/resources/views/pages/reserve.blade.php
index 823e8b9..17cab9a 100644
--- a/resources/views/pages/reserve.blade.php
+++ b/resources/views/pages/reserve.blade.php
@@ -17,24 +17,14 @@
@endif
<form action="{{ route('reserve') }}" method="POST">
@csrf
+
<!-- SPECIAL CALL -->
-<div class="form-group">
- <label for="special-call">Special Callsign:</label>
- <select class="form-control @error('scall') is-invalid @enderror" id="special-call" name="scall" required>
- @foreach ($signs as $sign)
- <option value="{{ $sign->sign }}" {{ old('scall') == $sign->sign ? 'selected' : '' }}>{{ $sign->sign }}</option>
- @endforeach
- </select>
+ <call-sign-description name="scall" old="{{ old('scall') }}" @error('scall') is-invalid="true" @enderror >
+ </call-sign-description>
@error('scall')
<div class="alert alert-danger mt-2">{{ $message }}</div>
@enderror
-</div>
-<div class="card mb-3">
- <div class="card-body pb-1">
- <div class="card-text" id="call-desc"></div>
- </div>
-</div>
@error('time')
<div class="alert alert-danger mt-2">{{ $message }}</div>
@@ -163,5 +153,4 @@
format: 'H:i'
});
</script>
- <script src="{{ asset('js/reserve.js') }}"></script>
@endsection
diff --git a/routes/web.php b/routes/web.php
index 20437b1..4616364 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -48,6 +48,7 @@ Route::post('/api/reservations', [ReservationsController::class, 'update'])->mid
Route::get('/special-calls/add', [SpecialCallsController::class, 'create'])->name('addSign')->middleware(['auth']);
Route::post('/special-calls/add', [SpecialCallsController::class, 'store'])->name('addSignForm')->middleware(['auth']);
+Route::get('/special-calls/show', [SpecialCallsController::class, 'index']);
Route::get('/special-calls/show/{name}', [SpecialCallsController::class, 'show']);
Route::get('/special-calls/edit/{id}', [SpecialCallsController::class, 'edit'])->name('editSign')->middleware(['auth']);
Route::post('/special-calls/edit/{id}', [SpecialCallsController::class, 'update'])->name('editSignForm')->middleware(['auth']);