feat: 添加性别枚举,更新用户设置页面以支持性别选择和生日选择功能

This commit is contained in:
2025-12-15 02:01:27 +07:00
parent 6998a66db5
commit 47f8418ddf
5 changed files with 64 additions and 41 deletions

8
components.d.ts vendored
View File

@@ -29,6 +29,8 @@ declare module 'vue' {
IonCardTitle: typeof import('@ionic/vue')['IonCardTitle'] IonCardTitle: typeof import('@ionic/vue')['IonCardTitle']
IonCheckbox: typeof import('@ionic/vue')['IonCheckbox'] IonCheckbox: typeof import('@ionic/vue')['IonCheckbox']
IonContent: typeof import('@ionic/vue')['IonContent'] IonContent: typeof import('@ionic/vue')['IonContent']
IonDatetime: typeof import('@ionic/vue')['IonDatetime']
IonDatetimeButton: typeof import('@ionic/vue')['IonDatetimeButton']
IonHeader: typeof import('@ionic/vue')['IonHeader'] IonHeader: typeof import('@ionic/vue')['IonHeader']
IonIcon: typeof import('@ionic/vue')['IonIcon'] IonIcon: typeof import('@ionic/vue')['IonIcon']
IonImg: typeof import('@ionic/vue')['IonImg'] IonImg: typeof import('@ionic/vue')['IonImg']
@@ -57,8 +59,10 @@ declare module 'vue' {
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
UiAvatar: typeof import('./src/components/ui/avatar/index.vue')['default'] UiAvatar: typeof import('./src/components/ui/avatar/index.vue')['default']
UiDivider: typeof import('./src/components/ui/divider/index.vue')['default'] UiDivider: typeof import('./src/components/ui/divider/index.vue')['default']
UiForm: typeof import('./src/components/ui/form/index.vue')['default']
UiInput: typeof import('./src/components/ui/input/index.vue')['default'] UiInput: typeof import('./src/components/ui/input/index.vue')['default']
UiInputLabel: typeof import('./src/components/ui/input-label/index.vue')['default'] UiInputLabel: typeof import('./src/components/ui/input-label/index.vue')['default']
UiSelect: typeof import('./src/components/ui/select/index.vue')['default']
UiSelectLabel: typeof import('./src/components/ui/select-label/index.vue')['default'] UiSelectLabel: typeof import('./src/components/ui/select-label/index.vue')['default']
} }
} }
@@ -82,6 +86,8 @@ declare global {
const IonCardTitle: typeof import('@ionic/vue')['IonCardTitle'] const IonCardTitle: typeof import('@ionic/vue')['IonCardTitle']
const IonCheckbox: typeof import('@ionic/vue')['IonCheckbox'] const IonCheckbox: typeof import('@ionic/vue')['IonCheckbox']
const IonContent: typeof import('@ionic/vue')['IonContent'] const IonContent: typeof import('@ionic/vue')['IonContent']
const IonDatetime: typeof import('@ionic/vue')['IonDatetime']
const IonDatetimeButton: typeof import('@ionic/vue')['IonDatetimeButton']
const IonHeader: typeof import('@ionic/vue')['IonHeader'] const IonHeader: typeof import('@ionic/vue')['IonHeader']
const IonIcon: typeof import('@ionic/vue')['IonIcon'] const IonIcon: typeof import('@ionic/vue')['IonIcon']
const IonImg: typeof import('@ionic/vue')['IonImg'] const IonImg: typeof import('@ionic/vue')['IonImg']
@@ -110,7 +116,9 @@ declare global {
const RouterView: typeof import('vue-router')['RouterView'] const RouterView: typeof import('vue-router')['RouterView']
const UiAvatar: typeof import('./src/components/ui/avatar/index.vue')['default'] const UiAvatar: typeof import('./src/components/ui/avatar/index.vue')['default']
const UiDivider: typeof import('./src/components/ui/divider/index.vue')['default'] const UiDivider: typeof import('./src/components/ui/divider/index.vue')['default']
const UiForm: typeof import('./src/components/ui/form/index.vue')['default']
const UiInput: typeof import('./src/components/ui/input/index.vue')['default'] const UiInput: typeof import('./src/components/ui/input/index.vue')['default']
const UiInputLabel: typeof import('./src/components/ui/input-label/index.vue')['default'] const UiInputLabel: typeof import('./src/components/ui/input-label/index.vue')['default']
const UiSelect: typeof import('./src/components/ui/select/index.vue')['default']
const UiSelectLabel: typeof import('./src/components/ui/select-label/index.vue')['default'] const UiSelectLabel: typeof import('./src/components/ui/select-label/index.vue')['default']
} }

View File

@@ -19,3 +19,9 @@ export enum ChainEnum {
ERC20 = "ERC20", ERC20 = "ERC20",
TRC20 = "TRC20", TRC20 = "TRC20",
} }
export enum GenderEnum {
MALE = "male",
FEMALE = "female",
OTHER = "other",
}

