|
1 | 1 | <script setup lang="ts"> |
2 | | -import { Alert, Button, Card, Flex } from '@dolanske/vui' |
3 | | -import { onMounted, ref } from 'vue' |
4 | | -import BannerEditor from '@/components/Profile/Banner/BannerEditor.vue' |
5 | | -import { USERS_BUCKET_ID } from '@/lib/storageAssets' |
6 | | -
|
7 | 2 | definePageMeta({ layout: 'default' }) |
8 | | -
|
9 | | -const userId = useUserId() |
10 | | -
|
11 | | -// ── Banner ──────────────────────────────────────────────────────────────────── |
12 | | -
|
13 | | -const supabase = useSupabaseClient() |
14 | | -
|
15 | | -const editorOpen = ref(false) |
16 | | -const bannerUrl = ref<string | null>(null) |
17 | | -const bannerDeleted = ref(false) |
18 | | -
|
19 | | -onMounted(async () => { |
20 | | - const id = userId.value |
21 | | - if (id == null) |
22 | | - return |
23 | | -
|
24 | | - const { data } = await supabase |
25 | | - .from('profiles') |
26 | | - .select('has_banner') |
27 | | - .eq('id', id) |
28 | | - .single() |
29 | | -
|
30 | | - if (data?.has_banner) { |
31 | | - const { data: urlData } = supabase.storage |
32 | | - .from(USERS_BUCKET_ID) |
33 | | - .getPublicUrl(`${id}/banner.webp`) |
34 | | - bannerUrl.value = `${urlData.publicUrl}?t=${Date.now()}` |
35 | | - } |
36 | | -}) |
37 | | -
|
38 | | -function onBannerSaved(url: string) { |
39 | | - bannerUrl.value = `${url}?t=${Date.now()}` |
40 | | - bannerDeleted.value = false |
41 | | -} |
42 | | -
|
43 | | -function onBannerDeleted() { |
44 | | - bannerUrl.value = null |
45 | | - bannerDeleted.value = true |
46 | | - setTimeout(() => { |
47 | | - bannerDeleted.value = false |
48 | | - }, 3000) |
49 | | -} |
50 | 3 | </script> |
51 | 4 |
|
52 | 5 | <template> |
53 | 6 | <div class="playground-page"> |
54 | 7 | <div class="container container-m"> |
55 | | - <Flex column gap="xl"> |
56 | | - <Flex column :gap="0"> |
57 | | - <h1>Forum Banner Editor</h1> |
58 | | - <p class="text-color-light"> |
59 | | - Create a banner image that appears below your forum replies. |
60 | | - </p> |
61 | | - </Flex> |
62 | | - |
63 | | - <Alert v-if="!userId" variant="warning"> |
64 | | - You must be signed in to edit your banner. |
65 | | - </Alert> |
66 | | - |
67 | | - <Card> |
68 | | - <template #header> |
69 | | - <h2>Banner Image</h2> |
70 | | - </template> |
71 | | - |
72 | | - <Flex column gap="m"> |
73 | | - <p class="text-color-light text-s"> |
74 | | - Create a banner image shown under your forum replies. Banners are 728×48 pixels, |
75 | | - stored as WebP, and scale to fit smaller screens. |
76 | | - </p> |
77 | | - |
78 | | - <!-- Current banner preview --> |
79 | | - <div v-if="bannerUrl" class="playground__banner-preview"> |
80 | | - <img |
81 | | - :src="bannerUrl" |
82 | | - alt="Your forum banner" |
83 | | - class="playground__banner-img" |
84 | | - > |
85 | | - </div> |
86 | | - |
87 | | - <Alert v-if="bannerDeleted" variant="success"> |
88 | | - Banner deleted. |
89 | | - </Alert> |
90 | | - |
91 | | - <div> |
92 | | - <Button |
93 | | - variant="accent" |
94 | | - :disabled="!userId" |
95 | | - @click="editorOpen = true" |
96 | | - > |
97 | | - <Icon name="ph:pencil-simple" /> |
98 | | - {{ bannerUrl ? 'Edit banner' : 'Create banner' }} |
99 | | - </Button> |
100 | | - </div> |
101 | | - </Flex> |
102 | | - </Card> |
103 | | - </Flex> |
| 8 | + <!-- playground --> |
104 | 9 | </div> |
105 | 10 | </div> |
106 | | - |
107 | | - <!-- Full-screen banner editor modal (rendered outside the card so it can go truly full-screen) --> |
108 | | - <BannerEditor |
109 | | - :open="editorOpen" |
110 | | - :user-id="userId" |
111 | | - @saved="onBannerSaved" |
112 | | - @deleted="onBannerDeleted" |
113 | | - @close="editorOpen = false" |
114 | | - /> |
115 | 11 | </template> |
116 | 12 |
|
117 | 13 | <style lang="scss" scoped> |
118 | 14 | .playground-page { |
119 | 15 | padding-block: 128px; |
120 | 16 | width: 100%; |
121 | 17 | } |
122 | | -
|
123 | | -.playground { |
124 | | - &__banner-preview { |
125 | | - border: 1px solid var(--color-border); |
126 | | - border-radius: var(--border-radius-s); |
127 | | - overflow: hidden; |
128 | | - background: var(--color-bg-lowered); |
129 | | - } |
130 | | -
|
131 | | - &__banner-img { |
132 | | - display: block; |
133 | | - width: 100%; |
134 | | - height: auto; |
135 | | - max-height: 48px; |
136 | | - object-fit: fill; |
137 | | - } |
138 | | -} |
139 | 18 | </style> |
0 commit comments