feat: signature dialog

This commit is contained in:
puriphatt 2024-06-07 12:20:57 +00:00
parent b3f04aa6cf
commit f98093835f
2 changed files with 183 additions and 5 deletions

View file

@ -0,0 +1,143 @@
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import SignaturePad from 'signature_pad';
defineExpose({ clearCanvas });
let canvasRef: HTMLCanvasElement | null = null;
const signaturePad = ref();
const currentColor = ref('blue');
const tab = ref('draw');
const initializeSignaturePad = () => {
if (canvasRef) {
signaturePad.value = new SignaturePad(canvasRef, {
backgroundColor: 'rgb(248,249,250)',
penColor: 'blue',
});
} else {
console.warn('Canvas reference not found. SignaturePad not initialized.');
}
};
function changeColor(color: string) {
signaturePad.value.penColor = color;
currentColor.value = color;
}
function clearCanvas() {
signaturePad.value.clear();
}
onMounted(() => {
canvasRef = document.querySelector('canvas');
initializeSignaturePad();
});
</script>
<template>
<div class="surface-1 bordered rounded">
<q-tabs
v-model="tab"
dense
align="left"
class="text-grey"
active-color="primary"
indicator-color="primary"
>
<q-tab
name="draw"
label="Draw"
style="border-top-left-radius: var(--radius-2)"
/>
<q-tab name="upload" label="Upload" />
</q-tabs>
<q-separator />
<q-tab-panels v-model="tab" animated>
<q-tab-panel name="draw">
<div class="column relative-position">
<div
class="absolute-top-right q-ma-md q-gutter-x-md row items-center"
>
<span
class="dot"
:class="{ active: currentColor === 'black' }"
style="background-color: black"
@click="changeColor('black')"
>
<q-icon
v-if="currentColor === 'black'"
name="mdi-check"
color="white"
size="sm"
/>
</span>
<span
:class="{ active: currentColor === 'red' }"
class="dot"
style="background-color: red"
@click="changeColor('red')"
>
<q-icon
v-if="currentColor === 'red'"
name="mdi-check"
color="white"
size="sm"
/>
</span>
<span
:class="{ active: currentColor === 'blue' }"
class="dot"
style="background-color: blue"
@click="changeColor('blue')"
>
<q-icon
v-if="currentColor === 'blue'"
name="mdi-check"
color="white"
size="sm"
/>
</span>
</div>
<canvas
class="signature-canvas"
ref="canvasRef"
id="signature-pad"
width="650"
height="300"
></canvas>
</div>
</q-tab-panel>
</q-tab-panels>
<!-- <div class="text-right q-gutter-x-md">
<q-btn id="clear" label="Clear" @click="signaturePad.clear()" />
</div> -->
</div>
</template>
<style scoped lang="scss">
.signature-canvas {
border: 1px solid var(--border-color);
border-radius: var(--radius-2);
}
.dot {
height: 25px;
width: 25px;
border-radius: 50%;
display: inline-flex;
justify-content: center;
align-items: center;
&.active {
height: 35px;
width: 35px;
}
}
.color-palette {
position: absolute;
display: inline-block;
}
</style>

View file

@ -13,7 +13,9 @@ import { useI18n } from 'vue-i18n';
import useLoader from 'stores/loader';
import DrawerComponent from 'components/DrawerComponent.vue';
import CanvasComponent from 'components/CanvasComponent.vue';
import useUserStore from 'src/stores/user';
import FormDialog from 'src/components/FormDialog.vue';
import { Option } from 'src/stores/user/types';
import { dialog } from 'src/stores/utils';
@ -37,12 +39,13 @@ const { visible } = storeToRefs(loaderStore);
const { locale } = useI18n({ useScope: 'global' });
const userStore = useUserStore();
const canvasModal = ref(false);
const leftDrawerOpen = ref(false);
const filterUnread = ref(false);
const unread = ref<number>(1);
const filterRole = ref<string[]>();
const userImage = ref<string>();
const canvasRef = ref();
const currentLanguage = ref<string>('ไทย');
const language: {
value: string;
@ -89,10 +92,16 @@ const notification = ref<Notification[]>([
const options = ref([
{
icon: 'mdi-lock-outline',
label: 'เปลี่ยนรหัสผ่าน',
label: 'changePassword',
value: 'op1',
color: 'primary',
},
{
icon: 'mdi-signature-freehand',
label: 'signature',
value: 'signature',
color: 'primary',
},
]);
function setActive(button: NotificationButton) {
@ -343,12 +352,21 @@ onMounted(async () => {
<q-separator />
<div class="column justify-center">
<q-list dense v-for="op in options" :key="op.label">
<q-item clickable>
<q-item
clickable
@click="
() => {
if (op.value === 'signature') {
canvasModal = true;
}
}
"
>
<q-item-section avatar>
<q-icon :name="op.icon" :color="op.color" size="20px" />
</q-item-section>
<q-item-section class="q-py-sm">
{{ op.label }}
{{ $t(op.label) }}
</q-item-section>
</q-item>
</q-list>
@ -376,7 +394,7 @@ onMounted(async () => {
style="color: var(--gray-6)"
@click="$q.dark.toggle()"
/>
<!-- เปลภาษา -->
<!-- เปลภาษา -->
<q-btn
flat
color="grey"
@ -417,6 +435,23 @@ onMounted(async () => {
<drawer-component v-model:leftDrawerOpen="leftDrawerOpen" />
<FormDialog
v-model:modal="canvasModal"
:title="$t('addSignature')"
no-app-box
:max-width="80"
>
<CanvasComponent ref="canvasRef" v-model:modal="canvasModal" />
<template #footer>
<q-btn
flat
dense
:label="$t('clear')"
@click="canvasRef.clearCanvas()"
/>
</template>
</FormDialog>
<global-loading :visibility="visible" />
</q-layout>
</template>