This commit is contained in:
2025-11-02 10:08:57 +03:00
parent 83d2666f22
commit d3d8b7522a
41 changed files with 518 additions and 496 deletions

View File

@@ -7,4 +7,4 @@
</script>
<style>
</style>
</style>

View File

@@ -8,107 +8,177 @@
</template>
<pn-scroll-list >
<div class="q-px-md">
<template #card-body-header>
<div
id="subscribe-current-balance"
class="flex w100 q-px-md q-py-sm row"
style="border-radius: var(--top-raduis); border: 1px solid var(--q-primary);"
class="flex w100 q-px-md q-py-md row"
>
<div class="flex w100 justify-between items-center no-wrap">
<div class="flex no-wrap items-center text-h6 col-9">
<div class="flex items-center text-grey">
{{ $t('subscribe__current_plan') }}
</div>
<div class="flex items-center column col-3">
<div class="flex items-center column text-right">
<span class="text-bold">
{{ currentPlanData?.name }}
</span>
<span class="text-caption" style="line-height: 0.5em;">
{{ $t('subscribe__plan_exp') }}
{{ date.formatDate(currentPlanData.exp * 1000, 'DD.MM.YYYY') }}
</span>
</div>
</div>
<div class="flex row w100 ow-wrap items-center text-caption q-pt-sm">
<div class="col-9">{{ $t('subscribe__plan_active_chats') }}</div>
<div class="col-3" align="center">
<span class="text-brand2 text-bold q-pr-xs">{{ currentPlanData?.active_chats }}</span>
<span class="text-grey">/{{ currentPlanData?.chatsQty }}</span>
<div
class="row w100 no-wrap items-center text-caption justify-between"
v-if="currentPlanData.name !== 'TEST'"
>
<div class="text-grey text-no-wrap ellipsis">
{{ $t('subscribe__plan_date') }}
</div>
</div>
</div>
<div class="flex w100 justify-center text-grey q-pt-md q-pb-none">{{ $t('subscribe__plans')}}</div>
<q-list separator>
<q-item
v-for="item in plans"
:key="item.id"
>
<q-item-section avatar>
<q-radio v-model="newPlan" :val="item" v-if="item.name!=='TEST'"/>
</q-item-section>
<q-item-section>
<q-item-label class="text-bold">{{ item.name }}</q-item-label>
<div class="flex no-wrap items-center text-caption">
<span v-if="item.chatsQty" class="q-pr-xs">
{{ $t('subscribe__chats_max') }}
</span>
<span v-if="item.chatsQty">
{{ item.chatsQty }}
</span>
<q-icon v-else name="mdi-all-inclusive" size="sm"/>
<span class="q-pl-xs">
{{ $t('subscribe__chats')}}
</span>
</div>
</q-item-section>
<q-item-section side>
<div v-if="item.price" class="flex column items-center">
<div class="flex no-wrap items-center">
<telegram-star color="gold" size="18px" class="q-mr-xs"/>
<span class="text-h6">{{ formatNumber(item.price) }}</span>
<span class="text-caption q-pl-xs">{{ $t('subscribe__per_month') }}</span>
</div>
</div>
<div v-else class="text-bold">
{{ $t('subscribe__free_tax') }}
</div>
</q-item-section>
</q-item>
</q-list>
<div class="flex w100 justify-center text-caption text-grey q-pt-sm text-center">
{{ $t('subscribe__plans_description') }}
</div>
<q-btn-group spread flat class="w100 q-py-sm">
<q-btn
v-for="period in periods"
:key="period.id"
:color="selectPeriod === period.value ? 'primary' : 'white'"
:text-color="selectPeriod === period.value ? 'white' : 'primary'"
@click="selectPeriod = period.value"
no-caps
>
<div class="column items-center w100 self-end">
<q-badge v-show="period.sale" color="red">{{ period.sale }}% off</q-badge>
<span>{{ $t(period.name) }}</span>
<span class="text-caption">({{ $t(period.name_in_days) }})</span>
</div>
</q-btn>
</q-btn-group>
<div class="text-caption column text-grey">
<span>{{ $t('subscribe__plans_period_notes') + ' ' }}</span>
<span
@click="router.push({ name: 'change_plan_rules' })"
class="text-info cursor-pointer"
>
{{ $t('subscribe__plans_period_notes_more_info') }}
<span class="text-no-wrap text-right">
{{ date.formatDate(currentPlanData.exp * 1000, 'DD.MM.YYYY') }}
</span>
</div>
<div class="row w100 no-wrap items-center text-caption text-grey justify-between">
<div>
{{ $t('subscribe__plan_active_chats') }}
</div>
<div class="text-right">
<span class="text-brand2 text-bold q-pr-xs">{{ currentPlanData?.active_chats }}</span>
<span>/{{ currentPlanData?.chatsQty }}</span>
</div>
</div>
</div>
</template>
<div class="w100 column items-center text-center text-grey q-px-md">
{{ $t('subscribe__plans')}}
<div class="text-caption">
{{ $t('subscribe__plans_description') }}
</div>
</div>
<q-list separator>
<q-item
v-for="item in plans"
:key="item.id"
clickable
v-ripple
tag="label"
:disable="item.name === 'TEST' && currentPlanData.name !== 'TEST'"
>
<q-item-section avatar>
<q-radio
v-model="newPlan"
:val="item"
:disable="item.name === 'TEST' && currentPlanData.name != 'TEST'"
:keep-color="item.name === 'TEST'&& currentPlanData.name !== 'TEST'"
:color="item.name === 'TEST' && currentPlanData.name !== 'TEST' ? 'grey-5' : ''"
/>
</q-item-section>
<q-item-section>
<div class="column">
<span class="text-bold">
{{ item.name }}
</span>
<div class="flex no-wrap items-center text-caption" style="line-height: 1em;">
<span v-if="item.chatsQty">
{{ $t('subscribe__chats_max') + ' ' + item.chatsQty }}
</span>
<q-icon v-else name="mdi-all-inclusive" size="sm"/>
<span class="q-pl-xs">
{{ $t('subscribe__chats')}}
</span>
</div>
<span
v-if="item.name === 'TEST' && currentPlanData.name !== 'TEST'"
class="text-caption text-grey-7"
>
{{ $t('subscribe__TEST_via_support')}}
</span>
</div>
</q-item-section>
<q-item-section
class="text-left"
:style="{ width: `${maxWidthStarsSection}px` }"
>
<q-resize-observer @resize="updateMaxWidthStarsSection" />
<div v-if="item.price" class="flex column justify-start">
<div class="flex no-wrap items-center">
<telegram-star color="gold" size="18px" class="q-mr-xs"/>
<span class="text-h6">{{ formatNumber(item.price) }}</span>
<span class="text-caption q-pl-xs">{{ $t('subscribe__per_month') }}</span>
</div>
</div>
<div v-else class="text-bold self-center">
{{ $t('subscribe__free_tax') }}
</div>
</q-item-section>
</q-item>
</q-list>
<div class="q-px-md">
<div class="w100 text-grey text-center q-pt-sm">
{{ $t('subscribe__plans_interval') }}
</div>
<q-btn-group spread flat class="w100 q-py-sm">
<q-btn
v-for="period in periods"
:key="period.id"
:outline="selectPeriod === period.value"
@click="selectPeriod = period.value"
:color="selectPeriod === period.value ? 'primary' : ''"
no-caps dense
>
<div class="column items-center w100 self-end">
<span
class="text-h6"
:class="selectPeriod === period.value ? 'text-primary' : 'text-black'"
>
{{ $t(period.name) }}
</span>
<div
class="row no-wrap w100 q-px-xs"
:class="period.sale ? 'justify-between' : 'justify-center'"
>
<span
class="text-caption text-grey"
>
{{ $t(period.name_in_days) }}
</span>
<q-badge v-show="period.sale" color="red">-{{ period.sale }}%</q-badge>
</div>
</div>
</q-btn>
</q-btn-group>
<div class="text-caption text-grey">
<span>{{ $t('subscribe__plans_period_notes') + ' ' }}</span>
<span
@click="router.push({ name: 'change_plan_rules' })"
class="text-info cursor-pointer"
>
{{ $t('subscribe__plans_period_notes_more_info') }}
</span>
</div>
<q-input
v-model="promocode"
dense
filled
:label="$t('subscribe__promocode')"
class="q-pt-md"
>
<template #append v-if="promocode !== ''">
<q-btn
round dense flat
color="primary"
icon="mdi-arrow-right-circle-outline"
@click="sendPromocode"
/>
</template>
</q-input>
</div>
</pn-scroll-list>
</pn-page-card>
@@ -121,12 +191,12 @@
import { date } from 'quasar'
import { useI18n } from 'vue-i18n'
import type { WebApp } from '@twa-dev/types'
import { colors } from 'quasar';
import { colors } from 'quasar'
import { useQuasar } from 'quasar'
const router = useRouter()
const tg = inject('tg') as WebApp
tg.MainButton.show()
// @ts-expect-error: get hex text
tg.MainButton.color = colors.getPaletteColor('primary')
@@ -146,7 +216,7 @@
const selectPeriod = ref(periods[1]?.value)
const newPlan = ref(plans[1])
const newPlan = ref(plans[0])
interface CurrentPlan {
plan: string
@@ -155,7 +225,7 @@
}
const currentPlan = ref<CurrentPlan>({ // temp, this get from api
plan: plans[0].val,
plan: plans[1].val,
active_chats: 20,
exp: Date.now() / 1000 + 500000
})
@@ -186,12 +256,12 @@
)
const newDateExp = date.addToDate(Date.now(), { months: Number(selectPeriod.value) })
return t('subscribe__pay') + ' ⭐' + stars +
return t(newPlan.value.id !== currentPlanData.value.id ? 'subscribe__pay' : 'subscribe__pay_renew') +
' ⭐' + stars +
' (' + t('subscribe__plan_exp') + ' ' +
date.formatDate(newDateExp, 'DD.MM.YYYY') + ')'
})
function formatNumber (number: string | number) {
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ")
}
@@ -201,6 +271,43 @@
watch(textBtn, () => tg.MainButton.setText(textBtn.value),
{ immediate: true })
watch(newPlan, () =>
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
{ newPlan.value.name === 'TEST' ? tg.MainButton.hide() : tg.MainButton.show() },
{ immediate: true })
const maxWidthStarsSection = ref(0)
interface sizeParams {
height: number,
width: number
}
function updateMaxWidthStarsSection (size: sizeParams) {
if (size.width > maxWidthStarsSection.value) {
maxWidthStarsSection.value = size.width
}
}
const promocode = ref('')
function sendPromocode () {
promocode.value = ''
showNotify('fail')
}
const $q = useQuasar()
const showNotify = (message: 'success' | 'fail') => {
$q.notify({
message: t(message === 'success' ? 'subscribe__promocode_success' : 'subscribe__promocode_fail'),
type: message === 'success' ? 'positive' : 'negative',
position: 'bottom',
timeout: 1000,
multiLine: true
})
}
</script>
<style lang="scss">