1<template>
2 {{ countDown }}
3</template>
4
5<script>
6 export default {
7 data() {
8 return {
9 countDown : 10
10 }
11 },
12 method: {
13 countDownTimer() {
14 if(this.countDown > 0) {
15 setTimeout(() => {
16 this.countDown -= 1
17 this.countDownTimer()
18 }, 1000)
19 }
20 }
21 }
22 created: {
23 this.countDownTimer()
24 }
25 }
26</script>
27
1<template>
2 {{ timerCount }}
3</template>
4
5<script>
6
7 export default {
8
9 data() {
10 return {
11 timerCount: 30
12 }
13 },
14
15 watch: {
16
17 timerCount: {
18 handler(value) {
19
20 if (value > 0) {
21 setTimeout(() => {
22 this.timerCount--;
23 }, 1000);
24 }
25
26 },
27 immediate: true // This ensures the watcher is triggered upon creation
28 }
29
30 }
31 }
32
33</script>
1<template>
2 {{ countDown }}
3 <button type="button" v-on:click="countdown = 5"> setTimeout </button>
4</template>
5
6<script>
7 export default {
8 data() {
9 return {
10 countDown : 0
11 }
12 },
13 method: {}
14 watch: {
15 countdown: function(val) {
16 if(val > 0) {
17 setTimeout(() => {
18 this.countdown -= 1;
19 }, 1000);
20 }
21 },
22 }
23 }
24</script>
25
1<template>
2 <div>
3 <slot :hour="hour" :min="min" :sec="sec"></slot>
4 </div>
5</template>
6
7<script>
8export default {
9 props : {
10 endDate : { // pass date object till when you want to run the timer
11 type : Date,
12 default(){
13 return new Date()
14 }
15 },
16 negative : { // optional, should countdown after 0 to negative
17 type : Boolean,
18 default : false
19 }
20 },
21 data(){
22 return{
23 now : new Date(),
24 timer : null
25 }
26 },
27 computed:{
28 hour(){
29 let h = Math.trunc((this.endDate - this.now) / 1000 / 3600);
30 return h>9?h:'0'+h;
31 },
32 min(){
33 let m = Math.trunc((this.endDate - this.now) / 1000 / 60) % 60;
34 return m>9?m:'0'+m;
35 },
36 sec(){
37 let s = Math.trunc((this.endDate - this.now)/1000) % 60
38 return s>9?s:'0'+s;
39 }
40 },
41 watch : {
42 endDate : {
43 immediate : true,
44 handler(newVal){
45 if(this.timer){
46 clearInterval(this.timer)
47 }
48 this.timer = setInterval(()=>{
49 this.now = new Date()
50 if(this.negative)
51 return
52 if(this.now > newVal){
53 this.now = newVal
54 this.$emit('endTime')
55 clearInterval(this.timer)
56 }
57 }, 1000)
58 }
59 }
60 },
61 beforeDestroy(){
62 clearInterval(this.timer)
63 }
64}
65</script>
66
1<template>
2 <div class="bg-white min-h-screen flex flex-col justify-center items-center">
3 <img src="~/assets/svg/phone-otp.svg" alt="" />
4 <div class="flex justify-evenly w-full my-10">
5 <input type="text" class="h-12 w-12 rounded-md bg-gray-300 text-lg text-center __input_next" maxlength="1" @keyup="focusNext" />
6 <input type="text" class="h-12 w-12 rounded-md bg-gray-300 text-lg text-center __input_next" maxlength="1" @keyup="focusNext" />
7 <input type="text" class="h-12 w-12 rounded-md bg-gray-300 text-lg text-center __input_next" maxlength="1" @keyup="focusNext" />
8 <input type="text" class="h-12 w-12 rounded-md bg-gray-300 text-lg text-center __input_next" maxlength="1" @keyup="focusNext" />
9 <input type="text" class="h-12 w-12 rounded-md bg-gray-300 text-lg text-center __input_next" maxlength="1" @keyup="focusNext" />
10 <input type="text" class="h-12 w-12 rounded-md bg-gray-300 text-lg text-center __input_next" maxlength="1" />
11 </div>
12 <div>Hantar kembali dalam</div>
13 <div v-if="timer !== null" class="text-primary font-bold mt-1">Waktu tersisa {{ countDownTimer }} detik</div>
14 <div v-else class="text-primary font-bold mt-1" @click="requestOTP">Request OTP code</div>
15 <div class="w-full p-5">
16 <div class="w-full bg-primary rounded-md text-center text-white py-2 text-lg">Sahkan</div>
17 </div>
18
19 <!-- otp pop up start -->
20 <div
21 class="fixed min-h-screen top-0 w-full flex justify-center items-center transition duration-500 transform"
22 :class="{ '-translate-y-full': !sendOtp }"
23 >
24 <div class="bg-white shadow-lg w-8/12 p-2 rounded-md flex flex-col items-center">
25 <div>
26 <i class="far fa-check-circle text-2xl text-green-500"></i>
27 </div>
28 <div>Send OTP code success !</div>
29 </div>
30 </div>
31 <!-- otp pop up start -->
32 </div>
33</template>
34<script>
35 export default {
36 data: () => ({
37 initialTimer: 60,
38 timer: 0,
39 phone: '',
40 audience: '',
41 sendOtp: false
42 }),
43 computed: {
44 countDownTimer() {
45 return this.timer
46 },
47 authAudience() {
48 return this.$store.state.auth.auth.audience
49 }
50 },
51 mounted() {
52 this.backTimer()
53 this.phone = `+${this.customerPhone || this.phone}`
54 this.audience = this.authAudience
55 },
56 methods: {
57 focusNext(event) {
58 event.target.nextElementSibling.focus()
59 },
60 backTimer() {
61 const inctTime = setInterval(() => {
62 const timer = this.initialTimer--
63 this.timer = timer
64 if (timer === 0) {
65 clearInterval(inctTime)
66 this.timer = null
67 }
68 }, 1000)
69 return inctTime
70 },
71 async requestOTP() {
72 try {
73 const res = await this.$axios.post(`${this.$config.API_URL}/auth/otp/phone`, {
74 phone: this.phone,
75 audience: this.audience
76 })
77 if (res.data) {
78 this.sendOtp = true
79 setTimeout(() => {
80 this.sendOtp = false
81 this.initialTimer = 60
82 this.backTimer()
83 }, 1500)
84 }
85 } catch (error) {
86 console.error(error)
87 }
88 }
89 }
90 }
91</script>
1<template>
2 {{ timerCount }}
3</template>
4
5<script>
6
7 export default {
8
9 data() {
10 return {
11 timerCount: 30
12 }
13 },
14
15 watch: {
16
17 timerCount: {
18 handler(value) {
19
20 if (value > 0) {
21 setTimeout(() => {
22 this.timerCount--;
23 }, 1000);
24 }
25
26 },
27 immediate: true // This ensures the watcher is triggered upon creation
28 }
29
30 }
31 }
32
33</script>
34