View File

@@ -18,4 +18,4 @@ export type WithdrawBody = Omit<Parameters<typeof client.api.withdraw.post>[0],
export type UserProfileData = Treaty.Data<typeof client.api.user.profile.get>["userProfile"]; export type UserProfileData = Treaty.Data<typeof client.api.user.profile.get>["userProfile"];
export type UpdateUserProfileBody = Parameters<typeof client.api.user.profile.put>[0]; export type UpdateUserProfileBody = NonNullable<Parameters<typeof client.api.user.profile.put>[0]>;

View File

@@ -0,0 +1,9 @@
<script lang='ts' setup>
</script>
<template>
hello world
</template>
<style lang='css' scoped></style>

View File

@@ -3,6 +3,7 @@ import type { UpdateUserProfileBody, UserProfileData } from "@/api/types";
import { alertController, toastController } from "@ionic/vue"; import { alertController, toastController } from "@ionic/vue";
import { arrowBackOutline } from "ionicons/icons"; import { arrowBackOutline } from "ionicons/icons";
import { client } from "@/api"; import { client } from "@/api";
import { GenderEnum } from "@/api/enum";
import { authClient } from "@/auth"; import { authClient } from "@/auth";
const router = useRouter(); const router = useRouter();
@@ -69,6 +70,14 @@ async function handleEditField(field: keyof UpdateUserProfileBody, label: string
await alert.present(); await alert.present();
} }
async function onUpdateSelect(value: UpdateUserProfileBody["gender"]) {
await updateProfile({ gender: value } as UpdateUserProfileBody);
}
async function onChangeDateTime(event: CustomEvent) {
const selectedDate = useDateFormat(event.detail.value, "YYYY-MM-DD");
await updateProfile({ birthday: selectedDate.value } as UpdateUserProfileBody);
}
async function handleSignOut() { async function handleSignOut() {
const alert = await alertController.create({ const alert = await alertController.create({
header: "Sign Out", header: "Sign Out",
@@ -133,48 +142,19 @@ onMounted(() => {
</ion-label> </ion-label>
</ion-item> </ion-item>
<ion-item button @click="handleEditField('gender', 'Gender')"> <ion-item button>
<ion-label> <ion-select interface="action-sheet" toggle-icon="" label-placement="floating" :model-value="userProfile?.gender" label="Gender" placeholder="Select Gender" @update:model-value="onUpdateSelect">
<p class="text-xs text-text-400"> <ion-select-option v-for="item in GenderEnum" :key="item" :value="item">
Gender {{ item }}
</p> </ion-select-option>
<h2 class="mt-1"> </ion-select>
{{ userProfile?.gender || 'Not set' }}
</h2>
</ion-label>
</ion-item> </ion-item>
<ion-item button @click="handleEditField('birthday', 'Birthday')"> <ion-item button>
<ion-label> <ion-datetime-button datetime="datetime" color="primary" />
<p class="text-xs text-text-400"> <ion-modal :keep-contents-mounted="true">
Birthday <ion-datetime id="datetime" :value="userProfile?.birthday" presentation="date" :prefer-wheel="true" @ion-change="onChangeDateTime" />
</p> </ion-modal>
<h2 class="mt-1">
{{ userProfile?.birthday || 'Not set' }}
</h2>
</ion-label>
</ion-item>
<ion-item button @click="handleEditField('country', 'Country')">
<ion-label>
<p class="text-xs text-text-400">
Country
</p>
<h2 class="mt-1">
{{ userProfile?.country || 'Not set' }}
</h2>
</ion-label>
</ion-item>
<ion-item button @click="handleEditField('city', 'City')">
<ion-label>
<p class="text-xs text-text-400">
City
</p>
<h2 class="mt-1">
{{ userProfile?.city || 'Not set' }}
</h2>
</ion-label>
</ion-item> </ion-item>
</ion-list> </ion-list>
@@ -192,4 +172,24 @@ onMounted(() => {
ion-avatar { ion-avatar {
--border-radius: 50%; --border-radius: 50%;
} }
ion-item {
--min-height: 60px;
}
ion-datetime {
--background: rgb(255 255 255);
--background-rgb: 255, 255, 255;
--wheel-highlight-background: rgb(194 194 194);
--wheel-fade-background-rgb: 255, 255, 255;
border-radius: 16px;
overflow: hidden;
}
@media (prefers-color-scheme: dark) {
ion-datetime {
--background: rgb(15, 15, 15);
--background-rgb: 15, 15, 15;
--wheel-highlight-background: rgb(50, 50, 50);
--wheel-highlight-border-radius: 48px;
--wheel-fade-background-rgb: 15, 15, 15;
}
}
</style> </style>