Custom card component for OTP display
This commit is contained in:
parent
e9c2ccc115
commit
879bf67b22
111
frontend/src/components/SecretCard.vue
Normal file
111
frontend/src/components/SecretCard.vue
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<template>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="card-top">
|
||||||
|
<span class="issuer">{{ issuer }}</span>
|
||||||
|
<button class="edit-button" @click="editSecret">
|
||||||
|
<img src="../assets/edit-icon.png" class="edit-icon" /></button
|
||||||
|
><br />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="user">{{ username }}</span> <br />
|
||||||
|
<span class="otp">{{ generateTotp(secret) }}</span>
|
||||||
|
<div class="timer" id="timer" :style="{ width: timerWidth + '%' }"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { TOTP } from "totp-generator";
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
id: Number,
|
||||||
|
issuer: String,
|
||||||
|
username: String,
|
||||||
|
secret: String,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
otp: 123456,
|
||||||
|
notes: "",
|
||||||
|
remainingTime: 0,
|
||||||
|
timerWidth: 0,
|
||||||
|
totalTime: 30,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
generateTotp(secret) {
|
||||||
|
const { otp, expires } = TOTP.generate(secret);
|
||||||
|
const remaining = (expires - Date.now()) / 30000;
|
||||||
|
this.remainingTime = remaining / 1000;
|
||||||
|
this.timerWidth = remaining * 100;
|
||||||
|
// console.log("hello");
|
||||||
|
return otp;
|
||||||
|
},
|
||||||
|
|
||||||
|
startTimer() {
|
||||||
|
this.interval = setInterval(() => {
|
||||||
|
if (this.remainingTime > 0) {
|
||||||
|
this.timerWidth = (this.remainingTime / this.totalTime) * 10;
|
||||||
|
} else {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
},
|
||||||
|
|
||||||
|
editSecret() {
|
||||||
|
this.$emit("edit", this.id);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
// this.startTimer();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.wrapper {
|
||||||
|
height: 110px;
|
||||||
|
width: 160px;
|
||||||
|
/* border: 1px solid black; */
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 4px 12px 4px 12px;
|
||||||
|
box-shadow: 1px 1px 8px #ccc;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.issuer {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user {
|
||||||
|
color: gray;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.otp {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timer {
|
||||||
|
/* width: 100%; */
|
||||||
|
height: 3px;
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-top {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.edit-button {
|
||||||
|
position: relative;
|
||||||
|
right: 0;
|
||||||
|
margin-left: auto;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user