Compare commits
4 Commits
49009af8e3
...
8cb4a14b94
| Author | SHA1 | Date | |
|---|---|---|---|
| 8cb4a14b94 | |||
| 0e2a08daf3 | |||
| f907dd5adb | |||
| 4ea494cdff |
22
package-lock.json
generated
22
package-lock.json
generated
@ -9,8 +9,10 @@
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@metamask/detect-provider": "^2.0.0",
|
||||
"html5-qrcode": "^2.3.8",
|
||||
"pinia": "^2.0.36",
|
||||
"vue": "^3.3.2",
|
||||
"vue-cookies": "^1.8.3",
|
||||
"vue-router": "^4.2.0",
|
||||
"web3": "^1.8.2"
|
||||
},
|
||||
@ -3350,6 +3352,11 @@
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/html5-qrcode": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.3.8.tgz",
|
||||
"integrity": "sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ=="
|
||||
},
|
||||
"node_modules/http-cache-semantics": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
|
||||
@ -5825,6 +5832,11 @@
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-cookies": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-cookies/-/vue-cookies-1.8.3.tgz",
|
||||
"integrity": "sha512-VBRsyRMVdahBgFfh389TMHPmDdr4URDJNMk4FKSCfuNITs7+jitBDhwyL4RJd3WUsfOYNNjPAkfbehyH9AFuoA=="
|
||||
},
|
||||
"node_modules/vue-eslint-parser": {
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.0.tgz",
|
||||
@ -8823,6 +8835,11 @@
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"html5-qrcode": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.3.8.tgz",
|
||||
"integrity": "sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ=="
|
||||
},
|
||||
"http-cache-semantics": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
|
||||
@ -10593,6 +10610,11 @@
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"vue-cookies": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-cookies/-/vue-cookies-1.8.3.tgz",
|
||||
"integrity": "sha512-VBRsyRMVdahBgFfh389TMHPmDdr4URDJNMk4FKSCfuNITs7+jitBDhwyL4RJd3WUsfOYNNjPAkfbehyH9AFuoA=="
|
||||
},
|
||||
"vue-eslint-parser": {
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.0.tgz",
|
||||
|
||||
@ -9,8 +9,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@metamask/detect-provider": "^2.0.0",
|
||||
"html5-qrcode": "^2.3.8",
|
||||
"pinia": "^2.0.36",
|
||||
"vue": "^3.3.2",
|
||||
"vue-cookies": "^1.8.3",
|
||||
"vue-router": "^4.2.0",
|
||||
"web3": "^1.8.2"
|
||||
},
|
||||
|
||||
@ -1,219 +1,239 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "SBT_addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "SBT_addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "recv",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
"inputs": [],
|
||||
"name": "recv",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "sbt",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "contract SoulboundToken",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
"inputs": [],
|
||||
"name": "sbt",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "contract SoulboundToken",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
},
|
||||
{
|
||||
"stateMutability": "payable",
|
||||
"type": "receive",
|
||||
"payable": true
|
||||
"stateMutability": "payable",
|
||||
"type": "receive",
|
||||
"payable": true
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "client",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setCredit",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "number",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "register",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "shop",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "pay",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "repay",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "payable",
|
||||
"type": "function",
|
||||
"payable": true
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "start_recv",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "stop_recv",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "client",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getCredit",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "client",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getArrear",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "client",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getClientOrders",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "client",
|
||||
"type": "address"
|
||||
"internalType": "bool",
|
||||
"name": "isFinished",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setCredit",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "number",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "register",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "shop",
|
||||
"type": "address"
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
"internalType": "address",
|
||||
"name": "shop",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "pay",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
],
|
||||
"internalType": "struct Order[]",
|
||||
"name": "",
|
||||
"type": "tuple[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "repay",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "payable",
|
||||
"type": "function",
|
||||
"payable": true
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "start_recv",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "stop_recv",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "client",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getCredit",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "client",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getArrear",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "client",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getClientOrders",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "isFinished",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "shop",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"internalType": "struct Order[]",
|
||||
"name": "",
|
||||
"type": "tuple[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "client",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getSBTNumber",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function",
|
||||
"constant": true
|
||||
}
|
||||
]
|
||||
]
|
||||
@ -39,6 +39,18 @@ hr {
|
||||
background: #060606;
|
||||
color: white;
|
||||
} */
|
||||
.panel {
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
background-color: #5B5B5B;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.panel-block {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.box.is-fullwidth h1.title.is-4{
|
||||
color: #060606;
|
||||
|
||||
74
src/components/ClientNav.vue
Normal file
74
src/components/ClientNav.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'ClientNav',
|
||||
props: ['path'],
|
||||
mounted () {
|
||||
console.log(this.path)
|
||||
this.navCSS[this.path] += ' is-active'
|
||||
console.log(this.navCSS)
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
navCSS: {
|
||||
main: 'panel-block',
|
||||
pay: 'panel-block',
|
||||
credit: 'panel-block',
|
||||
info: 'panel-block',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav class="panel">
|
||||
<p class="panel-heading">
|
||||
使用者選項
|
||||
</p>
|
||||
<RouterLink to="/client" :class="this.navCSS['main']">
|
||||
<span class="panel-icon">
|
||||
<i class="fas fa-book" aria-hidden="true"></i>
|
||||
</span>
|
||||
<template v-if="this.path == 'main'">
|
||||
<strong>主選單</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p>主選單</p>
|
||||
</template>
|
||||
</RouterLink>
|
||||
<RouterLink to="/client/info" :class="this.navCSS['info']">
|
||||
<span class="panel-icon">
|
||||
<i class="fas fa-book" aria-hidden="true"></i>
|
||||
</span>
|
||||
<template v-if="this.path == 'info'">
|
||||
<strong>個人資料</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p>個人資料</p>
|
||||
</template>
|
||||
</RouterLink>
|
||||
<RouterLink to="/client/pay" :class="this.navCSS['pay']">
|
||||
<span class="panel-icon">
|
||||
<i class="fas fa-book" aria-hidden="true"></i>
|
||||
</span>
|
||||
<template v-if="this.path == 'pay'">
|
||||
<strong>掃描支付</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p>掃描支付</p>
|
||||
</template>
|
||||
</RouterLink>
|
||||
<RouterLink to="/client/credit" :class="this.navCSS['credit']">
|
||||
<span class="panel-icon">
|
||||
<i class="fas fa-book" aria-hidden="true"></i>
|
||||
</span>
|
||||
<template v-if="this.path == 'credit'">
|
||||
<strong>信用紀錄</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p>信用紀錄</p>
|
||||
</template>
|
||||
</RouterLink>
|
||||
</nav>
|
||||
</template>
|
||||
@ -1,6 +1,79 @@
|
||||
<script>
|
||||
import detectEthereumProvider from '@metamask/detect-provider'
|
||||
import WarningModal from '../components/WarningModal.vue'
|
||||
import SuccessModal from '../components/SuccessModal.vue'
|
||||
import Web3 from 'web3'
|
||||
import Bank from '@/assets/Bank.json'
|
||||
|
||||
export default {
|
||||
name: 'PageNavbar'
|
||||
components: { WarningModal, SuccessModal },
|
||||
name: 'PageNavbar',
|
||||
data() {
|
||||
return {
|
||||
BankAddress: import.meta.env.VITE_BANK_ADDR,
|
||||
linked: false,
|
||||
address: '',
|
||||
msg:'',
|
||||
successModalStatus: false,
|
||||
warningModalStatus: false,
|
||||
web3: null,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.$cookies.isKey('linked'))
|
||||
if (!this.$cookies.isKey('linked')) {
|
||||
this.linked = false
|
||||
} else {
|
||||
this.linked = true
|
||||
this.address = this.$cookies.get('address')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async login() {
|
||||
const provider = await detectEthereumProvider()
|
||||
if (provider) {
|
||||
const chainId = await window.ethereum.request({ method: 'eth_chainId' })
|
||||
console.log(chainId)
|
||||
if (chainId == import.meta.env.VITE_CHAIN_ID) {
|
||||
const account = await window.ethereum.request({ method: 'eth_requestAccounts' })
|
||||
|
||||
// check from bank
|
||||
this.web3 = new Web3(window.ethereum)
|
||||
var token = new this.web3.eth.Contract(Bank, this.BankAddress)
|
||||
var clientAddr = (await this.web3.eth.getAccounts())[0]
|
||||
this.web3.eth.defaultAccount = clientAddr
|
||||
var returnNumber = await token.methods.getSBTNumber(clientAddr).call({from: clientAddr})
|
||||
if (returnNumber != 0){
|
||||
this.$cookies.set('address', clientAddr)
|
||||
this.$cookies.set('linked', true)
|
||||
this.$cookies.set('SBTNumber', returnNumber)
|
||||
this.linked = true
|
||||
this.address = this.$cookies.get('address')
|
||||
this.msg = '成功連接 MetaMask'
|
||||
this.successModalStatus = true
|
||||
} else {
|
||||
this.msg = '您可能還沒有註冊過!'
|
||||
this.warningModalStatus = true
|
||||
}
|
||||
} else {
|
||||
this.msg = '你連接的不是 Sepolia 測試網路,目前只接受 Sepolia address'
|
||||
this.warningModalStatus = true
|
||||
}
|
||||
} else {
|
||||
this.msg = 'no Metamask'
|
||||
this.warningModalStatus = true
|
||||
}
|
||||
},
|
||||
logout () {
|
||||
console.log('logout')
|
||||
this.linked = false
|
||||
this.address = ''
|
||||
this.$cookies.remove('linked')
|
||||
this.$cookies.remove('address')
|
||||
this.$cookies.remove('SBTNumber')
|
||||
this.$router.push('/')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -31,10 +104,16 @@ export default {
|
||||
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item">
|
||||
<div class="buttons">
|
||||
<RouterLink to="/signup" class="button is-primary is-outlined">Sign up</RouterLink>
|
||||
<RouterLink to="/login" class="button is-info is-outlined">Log in</RouterLink>
|
||||
</div>
|
||||
<template v-if="!linked">
|
||||
<div class="buttons">
|
||||
<RouterLink to="/signup" class="button is-primary is-outlined">Sign up</RouterLink>
|
||||
<a class="button is-info is-outlined" @click="login">Log in</a>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<RouterLink to="/client" class="button is-info is-outlined is-small is-rounded">{{ 'Hello! ' + address }}</RouterLink>
|
||||
<button class="button is-danger is-outlined is-small is-rounded" @click="logout">登出</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -42,4 +121,7 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<WarningModal :active="warningModalStatus" :errorMsg="msg" @closeModal="warningModalStatus=false"></WarningModal>
|
||||
<SuccessModal :active="successModalStatus" :successMsg="msg" @closeModal="successModalStatus=false" link="/client" btnName="繼續"></SuccessModal>
|
||||
|
||||
</template>
|
||||
|
||||
@ -3,10 +3,12 @@ import { createPinia } from 'pinia'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import VueCookies from 'vue-cookies'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
app.use(VueCookies, { expires: '7d'})
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
@ -3,6 +3,10 @@ import HomeView from '../views/HomeView.vue'
|
||||
import SignupView from '../views/SignupView.vue'
|
||||
import LinkSBTView from '../views/LinkSBTView.vue'
|
||||
import CreditView from '../views/CreditView.vue'
|
||||
import ClientMainView from '../views/ClientMainView.vue'
|
||||
import ClientInfoView from '../views/ClientInfoView.vue'
|
||||
import ClientCreditView from '../views/ClientCreditView.vue'
|
||||
import ClientPayView from '../views/ClientPayView.vue'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
@ -26,7 +30,27 @@ const router = createRouter({
|
||||
path: '/signup/credit',
|
||||
name: 'startcredit',
|
||||
component: CreditView
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/client',
|
||||
name: 'clientmain',
|
||||
component: ClientMainView
|
||||
},
|
||||
{
|
||||
path: '/client/info',
|
||||
name: 'clientinfo',
|
||||
component: ClientInfoView
|
||||
},
|
||||
{
|
||||
path: '/client/credit',
|
||||
name: 'clientcredit',
|
||||
component: ClientCreditView
|
||||
},
|
||||
{
|
||||
path: '/client/pay',
|
||||
name: 'clientpay',
|
||||
component: ClientPayView
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
111
src/views/ClientMainView.vue
Normal file
111
src/views/ClientMainView.vue
Normal file
@ -0,0 +1,111 @@
|
||||
<script>
|
||||
import Web3 from 'web3';
|
||||
import SBT from '@/assets/SBT.json'
|
||||
import PageTitle from '../components/PageTitle.vue'
|
||||
import detectEthereumProvider from '@metamask/detect-provider'
|
||||
import WarningModal from '../components/WarningModal.vue'
|
||||
import SuccessModal from '../components/SuccessModal.vue'
|
||||
import { useClientStore } from '../stores/Client.js'
|
||||
import ClientNav from '../components/ClientNav.vue'
|
||||
|
||||
// To use Html5QrcodeScanner (more info below)
|
||||
import { Html5QrcodeScanner } from "html5-qrcode";
|
||||
|
||||
// To use Html5Qrcode (more info below)
|
||||
import { Html5Qrcode } from "html5-qrcode";
|
||||
|
||||
|
||||
|
||||
export default {
|
||||
components: { PageTitle, WarningModal, SuccessModal, ClientNav },
|
||||
data() {
|
||||
return {
|
||||
SBTAddress: import.meta.env.VITE_SBT_ADDR,
|
||||
number: 0,
|
||||
warningModalStatus: false,
|
||||
successModalStatus: false,
|
||||
msg: '',
|
||||
clientAddr: '',
|
||||
web3: null,
|
||||
token: null,
|
||||
isWaiting: false,
|
||||
log: [],
|
||||
scanner: null
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.web3 = new Web3(window.ethereum)
|
||||
this.clientAddr = (await this.web3.eth.getAccounts())[0]
|
||||
this.web3.eth.defaultAccount = this.clientAddr
|
||||
},
|
||||
methods: {
|
||||
onScanSuccess(decodedText, decodedResult) {
|
||||
// handle the scanned code as you like, for example:
|
||||
console.log(`Code matched = ${decodedText}`, decodedResult);
|
||||
this.scanner.clear()
|
||||
},
|
||||
scan () {
|
||||
this.scanner = new Html5QrcodeScanner(
|
||||
"reader",
|
||||
{ fps: 10, qrbox: { width: 250, height: 250 } },
|
||||
/* verbose= */ false);
|
||||
this.scanner.render(this.onScanSuccess);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="blog-posts">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column is-2">
|
||||
<!-- <ClientNav path="main"></ClientNav> -->
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="container">
|
||||
<div class="block">
|
||||
<PageTitle title="Set Credit Limit" subtitle="根據 SBT 信用紀錄設定額度"></PageTitle>
|
||||
</div>
|
||||
<div class="block">
|
||||
|
||||
<div class="tile is-ancestor">
|
||||
<div class="tile is-vertical is-8">
|
||||
<div class="tile">
|
||||
<div class="tile is-parent is-vertical">
|
||||
|
||||
|
||||
<RouterLink to="/client/info" class="tile is-child notification is-info">
|
||||
<article>
|
||||
<p class="title"><i class="fas fa-user"></i> 個人資料</p>
|
||||
<!-- <p class="subtitle">Top tile</p> -->
|
||||
</article>
|
||||
</RouterLink>
|
||||
<RouterLink to="/client/pay" class="tile is-child notification is-info">
|
||||
<article>
|
||||
<p class="title"><i class="fas fa-credit-card"></i> 掃描支付</p>
|
||||
<!-- <p class="subtitle">Top tile</p> -->
|
||||
</article>
|
||||
</RouterLink>
|
||||
<RouterLink to="/client/credit" class="tile is-child notification is-info">
|
||||
<article>
|
||||
<p class="title"><i class="fas fa-history"></i> 信用紀錄</p>
|
||||
<!-- <p class="subtitle">Top tile</p> -->
|
||||
</article>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<WarningModal :active="warningModalStatus" :errorMsg="msg" @closeModal="warningModalStatus = false"></WarningModal>
|
||||
<SuccessModal :active="successModalStatus" :successMsg="msg" @closeModal="successModalStatus = false"
|
||||
link="/signup/linksbt" btnName="繼續"></SuccessModal>
|
||||
</template>
|
||||
@ -109,23 +109,35 @@ export default {
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="block">
|
||||
<h1 class="title is-4">警告紀錄</h1>
|
||||
<table class="table is-fullwidth is-striped is-hoverable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>發起預警之銀行</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<template v-for="(value, index) of log">
|
||||
<tr>
|
||||
<th>{{ index }}</th>
|
||||
<td>{{ value.bank }}</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<div class="columns">
|
||||
|
||||
<div class="column is-2 is-offset-4">
|
||||
<button @click="detect" class="button is-primary is-fullwidth is-medium is-outlined">Link to
|
||||
MetaMask</button>
|
||||
</div>
|
||||
<div class="column is-2">
|
||||
<RouterLink to="/" class="button is-danger is-fullwidth is-medium is-outlined">Cancel</RouterLink>
|
||||
<div class="column is-2 is-offset-5">
|
||||
<RouterLink to="/client" class="button is-primary is-fullwidth is-medium is-outlined">確認</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<WarningModal :active="warningModalStatus" :errorMsg="msg" @closeModal="warningModalStatus = false"></WarningModal>
|
||||
<SuccessModal :active="successModalStatus" :successMsg="msg" @closeModal="successModalStatus = false"
|
||||
link="/signup/linksbt" btnName="繼續"></SuccessModal>
|
||||
</template>
|
||||
|
||||
@ -42,6 +42,10 @@ export default {
|
||||
try {
|
||||
await this.bank.methods.register(this.number).send({ from: this.clientAddr })
|
||||
this.successModalStatus = true
|
||||
this.$cookies.set('linked', true)
|
||||
this.$cookies.set('SBTNumber', returnNumber)
|
||||
this.$cookies.set('address', this.clientAddr)
|
||||
|
||||
this.link = '/signup/credit'
|
||||
this.msg = '註冊成功!'
|
||||
} catch (error) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user