feat: 添加 QR 码生成和下载功能,优化用户界面布局

This commit is contained in:
2025-12-24 06:29:19 +07:00
parent 291eef6f60
commit a3390f82b5
3 changed files with 261 additions and 82 deletions

View File

@@ -37,6 +37,7 @@
"@tailwindcss/vite": "^4.1.18",
"@vee-validate/yup": "^4.15.1",
"@vueuse/core": "^14.1.0",
"@vueuse/integrations": "^14.1.0",
"@vueuse/router": "^14.1.0",
"better-auth": "^1.4.6",
"ethers": "^6.16.0",
@@ -44,6 +45,7 @@
"lightweight-charts": "^5.1.0",
"lodash-es": "^4.17.21",
"pinia": "^3.0.4",
"qrcode": "^1.5.4",
"tailwindcss": "^4.1.18",
"vee-validate": "^4.15.1",
"vue": "^3.5.25",
@@ -66,6 +68,7 @@
"@ionic/cli": "^7.2.1",
"@types/lodash-es": "^4.17.12",
"@types/node": "^24.10.2",
"@types/qrcode": "^1.5.6",
"@vitejs/plugin-legacy": "^7.2.1",
"@vitejs/plugin-vue": "^6.0.2",
"@vitejs/plugin-vue-jsx": "^5.1.2",

208
pnpm-lock.yaml generated
View File

