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

@@ -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>