diff --git a/NOTES.md b/NOTES.md new file mode 100644 index 0000000..8450ea7 --- /dev/null +++ b/NOTES.md @@ -0,0 +1,6 @@ +# Notes + +## Store examples + +https://moi-tvoi.ru/catalog/dekorativnye_igrushki/ +https://www.livemaster.ru/catalogue diff --git a/public/api/category-products-3.json b/public/api/category-products-3.json new file mode 100644 index 0000000..aac0646 --- /dev/null +++ b/public/api/category-products-3.json @@ -0,0 +1,30 @@ +[ + { + "id": 1, + "title": "toy 1", + "shortDesc": "Высота: 10см", + "images": ["toy.jpg"], + "price": 100 + }, + { + "id": 2, + "title": "toy 2", + "shortDesc": "Высота: 10см", + "images": ["toy.jpg"], + "price": 300 + }, + { + "id": 3, + "title": "toy 1", + "shortDesc": "Высота: 10см", + "images": ["toy.jpg"], + "price": 100 + }, + { + "id": 4, + "title": "toy 1", + "shortDesc": "Высота: 10см", + "images": ["toy.jpg"], + "price": 100 + } +] diff --git a/public/api/toy.jpg b/public/api/toy.jpg new file mode 100644 index 0000000..1661b19 Binary files /dev/null and b/public/api/toy.jpg differ diff --git a/src/app/assets/images/add-to-cart.svg b/src/app/assets/images/add-to-cart.svg new file mode 100644 index 0000000..e7c00b0 --- /dev/null +++ b/src/app/assets/images/add-to-cart.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/app/assets/images/favourite.svg b/src/app/assets/images/favourite.svg new file mode 100644 index 0000000..d0049fe --- /dev/null +++ b/src/app/assets/images/favourite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/assets/styles/vars.css b/src/app/assets/styles/vars.css index 62b7bae..949414b 100644 --- a/src/app/assets/styles/vars.css +++ b/src/app/assets/styles/vars.css @@ -2,7 +2,7 @@ * Typography * -------------------------------------------------------------------------- */ - @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap'); + @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap'); :root { --vwa-font-family-base: 'Roboto', sans-serif; diff --git a/src/app/components/headers/AppHeader.vue b/src/app/components/headers/AppHeader.vue index f75c409..693bffa 100644 --- a/src/app/components/headers/AppHeader.vue +++ b/src/app/components/headers/AppHeader.vue @@ -1,4 +1,6 @@ + + + + diff --git a/src/app/router/routes.ts b/src/app/router/routes.ts index 203488f..668a0a3 100644 --- a/src/app/router/routes.ts +++ b/src/app/router/routes.ts @@ -1,7 +1,7 @@ import type { RouteRecordRaw } from "vue-router"; import HomeView from "@/app/views/HomeView.vue"; import ProductCategoryView from "@/products/views/ProductCategoryView.vue"; -import ProductInfoView from "@/products/views/ProductInfoView.vue"; +import ProductView from "@/products/views/ProductView.vue"; import AboutView from "@/app/views/AboutView.vue"; import ContactsView from "@/app/views/ContactsView.vue"; @@ -14,7 +14,7 @@ const routes: RouteRecordRaw[] = [ { path: "/product/:productId", name: "product", - component: ProductInfoView, + component: ProductView, }, { path: "/category/:categoryId", diff --git a/src/app/services/api/index.ts b/src/app/services/api/index.ts index 6264d3a..0436e92 100644 --- a/src/app/services/api/index.ts +++ b/src/app/services/api/index.ts @@ -1,5 +1,6 @@ // import auth from "./auth"; import utils from "./utils"; +import products from "./products"; import { authInterceptor, notificationInterceptor } from "./interceptors"; import jsonrpc from "./jsonrpc"; import http from "./http"; @@ -10,6 +11,7 @@ import http from "./http"; const api = { utils, + products, http, init() { http.setOptions({ diff --git a/src/app/services/api/products.ts b/src/app/services/api/products.ts new file mode 100644 index 0000000..29f6c80 --- /dev/null +++ b/src/app/services/api/products.ts @@ -0,0 +1,11 @@ +import http from "./http"; + +const products = { + + async categoryProducts(categoryId) { + return http.get(`/arty-crafty/api/category-products-${categoryId}.json`); + }, + +}; + +export default products; diff --git a/src/products/components/ProductCard.vue b/src/products/components/ProductCard.vue new file mode 100644 index 0000000..18c898b --- /dev/null +++ b/src/products/components/ProductCard.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/src/products/composables/useFavourites.ts b/src/products/composables/useFavourites.ts new file mode 100644 index 0000000..62cd65a --- /dev/null +++ b/src/products/composables/useFavourites.ts @@ -0,0 +1,42 @@ +import { ref } from "vue"; + +const favArray = JSON.parse(localStorage.getItem("ac-favourites")) as number[] ?? []; +const favourites = ref>(new Set(favArray)); + +export function useFavourites() { + /** + * Determines if a product is in the favourites list. + * + * @param {number} productId - The ID of the product to check. + * @return {boolean} Returns true if the product is in the favourites list, otherwise false. + */ + function isInFavourites(productId: number): boolean { + return favourites.value.has(productId); + } + + /** + * Toggles the favourite status of a product. + * + * @param {number} productId - The ID of the product to toggle. + * @return {void} + */ + function toggleFavourite(productId: number) { + if (favourites.value.has(productId)) { + favourites.value.delete(productId); + } else { + favourites.value.add(productId); + } + localStorage.setItem("ac-favourites", JSON.stringify(listFavourites())); + } + + /** + * Returns a list of favorite products. + * + * @returns {Array} - The list of favorite product IDs. + */ + function listFavourites(): Array { + return Array.from(favourites.value); + } + + return { isInFavourites, toggleFavourite, listFavourites }; +} diff --git a/src/products/views/ProductCategoryView.vue b/src/products/views/ProductCategoryView.vue index 7491375..00e6161 100644 --- a/src/products/views/ProductCategoryView.vue +++ b/src/products/views/ProductCategoryView.vue @@ -1,9 +1,68 @@ - + - + + + diff --git a/src/products/views/ProductInfoView.vue b/src/products/views/ProductView.vue similarity index 100% rename from src/products/views/ProductInfoView.vue rename to src/products/views/ProductView.vue