Skip to content

Commit 3f38d52

Browse files
authored
feat: bonus program registration (#135)
1 parent 1b2a04f commit 3f38d52

26 files changed

Lines changed: 438 additions & 127 deletions

apps/storefront-telegram/app/app.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ export default defineAppConfig({
5151
title: 'font-semibold',
5252
},
5353
},
54+
drawer: {
55+
slots: {
56+
content: '!max-h-10/12',
57+
},
58+
},
5459
navigationMenu: {
5560
slots: {
5661
link: 'text-sm',

apps/storefront-telegram/app/components/CitySelector.vue

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
:dismissible="false"
66
should-scale-background
77
:set-background-color-on-scale="false"
8-
:ui="{
9-
content: 'max-h-10/12',
10-
}"
118
>
129
<template #content>
1310
<div class="p-4 pb-20 flex flex-col gap-3 overflow-y-auto">

apps/storefront-telegram/app/components/Navigation.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ const mainRoutes = computed<NavigationRoute[]>(() => [
2626
exact: true,
2727
},
2828
{
29-
path: '/user',
30-
name: 'user',
29+
path: '/client',
30+
name: 'client',
3131
title: 'Кабинет',
3232
icon: 'i-lucide-user',
3333
},
3434
{
35-
path: '/secret1',
35+
path: '/navigation',
3636
name: 'navigation',
3737
title: 'Меню',
3838
icon: 'i-lucide-menu',

apps/storefront-telegram/app/components/NavigationButton.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
name="i-lucide-arrow-up"
1515
class="size-6 motion-preset-shake"
1616
/>
17+
<UIcon
18+
v-else-if="canReturn"
19+
name="i-lucide-undo-2"
20+
class="size-6 motion-preset-shake"
21+
/>
1722
<UIcon
1823
v-else
1924
:name="route.icon"
@@ -42,9 +47,12 @@ const router = useRouter()
4247
const isThisRoute = computed(() => route.exact ? router.currentRoute.value.path === route.path : router.currentRoute.value.path.startsWith(route.path))
4348
4449
const { y } = useWindowScroll()
45-
const isCatalogButton = computed(() => route.path === '/')
50+
const isCatalogButton = computed(() => route.path === '/' && router.currentRoute.value.path === '/')
4651
const canScrollToTop = computed(() => isCatalogButton.value && y.value > 650)
4752
53+
const isClientButton = computed(() => route.path === '/client' && router.currentRoute.value.path.startsWith('/client'))
54+
const canReturn = computed(() => isClientButton.value && router.currentRoute.value.path !== '/client')
55+
4856
function handleScrollToTop() {
4957
vibrate()
5058
window.scrollTo({ top: 0, behavior: 'smooth' })
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<template>
2+
<div v-if="isShown" class="z-40 mx-auto h-dvh w-full fixed inset-0 overflow-y-hidden overscroll-y-none">
3+
<div v-confetti="{ particleCount: 240, duration: 4500, stageHeight: 1200, stageWidth: 900, force: 0.4 }" />
4+
</div>
5+
</template>
6+
7+
<script setup lang="ts">
8+
import { vConfetti } from '@neoconfetti/vue'
9+
10+
const { isShown } = useConfetti()
11+
</script>
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<template>
2+
<ClientPointsCardBottomBlock>
3+
<div>
4+
<h3 class="font-semibold">
5+
Активируйте ваши бонусные баллы!
6+
</h3>
7+
<p class="text-sm/4">
8+
Чтобы начать пользоваться программой лояльности и получать
9+
выгоду от накопленных баллов, необходимо завершить регистрацию
10+
</p>
11+
</div>
12+
13+
<UButton
14+
color="primary"
15+
block
16+
size="lg"
17+
label="Активировать"
18+
@click="handleClick"
19+
/>
20+
</ClientPointsCardBottomBlock>
21+
22+
<UDrawer
23+
v-model:open="isDrawerOpened"
24+
should-scale-background
25+
:set-background-color-on-scale="false"
26+
>
27+
<template #content>
28+
<div class="p-4 pb-20 flex flex-col gap-5 overflow-y-auto">
29+
<h2 class="text-xl/6 font-semibold">
30+
Регистрация в программе лояльности
31+
</h2>
32+
33+
<div class="flex flex-row gap-2 items-start text-base/5">
34+
<UIcon name="fluent:heart-circle-24-filled" class="shrink-0 size-6 text-primary" />
35+
<p>
36+
Кешбэк определяется по сумме заказов за все время. Максимальный — 15% от суммы заказа.
37+
Бонусные баллы автоматически сгорают через 180 дней при отсутствии активности.
38+
</p>
39+
</div>
40+
41+
<div class="flex flex-row gap-2 items-start text-base/5">
42+
<UIcon name="i-lucide-at-sign" class="shrink-0 size-6 text-primary" />
43+
<p>
44+
На указанный почтовый адрес будем отправлять онлайн чеки.
45+
</p>
46+
</div>
47+
48+
<div class="flex flex-row gap-2 items-start text-base/5">
49+
<UIcon name="i-lucide-cake" class="shrink-0 size-6 text-primary" />
50+
<p>
51+
К дню рождения будем присылать вкусные подарки.
52+
</p>
53+
</div>
54+
55+
<FormCompleteBonusProgramRegistration
56+
@submitted="handleClose()"
57+
/>
58+
59+
<p class="text-sm">
60+
Передавая данные, вы соглашаетесь с
61+
<ULink to="https://sushi-love.ru" target="_blank">
62+
условиями программы лояльности,
63+
</ULink>
64+
<ULink to="https://sushi-love.ru" target="_blank">
65+
политикой конфиденциальности
66+
</ULink> и <ULink to="https://sushi-love.ru" target="_blank">
67+
условиями обработки персональных данных.
68+
</ULink>
69+
</p>
70+
</div>
71+
</template>
72+
</UDrawer>
73+
</template>
74+
75+
<script setup lang="ts">
76+
const { vibrate } = useFeedback()
77+
78+
const isDrawerOpened = ref(false)
79+
80+
function handleClick() {
81+
vibrate()
82+
isDrawerOpened.value = !isDrawerOpened.value
83+
}
84+
85+
function handleClose() {
86+
isDrawerOpened.value = false
87+
}
88+
</script>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<template>
2+
<ClientPointsCardBottomBlock v-if="clientStore.nextLevel && clientStore.nextLevelAmount">
3+
<div>
4+
<h3 class="font-semibold">
5+
Повысьте кешбэк до {{ clientStore.nextLevel.cashback }}%
6+
</h3>
7+
<p class="text-sm/4">
8+
Закажите еще на {{ Intl.NumberFormat('ru').format(clientStore.nextLevelAmount) }} {{ channelStore.currencySign }}
9+
</p>
10+
</div>
11+
12+
<UProgress
13+
v-model="clientStore.nextLevelProgressPercent"
14+
color="primary"
15+
:ui="{
16+
base: 'bg-primary/10',
17+
}"
18+
/>
19+
</ClientPointsCardBottomBlock>
20+
</template>
21+
22+
<script setup lang="ts">
23+
const clientStore = useClientStore()
24+
const channelStore = useChannelStore()
25+
</script>

apps/storefront-telegram/app/components/UserPointsCard.vue renamed to apps/storefront-telegram/app/components/client/PointsCard.vue

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -51,37 +51,18 @@
5151
</div>
5252
</div>
5353

54-
<div v-if="clientStore.nextLevel && clientStore.nextLevelAmount" class="-mt-8 px-4 pt-12 pb-4 flex flex-col gap-3 tg-bg-section rounded-lg motion-preset-slide-up">
55-
<div>
56-
<h3 class="font-semibold">
57-
Повысьте кешбэк до {{ clientStore.nextLevel.cashback }}%
58-
</h3>
59-
<p class="text-sm/4">
60-
Закажите еще на {{ Intl.NumberFormat('ru').format(clientStore.nextLevelAmount) }} {{ channelStore.currencySign }}
61-
</p>
62-
</div>
63-
64-
<UProgress
65-
v-model="clientStore.nextLevelProgressPercent"
66-
color="primary"
67-
:ui="{
68-
base: 'bg-primary/10',
69-
}"
70-
/>
71-
</div>
54+
<ClientBonusProgramRegistration v-if="!clientStore.isBonusProgramParticipant" />
55+
<ClientLevelIncreaseProgress v-else />
7256
</div>
7357

7458
<UDrawer
7559
v-model:open="isDrawerOpened"
7660
should-scale-background
7761
:set-background-color-on-scale="false"
78-
:ui="{
79-
content: 'max-h-10/12',
80-
}"
8162
>
8263
<template #content>
8364
<div class="p-4 pb-20 flex flex-col gap-5 overflow-y-auto">
84-
<h2 class="text-xl font-semibold">
65+
<h2 class="text-xl/6 font-semibold">
8566
У вас есть {{ clientStore.points }} «Лавчиков»
8667
</h2>
8768

@@ -102,8 +83,8 @@
10283
</h3>
10384

10485
<p class="text-base/5">
105-
Кешбэк определяется по сумме заказов за все время. Система включает разные уровни
106-
с разными процентами возврата: базовый уровень даёт 5% кешбэка, а максимальный — 15%
86+
Кешбэк определяется по сумме заказов за все время. Система включает уровни
87+
с разными процентами возврата: базовый уровень даёт 5%, а максимальный — 15%
10788
от суммы заказа.
10889
</p>
10990
</div>
@@ -138,34 +119,13 @@
138119
</template>
139120

140121
<script setup lang="ts">
141-
import type { EventListener } from '@telegram-apps/sdk-vue'
142-
import { off, on } from '@telegram-apps/sdk-vue'
143-
144122
const { vibrate } = useFeedback()
123+
const { x, y } = useGyroscope()
145124
146125
const clientStore = useClientStore()
147-
const channelStore = useChannelStore()
148126
149127
const isDrawerOpened = ref(false)
150128
151-
const x = ref(0)
152-
const y = ref(0)
153-
const z = ref(0)
154-
155-
const listener: EventListener<'gyroscope_changed'> = (payload) => {
156-
x.value = payload.x
157-
y.value = payload.y
158-
z.value = payload.z
159-
}
160-
161-
onMounted(() => {
162-
on('gyroscope_changed', listener)
163-
})
164-
165-
onUnmounted(() => {
166-
off('gyroscope_changed', listener)
167-
})
168-
169129
function handleCardClick() {
170130
vibrate()
171131
isDrawerOpened.value = !isDrawerOpened.value
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<template>
2+
<div
3+
class="-mt-8 px-4 pt-12 pb-4 flex flex-col gap-3 tg-bg-section rounded-lg motion-preset-slide-up"
4+
>
5+
<slot />
6+
</div>
7+
</template>

0 commit comments

Comments
 (0)