Browse Source

fix dialog

pull/1244/head
Bernd Storath 9 months ago
parent
commit
facf027d4d
  1. 9
      .vscode/settings.json
  2. 2
      src/app.vue
  3. 113
      src/components/Clients/CreateDialog.vue
  4. 99
      src/components/Clients/DeleteDialog.vue
  5. 21
      src/components/Clients/QRCodeDialog.vue
  6. 8
      src/eslint.config.mjs
  7. 2
      src/nuxt.config.ts
  8. 233
      src/pages/index.vue
  9. 4993
      src/pnpm-lock.yaml
  10. 2
      src/stores/modal.ts

9
.vscode/settings.json

@ -3,10 +3,13 @@
"editor.useTabStops": false,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"nuxtr.vueFiles.style.addStyleTag": false,
"nuxtr.piniaFiles.defaultTemplate": "setup",
"nuxtr.monorepoMode.DirectoryName": "src",
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"nuxtr.vueFiles.style.addStyleTag": false,
"nuxtr.piniaFiles.defaultTemplate": "setup",
"nuxtr.monorepoMode.DirectoryName": "src"
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
}

2
src/app.vue

@ -1,9 +1,7 @@
<template>
<NuxtLayout>
<NuxtLayout name="header" />
<main>
<NuxtPage />
</main>
<NuxtLayout name="footer" />
</NuxtLayout>
</template>

113
src/components/Clients/CreateDialog.vue

@ -0,0 +1,113 @@
<template>
<!-- Create Dialog -->
<div
v-if="modalStore.clientCreate"
class="fixed z-10 inset-0 overflow-y-auto"
>
<div
class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
>
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 dark:bg-black opacity-75 dark:opacity-50"
/>
</div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true"
>&#8203;</span
>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95"
To: "opacity-100 tranneutral-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 tranneutral-y-0 sm:scale-100"
To: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95"
-->
<div
class="inline-block align-bottom bg-white dark:bg-neutral-700 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline"
>
<div class="bg-white dark:bg-neutral-700 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-800 sm:mx-0 sm:h-10 sm:w-10"
>
<IconsPlus class="h-6 w-6 text-white" />
</div>
<div
class="flex-grow mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left"
>
<h3
id="modal-headline"
class="text-lg leading-6 font-medium text-gray-900 dark:text-neutral-200"
>
{{ $t('newClient') }}
</h3>
<div class="mt-2">
<p class="text-sm text-gray-500">
<input
v-model.trim="modalStore.clientCreateName"
class="rounded p-2 border-2 dark:bg-neutral-700 dark:text-neutral-200 border-gray-100 dark:border-neutral-600 focus:border-gray-200 focus:dark:border-neutral-500 dark:placeholder:text-neutral-400 outline-none w-full"
type="text"
:placeholder="$t('name')"
/>
</p>
</div>
</div>
</div>
</div>
<div
class="bg-gray-50 dark:bg-neutral-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse"
>
<button
v-if="modalStore.clientCreateName.length"
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-800 text-base font-medium text-white hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm"
@click="
modalStore.createClient();
modalStore.clientCreate = null;
"
>
{{ $t('create') }}
</button>
<button
v-else
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-200 dark:bg-neutral-400 text-base font-medium text-white dark:text-neutral-300 sm:ml-3 sm:w-auto sm:text-sm cursor-not-allowed"
>
{{ $t('create') }}
</button>
<button
type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-neutral-500 shadow-sm px-4 py-2 bg-white dark:bg-neutral-500 text-base font-medium text-gray-700 dark:text-neutral-50 hover:bg-gray-50 dark:hover:bg-neutral-600 dark:hover:border-neutral-600 focus:outline-none sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
@click="modalStore.clientCreate = null"
>
{{ $t('cancel') }}
</button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const modalStore = useModalStore();
</script>

99
src/components/Clients/DeleteDialog.vue

