feat: store home page and product page
This commit is contained in:
parent
7a38f41350
commit
eb0e596d43
@ -13,7 +13,8 @@
|
||||
"public/js/shopping_cart.js"
|
||||
],
|
||||
"css/erpnext-web.css": [
|
||||
"public/scss/website.scss"
|
||||
"public/scss/website.scss",
|
||||
"public/scss/shopping_cart.scss"
|
||||
],
|
||||
"js/marketplace.min.js": [
|
||||
"public/js/hub/marketplace.js"
|
||||
|
206
erpnext/public/scss/shopping_cart.scss
Normal file
206
erpnext/public/scss/shopping_cart.scss
Normal file
@ -0,0 +1,206 @@
|
||||
@import "frappe/public/scss/desk/variables";
|
||||
@import "frappe/public/scss/mixins";
|
||||
|
||||
.carousel-control {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: white;
|
||||
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.08), 0px 1px 2px 1px rgba(0, 0, 0, 0.06);
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
.carousel-control-prev,
|
||||
.carousel-control-next {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.carousel-body {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.carousel-content {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-gap: 15px;
|
||||
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));;
|
||||
}
|
||||
|
||||
.product-category-section {
|
||||
.card:hover {
|
||||
box-shadow: 0px 16px 45px 6px rgba(0, 0, 0, 0.08), 0px 8px 10px -10px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
}
|
||||
|
||||
.item-card-group-section {
|
||||
.card {
|
||||
height: 360px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
// .card-body {
|
||||
// text-align: center;
|
||||
// }
|
||||
|
||||
// .featured-item {
|
||||
// .card-body {
|
||||
// text-align: left;
|
||||
// }
|
||||
// }
|
||||
|
||||
.card-img {
|
||||
max-height: 210px;
|
||||
object-fit: contain;
|
||||
margin-top: 1.25rem;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-size: 14px;
|
||||
color: var(--gray-800);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.product-description {
|
||||
font-size: 12px;
|
||||
color: var(--text-color);
|
||||
margin: 20px 0;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 6;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.product-category {
|
||||
font-size: 13px;
|
||||
color: var(--gray-600);
|
||||
margin: var(--margin-sm) 0;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-color);
|
||||
margin: var(--margin-sm) 0;
|
||||
}
|
||||
|
||||
.item-card {
|
||||
padding: var(--padding-sm);
|
||||
}
|
||||
}
|
||||
|
||||
#page-all-products {
|
||||
.page-header {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.filters-section {
|
||||
.title-section {
|
||||
border-bottom: 1px solid var(--table-border-color);
|
||||
}
|
||||
|
||||
.filter-title {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.clear-filters {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: var(--gray-700);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.filter-block {
|
||||
border-bottom: 1px solid var(--table-border-color);
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
.label-area {
|
||||
font-size: 13px;
|
||||
color: var(--gray-800);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.product-page {
|
||||
@include card($padding: var(--padding-md));
|
||||
min-height: 70vh;
|
||||
|
||||
.product-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.product-code {
|
||||
color: var(--gray-600);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.product-description {
|
||||
font-size: 13px;
|
||||
color: var(--gray-800);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.product-image {
|
||||
border-color: var(--table-border-color) !important;
|
||||
img {
|
||||
min-height: 320px;
|
||||
max-height: 30rem;
|
||||
min-width: 320px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-slideshow-image {
|
||||
height: 4rem;
|
||||
width: 4rem;
|
||||
object-fit: contain;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid var(--table-border-color);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover, &.active {
|
||||
border-color: $primary;
|
||||
}
|
||||
}
|
||||
|
||||
.item-cart {
|
||||
.product-price {
|
||||
font-size: 20px;
|
||||
color: var(--text-color);
|
||||
font-weight: 600;
|
||||
|
||||
.formatted-price {
|
||||
color: var(--gray-600);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.no-stock {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,10 @@
|
||||
@import "frappe/public/scss/website/variables";
|
||||
|
||||
.product-image img {
|
||||
min-height: 20rem;
|
||||
max-height: 30rem;
|
||||
}
|
||||
|
||||
.filter-options {
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.item-slideshow-image {
|
||||
height: 3rem;
|
||||
width: 3rem;
|
||||
object-fit: contain;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover, &.active {
|
||||
border-color: $primary;
|
||||
}
|
||||
}
|
||||
|
||||
.address-card {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
@ -43,10 +24,10 @@
|
||||
|
||||
.check {
|
||||
display: inline-flex;
|
||||
padding: 0.25rem;
|
||||
background: $primary;
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
padding: 0.25rem;
|
||||
background: $primary;
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
font-size: 12px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
@ -46,11 +46,11 @@
|
||||
{%- set primary_action_label = values['slide_' + index + '_primary_action_label'] -%}
|
||||
{%- set align = values['slide_' + index + '_content_align'] -%}
|
||||
{%- set theme = values['slide_' + index + '_theme'] -%}
|
||||
|
||||
|
||||
{%- if image -%}
|
||||
{{ slide(image, title, subtitle, primary_action, primary_action_label, index, align, theme) }}
|
||||
{%- endif -%}
|
||||
|
||||
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
{%- if show_controls -%}
|
||||
@ -82,31 +82,4 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.carousel-control {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: white;
|
||||
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.08), 0px 1px 2px 1px rgba(0, 0, 0, 0.06);
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
.carousel-control-prev,
|
||||
.carousel-control-next {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.carousel-body {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.carousel-content {
|
||||
max-width: 400px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,38 @@
|
||||
{% from "erpnext/templates/includes/macros.html" import item_card, item_card_body %}
|
||||
|
||||
<div class="section-with-cards item-card-group-section">
|
||||
<div class="item-group-header d-flex justify-content-between">
|
||||
<div class="title-section">
|
||||
{%- if title -%}
|
||||
<h2 class="section-title">{{ title }}</h2>
|
||||
{%- endif -%}
|
||||
{%- if subtitle -%}
|
||||
<p class="section-description">{{ subtitle }}</p>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
<div class="primary-action-section">
|
||||
{%- if primary_action -%}
|
||||
<a href="{{ action }}" class="btn btn-primary pull-right">
|
||||
{{ primary_action_label }}
|
||||
</a>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
{%- for index in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'] -%}
|
||||
{%- set item = values['card_' + index + '_item'] -%}
|
||||
{%- if item -%}
|
||||
{%- set item = frappe.get_doc("Item", item) -%}
|
||||
{{ item_card(
|
||||
item.item_name, item.image, item.route, item.description,
|
||||
item.standard_rate, item.item_group, values['card_' + index + '_featured'],
|
||||
True, "Center"
|
||||
) }}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -16,6 +16,21 @@
|
||||
"label": "Subtitle",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__unsaved": 1,
|
||||
"fieldname": "primary_action_label",
|
||||
"fieldtype": "Data",
|
||||
"label": "Primary Action Label",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "primary_action",
|
||||
"fieldtype": "Data",
|
||||
"label": "Primary Action",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "card_1",
|
||||
"fieldtype": "Section Break",
|
||||
@ -36,264 +51,210 @@
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_2",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 2",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_2_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_2_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_3",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 3",
|
||||
"options": "",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_3_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_3_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_4",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 4",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_4_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_4_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_5",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 5",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_5_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_5_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_6",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 6",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_6_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_6_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_7",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 7",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_7_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_7_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_8",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 8",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_8_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_8_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_9",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 9",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_9_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_9_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_10",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 10",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_10_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_10_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_11",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 11",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_11_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_11_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_12",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Card 12",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_12_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"options": "Item",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"__islocal": 1,
|
||||
"__unsaved": 1,
|
||||
"fieldname": "card_12_featured",
|
||||
"fieldtype": "Check",
|
||||
"label": "Featured",
|
||||
@ -301,7 +262,7 @@
|
||||
}
|
||||
],
|
||||
"idx": 0,
|
||||
"modified": "2020-11-17 16:37:46.325181",
|
||||
"modified": "2020-11-19 18:48:52.633045",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Shopping Cart",
|
||||
"name": "Item Card Group",
|
||||
|
@ -15,7 +15,7 @@
|
||||
</div>
|
||||
{%- endmacro -%}
|
||||
|
||||
<div class="section-with-cards">
|
||||
<div class="section-with-cards product-category-section">
|
||||
{%- if title -%}
|
||||
<h2 class="section-title">{{ title }}</h2>
|
||||
{%- endif -%}
|
||||
@ -37,17 +37,4 @@
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-gap: 15px;
|
||||
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0px 16px 45px 6px rgba(0, 0, 0, 0.08), 0px 8px 10px -10px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
</style>
|
||||
|
@ -7,17 +7,19 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block page_content %}
|
||||
{% from "erpnext/templates/includes/macros.html" import product_image %}
|
||||
<div class="item-content">
|
||||
<div class="product-page-content" itemscope itemtype="http://schema.org/Product">
|
||||
<div class="row mb-5">
|
||||
{% include "templates/generators/item/item_image.html" %}
|
||||
{% include "templates/generators/item/item_details.html" %}
|
||||
<div class="product-page">
|
||||
{% from "erpnext/templates/includes/macros.html" import product_image %}
|
||||
<div class="item-content">
|
||||
<div class="product-page-content" itemscope itemtype="http://schema.org/Product">
|
||||
<div class="row mb-5">
|
||||
{% include "templates/generators/item/item_image.html" %}
|
||||
{% include "templates/generators/item/item_details.html" %}
|
||||
</div>
|
||||
|
||||
{% include "templates/generators/item/item_specifications.html" %}
|
||||
|
||||
{{ doc.website_content or '' }}
|
||||
</div>
|
||||
|
||||
{% include "templates/generators/item/item_specifications.html" %}
|
||||
|
||||
{{ doc.website_content or '' }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -6,10 +6,10 @@
|
||||
<div class="item-cart row mt-2" data-variant-item-code="{{ item_code }}">
|
||||
<div class="col-md-12">
|
||||
{% if cart_settings.show_price and product_info.price %}
|
||||
<h4>
|
||||
<div class="product-price">
|
||||
{{ product_info.price.formatted_price_sales_uom }}
|
||||
<small class="text-muted">({{ product_info.price.formatted_price }} / {{ product_info.uom }})</small>
|
||||
</h4>
|
||||
<small class="formatted-price">({{ product_info.price.formatted_price }} / {{ product_info.uom }})</small>
|
||||
</div>
|
||||
{% else %}
|
||||
{{ _("Unit of Measurement") }} : {{ product_info.uom }}
|
||||
{% endif %}
|
||||
@ -17,11 +17,11 @@
|
||||
{% if cart_settings.show_stock_availability %}
|
||||
<div>
|
||||
{% if product_info.in_stock == 0 %}
|
||||
<span class="text-danger">
|
||||
<span class="text-danger no-stock">
|
||||
{{ _('Not in stock') }}
|
||||
</span>
|
||||
{% elif product_info.in_stock == 1 %}
|
||||
<span class="text-success">
|
||||
<span class="text-success has-stock">
|
||||
{{ _('In stock') }}
|
||||
{% if product_info.show_stock_qty and product_info.stock_qty %}
|
||||
({{ product_info.stock_qty[0][0] }})
|
||||
|
@ -1,14 +1,21 @@
|
||||
<div class="col-md-8">
|
||||
<!-- title -->
|
||||
<h1 itemprop="name">
|
||||
<div class="product-title" itemprop="name">
|
||||
{{ item_name }}
|
||||
</h1>
|
||||
<p class="text-muted">
|
||||
</div>
|
||||
<p class="product-code">
|
||||
<span>{{ _("Item Code") }}:</span>
|
||||
<span itemprop="productID">{{ doc.name }}</span>
|
||||
</p>
|
||||
{% if has_variants %}
|
||||
<!-- configure template -->
|
||||
{% include "templates/generators/item/item_configure.html" %}
|
||||
{% else %}
|
||||
<!-- add variant to cart -->
|
||||
{% include "templates/generators/item/item_add_to_cart.html" %}
|
||||
{% endif %}
|
||||
<!-- description -->
|
||||
<div itemprop="description">
|
||||
<div class="product-description" itemprop="description">
|
||||
{% if frappe.utils.strip_html(doc.web_long_description or '') %}
|
||||
{{ doc.web_long_description | safe }}
|
||||
{% elif frappe.utils.strip_html(doc.description or '') %}
|
||||
@ -17,12 +24,4 @@
|
||||
{{ _("No description given") }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if has_variants %}
|
||||
<!-- configure template -->
|
||||
{% include "templates/generators/item/item_configure.html" %}
|
||||
{% else %}
|
||||
<!-- add variant to cart -->
|
||||
{% include "templates/generators/item/item_add_to_cart.html" %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -1,42 +1,42 @@
|
||||
<div class="col-md-4 h-100">
|
||||
{% if slides %}
|
||||
{{ product_image(slides[0].image, 'product-image') }}
|
||||
<div class="item-slideshow">
|
||||
{% for item in slides %}
|
||||
<img class="item-slideshow-image mt-2 {% if loop.first %}active{% endif %}"
|
||||
src="{{ item.image }}" alt="{{ item.heading }}">
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- Simple image slideshow -->
|
||||
<script>
|
||||
frappe.ready(() => {
|
||||
$('.page_content').on('click', '.item-slideshow-image', (e) => {
|
||||
const $img = $(e.currentTarget);
|
||||
const link = $img.prop('src');
|
||||
const $product_image = $('.product-image');
|
||||
$product_image.find('a').prop('href', link);
|
||||
$product_image.find('img').prop('src', link);
|
||||
<div class="col-md-4 h-100 d-flex">
|
||||
{% if slides %}
|
||||
<div class="item-slideshow d-flex flex-column mr-3">
|
||||
{% for item in slides %}
|
||||
<img class="item-slideshow-image mb-2 {% if loop.first %}active{% endif %}"
|
||||
src="{{ item.image }}" alt="{{ item.heading }}">
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ product_image(slides[0].image, 'product-image') }}
|
||||
<!-- Simple image slideshow -->
|
||||
<script>
|
||||
frappe.ready(() => {
|
||||
$('.page_content').on('click', '.item-slideshow-image', (e) => {
|
||||
const $img = $(e.currentTarget);
|
||||
const link = $img.prop('src');
|
||||
const $product_image = $('.product-image');
|
||||
$product_image.find('a').prop('href', link);
|
||||
$product_image.find('img').prop('src', link);
|
||||
|
||||
$('.item-slideshow-image').removeClass('active');
|
||||
$img.addClass('active');
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% else %}
|
||||
{{ product_image(website_image or image or 'no-image.jpg', alt=website_image_alt or item_name) }}
|
||||
{% endif %}
|
||||
$('.item-slideshow-image').removeClass('active');
|
||||
$img.addClass('active');
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% else %}
|
||||
{{ product_image(website_image or image or 'no-image.jpg', alt=website_image_alt or item_name) }}
|
||||
{% endif %}
|
||||
|
||||
<!-- Simple image preview -->
|
||||
<!-- Simple image preview -->
|
||||
|
||||
<div class="image-zoom-view" style="display: none;">
|
||||
<button type="button" class="close" aria-label="Close">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x">
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="image-zoom-view" style="display: none;">
|
||||
<button type="button" class="close" aria-label="Close">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x">
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.website-image {
|
||||
|
@ -8,9 +8,9 @@
|
||||
{% endmacro %}
|
||||
|
||||
{% macro product_image(website_image, css_class="", alt="") %}
|
||||
<div class="border text-center rounded h-100 {{ css_class }}" style="overflow: hidden;">
|
||||
<div class="border text-center rounded h-100 {{ css_class }}" style="overflow: hidden;">
|
||||
<img itemprop="image" class="website-image h-100 w-100" alt="{{ alt }}" src="{{ frappe.utils.quoted(website_image or 'no-image.jpg') | abs_url }}">
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro media_image(website_image, name, css_class="") %}
|
||||
@ -18,13 +18,13 @@
|
||||
{% if not website_image -%}
|
||||
<div class="sidebar-standard-image"> <div class="standard-image" style="background-color: rgb(250, 251, 252);">{{name}}</div> </div>
|
||||
{%- endif %}
|
||||
{% if website_image -%}
|
||||
{% if website_image -%}
|
||||
<a href="{{ frappe.utils.quoted(website_image) }}">
|
||||
<img itemprop="image" src="{{ frappe.utils.quoted(website_image) | abs_url }}"
|
||||
class="img-responsive img-thumbnail sidebar-image" style="min-height:100%; min-width:100%;">
|
||||
</a>
|
||||
{%- endif %}
|
||||
</div>
|
||||
{%- endif %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_homepage_section(section) %}
|
||||
@ -57,4 +57,61 @@
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% endmacro %}
|
||||
{% endmacro %}
|
||||
|
||||
{%- macro item_card(title, image, url, description, rate, category, is_featured=False, is_full_width=False, align="Left") -%}
|
||||
{%- set align_items_class = resolve_class({
|
||||
'align-items-end': align == 'Right',
|
||||
'align-items-center': align == 'Center',
|
||||
'align-items-start': align == 'Left',
|
||||
}) -%}
|
||||
{%- set col_size = 3 if is_full_width else 4 -%}
|
||||
{% if is_featured %}
|
||||
<div class="col-sm-{{ col_size*2 }} item-card">
|
||||
<div class="card featured-item {{ align_items_class }}">
|
||||
{% if image %}
|
||||
<div class="row no-gutters">
|
||||
<div class="col-md-6">
|
||||
<img class="card-img" src="{{ image }}" alt="{{ title }}">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{{ item_card_body(title, description, url, rate, category, is_featured, align) }}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-md-12">
|
||||
{{ item_card_body(title, description, url, rate, category, is_featured, align) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-sm-{{ col_size }} item-card">
|
||||
<div class="card {{ align_items_class }}">
|
||||
{% if image %}
|
||||
<img class="card-img" src="{{ image }}" alt="{{ title }}">
|
||||
{% endif %}
|
||||
{{ item_card_body(title, description, url, rate, category, is_featured, align) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro item_card_body(title, description, url, rate, category, is_featured, align) -%}
|
||||
{%- set align_class = resolve_class({
|
||||
'text-right': align == 'Right',
|
||||
'text-center': align == 'Center' and not is_featured,
|
||||
'text-left': align == 'Left' or is_featured,
|
||||
}) -%}
|
||||
<div class="card-body {{ align_class }}">
|
||||
<div class="product-title">{{ title or '' }}</div>
|
||||
{% if is_featured %}
|
||||
<div class="product-price">{{ rate or '' }}</div>
|
||||
<div class="product-description ellipsis">{{ description or '' }}</div>
|
||||
{% else %}
|
||||
<div class="product-category">{{ category or '' }}</div>
|
||||
<div class="product-price">{{ rate or '' }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<a href="{{ url or '#' }}" class="stretched-link"></a>
|
||||
{%- endmacro -%}
|
@ -1,4 +1,4 @@
|
||||
{% from "erpnext/templates/includes/macros.html" import product_image_square %}
|
||||
{% from "erpnext/templates/includes/macros.html" import item_card, item_card_body %}
|
||||
|
||||
<a class="product-link product-list-link" href="{{ route|abs_url }}">
|
||||
<div class='row'>
|
||||
|
@ -1,12 +1,11 @@
|
||||
{% extends "templates/web.html" %}
|
||||
|
||||
{% block title %}{{ _('Products') }}{% endblock %}
|
||||
{% block header %}
|
||||
<h1>{{ _('Products') }}</h1>
|
||||
<div class="mb-6">{{ _('Products') }}</div>
|
||||
{% endblock header %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="row">
|
||||
<div class="row" style="display: none;">
|
||||
<div class="col-8">
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<input type="search" class="form-control" placeholder="{{_('Search')}}"
|
||||
@ -31,27 +30,34 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 order-2 col-md-8 order-md-1 products-list">
|
||||
{% if items %}
|
||||
{% for item in items %}
|
||||
{% include "erpnext/www/all-products/item_row.html" %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% include "erpnext/www/all-products/not_found.html" %}
|
||||
{% endif %}
|
||||
<div class="col-12 order-2 col-md-9 order-md-2 item-card-group-section">
|
||||
<div class="row">
|
||||
{% if items %}
|
||||
{% for item in items %}
|
||||
{% include "erpnext/www/all-products/item_row.html" %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% include "erpnext/www/all-products/not_found.html" %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 order-1 col-md-4 order-md-2">
|
||||
<div class="col-12 order-1 col-md-3 order-md-1">
|
||||
|
||||
{% if frappe.form_dict.start or frappe.form_dict.field_filters or frappe.form_dict.attribute_filters or frappe.form_dict.search %}
|
||||
<a class="mb-3 d-inline-block" href="/all-products">{{ _('Clear filters') }}</a>
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
<div class="collapse d-md-block" id="product-filters">
|
||||
<div class="collapse d-md-block mr-4 filters-section" id="product-filters">
|
||||
<div class="d-flex justify-content-between align-items-center mb-5 title-section">
|
||||
<div class="mb-4 filters-title" > {{ _('Filters') }} </div>
|
||||
<a class="mb-4 clear-filters" href="/all-products">{{ _('Clear All') }}</a>
|
||||
</div>
|
||||
{% for field_filter in field_filters %}
|
||||
{%- set item_field = field_filter[0] %}
|
||||
{%- set values = field_filter[1] %}
|
||||
<div class="mb-4">
|
||||
<h6>{{ item_field.label }}</h6>
|
||||
<div class="mb-4 filter-block pb-5">
|
||||
<div class="filter-label mb-3">{{ item_field.label }}</div>
|
||||
|
||||
{% if values | len > 20 %}
|
||||
<!-- show inline filter if values more than 20 -->
|
||||
@ -61,15 +67,15 @@
|
||||
{% if values %}
|
||||
<div class="filter-options">
|
||||
{% for value in values %}
|
||||
<div class="custom-control custom-checkbox" data-value="{{ value }}">
|
||||
<input type="checkbox"
|
||||
class="product-filter field-filter custom-control-input"
|
||||
id="{{value}}"
|
||||
data-filter-name="{{ item_field.fieldname }}"
|
||||
data-filter-value="{{ value }}"
|
||||
>
|
||||
<label class="custom-control-label" for="{{value}}">
|
||||
{{ value }}
|
||||
<div class="checkbox" data-value="{{ value }}">
|
||||
<label for="{{value}}">
|
||||
<input type="checkbox"
|
||||
class="product-filter field-filter"
|
||||
id="{{value}}"
|
||||
data-filter-name="{{ item_field.fieldname }}"
|
||||
data-filter-value="{{ value }}"
|
||||
>
|
||||
<span class="label-area">{{ value }}</span>
|
||||
</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
@ -81,9 +87,8 @@
|
||||
{% endfor %}
|
||||
|
||||
{% for attribute in attribute_filters %}
|
||||
<div class="mb-4">
|
||||
<h6>{{ attribute.name }}</h6>
|
||||
|
||||
<div class="mb-4 filter-block pb-5">
|
||||
<div class="filter-label mb-3">{{ attribute.name}}</div>
|
||||
{% if values | len > 20 %}
|
||||
<!-- show inline filter if values more than 20 -->
|
||||
<input type="text" class="form-control form-control-sm mb-2 product-filter-filter"/>
|
||||
@ -92,16 +97,15 @@
|
||||
{% if attribute.item_attribute_values %}
|
||||
<div class="filter-options">
|
||||
{% for attr_value in attribute.item_attribute_values %}
|
||||
<div class="custom-control custom-checkbox" data-value="{{ value }}">
|
||||
<input type="checkbox"
|
||||
class="product-filter attribute-filter custom-control-input"
|
||||
id="{{attr_value.name}}"
|
||||
data-attribute-name="{{ attribute.name }}"
|
||||
data-attribute-value="{{ attr_value.attribute_value }}"
|
||||
{% if attr_value.checked %} checked {% endif %}
|
||||
>
|
||||
<label class="custom-control-label" for="{{attr_value.name}}">
|
||||
{{ attr_value.attribute_value }}
|
||||
<div class="checkbox">
|
||||
<label data-value="{{ value }}">
|
||||
<input type="checkbox"
|
||||
class="product-filter attribute-filter"
|
||||
id="{{attr_value.name}}"
|
||||
data-attribute-name="{{ attribute.name }}"
|
||||
data-attribute-value="{{ attr_value.attribute_value }}"
|
||||
{% if attr_value.checked %} checked {% endif %}>
|
||||
<span class="label-area">{{ attr_value.attribute_value }}</span>
|
||||
</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
@ -158,6 +162,4 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% endblock %}
|
@ -1,24 +1,7 @@
|
||||
<div class="card mb-3">
|
||||
<div class="row no-gutters">
|
||||
<div class="col-md-3">
|
||||
<div class="card-body">
|
||||
<a class="no-underline" href="/{{ item.route }}">
|
||||
<img class="website-image" src="{{ item.website_image or item.image or 'no-image.jpg' }}" alt="{{ item.item_name }}">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<a class="text-dark" href="/{{ item.route }}">
|
||||
{{ item.item_name or item.name }}
|
||||
</a>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
{{ item.website_description or item.description or '<i class="text-muted">No description</i>' }}
|
||||
</p>
|
||||
<a href="/{{ item.route }}" class="btn btn-sm btn-light">{{ _('More details') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% from "erpnext/templates/includes/macros.html" import item_card, item_card_body %}
|
||||
|
||||
{{ item_card(
|
||||
item.item_name or item.name, item.website_image or item.image, item.route, item.website_description or item.description,
|
||||
item.standard_rate, item.item_group
|
||||
) }}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user