Skip to content

Commit

Permalink
Merge pull request #1 from vuesence/products
Browse files Browse the repository at this point in the history
Products
  • Loading branch information
altrusl authored Jan 14, 2024
2 parents 3fedcb5 + 612188d commit 6d18e8b
Show file tree
Hide file tree
Showing 15 changed files with 365 additions and 30 deletions.
6 changes: 6 additions & 0 deletions NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Notes

## Store examples

https://moi-tvoi.ru/catalog/dekorativnye_igrushki/
https://www.livemaster.ru/catalogue
30 changes: 30 additions & 0 deletions public/api/category-products-3.json
Original file line number Diff line number Diff line change
@@ -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
}
]
Binary file added public/api/toy.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/app/assets/images/add-to-cart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/app/assets/images/favourite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/app/assets/styles/vars.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
73 changes: 49 additions & 24 deletions src/app/components/headers/AppHeader.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<script setup lang="ts">
import IconBadge from "@/app/components/ui/IconBadge.vue";
import { useFavourites } from "@/products/composables/useFavourites";
import AppSearchBar from "@/app/components/searchbar/AppSearchBar.vue";
import BaseIcon from "@/app/components/ui/BaseIcon.vue";
import HamburgerIcon from "@/app/components/ui/HamburgerIcon.vue";
import { useAppConfig } from "@/app/composables/useAppConfig";
// import ThemeToggle from "@/app/components/ui/ThemeToggle.vue";
const { isDrawerOpen } = useAppConfig();
const { listFavourites } = useFavourites();
const links = [
{ title: "Декорация", route: { name: "category", params: { categoryId: 3 } } },
Expand All @@ -15,7 +18,7 @@ const links = [
];
const topnavItems = [
{ title: "Избранное", icon: "favourites", route: { name: "favourites" } },
// { title: "Избранное", icon: "favourites", route: { name: "favourites" } },
{ title: "Корзина", icon: "cart", route: { name: "cart" } },
{ title: "Войти", icon: "account", route: { name: "login" } },
];
Expand All @@ -41,10 +44,21 @@ const topnavItems = [
<!-- <button class="">
<BaseIcon size="20" name="orders" class="icon" fill1="white" />
</button> -->
<RouterLink v-for="item in topnavItems" :key="item.title" class="link" :to="item.route">
<RouterLink class="link" :to="{ name: 'favourites' }">
<div class="item">
<BaseIcon size="20" :name="item.icon" class="icon" fill1="white" />
<span class="title">{{ item.title }}</span>
<div class="icon-wrapper">
<BaseIcon size="20" name="favourites" class="icon" />
<IconBadge :num="listFavourites().length" />
</div>
<span class="title">Избранное</span>
</div>
</RouterLink>
<RouterLink v-for="item in topnavItems" :key="item.title" class="link" :to="item.route">
<div class="item-wrapper">
<div class="item">
<BaseIcon size="20" :name="item.icon" class="icon" fill1="white" />
<span class="title">{{ item.title }}</span>
</div>
</div>
</RouterLink>
<HamburgerIcon v-model="isDrawerOpen" class="drawer-toggle" />
Expand All @@ -70,6 +84,7 @@ const topnavItems = [
background-color: var(--vwa-c-bg);
z-index: 3;
border-bottom: 1px solid var(--vwa-c-divider);
.main-header {
display: flex;
align-items: center;
Expand All @@ -82,6 +97,7 @@ const topnavItems = [
max-width: 200px;
display: flex;
align-items: center;
.notebook &,
.desktop & {
width: 15rem;
Expand All @@ -92,12 +108,14 @@ const topnavItems = [
font-size: 1.2rem;
font-weight: 700;
color: var(--vwa-c-text-1);
.mobile &,
.tablet & {
display: none;
}
}
}
.search-bar {
margin: 0 0 0 1rem;
}
Expand All @@ -106,30 +124,37 @@ const topnavItems = [
display: flex;
align-items: center;
.item {
border: 0;
// color: var(--vwa-c-text-2);
color: var(--vwa-c-border);
display: flex;
flex-direction: column;
align-items: center;
margin: 0 1rem;
transition: all 0.3s ease-in-out;
.title {
font-weight: 300;
font-size: 0.8rem;
.item {
border: 0;
// color: var(--vwa-c-text-2);
color: var(--vwa-c-border);
display: flex;
flex-direction: column;
align-items: center;
margin: 0 1rem;
transition: all 0.3s ease-in-out;
.title {
font-weight: 300;
font-size: 0.8rem;
}
&:hover {
color: var(--vwa-c-text-2);
}
.mobile &,
.tablet & {
display: none;
}
.icon-wrapper {
position: relative;
}
}
&:hover {
color: var(--vwa-c-text-2);
}
.mobile &,
.tablet & {
display: none;
}
}
.drawer-toggle {
margin: 0 1em;
.notebook &,
.desktop & {
display: none;
Expand Down
26 changes: 26 additions & 0 deletions src/app/components/ui/IconBadge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script setup>
defineProps({
num: {
type: Number,
default: 0,
},
});
</script>

<template>
<span v-if="num > 0" class="badge">{{ num }}</span>
</template>

<style lang="scss" scoped>
.badge {
position: absolute;
top: -5px;
right: -5px;
border-radius: 50%;
background-color: red;
font-size: 8px;
color: white;
line-height: 7px;
padding: 3px 5px;;
}
</style>
4 changes: 2 additions & 2 deletions src/app/router/routes.ts
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -14,7 +14,7 @@ const routes: RouteRecordRaw[] = [
{
path: "/product/:productId",
name: "product",
component: ProductInfoView,
component: ProductView,
},
{
path: "/category/:categoryId",
Expand Down
2 changes: 2 additions & 0 deletions src/app/services/api/index.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -10,6 +11,7 @@ import http from "./http";

const api = {
utils,
products,
http,
init() {
http.setOptions({
Expand Down
11 changes: 11 additions & 0 deletions src/app/services/api/products.ts
Original file line number Diff line number Diff line change
@@ -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;
124 changes: 124 additions & 0 deletions src/products/components/ProductCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<script setup lang="ts">
import { useRouter } from "vue-router";
import BaseIcon from "@/app/components/ui/BaseIcon.vue";
import { useFavourites } from "@/products/composables/useFavourites";
const props = defineProps({
product: {
type: Object,
default: () => { },
},
});
const router = useRouter();
const { toggleFavourite, listFavourites, isInFavourites } = useFavourites();
function gotoProduct() {
router.push({ name: "product", params: { productId: props.product.id } });
}
function addToCart() {
console.log("addToCart", props.product);
toggleFavourite(props.product.id);
}
</script>

<template>
<div class="product-card">
{{ listFavourites() }}
<div class="images">
<img :src="`/arty-crafty/api/${product.images[0]}`" :alt="product.title" @click="gotoProduct()">
<BaseIcon
size="50"
name="favourite"
class="favourite-icon"
:class="{ selected: isInFavourites(product.id) }"
:fill="isInFavourites(product.id) ? 'currentColor' : 'none'"
@click="toggleFavourite(props.product.id)"
/>
</div>
<div class="description">
<h2 class="title">
{{ product.title }}
</h2>
<div class="desc">
{{ product.desc }}
</div>
<div class="price-wrapper" @click="addToCart()">
<div class="price">
{{ product.price }} <span class="currency-symbol">₽</span>
</div>
<!-- <button class="add-to-cart-button" type="button" title="Add to cart">
<BaseIcon size="20" name="add-to-cart" class="icon" fill1="white" />
</button> -->
</div>
</div>
</div>
</template>

<style lang="scss" scoped>
.product-card {
border: 1px solid var(--vwa-c-divider);
border-radius: 3px;
cursor: pointer;
width: 15rem;
.mobile & {
width: 100%;
}
.images {
position: relative;
img {
max-width: 100%;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
}
.favourite-icon {
position: absolute;
top: 0;
right: 0;
padding: 10px;
margin: 1rem;
transition: all 0.1s ease-in-out;
color: red !important;
// &.selected {
// color: red !important;
// }
}
}
.description {
padding: 0.4rem;
.title {
margin: 0.5rem 0;
}
.desc {
margin: 0.5rem 0;
}
.price-wrapper {
display: flex;
justify-content: space-between;
align-items: flex-end;
.price {
font-weight: 500;
font-size: 1.2rem;
.currency-symbol {
color: #999;
}
}
.add-to-cart-button {
padding: 10px;
cursor: pointer;
border: 1px solid transparent;
background-color: rgb(254, 114, 0);
color: rgb(255, 255, 255);
height: auto;
border-radius: 50%;
}
}
}
}
</style>
Loading

0 comments on commit 6d18e8b

Please sign in to comment.