# Pinia
# Stores
# store > products.ts
import { defineStore } from 'pinia';
import { collection, query, getDocs, orderBy } from "firebase/firestore";
import { db } from "../firebase";
export interface Product {
id: string;
title: string;
price: number;
description: string;
category: string;
image: string;
}
interface ProductState {
items: Record<string, Product>;
ids: string[];
productos: [];
total: number;
}
export const useProductStore = defineStore({
id: 'products',
state: (): ProductState => ({
items: {},
ids: [],
productos: [],
total: 0
}),
getters: {
list(): Product[] {
return this.ids.map((i) => this.items[i]);
},
loaded(): boolean {
return this.ids.length > 0;
},
},
actions: {
async obtenerDatos() {
const first = query(collection(db, "productos"), orderBy("title"));
this.productos = [];
const querySnapshot = await getDocs(first);
querySnapshot.forEach((doc) => {
let producto = doc.data();
producto.id = doc.id;
this.total = this.productos.push(producto);
console.log(this.total)
});
console.log("Este es el array productos", this.productos)
const data: Product[] = this.productos;
this.ids = data.map((product) => {
this.items[product.id] = product ;
return product.id;
});
console.log("Este es el array ids", this.ids)
console.log("Este es el objeto items", this.items)
},
},
});
# store > cart.ts
import { defineStore } from 'pinia';
import { CART_STORAGE } from '../composables/usePersistCart';
import { useProductStore } from './products';
// Tipos de datos
export interface Purchase {
productId: string;
quantity: number;
}
// Tipo de datos
interface CartState {
contents: Record<string, Purchase>;
}
// Tipo de datos
export interface CartPreview {
id: string;
image: string;
title: string;
quantity: number;
cost: number;
}
export const useCartStore = defineStore({
id: 'cart',
state: (): CartState => ({
contents: JSON.parse(localStorage.getItem(CART_STORAGE) as string) ?? {},
}),
getters: {
count(): number { // acumulado
return Object.keys(this.contents).reduce((acc, id) => {
return acc + this.contents[id].quantity;
}, 0);
},
total(): number {
const products = useProductStore();
return Object.keys(this.contents).reduce((acc, id) => {
return acc + products.items[id].price * this.contents[id].quantity;
}, 0);
},
formattedCart(): CartPreview[] {
const products = useProductStore();
if (!products.loaded) return [];
return Object.keys(this.contents).map((productId) => {
const purchase = this.contents[productId];
return {
id: purchase.productId,
image: products.items[purchase.productId].image,
title: products.items[purchase.productId].title,
quantity: purchase.quantity,
cost: purchase.quantity * products.items[purchase.productId].price,
};
});
},
},
actions: {
add(productId: string) {
if (this.contents[productId]) {
this.contents[productId].quantity += 1;
} else {
this.contents[productId] = {
productId,
quantity: 1,
};
}
},
remove(productId: string) {
if (!this.contents[productId]) {
return;
}
this.contents[productId].quantity -= 1;
if (this.contents[productId].quantity === 0) {
delete this.contents[productId];
}
},
},
});