add quick town selection and category selection from homescreen with localstorage!

This commit is contained in:
padreug 2025-02-11 01:41:12 +01:00
parent 73f5683fbc
commit 02e699aad5
24 changed files with 619 additions and 137 deletions

View file

@ -1,17 +1,74 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { useTheme } from '@/components/theme-provider'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import { computed } from 'vue'
import {
UtensilsCrossed,
Bed,
ShoppingBag,
Sparkles,
Car,
Ship,
HelpCircle,
} from 'lucide-vue-next'
import TukTuk from '@/components/icons/TukTuk.vue'
import { type DirectoryItem } from '@/types/directory'
const { t } = useI18n()
const { currentTown, setCurrentTown } = useTheme()
type CategoryType = DirectoryItem['category']
const categories: CategoryType[] = ['tuktuk', 'restaurant', 'services', 'goods', 'lodging', 'taxi', 'lancha']
const categoryIcons = {
restaurant: UtensilsCrossed,
lodging: Bed,
goods: ShoppingBag,
services: Sparkles,
tuktuk: TukTuk,
taxi: Car,
lancha: Ship,
other: HelpCircle,
} as const
const categoryColors = {
tuktuk: 'text-amber-500',
restaurant: 'text-orange-500',
lodging: 'text-purple-500',
goods: 'text-green-500',
services: 'text-pink-500',
taxi: 'text-yellow-500',
lancha: 'text-blue-500',
other: 'text-gray-500',
} as const
const towns = computed(() => [
{ id: 'all', label: t('directory.towns.all') },
{ id: 'San Marcos', label: 'San Marcos' },
{ id: 'San Pedro', label: 'San Pedro' },
{ id: 'Tzununa', label: 'Tzununa' },
{ id: 'Jaibalito', label: 'Jaibalito' },
{ id: 'San Pablo', label: 'San Pablo' },
{ id: 'Panajachel', label: 'Panajachel' },
])
</script>
<template>
<div class="container mx-auto px-4 py-8">
<div class="max-w-4xl mx-auto text-center space-y-8">
<h1 class="text-4xl font-bold tracking-tight sm:text-6xl">
<h1 class="text-3xl font-bold tracking-tight sm:text-6xl">
{{ t('home.title') }}
</h1>
<p class="text-xl text-muted-foreground">
<p class="text-lg sm:text-xl text-muted-foreground">
{{ t('home.subtitle') }}
</p>
@ -26,6 +83,53 @@ const { t } = useI18n()
{{ t('home.learnMore') }}
</router-link>
</div>
<!-- Town Selector -->
<div class="flex flex-col items-center gap-2 sm:gap-4">
<h2 class="text-lg sm:text-xl font-semibold">{{ t('home.selectTown') }}</h2>
<Select :model-value="currentTown" @update:model-value="setCurrentTown">
<SelectTrigger class="w-[200px]">
<SelectValue :placeholder="t('home.selectTownPlaceholder')" />
</SelectTrigger>
<SelectContent>
<SelectItem v-for="town in towns" :key="town.id" :value="town.id">
{{ town.label }}
</SelectItem>
</SelectContent>
</Select>
</div>
<!-- Category Buttons -->
<div class="relative mt-4 sm:mt-8">
<!-- 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>
<!-- Scrollable Container -->
<div class="flex overflow-x-auto gap-1 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"
:to="`/directory?category=${category}&town=${currentTown}`"
class="group flex-shrink-0 w-[100px] sm:w-[120px]"
>
<Button
variant="outline"
size="default"
class="w-full h-20 sm:h-24 flex flex-col items-center justify-center gap-1 sm:gap-2 group-hover:border-primary/50 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>
</Button>
</router-link>
</div>
</div>
</div>
</div>
</template>