end of section 4
This commit is contained in:
parent
15e0a2c160
commit
fc98c9746d
|
|
@ -0,0 +1,32 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "Range Rover Sport",
|
||||||
|
"price": "84,777",
|
||||||
|
"url": "https://www.carhelpcanada.com/wp-content/uploads/2019/12/2020-Range-Rover-Evoque-2.jpg",
|
||||||
|
"seats": 5,
|
||||||
|
"miles": "14,666",
|
||||||
|
"features": ["No Accidents", "Low KM", "Vehicle Detailed", "Leather Interior"],
|
||||||
|
"description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Debitis odio et laboriosam!"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "Rolls Royce Ghost",
|
||||||
|
"price": "455,000",
|
||||||
|
"url": "https://robbreport.com/wp-content/uploads/2021/03/1-5.jpg?w=1000",
|
||||||
|
"seats": 5,
|
||||||
|
"miles": "53,666",
|
||||||
|
"features": ["No Accidents", "Low KM", "Vehicle Detailed", "Leather Interior"],
|
||||||
|
"description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Debitis odio et laboriosam! Numquam ut rem, blanditiis est rerum tenetur maxime delectus"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"name": "Porsche Taycan",
|
||||||
|
"price": "180,434",
|
||||||
|
"url": "https://www.topgear.com/sites/default/files/cars-car/carousel/2021/02/pcgb20_1441_fine.jpg",
|
||||||
|
"seats": 5,
|
||||||
|
"miles": "0",
|
||||||
|
"features": ["No Accidents", "Low KM", "Vehicle Detailed", "Leather Interior"],
|
||||||
|
"description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Debitis odio et"
|
||||||
|
}
|
||||||
|
]
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,5 +1,9 @@
|
||||||
|
<script setup>
|
||||||
|
const {cars} = useCars();
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<CarCard/>
|
<CarCard v-for="car in cars" :key="car.id" :car="car" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -1,8 +1,16 @@
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
features : Array
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="mr-10 mt-5 border-b pb-5">
|
<div class="mr-10 mt-5 border-b pb-5">
|
||||||
<div class="flex text-lg mt-2">
|
<div class="flex text-lg mt-2" v-for="feat in features" :key="feat">
|
||||||
<p class="rounded text-lime-800 mr-3">X</p>
|
<p class="rounded text-lime-800 mr-3">X</p>
|
||||||
<p>leather Interior</p>
|
<p>{{feat}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
description : String
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
<p class="mb-10">Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, quaerat. Dignissimos, esse!</p>
|
<p class="mb-10">{{ description }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,3 +1,7 @@
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<!-- HOME HERO -->
|
<!-- HOME HERO -->
|
||||||
|
|
@ -12,7 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- HOME HERO -->
|
<!-- HOME HERO -->
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -1,29 +1,63 @@
|
||||||
|
<script setup>
|
||||||
|
const modal = ref({
|
||||||
|
make: false,
|
||||||
|
location: true,
|
||||||
|
price: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const city = ref("");
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
|
const updateModal = (key) => {
|
||||||
|
modal.value[key] = !modal.value[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChangeLocation = () => {
|
||||||
|
if (!city.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNaN(parseInt(city.value))) {
|
||||||
|
throw createError({
|
||||||
|
statusCode:400,
|
||||||
|
message:"invalid city"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updateModal('location');
|
||||||
|
navigateTo(`/city/${city.value}/car/${route.params.make}`);
|
||||||
|
city.value = "";
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div class="shadow border w-64 mr-10 z-30 h-[190px]">
|
<div class="shadow border w-64 mr-10 z-30 h-[190px]">
|
||||||
<div class="p-5 flex justify-between relative cursor-pointer border-b">
|
<div class="p-5 flex justify-between relative cursor-pointer border-b">
|
||||||
<h3>Location</h3>
|
<h3>Location</h3>
|
||||||
<h3 class="text-blue-400 capitalize">Toronto</h3>
|
<h3 @click="updateModal('location')" class="text-blue-400 capitalize">
|
||||||
<!-- <div class="absolute border shadow left-56 p-5 top-1 -m-1 bg-white">
|
{{ route.params.city }}
|
||||||
<input type="text" name="" id="" class="border p-1 rounded"/>
|
</h3>
|
||||||
<button class="bg-blue-400 w-full mt-2 rounded text-white p-1">Apply</button>
|
<div v-if="modal.location"
|
||||||
</div> -->
|
class="absolute border shadow left-56 p-5 top-1 -m-1 bg-white">
|
||||||
|
<input type="text" name="" id="" class="border p-1 rounded" v-model="city"/>
|
||||||
|
<button class="bg-blue-400 w-full mt-2 rounded text-white p-1" @click="onChangeLocation">Apply</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-5 flex justify-between relative cursor-pointer border-b">
|
<div class="p-5 flex justify-between relative cursor-pointer border-b">
|
||||||
<h3>Make</h3>
|
<h3>Make</h3>
|
||||||
<h3 class="text-blue-400 capitalize">Toyota</h3>
|
<h3 @click="updateModal('make')" class="text-blue-400 capitalize">Toyota</h3>
|
||||||
<!-- <div class="absolute border shadow left-56 p-5 top-1 -m-1 bg-white">
|
<div v-if="modal.make" class="absolute border shadow left-56 p-5 top-1 -m-1 bg-white">
|
||||||
<input type="text" name="" id="" class="border p-1 rounded"/>
|
<input type="text" name="" id="" class="border p-1 rounded"/>
|
||||||
<button class="bg-blue-400 w-full mt-2 rounded text-white p-1">Apply</button>
|
<button class="bg-blue-400 w-full mt-2 rounded text-white p-1">Apply</button>
|
||||||
</div> -->
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-5 flex justify-between relative cursor-pointer border-b">
|
<div class="p-5 flex justify-between relative cursor-pointer border-b">
|
||||||
<h3>Price</h3>
|
<h3>Price</h3>
|
||||||
<h3 class="text-blue-400 capitalize">Toyota</h3>
|
<h3 @click="updateModal('price')" class="text-blue-400 capitalize">Toyota</h3>
|
||||||
<!-- <div class="absolute border shadow left-56 p-5 top-1 -m-1 bg-white">
|
<div v-if="modal.price" class="absolute border shadow left-56 p-5 top-1 -m-1 bg-white">
|
||||||
<input type="text" name="" id="" class="border p-1 rounded"/>
|
<input type="text" name="" id="" class="border p-1 rounded"/>
|
||||||
<button class="bg-blue-400 w-full mt-2 rounded text-white p-1">Apply</button>
|
<button class="bg-blue-400 w-full mt-2 rounded text-white p-1">Apply</button>
|
||||||
</div> -->
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
import cars from "@/assets/cars.json"
|
||||||
|
|
||||||
|
export const useCars = () => {
|
||||||
|
return {
|
||||||
|
cars,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
export const useTest = () => {
|
|
||||||
return "TEST";
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<script setup>
|
||||||
|
const error = useError();
|
||||||
|
|
||||||
|
const handleError = () => {
|
||||||
|
clearError({
|
||||||
|
redirect: "/",
|
||||||
|
});
|
||||||
|
// navigateTo("/");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex h-screen justify-center items-center flex-col" v-if="error">
|
||||||
|
<h1 class="text-9xl">Error {{error.statusCode}}</h1>
|
||||||
|
<p class="mt-7 text-4xl">{{error.message}}</p>
|
||||||
|
<button
|
||||||
|
class="rounded mt-7 text-2xl bg-blue-400 py-4 text-white"
|
||||||
|
@click="handleError"
|
||||||
|
>Go Back
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -1,12 +1,29 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const {toTitleCase} = useUtilities();
|
const {toTitleCase} = useUtilities();
|
||||||
|
const {cars} = useCars();
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title :toTitleCase(route.params.name )
|
title :toTitleCase(route.params.name )
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const car = computed(() => {
|
||||||
|
return cars.find((_) => {
|
||||||
|
return _.id === parseInt(route.params.id)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (!car.value) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 404,
|
||||||
|
message: `Car with ID ${route.params.id} not found`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: "custom"
|
layout: "custom"
|
||||||
});
|
});
|
||||||
|
|
@ -14,11 +31,10 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div v-if="car">
|
||||||
<h1>test</h1>
|
<CarDetailHero :car="car"/>
|
||||||
<CarDetailHero/>
|
<CarDetailAttributes :features="car.features"/>
|
||||||
<CarDetailAttributes/>
|
<CarDetailDescription :description="car.description"/>
|
||||||
<CarDetailDescription/>
|
|
||||||
<CarDetailContact/>
|
<CarDetailContact/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -15,8 +15,18 @@
|
||||||
|
|
||||||
|
|
||||||
<div class="mt-32 flex">
|
<div class="mt-32 flex">
|
||||||
<CarSideBar/>
|
<NuxtErrorBoundary>
|
||||||
<NuxtPage />
|
<CarSideBar/>
|
||||||
|
<NuxtPage />
|
||||||
|
<template #error="{error}">
|
||||||
|
<div class="text-center mx-auto flex flex-col">
|
||||||
|
<h1 class="text-5xl text-red-600 mb-4">Sorry, something went wrong</h1>
|
||||||
|
<code>{{error}}</code>
|
||||||
|
<button class="text-white bg-blue-400 px-10 py-3 rounded mt-4"
|
||||||
|
@click="error.value = null">go back</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</NuxtErrorBoundary>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue