add new event and attendance table with automatic now timestamp
All checks were successful
Build Quasar SPA and Go Backend for memberApp / build-spa (push) Successful in 2m34s
Build Quasar SPA and Go Backend for memberApp / build-backend (amd64, .exe, windows) (push) Successful in 5m39s
Build Quasar SPA and Go Backend for memberApp / build-backend (amd64, , linux) (push) Successful in 5m46s
Build Quasar SPA and Go Backend for memberApp / build-backend (arm, 6, , linux) (push) Successful in 5m32s
Build Quasar SPA and Go Backend for memberApp / build-backend (arm64, , linux) (push) Successful in 5m35s
All checks were successful
Build Quasar SPA and Go Backend for memberApp / build-spa (push) Successful in 2m34s
Build Quasar SPA and Go Backend for memberApp / build-backend (amd64, .exe, windows) (push) Successful in 5m39s
Build Quasar SPA and Go Backend for memberApp / build-backend (amd64, , linux) (push) Successful in 5m46s
Build Quasar SPA and Go Backend for memberApp / build-backend (arm, 6, , linux) (push) Successful in 5m32s
Build Quasar SPA and Go Backend for memberApp / build-backend (arm64, , linux) (push) Successful in 5m35s
This commit is contained in:
91
src/components/AddToEvent.vue
Normal file
91
src/components/AddToEvent.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<DialogFrame ref="dialog" :header-title="localTitle">
|
||||
<div class="row justify-center">
|
||||
<q-select
|
||||
autofocus
|
||||
class="q-ml-md col-6"
|
||||
:label="$t('event')"
|
||||
filled
|
||||
:options="events"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
v-model="selected"
|
||||
@keyup.enter="save"
|
||||
map-options
|
||||
emit-value
|
||||
></q-select>
|
||||
</div>
|
||||
<div class="row justify-center">
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">{{ $t('save') }}</q-btn>
|
||||
</div>
|
||||
</DialogFrame>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DialogFrame from 'src/vueLib/dialog/DialogFrame.vue';
|
||||
import { ref } from 'vue';
|
||||
import { appApi } from 'src/boot/axios';
|
||||
import { useNotify } from 'src/vueLib/general/useNotify';
|
||||
import { i18n } from 'src/boot/lang';
|
||||
import type { Event, Events } from 'src/vueLib/models/event';
|
||||
import type { Members } from 'src/vueLib/models/member';
|
||||
import { useAttendeesTable } from 'src/vueLib/tables/attendees/AttendeesTable';
|
||||
import { useEventTable } from 'src/vueLib/tables/events/EventsTable';
|
||||
|
||||
const dialog = ref();
|
||||
const localTitle = ref('');
|
||||
const events = ref<Events>([{ id: -1, name: i18n.global.t('add'), attendees: [] }]);
|
||||
const selected = ref<Event>({ id: -1, name: i18n.global.t('add'), attendees: [] });
|
||||
const localMembers = ref<Members>([]);
|
||||
const { updateAttendees } = useAttendeesTable();
|
||||
const { updateEvents } = useEventTable();
|
||||
|
||||
const props = defineProps({
|
||||
endpoint: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
queryId: {
|
||||
type: Boolean,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update-event']);
|
||||
const { NotifyResponse } = useNotify();
|
||||
|
||||
function open(title: string, members: Members) {
|
||||
localTitle.value = title;
|
||||
localMembers.value = members;
|
||||
|
||||
events.value = [{ id: -1, name: i18n.global.t('add'), attendees: [] }];
|
||||
appApi
|
||||
.get('events')
|
||||
.then((resp) => {
|
||||
events.value.push(...resp.data);
|
||||
})
|
||||
.catch((err) => {
|
||||
NotifyResponse(err, 'error');
|
||||
});
|
||||
dialog.value?.open();
|
||||
}
|
||||
|
||||
async function save() {
|
||||
await appApi
|
||||
.post(props.endpoint, {
|
||||
id: selected.value,
|
||||
attendees: localMembers.value,
|
||||
})
|
||||
.then(() => {
|
||||
emit('update-event', localMembers.value);
|
||||
NotifyResponse(i18n.global.t('eventAdded'));
|
||||
dialog.value.close();
|
||||
})
|
||||
.catch((err) => {
|
||||
NotifyResponse(err, 'error');
|
||||
});
|
||||
await updateAttendees();
|
||||
updateEvents();
|
||||
}
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
@@ -1,17 +1,35 @@
|
||||
<template>
|
||||
<DialogFrame ref="dialog" :header-title="'Edit ' + localTitle">
|
||||
<div class="row justify-center">
|
||||
<q-input
|
||||
autofocus
|
||||
class="q-ml-md col-6"
|
||||
:label="localTitle"
|
||||
filled
|
||||
v-model="value"
|
||||
@keyup.enter="save"
|
||||
></q-input>
|
||||
<q-input autofocus :label="localTitle" filled v-model="value" @keyup.enter="save">
|
||||
<template v-if="['firstVisit', 'lastVisit', 'date'].includes(localField)" v-slot:prepend>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-date v-model="value" mask="YYYY-MM-DD HH:mm:ss">
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn :label="$t('now')" color="primary" no-caps flat @click="setTimeNow" />
|
||||
<q-btn no-caps v-close-popup :label="$t('close')" color="primary" flat />
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
<template v-if="['firstVisit', 'lastVisit', 'date'].includes(localField)" v-slot:append>
|
||||
<q-icon name="access_time" class="cursor-pointer">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-time with-seconds v-model="value" mask="YYYY-MM-DD HH:mm:ss" format24h>
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn :label="$t('now')" color="primary" no-caps flat @click="setTimeNow" />
|
||||
<q-btn no-caps v-close-popup :label="$t('close')" color="primary" flat />
|
||||
</div>
|
||||
</q-time>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
<div class="row justify-center">
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">Save</q-btn>
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">{{ $t('save') }}</q-btn>
|
||||
</div>
|
||||
</DialogFrame>
|
||||
</template>
|
||||
@@ -22,6 +40,7 @@ import { ref } from 'vue';
|
||||
import { appApi } from 'src/boot/axios';
|
||||
import type { Member } from 'src/vueLib/models/member';
|
||||
import { useNotify } from 'src/vueLib/general/useNotify';
|
||||
import { i18n } from 'src/boot/lang';
|
||||
|
||||
const dialog = ref();
|
||||
const localMember = ref();
|
||||
@@ -34,9 +53,6 @@ const props = defineProps({
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
queryId: {
|
||||
type: Boolean,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update']);
|
||||
@@ -52,26 +68,24 @@ function open(label: string, field: string, member: Member) {
|
||||
}
|
||||
|
||||
function save() {
|
||||
let query = props.endpoint;
|
||||
if (props.queryId) {
|
||||
query += '?id=' + localMember.value.id;
|
||||
}
|
||||
let payload = {};
|
||||
|
||||
if (value.value === localMember.value[localField.value]) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
id: localMember.value.id,
|
||||
[localField.value]: value.value,
|
||||
};
|
||||
payload = [
|
||||
{
|
||||
id: localMember.value.id,
|
||||
[localField.value]: value.value,
|
||||
},
|
||||
];
|
||||
|
||||
appApi
|
||||
.post(query, payload)
|
||||
.then((resp) => {
|
||||
.post(props.endpoint, payload)
|
||||
.then(() => {
|
||||
emit('update');
|
||||
NotifyResponse(resp.data);
|
||||
NotifyResponse(i18n.global.t('memberUpdated'));
|
||||
dialog.value.close();
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -79,5 +93,18 @@ function save() {
|
||||
});
|
||||
}
|
||||
|
||||
function setTimeNow() {
|
||||
const now = new Date();
|
||||
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0'); // Months are 0-based
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
const hours = String(now.getHours()).padStart(2, '0');
|
||||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||
|
||||
value.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
|
||||
93
src/components/EventEditAllDialog.vue
Normal file
93
src/components/EventEditAllDialog.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<DialogFrame
|
||||
ref="dialog"
|
||||
:header-title="newEvent ? $t('addNewEvent') : 'Edit ' + localEvent.name"
|
||||
:height="250"
|
||||
:width="500"
|
||||
>
|
||||
<q-form ref="form">
|
||||
<div class="row justify-center q-gutter-md">
|
||||
<q-input
|
||||
class="q-ml-md col-5 required"
|
||||
:label="$t('eventName')"
|
||||
filled
|
||||
:rules="[(val) => !!val || $t('eventNameIsRequired')]"
|
||||
v-model="localEvent.name"
|
||||
autofocus
|
||||
@keyup.enter="save"
|
||||
></q-input>
|
||||
</div>
|
||||
</q-form>
|
||||
<div class="row justify-center">
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">{{ $t('save') }}</q-btn>
|
||||
</div>
|
||||
</DialogFrame>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DialogFrame from 'src/vueLib/dialog/DialogFrame.vue';
|
||||
import { ref } from 'vue';
|
||||
import { appApi } from 'src/boot/axios';
|
||||
import type { Event } from 'src/vueLib/models/event';
|
||||
import { useNotify } from 'src/vueLib/general/useNotify';
|
||||
|
||||
const { NotifyResponse } = useNotify();
|
||||
const dialog = ref();
|
||||
const form = ref();
|
||||
const newEvent = ref(false);
|
||||
const localEvent = ref<Event>({
|
||||
id: 0,
|
||||
name: '',
|
||||
attendees: [],
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update']);
|
||||
|
||||
function open(Event: Event | null) {
|
||||
if (Event === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Event !== null) {
|
||||
localEvent.value = Event;
|
||||
newEvent.value = false;
|
||||
} else {
|
||||
localEvent.value = {
|
||||
id: 0,
|
||||
name: '',
|
||||
attendees: [],
|
||||
};
|
||||
newEvent.value = true;
|
||||
}
|
||||
|
||||
dialog.value?.open();
|
||||
}
|
||||
|
||||
async function save() {
|
||||
const valid = await form.value.validate();
|
||||
|
||||
if (!valid) return;
|
||||
|
||||
let query = 'events/edit?id=' + localEvent.value.id;
|
||||
if (newEvent.value) {
|
||||
query = 'events/add?name=' + localEvent.value.name;
|
||||
}
|
||||
|
||||
appApi
|
||||
.post(query, JSON.stringify(localEvent.value))
|
||||
.then(() => {
|
||||
emit('update');
|
||||
dialog.value.close();
|
||||
})
|
||||
.catch((err) => NotifyResponse(err, 'error'));
|
||||
}
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.required .q-field__label::after {
|
||||
content: ' *';
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
@@ -90,7 +90,7 @@
|
||||
</div>
|
||||
</q-form>
|
||||
<div class="row justify-center">
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">Save</q-btn>
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">{{ $t('save') }}</q-btn>
|
||||
</div>
|
||||
</DialogFrame>
|
||||
</template>
|
||||
@@ -101,6 +101,7 @@ import { ref } from 'vue';
|
||||
import { appApi } from 'src/boot/axios';
|
||||
import type { Member } from 'src/vueLib/models/member';
|
||||
import { useNotify } from 'src/vueLib/general/useNotify';
|
||||
import { i18n } from 'src/boot/lang';
|
||||
|
||||
const { NotifyResponse } = useNotify();
|
||||
const dialog = ref();
|
||||
@@ -158,18 +159,21 @@ function open(member: Member | null) {
|
||||
|
||||
async function save() {
|
||||
const valid = await form.value.validate();
|
||||
if (!valid) {
|
||||
NotifyResponse(i18n.global.t('notAllRequiredFieldsFilled'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!valid) return;
|
||||
|
||||
let query = 'members/edit?id=' + localMember.value.id;
|
||||
let query = 'members/edit';
|
||||
if (newMember.value) {
|
||||
query = 'members/add';
|
||||
}
|
||||
|
||||
appApi
|
||||
.post(query, JSON.stringify(localMember.value))
|
||||
await appApi
|
||||
.post(query, JSON.stringify([localMember.value]))
|
||||
.then(() => {
|
||||
emit('update-member');
|
||||
NotifyResponse(i18n.global.t('memberUpdated'));
|
||||
dialog.value.close();
|
||||
})
|
||||
.catch((err) => NotifyResponse(err, 'error'));
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</q-card>
|
||||
</div>
|
||||
<div class="row justify-center">
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">Save</q-btn>
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">{{ $t('save') }}</q-btn>
|
||||
</div>
|
||||
</DialogFrame>
|
||||
</template>
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
</div>
|
||||
</q-form>
|
||||
<div class="row justify-center">
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">Save</q-btn>
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">{{ $t('save') }}</q-btn>
|
||||
</div>
|
||||
</DialogFrame>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user