@@ -68,6 +68,9 @@ importers:
'@vueuse/core':
specifier: ^14.1.0
version: 14.1.0(vue@3.5.25(typescript@5.9.3))
'@vueuse/integrations':
specifier: ^14.1.0
version: 14.1.0(change-case@5.4.4)(qrcode@1.5.4)(vue@3.5.25(typescript@5.9.3))
'@vueuse/router':
specifier: ^14.1.0
version: 14.1.0(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
@@ -89,6 +92,9 @@ importers:
pinia:
specifier: ^3.0.4
version: 3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))
qrcode:
specifier: ^1.5.4
version: 1.5.4
tailwindcss:
specifier: ^4.1.18
version: 4.1.18
@@ -150,6 +156,9 @@ importers:
'@types/node':
specifier: ^24.10.2
version: 24.10.2
'@types/qrcode':
specifier: ^1.5.6
version: 1.5.6
'@vitejs/plugin-legacy':
specifier: ^7.2.1
version: 7.2.1(terser@5.44.1)(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))
@@ -1713,6 +1722,9 @@ packages:
'@types/node@24.10.2':
resolution: {integrity: sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==}
'@types/qrcode@1.5.6':
resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}
'@types/sinonjs__fake-timers@8.1.1':
resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==}
@@ -1954,6 +1966,48 @@ packages:
peerDependencies:
vue: ^3.5.0
'@vueuse/integrations@14.1.0':
resolution: {integrity: sha512-eNQPdisnO9SvdydTIXnTE7c29yOsJBD/xkwEyQLdhDC/LKbqrFpXHb3uS//7NcIrQO3fWVuvMGp8dbK6mNEMCA==}
peerDependencies:
async-validator: ^4
axios: ^1
change-case: ^5
drauu: ^0.4
focus-trap: ^7
fuse.js: ^7
idb-keyval: ^6
jwt-decode: ^4
nprogress: ^0.2
qrcode: ^1.5
sortablejs: ^1
universal-cookie: ^7 || ^8
vue: ^3.5.0
peerDependenciesMeta:
async-validator:
optional: true
axios:
optional: true
change-case:
optional: true
drauu:
optional: true
focus-trap:
optional: true
fuse.js:
optional: true
idb-keyval:
optional: true
jwt-decode:
optional: true
nprogress:
optional: true
qrcode:
optional: true
sortablejs:
optional: true
universal-cookie:
optional: true
'@vueuse/metadata@14.1.0':
resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==}
@@ -2250,6 +2304,10 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
camelcase@5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
caniuse-lite@1.0.30001760:
resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==}
@@ -2323,6 +2381,9 @@ packages:
resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==}
engines: {node: '>= 10'}
cliui@6.0.0:
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
@@ -2475,6 +2536,10 @@ packages:
supports-color:
optional: true
decamelize@1.2.0:
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'}
decimal.js@10.6.0:
resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
@@ -2524,6 +2589,9 @@ packages:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'}
dijkstrajs@1.0.3:
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
dotenv@17.2.3:
resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==}
engines: {node: '>=12'}
@@ -2986,6 +3054,10 @@ packages:
resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==}
engines: {node: '>=18'}
find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
find-up@5.0.0:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
@@ -3043,6 +3115,10 @@ packages:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
get-east-asian-width@1.4.0:
resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==}
engines: {node: '>=18'}
@@ -3523,6 +3599,10 @@ packages:
resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==}
engines: {node: '>=14'}
locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
@@ -3950,10 +4030,18 @@ packages:
ospath@1.2.2:
resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==}
p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
p-locate@4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
p-locate@5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
@@ -3962,6 +4050,10 @@ packages:
resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
engines: {node: '>=10'}
p-try@2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
pac-proxy-agent@7.2.0:
resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==}
engines: {node: '>= 14'}
@@ -4077,6 +4169,10 @@ packages:
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
engines: {node: '>=4'}
pngjs@5.0.0:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}
pnpm-workspace-yaml@1.4.2:
resolution: {integrity: sha512-L2EKuOeV8aSt3z0RNtdwkg96BHV4WRN9pN2oTHKkMQQRxVEHFXPTbB+nly6ip1qV+JQM6qBebSiMgPRBx8S0Vw==}
@@ -4139,6 +4235,11 @@ packages:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
qrcode@1.5.4:
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
engines: {node: '>=10.13.0'}
hasBin: true
qs@6.14.0:
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
engines: {node: '>=0.6'}
@@ -4199,10 +4300,17 @@ packages:
request-progress@3.0.0:
resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==}
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
require-from-string@2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
require-main-filename@2.0.0:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
reserved-identifiers@1.2.0:
resolution: {integrity: sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==}
engines: {node: '>=18'}
@@ -4305,6 +4413,9 @@ packages:
engines: {node: '>=10'}
hasBin: true
set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
set-cookie-parser@2.7.2:
resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==}
@@ -4951,6 +5062,9 @@ packages:
resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==}
engines: {node: '>=20'}
which-module@2.0.1:
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
@@ -5038,6 +5152,9 @@ packages:
xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
y18n@4.0.3:
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
@@ -5053,6 +5170,14 @@ packages:
engines: {node: '>= 14.6'}
hasBin: true
yargs-parser@18.1.3:
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
engines: {node: '>=6'}
yargs@15.4.1:
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
engines: {node: '>=8'}
yauzl@2.10.0:
resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
@@ -6758,6 +6883,10 @@ snapshots:
dependencies:
undici-types: 7.16.0
'@types/qrcode@1.5.6':
dependencies:
'@types/node': 24.10.2
'@types/sinonjs__fake-timers@8.1.1': {}
'@types/sizzle@2.3.10': {}
@@ -7113,6 +7242,15 @@ snapshots:
'@vueuse/shared': 14.1.0(vue@3.5.25(typescript@5.9.3))
vue: 3.5.25(typescript@5.9.3)
'@vueuse/integrations@14.1.0(change-case@5.4.4)(qrcode@1.5.4)(vue@3.5.25(typescript@5.9.3))':
dependencies:
'@vueuse/core': 14.1.0(vue@3.5.25(typescript@5.9.3))
'@vueuse/shared': 14.1.0(vue@3.5.25(typescript@5.9.3))
vue: 3.5.25(typescript@5.9.3)
optionalDependencies:
change-case: 5.4.4
qrcode: 1.5.4
'@vueuse/metadata@14.1.0': {}
'@vueuse/router@14.1.0(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))':
@@ -7370,6 +7508,8 @@ snapshots:
callsites@3.1.0: {}
camelcase@5.3.1: {}
caniuse-lite@1.0.30001760: {}
caseless@0.12.0: {}
@@ -7434,6 +7574,12 @@ snapshots:
cli-width@3.0.0: {}
cliui@6.0.0:
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 6.2.0
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
@@ -7594,6 +7740,8 @@ snapshots:
optionalDependencies:
supports-color: 8.1.1
decamelize@1.2.0: {}
decimal.js@10.6.0: {}
decode-named-character-reference@1.2.0:
@@ -7634,6 +7782,8 @@ snapshots:
diff@4.0.2: {}
dijkstrajs@1.0.3: {}
dotenv@17.2.3: {}
dunder-proto@1.0.1:
@@ -8201,6 +8351,11 @@ snapshots:
find-up-simple@1.0.1: {}
find-up@4.1.0:
dependencies:
locate-path: 5.0.0
path-exists: 4.0.0
find-up@5.0.0:
dependencies:
locate-path: 6.0.0
@@ -8262,6 +8417,8 @@ snapshots:
gensync@1.0.0-beta.2: {}
get-caller-file@2.0.5: {}
get-east-asian-width@1.4.0: {}
get-intrinsic@1.3.0:
@@ -8742,6 +8899,10 @@ snapshots:
pkg-types: 2.3.0
quansync: 0.2.11
locate-path@5.0.0:
dependencies:
p-locate: 4.1.0
locate-path@6.0.0:
dependencies:
p-locate: 5.0.0
@@ -9333,10 +9494,18 @@ snapshots:
ospath@1.2.2: {}
p-limit@2.3.0:
dependencies:
p-try: 2.2.0
p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
p-locate@4.1.0:
dependencies:
p-limit: 2.3.0
p-locate@5.0.0:
dependencies:
p-limit: 3.1.0
@@ -9345,6 +9514,8 @@ snapshots:
dependencies:
aggregate-error: 3.1.0
p-try@2.2.0: {}
pac-proxy-agent@7.2.0:
dependencies:
'@tootallnate/quickjs-emscripten': 0.23.0
@@ -9451,6 +9622,8 @@ snapshots:
pluralize@8.0.0: {}
pngjs@5.0.0: {}
pnpm-workspace-yaml@1.4.2:
dependencies:
yaml: 2.8.2
@@ -9513,6 +9686,12 @@ snapshots:
punycode@2.3.1: {}
qrcode@1.5.4:
dependencies:
dijkstrajs: 1.0.3
pngjs: 5.0.0
yargs: 15.4.1
qs@6.14.0:
dependencies:
side-channel: 1.1.0
@@ -9583,8 +9762,12 @@ snapshots:
dependencies:
throttleit: 1.0.1
require-directory@2.1.1: {}
require-from-string@2.0.2: {}
require-main-filename@2.0.0: {}
reserved-identifiers@1.2.0: {}
resolve-from@4.0.0: {}
@@ -9692,6 +9875,8 @@ snapshots:
semver@7.7.3: {}
set-blocking@2.0.0: {}
set-cookie-parser@2.7.2: {}
shebang-command@2.0.0:
@@ -10330,6 +10515,8 @@ snapshots:
tr46: 6.0.0
webidl-conversions: 8.0.0
which-module@2.0.1: {}
which@2.0.2:
dependencies:
isexe: 2.0.0
@@ -10397,6 +10584,8 @@ snapshots:
xmlchars@2.2.0: {}
y18n@4.0.3: {}
yallist@3.1.1: {}
yallist@4.0.0: {}
@@ -10408,6 +10597,25 @@ snapshots:
yaml@2.8.2: {}
yargs-parser@18.1.3:
dependencies:
camelcase: 5.3.1
decamelize: 1.2.0
yargs@15.4.1:
dependencies:
cliui: 6.0.0
decamelize: 1.2.0
find-up: 4.1.0
get-caller-file: 2.0.5
require-directory: 2.1.1
require-main-filename: 2.0.0
set-blocking: 2.0.0
string-width: 4.2.3
which-module: 2.0.1
y18n: 4.0.3
yargs-parser: 18.1.3
yauzl@2.10.0:
dependencies:
buffer-crc32: 0.2.13

