add tuktuk category (taxis will be for driving to the airport, etc)
This commit is contained in:
parent
1134671d7d
commit
73f5683fbc
9 changed files with 371 additions and 318 deletions
|
|
@ -79,7 +79,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
|
||||||
*/
|
*/
|
||||||
workbox.precacheAndRoute([{
|
workbox.precacheAndRoute([{
|
||||||
"url": "index.html",
|
"url": "index.html",
|
||||||
"revision": "0.dtkt23h1tmg"
|
"revision": "0.st6kb6leuvo"
|
||||||
}], {});
|
}], {});
|
||||||
workbox.cleanupOutdatedCaches();
|
workbox.cleanupOutdatedCaches();
|
||||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import {
|
||||||
HelpCircle,
|
HelpCircle,
|
||||||
Sparkles,
|
Sparkles,
|
||||||
} from 'lucide-vue-next'
|
} from 'lucide-vue-next'
|
||||||
|
import TukTuk from '@/components/icons/TukTuk.vue'
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
|
|
@ -36,6 +37,7 @@ const categoryIcons = {
|
||||||
goods: ShoppingBag,
|
goods: ShoppingBag,
|
||||||
services: Sparkles,
|
services: Sparkles,
|
||||||
taxi: Car,
|
taxi: Car,
|
||||||
|
tuktuk: TukTuk,
|
||||||
lancha: Ship,
|
lancha: Ship,
|
||||||
other: HelpCircle,
|
other: HelpCircle,
|
||||||
} as const
|
} as const
|
||||||
|
|
@ -46,6 +48,7 @@ const categoryColors = {
|
||||||
goods: 'text-green-500',
|
goods: 'text-green-500',
|
||||||
services: 'text-pink-500',
|
services: 'text-pink-500',
|
||||||
taxi: 'text-yellow-500',
|
taxi: 'text-yellow-500',
|
||||||
|
tuktuk: 'text-amber-500',
|
||||||
lancha: 'text-blue-500',
|
lancha: 'text-blue-500',
|
||||||
other: 'text-gray-500',
|
other: 'text-gray-500',
|
||||||
} as const
|
} as const
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import {
|
||||||
Ship,
|
Ship,
|
||||||
HelpCircle,
|
HelpCircle,
|
||||||
} from 'lucide-vue-next'
|
} from 'lucide-vue-next'
|
||||||
|
import TukTuk from '@/components/icons/TukTuk.vue'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
|
@ -41,6 +42,7 @@ watch(() => props.search, (newValue) => {
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
const categoryIcons = {
|
const categoryIcons = {
|
||||||
|
tuktuk: TukTuk,
|
||||||
restaurant: UtensilsCrossed,
|
restaurant: UtensilsCrossed,
|
||||||
lodging: Bed,
|
lodging: Bed,
|
||||||
goods: ShoppingBag,
|
goods: ShoppingBag,
|
||||||
|
|
@ -51,23 +53,25 @@ const categoryIcons = {
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
const categoryColors = {
|
const categoryColors = {
|
||||||
|
tuktuk: 'text-amber-500',
|
||||||
restaurant: 'text-orange-500',
|
restaurant: 'text-orange-500',
|
||||||
lodging: 'text-purple-500',
|
lodging: 'text-purple-500',
|
||||||
goods: 'text-green-500',
|
goods: 'text-green-500',
|
||||||
services: 'text-pink-500',
|
services: 'text-pink-500',
|
||||||
taxi: 'text-yellow-500',
|
|
||||||
lancha: 'text-blue-500',
|
lancha: 'text-blue-500',
|
||||||
|
taxi: 'text-yellow-500',
|
||||||
other: 'text-gray-500',
|
other: 'text-gray-500',
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
const categories = computed(() => [
|
const categories = computed(() => [
|
||||||
{ id: 'all', label: t('directory.categories.all') },
|
{ id: 'all', label: t('directory.categories.all') },
|
||||||
{ id: 'restaurant', label: t('directory.categories.restaurant'), icon: categoryIcons.restaurant },
|
{ id: 'restaurant', label: t('directory.categories.restaurant'), icon: categoryIcons.restaurant },
|
||||||
|
{ id: 'tuktuk', label: t('directory.categories.tuktuk'), icon: categoryIcons.tuktuk },
|
||||||
{ id: 'lodging', label: t('directory.categories.lodging'), icon: categoryIcons.lodging },
|
{ id: 'lodging', label: t('directory.categories.lodging'), icon: categoryIcons.lodging },
|
||||||
{ id: 'goods', label: t('directory.categories.goods'), icon: categoryIcons.goods },
|
{ id: 'goods', label: t('directory.categories.goods'), icon: categoryIcons.goods },
|
||||||
{ id: 'services', label: t('directory.categories.services'), icon: categoryIcons.services },
|
{ id: 'services', label: t('directory.categories.services'), icon: categoryIcons.services },
|
||||||
{ id: 'taxi', label: t('directory.categories.taxi'), icon: categoryIcons.taxi },
|
|
||||||
{ id: 'lancha', label: t('directory.categories.lancha'), icon: categoryIcons.lancha },
|
{ id: 'lancha', label: t('directory.categories.lancha'), icon: categoryIcons.lancha },
|
||||||
|
{ id: 'taxi', label: t('directory.categories.taxi'), icon: categoryIcons.taxi },
|
||||||
{ id: 'other', label: t('directory.categories.other'), icon: categoryIcons.other },
|
{ id: 'other', label: t('directory.categories.other'), icon: categoryIcons.other },
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
@ -89,34 +93,24 @@ const towns = computed(() => [
|
||||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
<Search class="h-5 w-5 text-muted-foreground" />
|
<Search class="h-5 w-5 text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input v-model="searchValue" type="text" class="pl-10 w-full" :placeholder="t('directory.search')"
|
||||||
v-model="searchValue"
|
inputmode="text" enterkeyhint="search" />
|
||||||
type="text"
|
|
||||||
class="pl-10 w-full"
|
|
||||||
:placeholder="t('directory.search')"
|
|
||||||
inputmode="text"
|
|
||||||
enterkeyhint="search"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col md:flex-row gap-1 sm:gap-2">
|
<div class="flex flex-col md:flex-row gap-1 sm:gap-2">
|
||||||
<!-- Category Filter -->
|
<!-- Category Filter -->
|
||||||
<div class="flex gap-1 sm:gap-2 overflow-x-auto pb-1 sm:pb-2 md:pb-0">
|
<div class="flex gap-1 sm:gap-2 overflow-x-auto pb-1 sm:pb-2 md:pb-0">
|
||||||
<Button v-for="cat in categories" :key="cat.id" @click="emit('update:category', cat.id)"
|
<Button v-for="cat in categories" :key="cat.id" @click="emit('update:category', cat.id)"
|
||||||
:variant="props.category === cat.id ? 'default' : 'secondary'" size="sm" class="rounded-full whitespace-nowrap">
|
:variant="props.category === cat.id ? 'default' : 'secondary'" size="sm"
|
||||||
|
class="rounded-full whitespace-nowrap">
|
||||||
<!-- Show only icon on mobile for non-'all' categories -->
|
<!-- Show only icon on mobile for non-'all' categories -->
|
||||||
<template v-if="cat.id !== 'all'">
|
<template v-if="cat.id !== 'all'">
|
||||||
<component :is="cat.icon"
|
<component :is="cat.icon" class="h-4 w-4 md:mr-2" :class="[
|
||||||
class="h-4 w-4 md:mr-2"
|
|
||||||
:class="[
|
|
||||||
props.category === cat.id ? '' : categoryColors[cat.id as keyof typeof categoryColors],
|
props.category === cat.id ? '' : categoryColors[cat.id as keyof typeof categoryColors],
|
||||||
'md:hidden'
|
'md:hidden'
|
||||||
]"
|
]" />
|
||||||
/>
|
<component :is="cat.icon" class="h-4 w-4 mr-2 hidden md:inline-block"
|
||||||
<component :is="cat.icon"
|
:class="props.category === cat.id ? '' : categoryColors[cat.id as keyof typeof categoryColors]" />
|
||||||
class="h-4 w-4 mr-2 hidden md:inline-block"
|
|
||||||
:class="props.category === cat.id ? '' : categoryColors[cat.id as keyof typeof categoryColors]"
|
|
||||||
/>
|
|
||||||
<span class="hidden md:inline">{{ cat.label }}</span>
|
<span class="hidden md:inline">{{ cat.label }}</span>
|
||||||
</template>
|
</template>
|
||||||
<!-- Always show text for 'all' category -->
|
<!-- Always show text for 'all' category -->
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import {
|
||||||
HelpCircle,
|
HelpCircle,
|
||||||
Sparkles,
|
Sparkles,
|
||||||
} from 'lucide-vue-next'
|
} from 'lucide-vue-next'
|
||||||
|
import TukTuk from '@/components/icons/TukTuk.vue'
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
|
|
@ -46,6 +47,7 @@ const categoryIcons = {
|
||||||
goods: ShoppingBag,
|
goods: ShoppingBag,
|
||||||
services: Sparkles,
|
services: Sparkles,
|
||||||
taxi: Car,
|
taxi: Car,
|
||||||
|
tuktuk: TukTuk,
|
||||||
lancha: Ship,
|
lancha: Ship,
|
||||||
other: HelpCircle,
|
other: HelpCircle,
|
||||||
} as const
|
} as const
|
||||||
|
|
@ -56,6 +58,7 @@ const categoryColors = {
|
||||||
goods: 'text-green-500',
|
goods: 'text-green-500',
|
||||||
services: 'text-pink-500',
|
services: 'text-pink-500',
|
||||||
taxi: 'text-yellow-500',
|
taxi: 'text-yellow-500',
|
||||||
|
tuktuk: 'text-amber-500',
|
||||||
lancha: 'text-blue-500',
|
lancha: 'text-blue-500',
|
||||||
other: 'text-gray-500',
|
other: 'text-gray-500',
|
||||||
} as const
|
} as const
|
||||||
|
|
|
||||||
27
src/components/icons/TukTuk.vue
Normal file
27
src/components/icons/TukTuk.vue
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g>
|
||||||
|
<path fill="currentColor" d="M55.467,315.733C24.892,315.733,0,340.617,0,371.2c0,30.583,24.892,55.467,55.467,55.467s55.467-24.883,55.467-55.467
|
||||||
|
C110.933,340.617,86.05,315.733,55.467,315.733z M55.467,409.6c-21.171,0-38.4-17.229-38.4-38.4s17.229-38.4,38.4-38.4
|
||||||
|
s38.4,17.229,38.4,38.4S76.646,409.6,55.467,409.6z"/>
|
||||||
|
<path fill="currentColor" d="M503.467,256h-8.533v-93.867c0-38.05-27.819-69.734-64.188-75.768c-1.212-0.657-2.603-1.033-4.079-1.033H153.6
|
||||||
|
c-0.29,0-0.572,0.009-0.862,0.043c-54.443,5.513-88.055,98.987-99.388,136.491H42.667c-4.71,0-8.533,3.823-8.533,8.533v34.133
|
||||||
|
c0,4.71,3.823,8.533,8.533,8.533h25.6v8.96c-2.807-0.282-5.649-0.427-8.533-0.427c-21.035,0-41.242,7.714-56.892,21.734
|
||||||
|
c-3.516,3.14-3.806,8.533-0.666,12.049c3.149,3.516,8.533,3.814,12.049,0.666c12.518-11.204,28.689-17.382,45.508-17.382
|
||||||
|
c37.641,0,68.267,30.626,68.267,68.267c0,4.71,3.823,8.533,8.533,8.533h222.549c4.164,28.902,29.022,51.2,59.051,51.2
|
||||||
|
c30.029,0,54.886-22.298,59.051-51.2h9.216c4.71,0,8.533-3.823,8.533-8.533V307.2h8.533c4.71,0,8.533-3.823,8.533-8.533v-34.133
|
||||||
|
C512,259.823,508.186,256,503.467,256z M154.061,102.4h264.073c32.939,0,59.733,26.795,59.733,59.733v85.333H358.4V128
|
||||||
|
c0-4.71-3.823-8.533-8.533-8.533H147.652l-13.406-8.943C140.629,106.044,147.243,103.168,154.061,102.4z M341.333,136.533v115.934
|
||||||
|
L309.7,284.1c-1.596,1.596-2.5,3.772-2.5,6.033v34.133h-59.733V136.533H341.333z M230.4,136.533v85.333H128.316l23.27-85.333
|
||||||
|
H230.4z M121.122,122.291l14.097,9.404l-23.287,85.393l-33.434-16.717C89.762,169.694,104.346,140.706,121.122,122.291z
|
||||||
|
M418.133,409.6c-20.599,0-37.837-14.686-41.805-34.133h83.61C455.979,394.914,438.741,409.6,418.133,409.6z M494.933,290.133
|
||||||
|
H486.4c-4.71,0-8.533,3.823-8.533,8.533V358.4H144.64c-3.43-34.372-27.332-62.805-59.307-72.883v-20.983
|
||||||
|
c0-4.71-3.823-8.533-8.533-8.533H51.2v-17.067h8.533c3.806,0,7.159-2.526,8.201-6.187c1.527-5.342,3.2-10.718,4.949-16.094
|
||||||
|
l42.769,21.385c1.186,0.589,2.492,0.896,3.814,0.896H230.4V332.8c0,4.71,3.823,8.533,8.533,8.533h76.8
|
||||||
|
c4.71,0,8.533-3.823,8.533-8.533v-39.134l29.141-29.133h124.459c0,4.71,3.823,8.533,8.533,8.533h8.533V290.133z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
@ -16,7 +16,7 @@ export const mockDirectoryItems: DirectoryItem[] = [
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
name: 'Axel',
|
name: 'Axel',
|
||||||
category: 'taxi',
|
category: 'tuktuk',
|
||||||
town: 'San Marcos',
|
town: 'San Marcos',
|
||||||
contact: '+502 3846 1220',
|
contact: '+502 3846 1220',
|
||||||
contactType: ['whatsapp', 'telegram'],
|
contactType: ['whatsapp', 'telegram'],
|
||||||
|
|
|
||||||
13
src/locales/en.json
Normal file
13
src/locales/en.json
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
"directory": {
|
||||||
|
"categories": {
|
||||||
|
"all": "All",
|
||||||
|
"tuktuk": "Tuk-tuk",
|
||||||
|
"restaurant": "Restaurant",
|
||||||
|
"lodging": "Lodging",
|
||||||
|
"goods": "Goods",
|
||||||
|
"services": "Services",
|
||||||
|
"taxi": "Taxi",
|
||||||
|
"lancha": "Boat",
|
||||||
|
"other": "Other"
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/locales/es.json
Normal file
13
src/locales/es.json
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
"directory": {
|
||||||
|
"categories": {
|
||||||
|
"all": "Todo",
|
||||||
|
"restaurant": "Restaurante",
|
||||||
|
"tuktuk": "Tuk-tuk",
|
||||||
|
"lodging": "Hospedaje",
|
||||||
|
"goods": "Productos",
|
||||||
|
"services": "Servicios",
|
||||||
|
"taxi": "Taxi",
|
||||||
|
"lancha": "Lancha",
|
||||||
|
"other": "Otro"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
export interface DirectoryItem {
|
export interface DirectoryItem {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
category: 'restaurant' | 'taxi' | 'lancha' | 'lodging' | 'goods' | 'services' | 'other'
|
category: 'restaurant' | 'lodging' | 'goods' | 'services' | 'tuktuk' | 'taxi' | 'lancha' | 'other'
|
||||||
local?: boolean
|
local?: boolean
|
||||||
description?: string
|
description?: string
|
||||||
url?: string
|
url?: string
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue