# Home
# Archivos Base
# src > main.ts
Importamos el archivo Tailwind CSS
import './index.css'
# src > firebase.ts
Añadimos el archivo firebase
import { initializeApp } from "firebase/app";
import { getFirestore } from 'firebase/firestore';
import { getStorage } from "firebase/storage";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
apiKey: "AIzaSyC-yjMEOwF0FAyC4Dsi3IqZcHqoZit4gyI",
authDomain: "tiendaarduinoes.firebaseapp.com",
projectId: "tiendaarduinoes",
storageBucket: "tiendaarduinoes.appspot.com",
messagingSenderId: "386838491375",
appId: "1:386838491375:web:518d05af8440e82cb6ab1a",
measurementId: "G-L90G5CE35V"
};
const firebaseApp = initializeApp(firebaseConfig);
const storage = getStorage(firebaseApp);
const firebase = initializeApp(firebaseConfig);
const db = getFirestore(firebase);
const auth = getAuth();
export { db, auth, storage };
# src > App.vue
Ejecutamos dos funciones:
- obtenerDatos(), base de datos de firestore
- stores > products.ts
- forEach
- map > ids + items
- usePersistCart(), localStorage / almacenamiento local de la cesta
- composables > usePersistCart.ts
<script setup lang="ts">
import Nav from './components/Nav.vue';
import { usePersistCart } from './composables/usePersistCart';
import { useProductStore } from './stores/products';
const productStore = useProductStore();
productStore.obtenerDatos();
usePersistCart();
</script>
<template>
<Nav />
<router-view></router-view>
</template>
# src > composables > usePersistCart.ts
import { onUnmounted } from "vue";
import { useCartStore } from "../stores/cart";
export const CART_STORAGE = "CART_STORAGE";
export const usePersistCart = () => {
const cartStore = useCartStore();
const unsub = cartStore.$subscribe(() => {
localStorage.setItem(CART_STORAGE, JSON.stringify(cartStore.contents));
});
onUnmounted(() => {
unsub();
});
};
# src > router > index.ts
import { createRouter, createWebHistory } from "vue-router";
import Home from "../views/Home.vue";
import Product from "../views/Product.vue";
import Cart from "../views/Cart.vue";
import Formulario from "../views/Formulario.vue";
const routes = [
{ path: "/", component: Home },
{ path: "/product/:productId", component: Product },
{ path: "/cart", component: Cart },
{ path: "/formulario", component: Formulario },
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
# src > views > Home.vue
Importaciones
- Importamos computed de vue
- Importamos 2 componentes
- Importamos la store
- Ejecutamos la función list
- map > return products
Componentes
- Esqueleto
- Tarjetas de producto
- v-for de products
<script setup lang="ts">
import { computed } from 'vue';
import ProductCard from '../components/ProductCard.vue';
import ProductCardSkeleton from '../components/ProductCardSkeleton.vue';
import { useProductStore } from '../stores/products';
const productStore = useProductStore();
const products = computed(() => productStore.list);
</script>
<template>
<div class="p-4 max-w-7xl mx-auto">
<div class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
<ProductCardSkeleton
v-show="!productStore.loaded"
v-for="n in 15"
:key="n"
/>
<ProductCard
v-for="product in products"
:key="product.id"
:product="product"
/>
</div>
</div>
</template>
# src > components > ProductCard.vue
- Importamos las stores función add y tipo interface
- Una utilidad para el tipo/formato de moneda
- Props de product
- Ruta dinámica router-link
<script setup lang="ts">
import { useCartStore } from '../stores/cart';
import type { Product } from '../stores/products';
import { toCurrency } from '../shared/utils';
const cartStore = useCartStore();
defineProps<{
product: Product;
}>();
</script>
<template>
<div class="card bordered">
<figure class="px-8 pt-10">
<img
:src="product.image"
alt="Card Image"
class="object-contain w-full h-64"
/>
</figure>
<div class="card-body">
<h2 class="card-title">
<router-link class="link link-hover" :to="`/product/${product.id}`">{{
product.title
}}</router-link>
</h2>
<p>{{ toCurrency(product.price) }}</p>
<div class="justify-end card-actions">
<button class="btn btn-primary" @click="cartStore.add(product.id)">
Añadir al carrito
</button>
</div>
</div>
</div>
</template>
# src > shared > utils.ts
/ El objecto Intl.NumberFormat habilita el formato numérico
// de acuerdo al idioma
const formatter = new Intl.NumberFormat("es-ES", {
style: "currency",
currency: "EUR",
});
export const toCurrency = (value: number) => formatter.format(value);