1
1
<template >
2
- <div >
3
- <div class =" text-h6 q-mb-md" >Verify Payment Details</div >
2
+ <div class =" payment-verification" >
4
3
5
- <q-card flat bordered >
4
+ <q-card flat class = " glass-effect q-mb-lg " >
6
5
<q-card-section >
7
6
<div class =" row q-mb-sm" >
8
- <div class =" col-4 text-weight-medium" >Amount</div >
9
- <div class =" col" >{{ decodedInvoice.amount }} sats</div >
7
+ <div class =" col-4 text-weight-medium text-white-8 " >Amount</div >
8
+ <div class =" col text-white text-weight-bold " >{{ decodedInvoice.amount }} sats</div >
10
9
</div >
11
10
12
11
<div class =" row q-mb-sm" >
13
- <div class =" col-4 text-weight-medium" >Description</div >
14
- <div class =" col" >{{ decodedInvoice.description }}</div >
12
+ <div class =" col-4 text-weight-medium text-white-8 " >Description</div >
13
+ <div class =" col text-white text-weight-bold " >{{ decodedInvoice.description }}</div >
15
14
</div >
16
15
17
16
<div class =" row q-mb-sm" >
18
- <div class =" col-4 text-weight-medium" >Payment Hash</div >
19
- <div class =" col text-wrap" >{{ decodedInvoice.paymentHash }}</div >
17
+ <div class =" col-4 text-weight-medium text-white-8 " >Payment Hash</div >
18
+ <div class =" col text-white text-weight-bold text- wrap" >{{ decodedInvoice.paymentHash }}</div >
20
19
</div >
21
20
22
21
<div class =" row q-mb-sm" >
23
- <div class =" col-4 text-weight-medium" >Expires</div >
24
- <div class =" col" >{{ formatExpiry }}</div >
22
+ <div class =" col-4 text-weight-medium text-white-8 " >Expires</div >
23
+ <div class =" col text-white text-weight-bold " >{{ formatExpiry }}</div >
25
24
</div >
26
25
</q-card-section >
27
26
</q-card >
28
27
29
- <SlideUnlock
30
- ref =" slideUnlock"
31
- :auto-width =" true"
32
- :circle =" true"
33
- text =" Slide to Pay"
34
- success-text =" Payment Confirmed!"
35
- @completed =" $emit('pay')"
36
- class =" q-mt-md"
37
- />
28
+ <div class =" q-mt-md payment-slider-container" >
29
+ <q-slide-item
30
+ @left =" $emit('pay')"
31
+ @action =" onSlideAction"
32
+ left-color =" transparent"
33
+ class =" no-border payment-slider"
34
+ >
35
+ <template v-slot :left >
36
+ <div class =" full-height full-width row justify-end items-center" >
37
+ <q-icon name =" check" size =" 32px" color =" white" />
38
+ </div >
39
+ </template >
40
+
41
+ <div class =" payment-slider-content" >
42
+ <div class =" slider-handle" >
43
+ <q-icon name =" bolt" color =" white" size =" 20px" />
44
+ </div >
45
+ <div class =" slider-text" >Slide to Pay</div >
46
+ </div >
47
+ </q-slide-item >
48
+ </div >
38
49
</div >
39
50
</template >
40
51
41
52
<script setup lang="ts">
42
- import { computed , ref } from ' vue'
53
+ import { computed } from ' vue'
43
54
import type { Bolt11Invoice } from ' src/components/models'
44
- import SlideUnlock from ' @j2only/slide-unlock'
45
55
46
56
const props = defineProps <{
47
57
decodedInvoice: Bolt11Invoice
48
58
}>()
49
59
60
+
50
61
defineEmits <{
51
62
cancel: []
52
63
pay: []
@@ -58,13 +69,94 @@ const formatExpiry = computed(() => {
58
69
return date .toLocaleString ()
59
70
})
60
71
61
- const slideUnlock = ref <InstanceType <typeof SlideUnlock > | null >(null )
72
+ function onSlideAction({ side , reset }: { side: ' left' | ' right' | ' top' | ' bottom' ; reset: () => void }) {
73
+ if (side === ' left' ) {
74
+ // If it's being slid to the left but not completed
75
+ setTimeout (() => {
76
+ reset ()
77
+ }, 300 )
78
+ }
79
+ }
62
80
</script >
63
81
64
82
<style scoped>
65
83
.text-wrap {
66
84
word-break : break-all ;
67
85
}
68
- </style >
69
86
70
- <style ></style >
87
+ .payment-verification {
88
+ padding-bottom : 20px ;
89
+ }
90
+
91
+ .text-white-8 {
92
+ color : rgba (255 , 255 , 255 , 0.8 );
93
+ }
94
+
95
+ /* Payment Slider Styling */
96
+ .payment-slider-container {
97
+ position : relative ;
98
+ width : 100% ;
99
+ border-radius : 30px ;
100
+ overflow : hidden ;
101
+ box-shadow : 0 4px 12px rgba (0 , 0 , 0 , 0.15 );
102
+ }
103
+
104
+ .payment-slider {
105
+ height : 56px ;
106
+ background : rgba (255 , 255 , 255 , 0.1 );
107
+ border-radius : 30px ;
108
+ }
109
+
110
+ .payment-slider :deep(.q-slide-item__left .q-icon ) {
111
+ opacity : 0 ;
112
+ transition : opacity 0.2s ;
113
+ }
114
+
115
+ .payment-slider :active :deep(.q-slide-item__left .q-icon ) {
116
+ opacity : 1 ;
117
+ }
118
+
119
+ .payment-slider :deep(.q-slide-item__left ) {
120
+ /* Remove the gradient background */
121
+ background : transparent !important ;
122
+ }
123
+
124
+ .payment-slider-content {
125
+ position : relative ;
126
+ display : flex ;
127
+ align-items : center ;
128
+ justify-content : center ;
129
+ width : 100% ;
130
+ height : 56px ;
131
+ padding-left : 56px ;
132
+ }
133
+
134
+ .slider-handle {
135
+ position : absolute ;
136
+ left : 6px ;
137
+ top : 8px ;
138
+ width : 40px ;
139
+ height : 40px ;
140
+ border-radius : 50% ;
141
+ background : linear-gradient (145deg , var (--q-primary ), #8000ff );
142
+ display : flex ;
143
+ align-items : center ;
144
+ justify-content : center ;
145
+ box-shadow : 0 2px 8px rgba (0 , 0 , 0 , 0.2 );
146
+ border : 1px solid rgba (255 , 255 , 255 , 0.2 );
147
+ z-index : 2 ;
148
+ }
149
+
150
+ .slider-text {
151
+ color : rgba (255 , 255 , 255 , 0.9 );
152
+ font-weight : 500 ;
153
+ font-size : larger ;
154
+ letter-spacing : 0.5px ;
155
+ z-index : 1 ;
156
+ }
157
+
158
+ /* Animation for successful slide */
159
+ .q-slide-item__content {
160
+ transition : transform 0.3s ;
161
+ }
162
+ </style >
0 commit comments