完善个人资料页面
This commit is contained in:
parent
980f52ee3b
commit
023cbf428c
@ -1,112 +1,158 @@
|
||||
<template>
|
||||
<Card
|
||||
v-if="!$team.pg?.jerp_partner"
|
||||
:title="$t('Jingrow Partner')"
|
||||
:subtitle="$t('Jingrow partner associated with your account')"
|
||||
class="mx-auto max-w-3xl"
|
||||
>
|
||||
<template #actions>
|
||||
<Button
|
||||
v-if="!$team.pg?.partner_email"
|
||||
icon-left="edit"
|
||||
@click="showAddPartnerCodeDialog = true"
|
||||
>
|
||||
{{ $t('Add Partner Code') }}
|
||||
</Button>
|
||||
<Button
|
||||
v-else
|
||||
icon-left="trash-2"
|
||||
@click="showRemovePartnerDialog = true"
|
||||
>
|
||||
{{ $t('Unlink Partner') }}
|
||||
</Button>
|
||||
<n-card v-if="!$team.pg?.jerp_partner" class="partner-card">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold">{{ $t('Jingrow Partner') }}</h3>
|
||||
<p class="text-sm text-gray-600 mt-1">{{ $t('Jingrow partner associated with your account') }}</p>
|
||||
</div>
|
||||
<n-button
|
||||
v-if="!$team.pg?.partner_email"
|
||||
@click="showAddPartnerCodeDialog = true"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon><EditIcon /></n-icon>
|
||||
</template>
|
||||
{{ $t('Add Partner Code') }}
|
||||
</n-button>
|
||||
<n-button
|
||||
v-else
|
||||
type="error"
|
||||
@click="showRemovePartnerDialog = true"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon><TrashIcon /></n-icon>
|
||||
</template>
|
||||
{{ $t('Unlink Partner') }}
|
||||
</n-button>
|
||||
</div>
|
||||
</template>
|
||||
<div class="py-4">
|
||||
<span
|
||||
class="text-base font-medium text-gray-700"
|
||||
<div class="py-2">
|
||||
<p
|
||||
v-if="!$team.pg?.partner_email"
|
||||
class="text-sm text-gray-700"
|
||||
>
|
||||
{{ $t('Have a Jingrow partner referral code? Click') }}
|
||||
<strong>{{ $t('Add Partner Code') }}</strong>
|
||||
{{ $t('to associate with your partner team.') }}
|
||||
</span>
|
||||
<ListItem
|
||||
v-else
|
||||
:title="partner_billing_name"
|
||||
:subtitle="$team.pg?.partner_email"
|
||||
/>
|
||||
</p>
|
||||
<div v-else class="flex items-center gap-3">
|
||||
<div class="flex-1">
|
||||
<p class="text-sm font-medium text-gray-900">{{ partner_billing_name }}</p>
|
||||
<p class="text-sm text-gray-600">{{ $team.pg?.partner_email }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Dialog
|
||||
:options="{
|
||||
title: $t('Link Partner Account'),
|
||||
actions: [
|
||||
{
|
||||
label: $t('Submit'),
|
||||
variant: 'solid',
|
||||
onClick: () => $resources.addPartnerCode.submit(),
|
||||
},
|
||||
],
|
||||
}"
|
||||
v-model="showAddPartnerCodeDialog"
|
||||
|
||||
<!-- 添加合作伙伴代码对话框 -->
|
||||
<n-modal
|
||||
v-model:show="showAddPartnerCodeDialog"
|
||||
preset="card"
|
||||
:title="$t('Link Partner Account')"
|
||||
:style="modalStyle"
|
||||
:mask-closable="true"
|
||||
:close-on-esc="true"
|
||||
>
|
||||
<template v-slot:body-content>
|
||||
<p class="pb-2 text-p-base">
|
||||
<template #header>
|
||||
<span class="text-lg font-semibold">{{ $t('Link Partner Account') }}</span>
|
||||
</template>
|
||||
<n-space vertical :size="16">
|
||||
<p class="text-sm text-gray-700">
|
||||
{{ $t('Enter the partner code provided by your partner') }}
|
||||
</p>
|
||||
<div class="rounded border border-gray-200 bg-gray-100 p-2 mb-4">
|
||||
<span class="text-sm leading-[1.5] text-gray-700">
|
||||
<strong>{{ $t('Note') }}</strong>: {{ $t('After linking with a partner, the following information will be shared with your partner team:') }}
|
||||
<br />
|
||||
<n-alert type="info" :title="$t('Note')">
|
||||
{{ $t('After linking with a partner, the following information will be shared with your partner team:') }}
|
||||
<ul class="mt-2 ml-4 list-disc">
|
||||
<li>{{ $t('Billing Name') }}</li>
|
||||
<li>{{ $t('Monthly Billing Amount') }}</li>
|
||||
</span>
|
||||
</div>
|
||||
<FormControl
|
||||
:placeholder="$t('For example: rGjw3hJ81b')"
|
||||
v-model="code"
|
||||
@input="referralCodeChange"
|
||||
</ul>
|
||||
</n-alert>
|
||||
<n-form-item :label="$t('Partner Code')">
|
||||
<n-input
|
||||
v-model:value="code"
|
||||
:placeholder="$t('For example: rGjw3hJ81b')"
|
||||
:size="inputSize"
|
||||
@input="referralCodeChange"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-alert
|
||||
v-if="partnerExists"
|
||||
type="success"
|
||||
:title="$t('Referral code {code} belongs to {partner}', { code, partner })"
|
||||
/>
|
||||
<div class="mt-1">
|
||||
<div v-if="partnerExists" class="text-sm text-green-600" role="alert">
|
||||
{{ $t('Referral code {code} belongs to {partner}', { code, partner }) }}
|
||||
</div>
|
||||
</div>
|
||||
<n-alert
|
||||
v-if="errorMessage"
|
||||
type="error"
|
||||
:title="errorMessage"
|
||||
/>
|
||||
</n-space>
|
||||
<template #action>
|
||||
<n-space :vertical="isMobile" :size="isMobile ? 12 : 16" class="w-full">
|
||||
<n-button @click="showAddPartnerCodeDialog = false" :block="isMobile" :size="buttonSize">
|
||||
{{ $t('Cancel') }}
|
||||
</n-button>
|
||||
<n-button
|
||||
type="primary"
|
||||
@click="handleAddPartnerCode"
|
||||
:loading="$resources.addPartnerCode.loading"
|
||||
:disabled="!partnerExists"
|
||||
:block="isMobile"
|
||||
:size="buttonSize"
|
||||
>
|
||||
{{ $t('Submit') }}
|
||||
</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</Dialog>
|
||||
</n-modal>
|
||||
|
||||
<Dialog
|
||||
v-model="showRemovePartnerDialog"
|
||||
:options="{
|
||||
title: $t('Remove Partner'),
|
||||
actions: [
|
||||
{
|
||||
label: $t('Remove'),
|
||||
variant: 'solid',
|
||||
theme: 'red',
|
||||
onClick: () => {
|
||||
$resources.removePartner.submit();
|
||||
},
|
||||
},
|
||||
],
|
||||
}"
|
||||
<!-- 移除合作伙伴对话框 -->
|
||||
<n-modal
|
||||
v-model:show="showRemovePartnerDialog"
|
||||
preset="dialog"
|
||||
:title="$t('Remove Partner')"
|
||||
:positive-text="$t('Remove')"
|
||||
:positive-button-props="{ type: 'error' }"
|
||||
:loading="$resources.removePartner.loading"
|
||||
:mask-closable="true"
|
||||
:close-on-esc="true"
|
||||
@positive-click="() => $resources.removePartner.submit()"
|
||||
>
|
||||
<template v-slot:body-content>
|
||||
<p class="text-p-base pb-3">
|
||||
{{ $t('This will remove the partner associated with your account. Are you sure you want to remove this partner?') }}
|
||||
</p>
|
||||
</template>
|
||||
</Dialog>
|
||||
</Card>
|
||||
<p class="text-base">
|
||||
{{ $t('This will remove the partner associated with your account. Are you sure you want to remove this partner?') }}
|
||||
</p>
|
||||
</n-modal>
|
||||
</n-card>
|
||||
</template>
|
||||
<script>
|
||||
import { Card, FormControl, jingrowRequest, debounce } from 'jingrow-ui';
|
||||
import {
|
||||
NCard,
|
||||
NButton,
|
||||
NIcon,
|
||||
NModal,
|
||||
NSpace,
|
||||
NFormItem,
|
||||
NInput,
|
||||
NAlert,
|
||||
} from 'naive-ui';
|
||||
import { jingrowRequest, debounce } from 'jingrow-ui';
|
||||
import { DashboardError } from '../../../utils/error';
|
||||
import { toast } from 'vue-sonner';
|
||||
import EditIcon from '~icons/lucide/edit';
|
||||
import TrashIcon from '~icons/lucide/trash-2';
|
||||
|
||||
export default {
|
||||
name: 'AccountPartner',
|
||||
components: {
|
||||
Card,
|
||||
FormControl,
|
||||
NCard,
|
||||
NButton,
|
||||
NIcon,
|
||||
NModal,
|
||||
NSpace,
|
||||
NFormItem,
|
||||
NInput,
|
||||
NAlert,
|
||||
EditIcon,
|
||||
TrashIcon,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -160,32 +206,89 @@ export default {
|
||||
};
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isMobile() {
|
||||
return window.innerWidth <= 768;
|
||||
},
|
||||
modalStyle() {
|
||||
return {
|
||||
width: this.isMobile ? '95vw' : '800px',
|
||||
maxWidth: this.isMobile ? '95vw' : '90vw',
|
||||
};
|
||||
},
|
||||
inputSize() {
|
||||
return this.isMobile ? 'medium' : 'large';
|
||||
},
|
||||
buttonSize() {
|
||||
return this.isMobile ? 'medium' : 'medium';
|
||||
},
|
||||
partner_billing_name() {
|
||||
return this.$resources.partnerName?.data || '';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
referralCodeChange: debounce(async function (e) {
|
||||
let code = e.target.value;
|
||||
this.partnerExists = false;
|
||||
this.errorMessage = '';
|
||||
|
||||
let result = await jingrowRequest({
|
||||
url: 'jcloud.api.partner.validate_partner_code',
|
||||
params: { code: code },
|
||||
});
|
||||
if (!code) {
|
||||
return;
|
||||
}
|
||||
|
||||
let isValidCode = result[0];
|
||||
let partnerName = result[1];
|
||||
try {
|
||||
let result = await jingrowRequest({
|
||||
url: 'jcloud.api.partner.validate_partner_code',
|
||||
params: { code: code },
|
||||
});
|
||||
|
||||
if (isValidCode) {
|
||||
this.partnerExists = true;
|
||||
this.referralCode = code;
|
||||
this.partner = partnerName;
|
||||
} else {
|
||||
this.errorMessage = this.$t('{code} is an invalid referral code', { code });
|
||||
let isValidCode = result[0];
|
||||
let partnerName = result[1];
|
||||
|
||||
if (isValidCode) {
|
||||
this.partnerExists = true;
|
||||
this.partner = partnerName;
|
||||
} else {
|
||||
this.errorMessage = this.$t('{code} is an invalid referral code', { code });
|
||||
}
|
||||
} catch (error) {
|
||||
this.errorMessage = this.$t('Failed to validate partner code');
|
||||
}
|
||||
}, 500),
|
||||
},
|
||||
computed: {
|
||||
partner_billing_name() {
|
||||
return this.$resources.partnerName.data;
|
||||
handleAddPartnerCode() {
|
||||
if (this.partnerExists) {
|
||||
this.$resources.addPartnerCode.submit();
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.partner-card {
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
transition: box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.partner-card:hover {
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.partner-card {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
:deep(.partner-card .n-card-header) {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
:deep(.partner-card .n-card-header .n-button) {
|
||||
width: 100%;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -153,7 +153,14 @@
|
||||
</n-list-item>
|
||||
</n-list>
|
||||
</n-card>
|
||||
|
||||
<!-- 推荐有礼组件 -->
|
||||
<AccountReferral />
|
||||
|
||||
<!-- Jingrow 合作伙伴组件 -->
|
||||
<AccountPartner />
|
||||
</n-space>
|
||||
|
||||
<!-- 编辑资料对话框 -->
|
||||
<n-modal
|
||||
v-model:show="showProfileEditDialog"
|
||||
@ -331,6 +338,8 @@ import TFADialog from './TFADialog.vue';
|
||||
import ResetPasswordDialog from './ResetPasswordDialog.vue';
|
||||
import router from '../../../router';
|
||||
import AddPrepaidCreditsDialog from '../../billing/AddPrepaidCreditsDialog.vue';
|
||||
import AccountReferral from './AccountReferral.vue';
|
||||
import AccountPartner from './AccountPartner.vue';
|
||||
import EditIcon from '~icons/lucide/edit';
|
||||
|
||||
export default {
|
||||
@ -355,6 +364,8 @@ export default {
|
||||
ResetPasswordDialog,
|
||||
FileUploader,
|
||||
AddPrepaidCreditsDialog,
|
||||
AccountReferral,
|
||||
AccountPartner,
|
||||
EditIcon,
|
||||
},
|
||||
data() {
|
||||
|
||||
@ -1,27 +1,29 @@
|
||||
<template>
|
||||
<Card
|
||||
v-if="referralLink"
|
||||
:title="$t('Referral Program')"
|
||||
:subtitle="$t('Your exclusive referral link')"
|
||||
class="mx-auto max-w-3xl"
|
||||
>
|
||||
<div class="flex flex-col space-y-4 overflow-hidden">
|
||||
<n-card v-if="referralLink" class="referral-card">
|
||||
<template #header>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold">{{ $t('Referral Program') }}</h3>
|
||||
<p class="text-sm text-gray-600 mt-1">{{ $t('Your exclusive referral link') }}</p>
|
||||
</div>
|
||||
</template>
|
||||
<n-space vertical :size="16">
|
||||
<ClickToCopyField :textContent="referralLink" />
|
||||
<span class="text-sm font-medium leading-4 text-gray-700">
|
||||
<p class="text-sm text-gray-700">
|
||||
{{ $t('Invite others to join Jingrow,') }}
|
||||
<strong>
|
||||
{{ $t('when they register and spend at least ¥100, you will get ¥20') }}
|
||||
</strong>
|
||||
</span>
|
||||
</div>
|
||||
</Card>
|
||||
<strong>{{ $t('when they register and spend at least ¥100, you will get ¥20') }}</strong>
|
||||
</p>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</template>
|
||||
<script>
|
||||
import { NCard, NSpace } from 'naive-ui';
|
||||
import ClickToCopyField from '../../ClickToCopyField.vue';
|
||||
|
||||
export default {
|
||||
name: 'AccountReferral',
|
||||
components: {
|
||||
NCard,
|
||||
NSpace,
|
||||
ClickToCopyField
|
||||
},
|
||||
computed: {
|
||||
@ -34,3 +36,21 @@ export default {
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.referral-card {
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
transition: box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.referral-card:hover {
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.referral-card {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,17 +1,11 @@
|
||||
<template>
|
||||
<div class="p-5">
|
||||
<div class="space-y-5">
|
||||
<AccountProfile />
|
||||
<AccountReferral />
|
||||
<AccountPartner />
|
||||
</div>
|
||||
<AccountProfile />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import AccountProfile from './AccountProfile.vue';
|
||||
import AccountReferral from './AccountReferral.vue';
|
||||
import AccountPartner from './AccountPartner.vue';
|
||||
|
||||
document.title = '设置 - 个人资料';
|
||||
</script>
|
||||
@ -969,6 +969,7 @@ when they register and spend at least ¥100, you will get ¥20,当他们注册
|
||||
Jingrow Partner,Jingrow 合作伙伴,
|
||||
Jingrow partner associated with your account,与您的账户关联的 Jingrow 合作伙伴,
|
||||
Add Partner Code,添加合作伙伴代码,
|
||||
Partner Code,合作伙伴代码,
|
||||
Unlink Partner,取消关联合作伙伴,
|
||||
Have a Jingrow partner referral code? Click,有 Jingrow 合作伙伴推荐代码吗?点击,
|
||||
to associate with your partner team.,以与您的合作伙伴团队关联。,
|
||||
|
||||
|
Can't render this file because it has a wrong number of fields in line 400.
|
Loading…
x
Reference in New Issue
Block a user