@ -0,0 +1,99 @@
<template>
<div
v-if="modalStore.clientDelete"
class="fixed z-10 inset-0 overflow-y-auto"
>
<div
class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
>
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 dark:bg-black opacity-75 dark:opacity-50"
/>
</div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true"
>&#8203;</span
>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95"
To: "opacity-100 tranneutral-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 tranneutral-y-0 sm:scale-100"
To: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95"
-->
<div
class="inline-block align-bottom bg-white dark:bg-neutral-700 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline"
>
<div class="bg-white dark:bg-neutral-700 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10"
>
<IconsWarning class="h-6 w-6 text-red-600" />
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3
id="modal-headline"
class="text-lg leading-6 font-medium text-gray-900 dark:text-neutral-200"
>
{{ $t('deleteClient') }}
</h3>
<div class="mt-2">
<p class="text-sm text-gray-500 dark:text-neutral-300">
{{ $t('deleteDialog1') }}
<strong>{{ modalStore.clientDelete.name }}</strong
>? {{ $t('deleteDialog2') }}
</p>
</div>
</div>
</div>
</div>
<div
class="bg-gray-50 dark:bg-neutral-600 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse"
>
<button
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 dark:bg-red-600 text-base font-medium text-white dark:text-white hover:bg-red-700 dark:hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm"
@click="
modalStore.deleteClient(modalStore.clientDelete);
modalStore.clientDelete = null;
"
>
{{ $t('deleteClient') }}
</button>
<button
type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-neutral-500 shadow-sm px-4 py-2 bg-white dark:bg-neutral-500 text-base font-medium text-gray-700 dark:text-neutral-50 hover:bg-gray-50 dark:hover:bg-neutral-600 dark:hover:border-neutral-600 focus:outline-none sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
@click="modalStore.clientDelete = null"
>
{{ $t('cancel') }}
</button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const modalStore = useModalStore();
</script>

21
src/components/Clients/QRCodeDialog.vue

@ -0,0 +1,21 @@
<template>
<div v-if="modalStore.qrcode">
<div
class="bg-black bg-opacity-50 fixed top-0 right-0 left-0 bottom-0 flex items-center justify-center z-20"
>
<div class="bg-white rounded-md shadow-lg relative p-8">
<button
class="absolute right-4 top-4 text-gray-600 dark:text-neutral-500 hover:text-gray-800 dark:hover:text-neutral-700"
@click="modalStore.qrcode = null"
>
<IconsClose class="w-8" />
</button>
<img :src="modalStore.qrcode" />
</div>
</div>
</div>
</template>
<script setup lang="ts">
const modalStore = useModalStore();
</script>

8
src/eslint.config.mjs

@ -1,10 +1,4 @@
import { createConfigForNuxt } from '@nuxt/eslint-config/flat';
import eslintConfigPrettier from 'eslint-config-prettier';
export default createConfigForNuxt()
.append({
rules: {
'vue/no-multiple-template-root': 'off',
},
})
.append(eslintConfigPrettier);
export default createConfigForNuxt().append(eslintConfigPrettier);

2
src/nuxt.config.ts

