Browse Source

Version inicial con ferrari

main
rodley82 1 month ago
commit
729c2e0897
  1. 114
      assets/app.js
  2. BIN
      assets/ferrari_1.jpg
  3. BIN
      assets/ferrari_2.jpg
  4. BIN
      assets/ferrari_3.jpg
  5. 397
      assets/styles.css
  6. 67
      data.json
  7. 180
      index.html

114
assets/app.js

@ -0,0 +1,114 @@
const { createApp, ref, onMounted, computed } = Vue;
createApp({
setup() {
const carData = ref({});
const isLoading = ref(true);
const error = ref(null);
// Function to load configuration from data.json
const loadCarData = async () => {
try {
const dataJsonPath = './data.json';
const response = await fetch(dataJsonPath, { cache: 'no-store', headers: { 'Cache-Control': 'no-cache' } });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
carData.value = data;
isLoading.value = false;
} catch (err) {
console.error('Error loading car data:', err);
error.value = err.message;
isLoading.value = false;
}
};
onMounted(async () => {
// Set page title based on device
document.title = window.innerWidth <= 768 ? 'Auto en Venta' : (carData.value?.pageTitle);
// Load car data from data.json
await loadCarData();
// Initialize carousel and animations after data is loaded
if (!error.value) {
// Wait for DOM to be fully updated
setTimeout(() => {
// Initialize AOS animations
AOS.init({
duration: 800,
easing: 'ease-in-out',
once: true,
mirror: false,
offset: 50
});
// Initialize enhanced mobile-friendly carousel
try {
// Make sure the carousel element exists before initializing
const carouselElement = document.getElementById('carCarousel');
// Check if carousel element exists and has carousel items
if (carouselElement && carData.value && carData.value.carImages && carData.value.carImages.length > 0) {
// Wait a bit more for images to load
setTimeout(() => {
// Initialize with simpler options to ensure compatibility
bulmaCarousel.attach('#carCarousel', {
slidesToScroll: 1,
slidesToShow: 1,
loop: true,
autoplay: true,
autoplaySpeed: 3000,
pagination: true
});
console.log('Carousel initialized successfully');
}, 200);
} else {
console.error('Carousel element not found or no images available');
}
} catch (error) {
console.error('Error initializing carousel:', error);
// Fallback: Create a simple manual carousel if Bulma carousel fails
try {
const carouselElement = document.getElementById('carCarousel');
if (carouselElement) {
// Add a class to indicate fallback mode
carouselElement.classList.add('fallback-carousel');
// Get all carousel items
const items = carouselElement.querySelectorAll('.carousel-item');
if (items.length > 0) {
// Show only the first item initially
items.forEach((item, index) => {
item.style.display = index === 0 ? 'block' : 'none';
});
console.log('Fallback carousel initialized');
}
}
} catch (fallbackError) {
console.error('Error initializing fallback carousel:', fallbackError);
}
}
// Add fade-in animation to elements with class 'fade-in'
document.querySelectorAll('.fade-in').forEach((el, index) => {
setTimeout(() => {
el.classList.add('visible');
}, 100 * index);
});
}, 300); // Increased timeout to ensure DOM is ready
}
});
return {
carData,
isLoading,
error
};
}
}).mount('#app');

BIN
assets/ferrari_1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

BIN
assets/ferrari_2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

BIN
assets/ferrari_3.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

397
assets/styles.css

