1+ <template >
2+ <q-dialog ref =" dialogRef" @hide =" onDialogHide" >
3+ <q-card class =" share-dialog-card" >
4+ <q-btn
5+ icon =" close"
6+ flat
7+ round
8+ dense
9+ class =" close-button"
10+ @click =" onDialogCancel"
11+ />
12+
13+ <div class =" dialog-content" >
14+ <div class =" qr-code-container" >
15+ <img v-if =" qrCodeDataUrl" :src =" qrCodeDataUrl" alt =" QR Code" />
16+ </div >
17+
18+ <q-btn
19+ no-caps
20+ class =" copy-button"
21+ @click =" copyUrl"
22+ >
23+ <div class =" flex items-center no-wrap" >
24+ <div >Copy link to conversation</div >
25+ </div >
26+ </q-btn >
27+ </div >
28+ </q-card >
29+ </q-dialog >
30+ </template >
31+
32+ <script setup lang="ts">
33+ import { useDialogPluginComponent , useQuasar , copyToClipboard } from " quasar" ;
34+ import QRCode from " qrcode" ;
35+ import { ref , onMounted } from " vue" ;
36+
37+ const props = defineProps <{
38+ url: string ;
39+ title: string ;
40+ }>();
41+
42+ defineEmits ([... useDialogPluginComponent .emits ]);
43+
44+ const { dialogRef, onDialogHide, onDialogCancel } = useDialogPluginComponent ();
45+ const $q = useQuasar ();
46+
47+ const qrCodeDataUrl = ref (" " );
48+
49+ onMounted (async () => {
50+ try {
51+ qrCodeDataUrl .value = await QRCode .toDataURL (props .url , {
52+ width: 218 ,
53+ margin: 1 ,
54+ color: {
55+ dark: " #000000" ,
56+ light: " #0000" , // Transparent background
57+ },
58+ });
59+ } catch (err ) {
60+ console .error (err );
61+ }
62+ });
63+
64+ function copyUrl() {
65+ copyToClipboard (props .url )
66+ .then (() => {
67+ $q .notify ({
68+ message: " Copied to clipboard!" ,
69+ color: " positive" ,
70+ position: " top" ,
71+ icon: " check" ,
72+ });
73+ })
74+ .catch (() => {
75+ $q .notify ({
76+ message: " Could not copy to clipboard." ,
77+ color: " negative" ,
78+ position: " top" ,
79+ icon: " warning" ,
80+ });
81+ });
82+ }
83+ </script >
84+
85+ <style scoped lang="scss">
86+ .share-dialog-card {
87+ width : 428px ;
88+ height : 450px ;
89+ border-radius : 32px ;
90+ background : linear-gradient (114.81deg , #f1eeff 46.45% , #e8f1ff 100.1% );
91+ padding : 24px ;
92+ position : relative ;
93+ display : flex ;
94+ flex-direction : column ;
95+ align-items : center ;
96+ }
97+
98+ .close-button {
99+ position : absolute ;
100+ top : 16px ;
101+ right : 16px ;
102+ width : 48px ;
103+ height : 48px ;
104+ border-radius : 16px ;
105+ background-color : rgba (0 , 0 , 0 , 0.05 );
106+ }
107+
108+ .dialog-content {
109+ display : flex ;
110+ flex-direction : column ;
111+ align-items : center ;
112+ gap : 16px ;
113+ width : 100% ;
114+ flex-grow : 1 ; /* Allow container to grow */
115+ justify-content : center ; /* Center content vertically */
116+ }
117+
118+
119+ .qr-code-container {
120+ width : 218px ;
121+ height : 218px ;
122+ display : flex ;
123+ align-items : center ;
124+ justify-content : center ;
125+ }
126+
127+ .copy-button {
128+ width : 241px ;
129+ height : 48px ;
130+ border-radius : 16px ;
131+ background : linear-gradient (180deg , #6b4eff 30.96% , #4f92f6 99.99% );
132+ color : white ;
133+ font-family : " Albert Sans" , sans-serif ;
134+ font-weight : 500 ;
135+ font-size : 16px ; // Adjusted to fit better
136+ line-height : 24px ;
137+ }
138+ </style >
0 commit comments