@ -6,7 +6,7 @@ export default defineNuxtConfig({
'@nuxtjs/i18n',
'@nuxtjs/tailwindcss',
'@pinia/nuxt',
'@eschricht/nuxt-color-mode'
'@eschricht/nuxt-color-mode',
],
colorMode: {
preference: 'system',

233
src/pages/index.vue

@ -1,4 +1,5 @@
<template>
<main>
<div class="container mx-auto max-w-3xl px-3 md:px-0">
<div
class="shadow-md rounded-lg bg-white dark:bg-neutral-700 overflow-hidden"
@ -35,229 +36,10 @@
</div>
</div>
<!-- QR Code-->
<div v-if="modalStore.qrcode">
<div
class="bg-black bg-opacity-50 fixed top-0 right-0 left-0 bottom-0 flex items-center justify-center z-20"
>
<div class="bg-white rounded-md shadow-lg relative p-8">
<button
class="absolute right-4 top-4 text-gray-600 dark:text-neutral-500 hover:text-gray-800 dark:hover:text-neutral-700"
@click="modalStore.qrcode = null"
>
<IconsClose class="w-8" />
</button>
<img :src="modalStore.qrcode" />
</div>
</div>
<!-- Create Dialog -->
<div
v-if="modalStore.clientCreate"
class="fixed z-10 inset-0 overflow-y-auto"
>
<div
class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
>
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 dark:bg-black opacity-75 dark:opacity-50"
/>
</div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true"
>&#8203;</span
>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95"
To: "opacity-100 tranneutral-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 tranneutral-y-0 sm:scale-100"
To: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95"
-->
<div
class="inline-block align-bottom bg-white dark:bg-neutral-700 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline"
>
<div
class="bg-white dark:bg-neutral-700 px-4 pt-5 pb-4 sm:p-6 sm:pb-4"
>
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-800 sm:mx-0 sm:h-10 sm:w-10"
>
<IconsPlus class="h-6 w-6 text-white" />
</div>
<div
class="flex-grow mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left"
>
<h3
id="modal-headline"
class="text-lg leading-6 font-medium text-gray-900 dark:text-neutral-200"
>
{{ $t('newClient') }}
</h3>
<div class="mt-2">
<p class="text-sm text-gray-500">
<input
v-model.trim="modalStore.clientCreateName"
class="rounded p-2 border-2 dark:bg-neutral-700 dark:text-neutral-200 border-gray-100 dark:border-neutral-600 focus:border-gray-200 focus:dark:border-neutral-500 dark:placeholder:text-neutral-400 outline-none w-full"
type="text"
:placeholder="$t('name')"
/>
</p>
</div>
</div>
</div>
</div>
<div
class="bg-gray-50 dark:bg-neutral-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse"
>
<button
v-if="modalStore.clientCreateName.length"
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-800 text-base font-medium text-white hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm"
@click="
modalStore.createClient();
modalStore.clientCreate = null;
"
>
{{ $t('create') }}
</button>
<button
v-else
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-200 dark:bg-neutral-400 text-base font-medium text-white dark:text-neutral-300 sm:ml-3 sm:w-auto sm:text-sm cursor-not-allowed"
>
{{ $t('create') }}
</button>
<button
type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-neutral-500 shadow-sm px-4 py-2 bg-white dark:bg-neutral-500 text-base font-medium text-gray-700 dark:text-neutral-50 hover:bg-gray-50 dark:hover:bg-neutral-600 dark:hover:border-neutral-600 focus:outline-none sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
@click="modalStore.clientCreate = null"
>
{{ $t('cancel') }}
</button>
</div>
</div>
</div>
</div>
<!-- Delete Dialog -->
<div
v-if="modalStore.clientDelete"
class="fixed z-10 inset-0 overflow-y-auto"
>
<div
class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
>
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 dark:bg-black opacity-75 dark:opacity-50"
/>
</div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true"
>&#8203;</span
>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95"
To: "opacity-100 tranneutral-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 tranneutral-y-0 sm:scale-100"
To: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95"
-->
<div
class="inline-block align-bottom bg-white dark:bg-neutral-700 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline"
>
<div
class="bg-white dark:bg-neutral-700 px-4 pt-5 pb-4 sm:p-6 sm:pb-4"
>
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10"
>
<IconsWarning class="h-6 w-6 text-red-600" />
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3
id="modal-headline"
class="text-lg leading-6 font-medium text-gray-900 dark:text-neutral-200"
>
{{ $t('deleteClient') }}
</h3>
<div class="mt-2">
<p class="text-sm text-gray-500 dark:text-neutral-300">
{{ $t('deleteDialog1') }}
<strong>{{ modalStore.clientDelete.name }}</strong
>? {{ $t('deleteDialog2') }}
</p>
</div>
</div>
</div>
</div>
<div
class="bg-gray-50 dark:bg-neutral-600 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse"
>
<button
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 dark:bg-red-600 text-base font-medium text-white dark:text-white hover:bg-red-700 dark:hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm"
@click="
modalStore.deleteClient(modalStore.clientDelete);
modalStore.clientDelete = null;
"
>
{{ $t('deleteClient') }}
</button>
<button
type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-neutral-500 shadow-sm px-4 py-2 bg-white dark:bg-neutral-500 text-base font-medium text-gray-700 dark:text-neutral-50 hover:bg-gray-50 dark:hover:bg-neutral-600 dark:hover:border-neutral-600 focus:outline-none sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
@click="modalStore.clientDelete = null"
>
{{ $t('cancel') }}
</button>
</div>
</div>
</div>
</div>
</div>
<ClientsQRCodeDialog />
<ClientsCreateDialog />
<ClientsDeleteDialog />
</main>
</template>
<script setup lang="ts">
@ -265,11 +47,6 @@ const authStore = useAuthStore();
authStore.update();
const globalStore = useGlobalStore();
const clientsStore = useClientsStore();
const modalStore = useModalStore();
watchEffect(() => {
console.log(modalStore.clientDelete, modalStore.clientDelete ? true : false);
});
const intervalId = ref<NodeJS.Timeout | null>(null);

4993
src/pnpm-lock.yaml

File diff suppressed because it is too large

2
src/stores/modal.ts

@ -16,6 +16,7 @@ export const useModalStore = defineStore('Modal', () => {
.catch((err) => alert(err.message || err.toString()))
.finally(() => clientsStore.refresh().catch(console.error));
}
function deleteClient(client: WGClient | null) {
if (client === null) {
return;
@ -25,6 +26,7 @@ export const useModalStore = defineStore('Modal', () => {
.catch((err) => alert(err.message || err.toString()))
.finally(() => clientsStore.refresh().catch(console.error));
}
return {
clientDelete,
clientCreate,

Loading…
Cancel
Save