View File

@@ -1,8 +1,20 @@
<script lang='ts' setup>
import { useQRCode } from "@vueuse/integrations/useQRCode";
import { copyOutline, qrCodeOutline, shareOutline } from "ionicons/icons";
import MaterialSymbolsDownload from "~icons/material-symbols/download";
import MaterialSymbolsUpload from "~icons/material-symbols/upload";
const userStore = useUserStore();
const { userProfile } = storeToRefs(userStore);
const url = computed(() => {
return `riwaapp://onchain-address?user=${userProfile.value?.user.email}`;
});
const qrcode = useQRCode(url, {
type: "image/webp",
rendererOpts: {
quality: 1,
},
});
</script>
<template>
@@ -16,27 +28,26 @@ const { userProfile } = storeToRefs(userStore);
</IonToolbar>
</IonHeader>
<IonContent :fullscreen="true" class="ion-padding">
<div class="content-wrapper">
<div class="container">
<div class="user-info">
<div class="avatar-wrapper">
<ui-avatar class="size-18" />
<div class="flex justify-center items-center flex-col mt-20">
<div class="w-[80vw] h-[80vw] bg-text-900 max-w-130 max-h-130 rounded-[14px] p-4 flex flex-col justify-center items-center relative border border-text-500">
<div class="absolute top-0 left-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col items-center">
<div class="p-1 rounded-full w-fit">
<ui-avatar class="size-15 border border-[--border-color]" />
</div>
<IonText class="user-email">
{{ userProfile?.user.email }}
</IonText>
</div>
<div class="ion-text-center address-info">
<ion-icon :icon="qrCodeOutline" class="qr-code" />
<div class="mt-4px">
<div class="ion-text-center w-full mt-5 flex flex-col items-center">
<div class="w-[50vw] h-[50vw] max-w-62.5 max-h-62.5 flex justify-center items-center">
<img :src="qrcode" alt="QR Code" class="w-[90%] h-[90%] rounded-2xl">
</div>
<div class="mt-4">
<ion-text color="secondary">
<div class="text-sm">
<div class="text-sm text-text-500 font-semibold">
Onchain address
</div>
</ion-text>
<ion-text>
<div class="mt-4px">
<div class="mt-4px text-md font-mono break-all">
0x1234567890abcdef1234
</div>
</ion-text>
@@ -44,15 +55,23 @@ const { userProfile } = storeToRefs(userStore);
</div>
</div>
<div class="ion-margin-top ion-text-center flex gap-6">
<ion-button fill="clear">
<ion-icon slot="start" :icon="shareOutline" />
Share
</ion-button>
<ion-button fill="clear">
<ion-icon slot="start" :icon="copyOutline" />
Copy
</ion-button>
<div class="ion-text-center flex justify-between gap-6 w-[50%] mt-14">
<div class="button">
<div class="icon">
<MaterialSymbolsUpload class="text-xl" />
</div>
<div class="text">
Share
</div>
</div>
<div class="button">
<div class="icon">
<MaterialSymbolsDownload class="text-xl" />
</div>
<div class="text">
Copy
</div>
</div>
</div>
</div>
</IonContent>
@@ -60,67 +79,16 @@ const { userProfile } = storeToRefs(userStore);
</template>
<style lang="css" scoped>
.content-wrapper {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
height: 100%;
--background: #f4f6f8;
--border-color: #c6c5c5;
@reference "tailwindcss";
.button {
@apply flex flex-col items-center gap-2 text-[text-500] font-medium;
}
.ion-palette-dark {
.content-wrapper {
--background: #232324;
--border-color: #3a3a3b;
}
.icon {
@apply p-2.5 bg-(--ion-text-color-step-700) rounded-full;
}
.container {
width: 80vw;
height: 80vw;
max-width: 500px;
max-height: 500px;
border-radius: 14px;
padding: 16px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
background-color: var(--background);
border: 1px solid var(--border-color);
}
.user-email {
margin-top: 4px;
font-weight: 500;
font-size: 1.1rem;
}
.user-info {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
}
.avatar-wrapper {
background-color: var(--background);
padding: 4px;
border-radius: 100%;
width: fit-content;
}
.avatar {
border: 1px solid var(--border-color);
}
.address-info {
width: 100%;
margin-top: 20px;
}
.qr-code {
width: 50vw;
height: 50vw;
max-width: 250px;
max-height: 250px;
.text {
@apply text-sm;
}
</style>