|
3 | 3 | <UContainer class="mx-auto max-w-7xl space-y-8 px-4 py-8"> |
4 | 4 | <h1 class="sr-only">User Profile</h1> |
5 | 5 | <section |
6 | | - class="relative flex flex-col items-center justify-center gap-6 overflow-hidden rounded-xl border-2 border-base-200 bg-base-200/30 p-8 md:flex-row md:border-4 md:p-12" |
| 6 | + class="relative flex flex-col items-center justify-center gap-6 overflow-hidden rounded-xl border-2 border-base-200 bg-base-200/30 p-6 shadow-sm md:flex-row md:border-4 md:p-8" |
7 | 7 | > |
8 | 8 | <!-- decorative left accent (sidebar-like) --> |
9 | 9 | <div |
10 | | - class="absolute inset-y-2 left-0 hidden w-1 rounded-r-md bg-primary/40 md:block" |
| 10 | + class="absolute inset-y-2 left-0 hidden w-1 rounded-r-md bg-primary/30 md:block" |
11 | 11 | aria-hidden="true" |
12 | 12 | ></div> |
13 | 13 | <div v-if="!user" class="flex flex-col items-center justify-center space-y-6"> |
|
89 | 89 | </section> |
90 | 90 |
|
91 | 91 | <section |
92 | | - class="relative flex flex-col items-center justify-center divide-y divide-base-200/50 overflow-hidden rounded-xl border-2 border-base-200 bg-base-200/20 shadow-lg md:border-4" |
| 92 | + class="relative flex flex-col items-center justify-center divide-y divide-base-200/50 overflow-hidden rounded-xl border-2 border-base-200 bg-base-200/20 md:border-4" |
93 | 93 | > |
94 | 94 | <!-- subtle left accent to mirror dashboard sidebar --> |
95 | 95 | <div |
96 | | - class="absolute inset-y-2 left-0 hidden w-1 rounded-r-md bg-secondary/20 md:block" |
| 96 | + class="absolute inset-y-2 left-0 hidden w-1 rounded-r-md bg-secondary/30 md:block" |
97 | 97 | aria-hidden="true" |
98 | 98 | ></div> |
99 | 99 | <UTabs |
|
103 | 103 | class="flex w-full flex-col items-center justify-center" |
104 | 104 | > |
105 | 105 | <template #content="{ item }"> |
106 | | - <div class="p-8"> |
| 106 | + <div class="p-6 md:p-8"> |
107 | 107 | <div v-if="item.value === 'servers'" class="space-y-6"> |
108 | | - <!-- Server Section Header --> |
109 | | - <div class="mb-4"> |
110 | | - <h2 class="text-2xl font-bold text-base-content">Servers</h2> |
111 | | - <div class="mt-1 text-base-content/60"> |
112 | | - <USkeleton v-if="isLoading" class="inline-block h-5 w-48" /> |
113 | | - <span v-else>{{ guilds.length ?? 0 }} servers</span> |
114 | | - </div> |
115 | | - </div> |
116 | | - |
| 108 | + <h2 class="sr-only">Servers</h2> |
117 | 109 | <!-- Search and Controls Section --> |
118 | | - <div class="mb-4 flex flex-wrap items-center justify-between gap-4"> |
119 | | - <div class="flex items-end gap-2"> |
120 | | - <UFieldGroup class="flex items-start gap-2"> |
121 | | - <UInput |
122 | | - ref="input" |
123 | | - v-model="searchQuery" |
124 | | - aria-label="Search servers" |
125 | | - name="search" |
126 | | - type="text" |
127 | | - placeholder="Search servers..." |
128 | | - icon="heroicons:magnifying-glass-circle" |
129 | | - :is-loading |
130 | | - is-loading-icon="lucide:loader" |
131 | | - class="flex max-w-xs items-start" |
132 | | - > |
133 | | - <template v-if="searchQuery?.length" #trailing> |
134 | | - <UButton |
135 | | - color="neutral" |
136 | | - variant="link" |
137 | | - size="sm" |
138 | | - icon="lucide:circle-x" |
139 | | - aria-label="Clear input" |
140 | | - @click="undoSearch()" |
141 | | - /> |
142 | | - </template> |
143 | | - </UInput> |
144 | | - </UFieldGroup> |
145 | | - <!-- Mobile Buttons (no view toggle) --> |
146 | | - <UFieldGroup size="sm" class="join flex items-end sm:hidden"> |
147 | | - <!-- Manageable Only Toggle Button --> |
| 110 | + <div class="mb-4 flex flex-wrap items-center gap-4"> |
| 111 | + <UInput |
| 112 | + ref="input" |
| 113 | + v-model="searchQuery" |
| 114 | + aria-label="Search servers" |
| 115 | + name="search" |
| 116 | + type="text" |
| 117 | + placeholder="Search servers..." |
| 118 | + icon="heroicons:magnifying-glass-circle" |
| 119 | + :is-loading |
| 120 | + is-loading-icon="lucide:loader" |
| 121 | + class="flex max-w-xs items-start" |
| 122 | + > |
| 123 | + <template v-if="searchQuery?.length" #trailing> |
148 | 124 | <UButton |
149 | | - class="join-item" |
150 | | - color="primary" |
151 | | - :is-loading |
152 | | - is-loading-icon="lucide:loader" |
153 | | - icon="heroicons:shield-check" |
154 | | - @click="toggleShowManageableOnly()" |
| 125 | + color="neutral" |
| 126 | + variant="link" |
| 127 | + size="sm" |
| 128 | + icon="lucide:circle-x" |
| 129 | + aria-label="Clear input" |
| 130 | + @click="undoSearch()" |
155 | 131 | /> |
156 | | - |
157 | | - <!-- Sort Button --> |
158 | | - <UButton |
159 | | - class="join-item" |
160 | | - color="primary" |
161 | | - :is-loading |
162 | | - @click="toggleSortOrder()" |
163 | | - > |
164 | | - <template #leading> |
165 | | - <UIcon |
166 | | - v-motion |
167 | | - :initial="{ opacity: 0 }" |
168 | | - :enter="{ |
169 | | - opacity: 1, |
170 | | - transition: { duration: 150 }, |
171 | | - }" |
172 | | - :leave="{ |
173 | | - opacity: 0, |
174 | | - transition: { duration: 150 }, |
175 | | - }" |
176 | | - :name=" |
177 | | - sortAscending |
178 | | - ? 'lucide:arrow-up-a-z' |
179 | | - : 'lucide:arrow-down-z-a' |
180 | | - " |
181 | | - /> |
182 | | - </template> |
183 | | - </UButton> |
184 | | - |
185 | | - <!-- Refresh Button --> |
186 | | - <UButton |
187 | | - v-if="filteredGuilds.length === 0" |
188 | | - class="join-item" |
189 | | - color="primary" |
190 | | - :is-loading |
191 | | - is-loading-icon="lucide:loader" |
192 | | - icon="heroicons:arrow-path-20-solid" |
193 | | - @click="refresh()" |
194 | | - /> |
195 | | - </UFieldGroup> |
196 | | - |
197 | | - <!-- Desktop Buttons (with view toggle) --> |
198 | | - <UFieldGroup size="sm" class="join hidden items-end sm:flex"> |
199 | | - <!-- |
| 132 | + </template> |
| 133 | + </UInput> |
| 134 | + <!-- Mobile Buttons (no view toggle) --> |
| 135 | + <UFieldGroup size="sm" class="join flex items-end sm:hidden"> |
| 136 | + <!-- Manageable Only Toggle Button --> |
| 137 | + <UButton |
| 138 | + class="join-item" |
| 139 | + color="primary" |
| 140 | + :is-loading |
| 141 | + is-loading-icon="lucide:loader" |
| 142 | + icon="heroicons:shield-check" |
| 143 | + aria-label="Toggle manageable only" |
| 144 | + @click="toggleShowManageableOnly()" |
| 145 | + /> |
| 146 | + |
| 147 | + <!-- Sort Button --> |
| 148 | + <UButton |
| 149 | + class="join-item" |
| 150 | + color="primary" |
| 151 | + :is-loading |
| 152 | + :aria-label="sortAscending ? 'Sort Z to A' : 'Sort A to Z'" |
| 153 | + @click="toggleSortOrder()" |
| 154 | + > |
| 155 | + <template #leading> |
| 156 | + <UIcon |
| 157 | + v-motion |
| 158 | + :initial="{ opacity: 0 }" |
| 159 | + :enter="{ |
| 160 | + opacity: 1, |
| 161 | + transition: { duration: 150 }, |
| 162 | + }" |
| 163 | + :leave="{ |
| 164 | + opacity: 0, |
| 165 | + transition: { duration: 150 }, |
| 166 | + }" |
| 167 | + :name=" |
| 168 | + sortAscending |
| 169 | + ? 'lucide:arrow-up-a-z' |
| 170 | + : 'lucide:arrow-down-z-a' |
| 171 | + " |
| 172 | + /> |
| 173 | + </template> |
| 174 | + </UButton> |
| 175 | + |
| 176 | + <!-- Refresh Button --> |
| 177 | + <UButton |
| 178 | + v-if="filteredGuilds.length === 0" |
| 179 | + class="join-item" |
| 180 | + color="primary" |
| 181 | + :is-loading |
| 182 | + is-loading-icon="lucide:loader" |
| 183 | + icon="heroicons:arrow-path-20-solid" |
| 184 | + aria-label="Refresh servers" |
| 185 | + @click="refresh()" |
| 186 | + /> |
| 187 | + </UFieldGroup> |
| 188 | + |
| 189 | + <!-- Desktop Buttons (with view toggle) --> |
| 190 | + <UFieldGroup size="sm" class="join hidden items-end sm:flex"> |
| 191 | + <!-- |
200 | 192 | Manageable |
201 | 193 | Only |
202 | 194 | Toggle |
203 | 195 | Button |
204 | 196 | --> |
205 | | - <UButton |
206 | | - class="join-item" |
207 | | - color="primary" |
208 | | - :is-loading |
209 | | - is-loading-icon="lucide:loader" |
210 | | - icon="heroicons:shield-check" |
211 | | - @click="toggleShowManageableOnly()" |
212 | | - > |
213 | | - <span>Manageable</span> |
214 | | - </UButton> |
215 | | - |
216 | | - <!-- Sort Button --> |
217 | | - <UButton |
218 | | - class="join-item" |
219 | | - color="primary" |
220 | | - :is-loading |
221 | | - @click="toggleSortOrder()" |
222 | | - > |
223 | | - <template #leading> |
224 | | - <UIcon |
225 | | - v-motion |
226 | | - :initial="{ opacity: 0 }" |
227 | | - :enter="{ |
228 | | - opacity: 1, |
229 | | - transition: { duration: 150 }, |
230 | | - }" |
231 | | - :leave="{ |
232 | | - opacity: 0, |
233 | | - transition: { duration: 150 }, |
234 | | - }" |
235 | | - :name=" |
236 | | - sortAscending |
237 | | - ? 'lucide:arrow-up-a-z' |
238 | | - : 'lucide:arrow-down-z-a' |
239 | | - " |
240 | | - /> |
241 | | - </template> |
242 | | - </UButton> |
243 | | - |
244 | | - <!-- Refresh Button --> |
245 | | - <UButton |
246 | | - v-if="filteredGuilds.length === 0" |
247 | | - class="join-item" |
248 | | - color="primary" |
249 | | - :is-loading |
250 | | - is-loading-icon="lucide:loader" |
251 | | - icon="heroicons:arrow-path-20-solid" |
252 | | - @click="refresh()" |
253 | | - > |
254 | | - <span>Refresh</span> |
255 | | - </UButton> |
256 | | - </UFieldGroup> |
257 | | - </div> |
258 | | - <!-- Search Input for Desktop --> |
| 197 | + <UButton |
| 198 | + class="join-item" |
| 199 | + color="primary" |
| 200 | + :is-loading |
| 201 | + is-loading-icon="lucide:loader" |
| 202 | + icon="heroicons:shield-check" |
| 203 | + @click="toggleShowManageableOnly()" |
| 204 | + > |
| 205 | + <span>Manageable</span> |
| 206 | + </UButton> |
| 207 | + |
| 208 | + <!-- Sort Button --> |
| 209 | + <UButton |
| 210 | + class="join-item" |
| 211 | + color="primary" |
| 212 | + :is-loading |
| 213 | + :aria-label="sortAscending ? 'Sort Z to A' : 'Sort A to Z'" |
| 214 | + @click="toggleSortOrder()" |
| 215 | + > |
| 216 | + <template #leading> |
| 217 | + <UIcon |
| 218 | + v-motion |
| 219 | + :initial="{ opacity: 0 }" |
| 220 | + :enter="{ |
| 221 | + opacity: 1, |
| 222 | + transition: { duration: 150 }, |
| 223 | + }" |
| 224 | + :leave="{ |
| 225 | + opacity: 0, |
| 226 | + transition: { duration: 150 }, |
| 227 | + }" |
| 228 | + :name=" |
| 229 | + sortAscending |
| 230 | + ? 'lucide:arrow-up-a-z' |
| 231 | + : 'lucide:arrow-down-z-a' |
| 232 | + " |
| 233 | + /> |
| 234 | + </template> |
| 235 | + </UButton> |
| 236 | + |
| 237 | + <!-- Refresh Button --> |
| 238 | + <UButton |
| 239 | + v-if="filteredGuilds.length === 0" |
| 240 | + class="join-item" |
| 241 | + color="primary" |
| 242 | + :is-loading |
| 243 | + is-loading-icon="lucide:loader" |
| 244 | + icon="heroicons:arrow-path-20-solid" |
| 245 | + @click="refresh()" |
| 246 | + > |
| 247 | + <span>Refresh</span> |
| 248 | + </UButton> |
| 249 | + </UFieldGroup> |
259 | 250 | </div> |
260 | 251 | <div class="space-y-4 md:space-y-2"> |
261 | 252 | <GuildCards |
|
0 commit comments