Files
tp/main_dc/yalarba/easySite/app/components/objects/ObjectCard.vue
T
valitovgaziz 2941b14b38 flatten easySite directory: remove extra easySite/easySite nesting
- Moved contents of main_dc/yalarba/easySite/easySite/ up to easySite/
- Updated docker-compose.yml build context path
- Deleted empty nested easySite/ directory
2026-06-12 11:16:15 +05:00

116 lines
3.1 KiB
Vue

<template>
<div class="card cursor-pointer hover:shadow-lg transition-shadow" @click="$emit('click')">
<div class="relative">
<img
:src="object.images[0] || '/images/placeholder.jpg'"
:alt="object.title"
class="w-full h-48 object-cover"
>
<div class="absolute top-3 right-3">
<span class="badge badge-primary">
{{ getTypeLabel(object.type) }}
</span>
</div>
</div>
<div class="card-body">
<h3 class="font-semibold text-lg mb-2 line-clamp-2">{{ object.title }}</h3>
<p class="text-gray-600 mb-3 flex items-center gap-1">
📍 {{ object.city }}, {{ object.country }}
</p>
<p class="text-sm text-gray-600 mb-4 line-clamp-2">
{{ object.description }}
</p>
<div class="flex flex-wrap gap-1 mb-4">
<span
v-for="amenity in object.amenities.slice(0, 3)"
:key="amenity"
class="badge badge-secondary text-xs"
>
{{ getAmenityLabel(amenity) }}
</span>
<span
v-if="object.amenities.length > 3"
class="badge badge-outline text-xs"
>
+{{ object.amenities.length - 3 }}
</span>
</div>
<div class="flex items-center justify-between">
<div class="text-lg font-semibold text-primary-600">
{{ formatPrice(object.price) }}
<span class="text-sm text-gray-500">{{ getPriceUnitLabel(object.priceUnit) }}</span>
</div>
<div v-if="object.rating" class="flex items-center gap-1">
<span class="text-yellow-500"></span>
<span class="font-medium">{{ object.rating }}</span>
<span class="text-gray-500 text-sm">({{ object.reviewCount }})</span>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import type { ObjectItem } from '~/composables/useObjects'
interface Props {
object: ObjectItem
}
defineProps<Props>()
defineEmits<{
click: []
}>()
const getTypeLabel = (type: string) => {
const types: Record<string, string> = {
hotel: 'Отель',
apartment: 'Апартаменты',
villa: 'Вилла',
camping: 'Кемпинг',
restaurant: 'Ресторан',
attraction: 'Достопримечательность'
}
return types[type] || type
}
const getAmenityLabel = (amenity: string) => {
const amenities: Record<string, string> = {
wifi: 'Wi-Fi',
parking: 'Парковка',
breakfast: 'Завтрак',
pool: 'Бассейн',
spa: 'СПА',
kitchen: 'Кухня',
washing_machine: 'Стиральная машина'
}
return amenities[amenity] || amenity
}
const getPriceUnitLabel = (unit: string) => {
const units: Record<string, string> = {
per_night: '/ночь',
per_person: '/чел',
fixed: ''
}
return units[unit] || unit
}
const formatPrice = (price: number) => {
return new Intl.NumberFormat('ru-RU').format(price) + ' ₽'
}
</script>
<style scoped>
.line-clamp-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
</style>