improve UI
This commit is contained in:
parent
b32c609a3b
commit
f3eb1622eb
9 changed files with 320 additions and 231 deletions
|
|
@ -79,7 +79,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
|
|||
*/
|
||||
workbox.precacheAndRoute([{
|
||||
"url": "index.html",
|
||||
"revision": "0.3s1v9t4dfmo"
|
||||
"revision": "0.fnrrna5najg"
|
||||
}], {});
|
||||
workbox.cleanupOutdatedCaches();
|
||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||
|
|
|
|||
|
|
@ -1,165 +1,182 @@
|
|||
@import "tailwindcss";
|
||||
|
||||
@layer base {
|
||||
|
||||
:root {
|
||||
/* Catppuccin Latte */
|
||||
--color-background: #eff1f5;
|
||||
--color-foreground: #4c4f69;
|
||||
--color-card: #e6e9ef;
|
||||
--color-card-foreground: #4c4f69;
|
||||
--color-popover: #e6e9ef;
|
||||
--color-popover-foreground: #4c4f69;
|
||||
--color-primary: #1e66f5;
|
||||
--color-primary-foreground: #eff1f5;
|
||||
--color-secondary: #ccd0da;
|
||||
--color-secondary-foreground: #4c4f69;
|
||||
--color-muted: #ccd0da;
|
||||
--color-muted-foreground: #6c6f85;
|
||||
--color-accent: #dc8a78;
|
||||
--color-accent-foreground: #eff1f5;
|
||||
--color-destructive: #d20f39;
|
||||
--color-destructive-foreground: #eff1f5;
|
||||
--color-border: #bcc0cc;
|
||||
--color-input: #bcc0cc;
|
||||
--color-ring: #1e66f5;
|
||||
--radius: 0.5rem;
|
||||
--popover: 220 23% 95%;
|
||||
--background: 227 92% 95%;
|
||||
--foreground: 234 16% 35%;
|
||||
|
||||
--card: 225 23% 92%;
|
||||
--card-foreground: 234 16% 35%;
|
||||
|
||||
--popover: 225 23% 92%;
|
||||
--popover-foreground: 234 16% 35%;
|
||||
/* Fallback colors for older browsers */
|
||||
--fallback-background: #ffffff;
|
||||
--fallback-popover: #f5f5f5;
|
||||
|
||||
--primary: 220 91% 54%;
|
||||
--primary-foreground: 227 92% 95%;
|
||||
|
||||
--secondary: 227 23% 83%;
|
||||
--secondary-foreground: 234 16% 35%;
|
||||
|
||||
--muted: 227 23% 83%;
|
||||
--muted-foreground: 231 11% 47%;
|
||||
|
||||
--accent: 11 83% 67%;
|
||||
--accent-foreground: 227 92% 95%;
|
||||
|
||||
--destructive: 347 87% 44%;
|
||||
--destructive-foreground: 227 92% 95%;
|
||||
|
||||
--border: 228 17% 77%;
|
||||
--input: 228 17% 77%;
|
||||
--ring: 220 91% 54%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
/* Catppuccin Macchiato - we'll use the same colors for dark mode */
|
||||
--color-background: #24273a;
|
||||
--color-foreground: #cad3f5;
|
||||
--color-card: #1e2030;
|
||||
--color-card-foreground: #cad3f5;
|
||||
--color-popover: #1e2030;
|
||||
--color-popover-foreground: #cad3f5;
|
||||
--color-primary: #8aadf4;
|
||||
--color-primary-foreground: #24273a;
|
||||
--color-secondary: #363a4f;
|
||||
--color-secondary-foreground: #cad3f5;
|
||||
--color-muted: #363a4f;
|
||||
--color-muted-foreground: #a5adcb;
|
||||
--color-accent: #f4dbd6;
|
||||
--color-accent-foreground: #24273a;
|
||||
--color-destructive: #ed8796;
|
||||
--color-destructive-foreground: #24273a;
|
||||
--color-border: #363a4f;
|
||||
--color-input: #363a4f;
|
||||
--color-ring: #8aadf4;
|
||||
--popover: 240 21% 15%;
|
||||
--popover-foreground: 226 64% 88%;
|
||||
/* Fallback colors for older browsers */
|
||||
--fallback-background: #1e1e2e;
|
||||
--fallback-popover: #313244;
|
||||
}
|
||||
--background: 233 31% 18%;
|
||||
--foreground: 227 68% 88%;
|
||||
|
||||
--card: 234 32% 15%;
|
||||
--card-foreground: 227 68% 88%;
|
||||
|
||||
--popover: 234 32% 15%;
|
||||
--popover-foreground: 227 68% 88%;
|
||||
|
||||
--primary: 220 83% 76%;
|
||||
--primary-foreground: 233 31% 18%;
|
||||
|
||||
--secondary: 233 25% 26%;
|
||||
--secondary-foreground: 227 68% 88%;
|
||||
|
||||
--muted: 233 25% 26%;
|
||||
--muted-foreground: 225 27% 72%;
|
||||
|
||||
--accent: 11 77% 90%;
|
||||
--accent-foreground: 233 31% 18%;
|
||||
|
||||
--destructive: 351 74% 76%;
|
||||
--destructive-foreground: 233 31% 18%;
|
||||
|
||||
--border: 233 25% 26%;
|
||||
--input: 233 25% 26%;
|
||||
--ring: 220 83% 76%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply box-border;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
background-color: hsl(var(--background));
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
}
|
||||
|
||||
@utility bg-background {
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
@layer utilities {
|
||||
.bg-background {
|
||||
background-color: hsl(var(--background));
|
||||
}
|
||||
.bg-foreground {
|
||||
background-color: hsl(var(--foreground));
|
||||
}
|
||||
.bg-card {
|
||||
background-color: hsl(var(--card));
|
||||
}
|
||||
.bg-card-foreground {
|
||||
background-color: hsl(var(--card-foreground));
|
||||
}
|
||||
.bg-popover {
|
||||
background-color: hsl(var(--popover));
|
||||
}
|
||||
.bg-popover-foreground {
|
||||
background-color: hsl(var(--popover-foreground));
|
||||
}
|
||||
.bg-primary {
|
||||
background-color: hsl(var(--primary));
|
||||
}
|
||||
.bg-primary-foreground {
|
||||
background-color: hsl(var(--primary-foreground));
|
||||
}
|
||||
.bg-secondary {
|
||||
background-color: hsl(var(--secondary));
|
||||
}
|
||||
.bg-secondary-foreground {
|
||||
background-color: hsl(var(--secondary-foreground));
|
||||
}
|
||||
.bg-muted {
|
||||
background-color: hsl(var(--muted));
|
||||
}
|
||||
.bg-muted-foreground {
|
||||
background-color: hsl(var(--muted-foreground));
|
||||
}
|
||||
.bg-accent {
|
||||
background-color: hsl(var(--accent));
|
||||
}
|
||||
.bg-accent-foreground {
|
||||
background-color: hsl(var(--accent-foreground));
|
||||
}
|
||||
.bg-destructive {
|
||||
background-color: hsl(var(--destructive));
|
||||
}
|
||||
.bg-destructive-foreground {
|
||||
background-color: hsl(var(--destructive-foreground));
|
||||
}
|
||||
|
||||
@utility text-foreground {
|
||||
color: var(--color-foreground);
|
||||
}
|
||||
.text-background {
|
||||
color: hsl(var(--background));
|
||||
}
|
||||
.text-foreground {
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
.text-card {
|
||||
color: hsl(var(--card));
|
||||
}
|
||||
.text-card-foreground {
|
||||
color: hsl(var(--card-foreground));
|
||||
}
|
||||
.text-popover {
|
||||
color: hsl(var(--popover));
|
||||
}
|
||||
.text-popover-foreground {
|
||||
color: hsl(var(--popover-foreground));
|
||||
}
|
||||
.text-primary {
|
||||
color: hsl(var(--primary));
|
||||
}
|
||||
.text-primary-foreground {
|
||||
color: hsl(var(--primary-foreground));
|
||||
}
|
||||
.text-secondary {
|
||||
color: hsl(var(--secondary));
|
||||
}
|
||||
.text-secondary-foreground {
|
||||
color: hsl(var(--secondary-foreground));
|
||||
}
|
||||
.text-muted {
|
||||
color: hsl(var(--muted));
|
||||
}
|
||||
.text-muted-foreground {
|
||||
color: hsl(var(--muted-foreground));
|
||||
}
|
||||
.text-accent {
|
||||
color: hsl(var(--accent));
|
||||
}
|
||||
.text-accent-foreground {
|
||||
color: hsl(var(--accent-foreground));
|
||||
}
|
||||
.text-destructive {
|
||||
color: hsl(var(--destructive));
|
||||
}
|
||||
.text-destructive-foreground {
|
||||
color: hsl(var(--destructive-foreground));
|
||||
}
|
||||
|
||||
/* Add other utility classes for colors */
|
||||
@utility bg-card {
|
||||
background-color: var(--color-card);
|
||||
}
|
||||
|
||||
@utility text-card-foreground {
|
||||
color: var(--color-card-foreground);
|
||||
}
|
||||
|
||||
@utility bg-primary {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
@utility text-primary-foreground {
|
||||
color: var(--color-primary-foreground);
|
||||
}
|
||||
|
||||
/* ... add other utility classes as needed ... */
|
||||
/* :root { */
|
||||
/* /* gruvbox light theme */ */
|
||||
/* --color-background: hsl(32 92% 87%); /* bg0 */ */
|
||||
/* --color-foreground: hsl(40 13% 23%); /* fg */ */
|
||||
/**/
|
||||
/* --color-card: hsl(39 59% 88%); /* bg1 */ */
|
||||
/* --color-card-foreground: hsl(40 13% 23%); /* fg */ */
|
||||
/**/
|
||||
/* --color-popover: hsl(39 59% 88%); /* bg1 */ */
|
||||
/* --color-popover-foreground: hsl(40 13% 23%); /* fg */ */
|
||||
/**/
|
||||
/* --color-primary: hsl(0 100% 31%); /* red */ */
|
||||
/* --color-primary-foreground: hsl(40 92% 88%); /* bg */ */
|
||||
/**/
|
||||
/* --color-secondary: hsl(39 46% 81%); /* bg2 */ */
|
||||
/* --color-secondary-foreground: hsl(40 13% 23%); /* fg */ */
|
||||
/**/
|
||||
/* --color-muted: hsl(37 29% 73%); /* bg3 */ */
|
||||
/* --color-muted-foreground: hsl(40 4% 36%); /* gray */ */
|
||||
/**/
|
||||
/* --color-accent: hsl(40 71% 49%); /* yellow */ */
|
||||
/* --color-accent-foreground: hsl(0 0% 16%); */
|
||||
/**/
|
||||
/* --color-destructive: hsl(0 76% 46%); /* bright_red */ */
|
||||
/* --color-destructive-foreground: hsl(40 92% 88%); /* bg */ */
|
||||
/**/
|
||||
/* --color-border: hsl(33 14% 59%); /* fg4 */ */
|
||||
/* --color-input: hsl(33 14% 59%); /* fg4 */ */
|
||||
/* --color-ring: hsl(0 100% 31%); /* red */ */
|
||||
/**/
|
||||
/* --radius: 0.5rem; */
|
||||
/* } */
|
||||
|
||||
/* .dark { */
|
||||
/* /* gruvbox dark theme */ */
|
||||
/* --color-background: hsl(0 0% 16%); /* bg0 */ */
|
||||
/* --color-foreground: hsl(40 92% 88%); /* fg */ */
|
||||
/**/
|
||||
/* --color-card: hsl(0 7% 23%); /* bg1 */ */
|
||||
/* --color-card-foreground: hsl(40 92% 88%); /* fg */ */
|
||||
/**/
|
||||
/* --color-popover: hsl(0 7% 23%); /* bg1 */ */
|
||||
/* --color-popover-foreground: hsl(40 92% 88%); /* fg */ */
|
||||
/**/
|
||||
/* --color-primary: hsl(6 93% 59%); /* red */ */
|
||||
/* --color-primary-foreground: hsl(0 0% 16%); /* bg */ */
|
||||
/**/
|
||||
/* --color-secondary: hsl(0 5% 29%); /* bg2 */ */
|
||||
/* --color-secondary-foreground: hsl(40 92% 88%); /* fg */ */
|
||||
/**/
|
||||
/* --color-muted: hsl(20 6% 36%); /* bg3 */ */
|
||||
/* --color-muted-foreground: hsl(33 14% 59%); /* gray */ */
|
||||
/**/
|
||||
/* --color-accent: hsl(42 95% 58%); /* yellow */ */
|
||||
/* --color-accent-foreground: hsl(0 0% 16%); */
|
||||
/**/
|
||||
/* --color-destructive: hsl(6 93% 59%); /* bright_red */ */
|
||||
/* --color-destructive-foreground: hsl(40 92% 88%); /* bg */ */
|
||||
/**/
|
||||
/* --color-border: hsl(24 10% 51%); /* fg4 */ */
|
||||
/* --color-input: hsl(24 10% 51%); /* fg4 */ */
|
||||
/* --color-ring: hsl(6 93% 59%); /* red */ */
|
||||
/* } */
|
||||
|
||||
@supports not (backdrop-filter: blur(1px)) {
|
||||
.select-content {
|
||||
background-color: var(--fallback-background) !important;
|
||||
@supports not (backdrop-filter: blur(1px)) {
|
||||
.select-content {
|
||||
background-color: hsl(var(--background));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
64
src/assets/index.css.gruv
Normal file
64
src/assets/index.css.gruv
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* ... add other utility classes as needed ... */
|
||||
/* :root { */
|
||||
/* /* gruvbox light theme */ */
|
||||
/* --color-background: hsl(32 92% 87%); /* bg0 */ */
|
||||
/* --color-foreground: hsl(40 13% 23%); /* fg */ */
|
||||
/**/
|
||||
/* --color-card: hsl(39 59% 88%); /* bg1 */ */
|
||||
/* --color-card-foreground: hsl(40 13% 23%); /* fg */ */
|
||||
/**/
|
||||
/* --color-popover: hsl(39 59% 88%); /* bg1 */ */
|
||||
/* --color-popover-foreground: hsl(40 13% 23%); /* fg */ */
|
||||
/**/
|
||||
/* --color-primary: hsl(0 100% 31%); /* red */ */
|
||||
/* --color-primary-foreground: hsl(40 92% 88%); /* bg */ */
|
||||
/**/
|
||||
/* --color-secondary: hsl(39 46% 81%); /* bg2 */ */
|
||||
/* --color-secondary-foreground: hsl(40 13% 23%); /* fg */ */
|
||||
/**/
|
||||
/* --color-muted: hsl(37 29% 73%); /* bg3 */ */
|
||||
/* --color-muted-foreground: hsl(40 4% 36%); /* gray */ */
|
||||
/**/
|
||||
/* --color-accent: hsl(40 71% 49%); /* yellow */ */
|
||||
/* --color-accent-foreground: hsl(0 0% 16%); */
|
||||
/**/
|
||||
/* --color-destructive: hsl(0 76% 46%); /* bright_red */ */
|
||||
/* --color-destructive-foreground: hsl(40 92% 88%); /* bg */ */
|
||||
/**/
|
||||
/* --color-border: hsl(33 14% 59%); /* fg4 */ */
|
||||
/* --color-input: hsl(33 14% 59%); /* fg4 */ */
|
||||
/* --color-ring: hsl(0 100% 31%); /* red */ */
|
||||
/**/
|
||||
/* --radius: 0.5rem; */
|
||||
/* } */
|
||||
|
||||
/* .dark { */
|
||||
/* /* gruvbox dark theme */ */
|
||||
/* --color-background: hsl(0 0% 16%); /* bg0 */ */
|
||||
/* --color-foreground: hsl(40 92% 88%); /* fg */ */
|
||||
/**/
|
||||
/* --color-card: hsl(0 7% 23%); /* bg1 */ */
|
||||
/* --color-card-foreground: hsl(40 92% 88%); /* fg */ */
|
||||
/**/
|
||||
/* --color-popover: hsl(0 7% 23%); /* bg1 */ */
|
||||
/* --color-popover-foreground: hsl(40 92% 88%); /* fg */ */
|
||||
/**/
|
||||
/* --color-primary: hsl(6 93% 59%); /* red */ */
|
||||
/* --color-primary-foreground: hsl(0 0% 16%); /* bg */ */
|
||||
/**/
|
||||
/* --color-secondary: hsl(0 5% 29%); /* bg2 */ */
|
||||
/* --color-secondary-foreground: hsl(40 92% 88%); /* fg */ */
|
||||
/**/
|
||||
/* --color-muted: hsl(20 6% 36%); /* bg3 */ */
|
||||
/* --color-muted-foreground: hsl(33 14% 59%); /* gray */ */
|
||||
/**/
|
||||
/* --color-accent: hsl(42 95% 58%); /* yellow */ */
|
||||
/* --color-accent-foreground: hsl(0 0% 16%); */
|
||||
/**/
|
||||
/* --color-destructive: hsl(6 93% 59%); /* bright_red */ */
|
||||
/* --color-destructive-foreground: hsl(40 92% 88%); /* bg */ */
|
||||
/**/
|
||||
/* --color-border: hsl(24 10% 51%); /* fg4 */ */
|
||||
/* --color-input: hsl(24 10% 51%); /* fg4 */ */
|
||||
/* --color-ring: hsl(6 93% 59%); /* red */ */
|
||||
/* } */
|
||||
|
|
@ -16,11 +16,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive
|
||||
:as="as"
|
||||
:as-child="asChild"
|
||||
:class="cn(buttonVariants({ variant, size }), props.class)"
|
||||
>
|
||||
<Primitive :as="as" :as-child="asChild" :class="cn(buttonVariants({ variant, size }), props.class)">
|
||||
<slot />
|
||||
</Primitive>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const hasCopied = ref(false)
|
|||
|
||||
const copyPrivateKey = async () => {
|
||||
if (!nostrStore.account?.privkey) return
|
||||
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(nostrStore.account.privkey)
|
||||
hasCopied.value = true
|
||||
|
|
@ -43,44 +43,34 @@ const handleLogout = () => {
|
|||
</DialogTrigger>
|
||||
<DialogContent class="sm:max-w-md">
|
||||
<DialogHeader class="space-y-4">
|
||||
<div class="mx-auto w-12 h-12 rounded-full bg-gradient-to-br from-red-500 to-orange-500 p-0.5 shadow-lg">
|
||||
<div class="mx-auto w-12 h-12 rounded-full bg-gradient-to-br from-primary to-primary/80 p-0.5">
|
||||
<div class="w-full h-full rounded-full bg-background flex items-center justify-center">
|
||||
<ShieldAlert class="h-6 w-6 text-red-500" />
|
||||
<ShieldAlert class="h-6 w-6 text-primary" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center space-y-2">
|
||||
<DialogTitle class="text-xl font-semibold text-red-500">
|
||||
<DialogTitle class="text-xl font-semibold text-foreground">
|
||||
Backup Required
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
If you haven't saved your private key, you will permanently lose access to this chat history. Make sure to copy and securely store your private key before logging out.
|
||||
<DialogDescription class="text-muted-foreground">
|
||||
If you haven't saved your private key, you will permanently lose access to this chat history. Make sure to
|
||||
copy and securely store your private key before logging out.
|
||||
</DialogDescription>
|
||||
</div>
|
||||
</DialogHeader>
|
||||
<div class="flex flex-col gap-4 py-6">
|
||||
<Button
|
||||
class="w-full"
|
||||
variant="outline"
|
||||
@click="copyPrivateKey"
|
||||
>
|
||||
<Button class="w-full bg-muted hover:bg-muted/80 text-muted-foreground" variant="outline"
|
||||
@click="copyPrivateKey">
|
||||
<Copy v-if="!hasCopied" class="h-4 w-4 mr-2" />
|
||||
<Check v-else class="h-4 w-4 mr-2" />
|
||||
{{ hasCopied ? 'Copied!' : 'Copy Private Key' }}
|
||||
</Button>
|
||||
</div>
|
||||
<DialogFooter class="flex flex-col sm:flex-row gap-2 sm:gap-3">
|
||||
<Button
|
||||
variant="ghost"
|
||||
@click="() => isOpen = false"
|
||||
class="flex-1 sm:flex-none"
|
||||
>
|
||||
<Button variant="ghost" @click="() => isOpen = false" class="flex-1 sm:flex-none hover:bg-muted">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="destructive"
|
||||
@click="handleLogout"
|
||||
class="flex-1 sm:flex-none"
|
||||
>
|
||||
<Button variant="destructive" @click="handleLogout" class="flex-1 sm:flex-none">
|
||||
<LogOut class="h-4 w-4 mr-2" />
|
||||
Logout
|
||||
</Button>
|
||||
|
|
@ -92,7 +82,7 @@ const handleLogout = () => {
|
|||
<style scoped>
|
||||
/* Improved focus styles */
|
||||
:focus-visible {
|
||||
outline: 2px solid #cba6f7;
|
||||
outline: 2px solid hsl(var(--primary));
|
||||
outline-offset: 2px;
|
||||
transition: outline-offset 0.2s ease;
|
||||
}
|
||||
|
|
@ -112,4 +102,4 @@ button:not(:disabled):active {
|
|||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 300ms;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
export default {
|
||||
nav: {
|
||||
title: 'Directorio Atitlán',
|
||||
home: 'Inicio',
|
||||
directory: 'Directorio',
|
||||
faq: 'Preguntas',
|
||||
support: 'Soporte',
|
||||
login: 'Iniciar Sesión',
|
||||
logout: 'Cerrar Sesión'
|
||||
title: 'Directorio Atitlán'
|
||||
},
|
||||
home: {
|
||||
title: 'Encuentra Aceptadores de Bitcoin Lightning',
|
||||
|
|
@ -17,7 +14,7 @@ export default {
|
|||
selectTownPlaceholder: 'Selecciona tu ubicación...'
|
||||
},
|
||||
directory: {
|
||||
title: 'Directorio',
|
||||
title: 'Directorio de Pagos Lightning',
|
||||
subtitle: 'Encuentra lugares que aceptan pagos Bitcoin Lightning',
|
||||
search: 'Buscar...',
|
||||
categories: {
|
||||
|
|
|
|||
|
|
@ -60,27 +60,52 @@ const filteredItems = computed(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container mx-auto px-4 py-2 md:py-8">
|
||||
<div class="space-y-4">
|
||||
<div class="px-0 md:container md:px-4 py-2 md:py-8">
|
||||
<div class="space-y-4 md:space-y-6">
|
||||
<!-- Directory Header -->
|
||||
<div class="hidden md:block text-center space-y-2 mb-6">
|
||||
<h1 class="text-2xl font-bold tracking-tight sm:text-3xl">
|
||||
<div class="text-center space-y-2 mb-2 md:mb-6">
|
||||
<h1 class="md:hidden text-lg font-semibold tracking-tight px-4">
|
||||
{{ t('directory.title') }}
|
||||
</h1>
|
||||
<p class="text-sm sm:text-base text-muted-foreground">
|
||||
{{ t('directory.subtitle') }}
|
||||
</p>
|
||||
<div class="hidden md:block space-y-2">
|
||||
<h1 class="text-2xl font-bold tracking-tight sm:text-3xl">
|
||||
{{ t('directory.title') }}
|
||||
</h1>
|
||||
<p class="text-sm sm:text-base text-muted-foreground">
|
||||
{{ t('directory.subtitle') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sticky Container for Filter -->
|
||||
<div class="sticky top-14 z-40 -mx-4 bg-background/95 backdrop-blur-sm border-b w-screen left-0">
|
||||
<div class="container mx-auto px-4">
|
||||
<DirectoryFilter v-model:category="category" v-model:search="search" v-model:town="town" class="py-4" />
|
||||
<div class="sticky top-14 z-40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b md:border-b-0 w-full shadow-sm transition-all duration-200">
|
||||
<div class="w-full">
|
||||
<DirectoryFilter v-model:category="category" v-model:search="search" v-model:town="town" class="py-3 px-4" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Directory Grid -->
|
||||
<DirectoryGrid :items="filteredItems" class="pt-4" />
|
||||
<div class="pt-4 px-4 md:px-0">
|
||||
<DirectoryGrid :items="filteredItems" class="transition-all duration-300" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.fade-move,
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
.fade-leave-active {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -63,21 +63,24 @@ const towns = computed(() => [
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="max-w-3xl mx-auto text-center space-y-6 sm:space-y-8">
|
||||
<h1 class="text-3xl font-bold tracking-tight sm:text-6xl">
|
||||
{{ t('home.title') }}
|
||||
</h1>
|
||||
<div class="container mx-auto px-4 py-8 sm:py-12">
|
||||
<div class="max-w-3xl mx-auto text-center space-y-8 sm:space-y-12">
|
||||
<!-- Hero Section -->
|
||||
<div class="space-y-4">
|
||||
<h1 class="text-4xl font-bold tracking-tight sm:text-6xl text-foreground animate-in fade-in slide-in-from-bottom-4 duration-1000 fill-mode-both">
|
||||
{{ t('home.title') }}
|
||||
</h1>
|
||||
|
||||
<p class="text-base sm:text-lg text-muted-foreground max-w-2xl mx-auto">
|
||||
{{ t('home.subtitle') }}
|
||||
</p>
|
||||
<p class="text-base sm:text-lg text-muted-foreground max-w-2xl mx-auto animate-in fade-in slide-in-from-bottom-4 duration-1000 delay-150 fill-mode-both">
|
||||
{{ t('home.subtitle') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Town Selector - Move above category buttons -->
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<!-- Town Selector -->
|
||||
<div class="flex flex-col items-center gap-3 animate-in fade-in slide-in-from-bottom-4 duration-1000 delay-300 fill-mode-both">
|
||||
<h2 class="text-base font-medium text-muted-foreground">{{ t('home.selectTown') }}</h2>
|
||||
<Select :model-value="currentTown" @update:model-value="setCurrentTown">
|
||||
<SelectTrigger class="w-[200px]">
|
||||
<SelectTrigger class="w-[240px] h-11">
|
||||
<SelectValue :placeholder="t('home.selectTownPlaceholder')" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
|
|
@ -88,48 +91,45 @@ const towns = computed(() => [
|
|||
</Select>
|
||||
</div>
|
||||
|
||||
<!-- Category Buttons - Adjust spacing -->
|
||||
<div class="relative -mx-4 sm:mx-0">
|
||||
<!-- Category Buttons -->
|
||||
<div class="relative mx-auto max-w-2xl pt-4 animate-in fade-in slide-in-from-bottom-4 duration-1000 delay-500 fill-mode-both">
|
||||
<!-- Gradient Fade Edges -->
|
||||
<div class="absolute left-0 top-0 bottom-0 w-4 bg-gradient-to-r from-background to-transparent z-10"></div>
|
||||
<div class="absolute right-0 top-0 bottom-0 w-4 bg-gradient-to-l from-background to-transparent z-10"></div>
|
||||
|
||||
<div class="absolute left-0 top-0 bottom-0 w-4 bg-gradient-to-r from-background to-transparent z-10 sm:hidden"></div>
|
||||
<div class="absolute right-0 top-0 bottom-0 w-4 bg-gradient-to-l from-background to-transparent z-10 sm:hidden"></div>
|
||||
|
||||
<!-- Scrollable Container -->
|
||||
<div class="flex overflow-x-auto gap-1 px-4 pb-4
|
||||
<div class="flex overflow-x-auto gap-2 px-4 pb-4
|
||||
[&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]
|
||||
sm:justify-center">
|
||||
<router-link
|
||||
v-for="category in categories"
|
||||
:key="category"
|
||||
sm:flex-wrap sm:justify-center sm:gap-4 sm:px-0">
|
||||
<router-link v-for="category in categories" :key="category"
|
||||
:to="`/directory?category=${category}&town=${currentTown}`"
|
||||
class="group flex-shrink-0 w-[100px] sm:w-[120px]"
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="default"
|
||||
class="w-full h-20 sm:h-24 flex flex-col items-center justify-center gap-1 sm:gap-2 group-hover:bg-accent transition-colors"
|
||||
>
|
||||
<component
|
||||
:is="categoryIcons[category]"
|
||||
class="h-6 w-6 sm:h-7 sm:w-7"
|
||||
:class="categoryColors[category]"
|
||||
/>
|
||||
<span class="text-xs sm:text-sm">{{ t(`directory.categories.${category}`) }}</span>
|
||||
class="flex-shrink-0 w-[100px] sm:w-[110px]">
|
||||
<Button variant="ghost" size="default"
|
||||
class="w-full h-20 sm:h-24 flex flex-col items-center justify-center gap-1.5 sm:gap-2.5
|
||||
hover:bg-accent hover:scale-105 active:scale-100 transition-all duration-200 group">
|
||||
<component :is="categoryIcons[category]"
|
||||
class="h-6 w-6 sm:h-7 sm:w-7 transition-transform duration-200 group-hover:scale-110"
|
||||
:class="categoryColors[category]" />
|
||||
<span class="text-xs sm:text-sm font-medium text-muted-foreground group-hover:text-foreground transition-colors">
|
||||
{{ t(`directory.categories.${category}`) }}
|
||||
</span>
|
||||
</Button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Move action buttons to bottom -->
|
||||
<div class="flex flex-col sm:flex-row gap-2 sm:gap-4 justify-center mt-4">
|
||||
<router-link to="/directory"
|
||||
class="inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90">
|
||||
{{ t('home.browse') }}
|
||||
<!-- Action Buttons -->
|
||||
<div class="flex flex-col sm:flex-row gap-3 sm:gap-4 justify-center pt-4 animate-in fade-in slide-in-from-bottom-4 duration-1000 delay-700 fill-mode-both">
|
||||
<router-link to="/directory" class="sm:w-[160px]">
|
||||
<Button variant="default" size="lg" class="w-full font-medium">
|
||||
{{ t('home.browse') }}
|
||||
</Button>
|
||||
</router-link>
|
||||
|
||||
<router-link to="/faq"
|
||||
class="inline-flex items-center justify-center rounded-md border border-input bg-background px-6 py-3 text-sm font-medium hover:bg-accent hover:text-accent-foreground">
|
||||
{{ t('home.learnMore') }}
|
||||
<router-link to="/faq" class="sm:w-[160px]">
|
||||
<Button variant="outline" size="lg" class="w-full font-medium">
|
||||
{{ t('home.learnMore') }}
|
||||
</Button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue