Skip to content

Commit 6ddf549

Browse files
authored
feat: card with parallax (#126)
1 parent 7f6cee2 commit 6ddf549

File tree

4 files changed

+94
-17
lines changed

4 files changed

+94
-17
lines changed
Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,58 @@
11
<template>
2-
<div class="aspect-3/2 bg-primary rounded-lg">
3-
<div class="w-full h-full p-4 flex flex-col justify-between tg-text-button">
4-
<div class="text-lg/5 font-semibold">
5-
{{ clientStore.fullName }}
2+
<div ref="target" class="relative w-full h-auto aspect-3/2 perspective-normal motion-preset-slide-down">
3+
<div
4+
class="absolute inset-0 bg-primary rounded-lg"
5+
:style="{
6+
transform: `rotateX(${parallax.roll * 3}deg) rotateY(${parallax.tilt * 3}deg)`,
7+
}"
8+
/>
9+
10+
<div
11+
class="z-10 w-full h-full p-4 flex flex-col justify-between tg-text-button"
12+
:style="{
13+
transform: `rotateX(${parallax.roll * 2}deg) rotateY(${parallax.tilt * 2}deg)`,
14+
}"
15+
>
16+
<div class="flex flex-row justify-between items-center">
17+
<div class="flex flex-col gap-3">
18+
<div class="text-lg/5 font-medium">
19+
Карта лояльности
20+
</div>
21+
<div class="flex flex-row gap-1.5 items-center">
22+
<p class="text-3xl/5 font-semibold">
23+
680
24+
</p>
25+
<UIcon name="fluent:heart-circle-24-filled" class="size-6" />
26+
</div>
27+
</div>
28+
29+
<img
30+
src="/sushi-heart.svg"
31+
alt=""
32+
class="w-12 opacity-20 invert-100"
33+
>
634
</div>
7-
<div class="text-3xl/5 font-bold">
8-
5%
35+
36+
<div class="flex flex-row justify-between items-center">
37+
<div class="flex flex-row gap-2 items-center">
38+
<div class="px-3.5 py-1.5 text-2xl/5 text-primary font-bold ring ring-default bg-default rounded-2xl">
39+
5%
40+
</div>
41+
42+
<div>
43+
Кешбэк
44+
</div>
45+
</div>
46+
47+
<UIcon name="i-lucide-info" class="size-6" />
948
</div>
1049
</div>
1150
</div>
1251
</template>
1352

1453
<script setup lang="ts">
15-
const clientStore = useClientStore()
54+
import { useParallax } from '@vueuse/core'
55+
56+
const target = useTemplateRef<HTMLElement>('target')
57+
const parallax = reactive(useParallax(target))
1658
</script>

apps/storefront-telegram/app/components/catalog/CategoriesSliderMenu.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
2-
<div class="z-40 sticky top-0 h-fit tg-content-safe-area-top tg-bg-secondary">
3-
<div class="max-w-full overflow-x-scroll snap-x">
2+
<div class="z-40 sticky -top-0.5 h-fit tg-safe-area tg-bg-secondary">
3+
<div class="max-w-full overflow-x-scroll snap-x tg-content-safe-area-top">
44
<div class="py-1 w-max flex flex-row flex-wrap gap-1">
55
<div
66
v-for="category in menuStore.menu?.categories"
Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,35 @@
11
<template>
22
<PageContainer>
3+
<div class="flex flex-col gap-1">
4+
<h1 class="text-xl/5 font-bold">
5+
{{ clientStore.fullName }}
6+
</h1>
7+
<p v-if="clientStore.formattedPhone" class="text-muted text-sm/5 font-medium">
8+
{{ clientStore.formattedPhone }}
9+
</p>
10+
</div>
11+
312
<UserPointsCard />
413

5-
<div class="flex flex-row gap-3.5 items-center">
6-
<div class="flex flex-col gap-1">
7-
<h2 class="text-lg/5 font-bold">
8-
Тут будет меню
9-
</h2>
10-
</div>
14+
<div class="flex flex-col gap-1">
15+
<UButtonGroup orientation="vertical" size="xl">
16+
<UButton
17+
color="neutral"
18+
variant="subtle"
19+
label="Мои заказы"
20+
icon="i-lucide-shopping-basket"
21+
/>
22+
<UButton
23+
color="neutral"
24+
variant="outline"
25+
label="Мои адреса"
26+
icon="i-lucide-map-pin-house"
27+
/>
28+
</UButtonGroup>
1129
</div>
1230
</PageContainer>
1331
</template>
32+
33+
<script setup lang="ts">
34+
const clientStore = useClientStore()
35+
</script>

apps/storefront-telegram/app/stores/client.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { initDataRaw as _initDataRaw, initDataState as _initDataState, useSignal } from '@telegram-apps/sdk-vue'
2+
import { parsePhoneNumberWithError } from 'libphonenumber-js'
23

34
export const useClientStore = defineStore('client', () => {
45
const id = ref<string | undefined>(undefined)
56
const name = ref<string | undefined>(undefined)
67
const surname = ref<string | undefined>(undefined)
7-
// const phone = ref<string | null>(null)
8+
const phone = ref<string | undefined>(undefined)
89
const avatarUrl = ref<string | null>(null)
910

1011
const initDataRaw = useSignal(_initDataRaw)
@@ -14,6 +15,16 @@ export const useClientStore = defineStore('client', () => {
1415
return `${name.value} ${surname.value}`
1516
})
1617

18+
const formattedPhone = computed(() => {
19+
if (!phone.value) {
20+
return ''
21+
}
22+
23+
const phoneNumber = parsePhoneNumberWithError(phone.value, 'RU')
24+
25+
return phoneNumber?.format('INTERNATIONAL')
26+
})
27+
1728
async function update() {
1829
try {
1930
const data = await $fetch('/api/auth/me', {
@@ -26,9 +37,9 @@ export const useClientStore = defineStore('client', () => {
2637
}
2738

2839
id.value = data.id
40+
phone.value = data.phone
2941
name.value = data.name
3042
surname.value = data.surname ?? ''
31-
// phone.value = data.phone
3243
avatarUrl.value = data.avatarUrl
3344
} catch (error) {
3445
if (error instanceof Error) {
@@ -68,11 +79,13 @@ export const useClientStore = defineStore('client', () => {
6879

6980
return {
7081
id,
82+
phone,
7183
name,
7284
surname,
7385
avatarUrl,
7486

7587
fullName,
88+
formattedPhone,
7689

7790
initDataRaw,
7891
initDataState,

0 commit comments

Comments
 (0)