@ -0,0 +1,397 @@
/* Base styles and variables */
:root {
--primary-color: #FF5F40;
--primary-dark: #E04B30;
--secondary-color: #2C3E50;
--accent-color: #3498DB;
--light-bg: #F8F9FA;
--dark-text: #2C3E50;
--light-text: #FFFFFF;
--border-radius: 10px;
--box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
--gradient-primary: linear-gradient(135deg, #FF5F40 0%, #E04B30 100%);
--gradient-dark: linear-gradient(135deg, #2C3E50 0%, #1A252F 100%);
}
/* Global styles */
body {
font-family: 'Montserrat', sans-serif;
color: var(--dark-text);
background-color: var(--light-bg);
line-height: 1.6;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Poppins', sans-serif;
font-weight: 600;
}
[v-cloak] {
display: none;
}
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.9);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.loading-overlay .progress {
width: 80%;
max-width: 300px;
height: 8px;
border-radius: 4px;
overflow: hidden;
}
/* Hero section styling */
.hero.is-primary {
background: var(--gradient-primary);
position: relative;
overflow: hidden;
}
.hero.is-primary::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('https://images.unsplash.com/photo-1492144534655-ae79c964c9d7?ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80');
background-size: cover;
background-position: center;
opacity: 0.15;
z-index: 0;
}
.hero-body {
position: relative;
z-index: 1;
padding: 4rem 1.5rem;
}
.hero .title {
font-weight: 700;
letter-spacing: -0.5px;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.hero .subtitle {
font-weight: 400;
max-width: 600px;
margin: 1rem auto 0;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
/* Section styling */
.section {
padding: 3rem 1.5rem;
}
.section-title {
position: relative;
margin-bottom: 2rem;
padding-bottom: 0.75rem;
}
.section-title::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 60px;
height: 4px;
background: var(--primary-color);
border-radius: 2px;
}
/* Card styling */
.card {
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
overflow: hidden;
transition: transform 0.3s ease, box-shadow 0.3s ease;
height: 100%;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 25px rgba(0, 0, 0, 0.15);
}
/* Carousel styling */
.carousel-container {
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: var(--box-shadow);
margin-bottom: 2.5rem;
}
/* Ensure images are properly sized */
.carousel .carousel-item img {
width: 100%;
height: 450px;
object-fit: cover;
}
/* Style carousel navigation */
.carousel-nav-left,
.carousel-nav-right {
background-color: rgba(255, 255, 255, 0.8);
border-radius: 50%;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
transition: all 0.2s ease;
cursor: pointer;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.carousel-nav-left {
left: 10px;
}
.carousel-nav-right {
right: 10px;
}
.carousel-nav-left:hover,
.carousel-nav-right:hover {
background-color: white;
transform: translateY(-50%) scale(1.1);
}
/* Style carousel indicators */
.carousel-indicator {
background-color: rgba(255, 255, 255, 0.6);
border: 1px solid rgba(0, 0, 0, 0.1);
}
.carousel-indicator.is-active {
background-color: var(--primary-color);
}
/* Fallback carousel styles */
.fallback-carousel {
position: relative;
overflow: hidden;
border-radius: var(--border-radius);
}
.fallback-carousel .carousel-item {
transition: opacity 0.5s ease;
}
.fallback-carousel .carousel-nav-left,
.fallback-carousel .carousel-nav-right {
z-index: 10;
cursor: pointer;
}
/* Feature highlights */
.feature-highlight {
text-align: center;
padding: 1.5rem;
margin-bottom: 1.5rem;
background-color: white;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
transition: transform 0.3s ease;
}
.feature-highlight:hover {
transform: translateY(-5px);
}
.feature-icon {
font-size: 2rem;
color: var(--primary-color);
margin-bottom: 1rem;
display: inline-block;
background: rgba(255, 95, 64, 0.1);
padding: 1rem;
border-radius: 50%;
}
/* Specs table styling */
.specs-table {
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: var(--box-shadow);
}
.specs-table .table {
background-color: white;
margin-bottom: 0;
}
.specs-table th {
background-color: var(--secondary-color);
color: white;
font-weight: 600;
}
.specs-table tr:nth-child(even) {
background-color: rgba(0, 0, 0, 0.02);
}
/* WhatsApp button styling */
.cta-container {
text-align: center;
padding: 2rem;
background: white;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
margin: 2rem 0;
}
.whatsapp-button {
background: var(--gradient-primary);
color: white !important;
padding: 12px 28px;
border-radius: 50px;
font-weight: 600;
font-size: 1.1rem;
display: inline-flex;
align-items: center;
gap: 10px;
box-shadow: 0 4px 15px rgba(255, 95, 64, 0.4);
transition: all 0.3s ease;
border: none;
}
.whatsapp-button:hover,
.whatsapp-button:focus {
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(255, 95, 64, 0.5);
background: linear-gradient(135deg, #FF7E66 0%, #E04B30 100%);
}
.whatsapp-button:active {
transform: translateY(-1px);
}
.whatsapp-button i {
font-size: 1.4rem;
}
/* Footer styling */
.footer {
background-color: var(--secondary-color);
color: white;
padding: 3rem 1.5rem;
}
.footer strong {
color: white;
}
/* Price tag */
.price-tag {
background: var(--gradient-primary);
color: white;
/*display: inline-block; */
padding: 0.75rem 1.5rem;
border-radius: 50px;
font-weight: 700;
font-size: 1.5rem;
margin: 1rem 0;
box-shadow: 0 4px 10px rgba(255, 95, 64, 0.3);
}
/* Mobile-specific styles */
@media screen and (max-width: 768px) {
html,
body {
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
}
body {
position: relative;
width: 100%;
}
.hero-body {
padding: 3rem 1rem;
}
.carousel .carousel-item img {
height: 300px;
}
.carousel-nav-left,
.carousel-nav-right {
width: 35px;
height: 35px;
}
.table-container {
overflow-x: auto;
}
.title.is-1 {
font-size: 2rem !important;
}
.title.is-3 {
font-size: 1.5rem !important;
}
.section {
padding: 2rem 1rem;
}
.whatsapp-button {
width: 100%;
max-width: 300px;
font-size: 1rem;
padding: 12px 16px;
}
.container {
padding: 0 15px;
}
}
/* Animation classes */
.fade-in {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.fade-in.visible {
opacity: 1;
transform: translateY(0);
}
/* Optimize image loading */
img {
display: block;
}
/* Mobile-optimized table container */
.is-mobile-optimized {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}

67
data.json

@ -0,0 +1,67 @@
{
"pageTitle": "Me venden!",
"heroTitle": "¡Fantastica Ferrari de coleccionen Venta!",
"heroSubtitle": "Dueño vende directo sin intermediarios listo para transferencia inmediata.",
"galleryTitle": "Galería de Fotos",
"carImages": [
{
"src": "assets/ferrari_1.jpg",
"alt": "Imagen de Auto 1"
},
{
"src": "assets/ferrari_2.jpg",
"alt": "Imagen de Auto 2"
},
{
"src": "assets/ferrari_3.jpg",
"alt": "Imagen de Auto 3"
}
],
"specTitle": "Especificaciones del Auto",
"carSpecs": [
{
"feature": "Marca",
"detail": "Ferrari",
"extra": "Excelente estado"
},
{
"feature": "Modelo",
"detail": "Ferrari 488"
},
{
"feature": "Año",
"detail": "1970"
},
{
"feature": "Kilometraje",
"detail": "350.000 km"
},
{
"feature": "Color",
"detail": "Rojo"
},
{
"feature": "Motor",
"detail": "4.0L 8 valvulas",
"extra": "Nunca tuvo GNC"
},
{
"feature": "Transmisión",
"detail": "Manual"
},
{
"feature": "Tipo de Combustible",
"detail": "Nafta"
},
{
"feature": "Precio",
"detail": "$77.000.000 (Negociable)"
}
],
"contactInfo": {
"whatsappNumber": "+5493511234567",
"whatsappText": "Hola, estoy interesado en tu auto en venta!",
"buttonText": "Contactar por WhatsApp"
},
"footerText": "<strong>Creado con <a href='https://qrcrafter.com' target='_blank' rel='noopener noreferrer'>QRCrafter.com</a></strong>"
}

180
index.html

@ -0,0 +1,180 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
<meta name="theme-color" content="#FF5F40">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>{{ carData && carData.pageTitle ? carData.pageTitle : '¡Auto en Venta!' }}</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma-carousel@4.0.4/dist/css/bulma-carousel.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&family=Poppins:wght@300;400;500;600;700&display=swap">
<!-- Add Vue.js -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<!-- Add carousel script in head to ensure it's loaded before use -->
<script src="https://cdn.jsdelivr.net/npm/bulma-carousel@4.0.4/dist/js/bulma-carousel.min.js"></script>
<!-- Add AOS for animations -->
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<link rel="stylesheet" href="assets/styles.css">
</head>
<body>
<div id="app" v-cloak>
<div v-if="isLoading" class="loading-overlay">
<progress class="progress is-primary" max="100">Loading</progress>
</div>
<div v-else-if="error" class="notification is-danger">
<button class="delete"></button>
Error al cargar los datos: {{ error }}
</div>
<template v-else>
<section class="hero is-primary">
<div class="hero-body">
<div class="container">
<h1 class="title is-1 has-text-centered is-size-3-mobile" data-aos="fade-down">
{{ carData.heroTitle }}
</h1>
<p class="subtitle has-text-centered is-size-6-mobile" data-aos="fade-up" data-aos-delay="200">
{{ carData.heroSubtitle }}
</p>
<div class="price-tag has-text-centered" data-aos="zoom-in" data-aos-delay="400">
<i class="fas fa-tag mr-2"></i> {{ carData.carSpecs.find(spec => spec.feature === 'Precio')?.detail }}
</div>
<div class="buttons is-centered mt-4" data-aos="fade-up" data-aos-delay="600">
<a :href="`https://wa.me/${carData.contactInfo.whatsappNumber}?text=${encodeURIComponent(carData.contactInfo.whatsappText)}`"
class="button is-white is-outlined is-rounded" target="_blank" rel="noopener noreferrer">
<span class="icon"><i class="fab fa-whatsapp"></i></span>
<span>Escribime</span>
</a>
</div>
</div>
</div>
</section>
<section class="section">
<div class="container">
<!-- Key Features Highlights -->
<div class="columns is-multiline mb-6" data-aos="fade-up">
<div class="column is-3-desktop is-6-tablet">
<div class="feature-highlight">
<span class="feature-icon">
<i class="fas fa-car"></i>
</span>
<h3 class="title is-5">
{{ carData.carSpecs.find(spec => spec.feature === 'Marca')?.detail }} {{ carData.carSpecs.find(spec =>
spec.feature === 'Modelo')?.detail }}
</h3>
<p>{{ carData.carSpecs.find(spec => spec.feature === 'Marca')?.extra }}</p>
</div>
</div>
<div class="column is-3-desktop is-6-tablet">
<div class="feature-highlight">
<span class="feature-icon">
<i class="fas fa-tachometer-alt"></i>
</span>
<h3 class="title is-5">{{ carData.carSpecs.find(spec => spec.feature === 'Kilometraje')?.detail }}</h3>
<p>{{ carData.carSpecs.find(spec => spec.feature === 'Kilometraje')?.extra }}</p>
</div>
</div>
<div class="column is-3-desktop is-6-tablet">
<div class="feature-highlight">
<span class="feature-icon">
<i class="fas fa-calendar-alt"></i>
</span>
<h3 class="title is-5">{{ carData.carSpecs.find(spec => spec.feature === 'Año')?.detail }}</h3>
<p>{{ carData.carSpecs.find(spec => spec.feature === 'Año')?.extra }}</p>
</div>
</div>
<div class="column is-3-desktop is-6-tablet">
<div class="feature-highlight">
<span class="feature-icon">
<i class="fas fa-gas-pump"></i>
</span>
<h3 class="title is-5">{{ carData.carSpecs.find(spec => spec.feature === 'Motor')?.detail }}</h3>
<p>{{ carData.carSpecs.find(spec => spec.feature === 'Motor')?.extra }}</p>
</div>
</div>
</div>
<!-- Gallery Section -->
<h2 class="title is-3 is-size-4-mobile section-title" data-aos="fade-right">{{ carData.galleryTitle }}</h2>
<div class="carousel-container" data-aos="fade-up">
<!-- Using the proper structure for Bulma Carousel -->
<div id="carCarousel" class="carousel">
<div v-for="(image, index) in carData.carImages" :key="index" class="carousel-item">
<figure class="image is-4by3">
<a :href="image.src" target="_blank" rel="noopener noreferrer">
<img :src="image.src" :alt="image.alt" loading="lazy">
</a>
</figure>
</div>
</div>
</div>
<h2 class="title is-3 is-size-4-mobile section-title">{{ carData.specTitle }}</h2>
<div class="specs-table is-mobile-optimized">
<table class="table is-bordered is-hoverable is-fullwidth is-size-7-mobile">
<thead>
<tr>
<th><i class="fas fa-clipboard-list mr-2"></i>Característica</th>
<th><i class="fas fa-info-circle mr-2"></i>Detalle</th>
</tr>
</thead>
<tbody>
<tr v-for="(spec, index) in carData.carSpecs" :key="index">
<td><strong>{{ spec.feature }}</strong></td>
<td>{{ spec.detail }}</td>
</tr>
</tbody>
</table>
</div>
<div class="cta-container mt-6">
<h3 class="title is-4 mb-4">¿Te interesa?</h3>
<p class="subtitle is-6 mb-5">Escribime para coordinar una visita o solicitar más información</p>
<a :href="`https://wa.me/${carData.contactInfo.whatsappNumber}?text=${encodeURIComponent(carData.contactInfo.whatsappText)}`"
class="whatsapp-button" target="_blank" rel="noopener noreferrer" aria-label="Contactar por WhatsApp">
<i class="fab fa-whatsapp"></i>
<span>{{ carData.contactInfo.buttonText }}</span>
</a>
</div>
</div>
</section>
<footer class="footer">
<div class="content has-text-centered">
<div class="columns is-centered">
<div class="column is-8">
<p class="mb-4">
<span v-html="carData.footerText"></span>
</p>
</div>
</div>
</div>
</footer>
</template>
</div>
<script src="assets/app.js"></script>
</body>
</html>
Loading…
Cancel
Save