Compare commits
2 Commits
fe5f0736f2
...
85b18161fd
| Author | SHA1 | Date | |
|---|---|---|---|
| 85b18161fd | |||
| 09c14785e7 |
@@ -34,7 +34,7 @@ function idmObserveEachOncePM(elements, callback, options = {}) {
|
||||
{
|
||||
threshold: 0.1,
|
||||
...options,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
elements.forEach((el) => observer.observe(el));
|
||||
@@ -45,7 +45,7 @@ idmObserveEachOncePM(
|
||||
document.querySelectorAll(".idm_picture__module"),
|
||||
(entry) => {
|
||||
idmPictureModuleProductsPM(entry.target);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// GRAPHQL QUERY
|
||||
@@ -144,6 +144,7 @@ function idmGetSingleProdGraphQLPM({
|
||||
name
|
||||
link
|
||||
type
|
||||
icon
|
||||
${labels ? "zones" : ""}
|
||||
${
|
||||
opinions
|
||||
@@ -239,7 +240,7 @@ async function idmHandleAddToBasketPM(e) {
|
||||
Alertek.Error(
|
||||
idmPhotoModuleLiteralsPM[
|
||||
"Coś poszło nie tak podczas dodawania do koszyka. Spróbuj ponownie lub odśwież stronę"
|
||||
]
|
||||
],
|
||||
);
|
||||
buttonEl.innerHTML = `<span>${buttonEl.dataset.error}</span>`;
|
||||
buttonEl.classList.add("--error");
|
||||
@@ -267,20 +268,10 @@ function idmMarkupAddToBasketPM(prodData) {
|
||||
|
||||
return `<form class="add_to_basket" action="/basketchange.php" type="post">
|
||||
<input class="product__add_mode" type="hidden" value="1" name="mode">
|
||||
<input class="product__add_id" type="hidden" value="${
|
||||
prodData.id
|
||||
}" name="mode">
|
||||
<input class="product__add_size" type="hidden" value="${
|
||||
prodData.sizes?.[0]?.id || "uniw"
|
||||
}" name="mode">
|
||||
<input class="product__add_number" type="hidden" value="${
|
||||
prodData.unit?.sellBy || 1
|
||||
}" name="mode">
|
||||
<button class="btn --solid --medium add_to_basket__button" tabindex="0" data-success="${
|
||||
idmPhotoModuleLiteralsPM["Dodany"]
|
||||
}" data-error="${idmPhotoModuleLiteralsPM["Wystąpił błąd"]}" data-text="${
|
||||
idmPhotoModuleLiteralsPM["Do koszyka"]
|
||||
}">
|
||||
<input class="product__add_id" type="hidden" value="${prodData.id}" name="mode">
|
||||
<input class="product__add_size" type="hidden" value="${prodData.sizes?.[0]?.id || "uniw"}" name="mode">
|
||||
<input class="product__add_number" type="hidden" value="${prodData.unit?.sellBy || 1}" name="mode">
|
||||
<button class="btn --solid --medium add_to_basket__button" tabindex="0" data-success="${idmPhotoModuleLiteralsPM["Dodany"]}" data-error="${idmPhotoModuleLiteralsPM["Wystąpił błąd"]}" data-text="${idmPhotoModuleLiteralsPM["Do koszyka"]}">
|
||||
<span>${idmPhotoModuleLiteralsPM["Do koszyka"]}</span>
|
||||
</button>
|
||||
</form>`;
|
||||
@@ -291,9 +282,7 @@ function idmMarkupPricePM({ prodData, addToBasket }) {
|
||||
|
||||
let priceMarkup;
|
||||
if (!addToBasket)
|
||||
priceMarkup = `<div class="product_prices"><span class="price --normal --main">${
|
||||
prodData.price?.price?.[app_shop.vars.priceType]?.formatted
|
||||
}</span></div>`;
|
||||
priceMarkup = `<div class="product_prices"><span class="price --normal --main">${prodData.price?.price?.[app_shop.vars.priceType]?.formatted}</span></div>`;
|
||||
else {
|
||||
const currentSize = prodData?.sizes?.[0] || prodData;
|
||||
|
||||
@@ -313,9 +302,7 @@ function idmMarkupPricePM({ prodData, addToBasket }) {
|
||||
const maxPercent = currentSize?.price?.youSavePercent;
|
||||
|
||||
priceMarkup = `
|
||||
<div class="product_prices ${omnibusPrice ? `--omnibus` : ""} ${
|
||||
isOmnibusHigher ? `--omnibus-higher` : ""
|
||||
} ${omnibusPrice === maxPrice ? "--omnibus-short" : ""}">
|
||||
<div class="product_prices ${omnibusPrice ? `--omnibus` : ""} ${isOmnibusHigher ? `--omnibus-higher` : ""} ${omnibusPrice === maxPrice ? "--omnibus-short" : ""}">
|
||||
<span class="price --normal --main">${price}</span>
|
||||
${
|
||||
omnibusPrice && typeof omnibusPercent === "number"
|
||||
@@ -382,7 +369,7 @@ async function idmPictureModuleProductsPM(containerEL) {
|
||||
opinions: isOpinions,
|
||||
addToBasket: isAddToBasket,
|
||||
})}`,
|
||||
""
|
||||
"",
|
||||
)}}`,
|
||||
}),
|
||||
});
|
||||
@@ -420,41 +407,32 @@ async function idmPictureModuleProductsPM(containerEL) {
|
||||
|
||||
// OPINIE
|
||||
let opinionsHTML = "";
|
||||
if (isOpinions) {
|
||||
if (
|
||||
isOpinions &&
|
||||
typeof prodData.opinion?.rating === "number" &&
|
||||
typeof prodData.opinion?.count === "number"
|
||||
) {
|
||||
opinionsHTML = `
|
||||
<div class="product_opinions__stars">
|
||||
<i class="icon-star ${
|
||||
prodData.opinion?.rating > 0.5 ? "--active" : ""
|
||||
}"></i>
|
||||
<i class="icon-star ${
|
||||
prodData.opinion?.rating > 1.5 ? "--active" : ""
|
||||
}"></i>
|
||||
<i class="icon-star ${
|
||||
prodData.opinion?.rating > 2.5 ? "--active" : ""
|
||||
}"></i>
|
||||
<i class="icon-star ${
|
||||
prodData.opinion?.rating > 3.5 ? "--active" : ""
|
||||
}"></i>
|
||||
<i class="icon-star ${
|
||||
prodData.opinion?.rating > 4.5 ? "--active" : ""
|
||||
}"></i>
|
||||
<i class="icon-star ${prodData.opinion.rating > 0.5 ? "--active" : ""}"></i>
|
||||
<i class="icon-star ${prodData.opinion.rating > 1.5 ? "--active" : ""}"></i>
|
||||
<i class="icon-star ${prodData.opinion.rating > 2.5 ? "--active" : ""}"></i>
|
||||
<i class="icon-star ${prodData.opinion.rating > 3.5 ? "--active" : ""}"></i>
|
||||
<i class="icon-star ${prodData.opinion.rating > 4.5 ? "--active" : ""}"></i>
|
||||
</div>
|
||||
<span class="product_opinions__score">${
|
||||
prodData.opinion.rating
|
||||
} / 5.00 </span>
|
||||
<span class="product_opinions__score">${prodData.opinion.rating} / 5.00 </span>
|
||||
<span class="product_opinions__count">${prodData.opinion.count}</span>
|
||||
`;
|
||||
}
|
||||
prodEl.innerHTML = `
|
||||
<a href="${prodData.link}" class="product_icon --mobile"><img src="${prodData.icon}" alt="${prodData.name}" tabindex="-1"/></a>
|
||||
<div class="product_info__container">
|
||||
${isLabels ? `<strong class="label_icons">${labelsHTML}</strong>` : ""}
|
||||
${
|
||||
isOpinions
|
||||
? `<div class="product_opinions">${opinionsHTML}</div>`
|
||||
: ""
|
||||
}
|
||||
${isOpinions ? `<div class="product_opinions">${opinionsHTML}</div>` : ""}
|
||||
<a class="product_name" href="${prodData.link}">${prodData.name}</a>
|
||||
${idmMarkupPricePM({ prodData, addToBasket: isAddToBasket })}
|
||||
${isAddToBasket ? idmMarkupAddToBasketPM(prodData) : ""}
|
||||
</div>
|
||||
`;
|
||||
|
||||
idmInitEventsPM({
|
||||
@@ -464,7 +442,7 @@ async function idmPictureModuleProductsPM(containerEL) {
|
||||
});
|
||||
} catch (err) {
|
||||
allProdEl?.forEach((prodEl) =>
|
||||
prodEl.closest(".idm_picture__product")?.remove()
|
||||
prodEl.closest(".idm_picture__product")?.remove(),
|
||||
);
|
||||
console.error(err);
|
||||
}
|
||||
@@ -474,21 +452,31 @@ async function idmPictureModuleProductsPM(containerEL) {
|
||||
document.body.addEventListener("click", (e) => {
|
||||
if (app_shop.vars.view === 3 || app_shop.vars.view === 4) return;
|
||||
|
||||
const prodContainerEl = e.target.closest(".idm_picture__product");
|
||||
const moduleCotnainer = e.target.closest(".idm_picture__module");
|
||||
const prodContainerEl = e.target
|
||||
.closest(".idm_picture__product")
|
||||
?.querySelector(".product_info");
|
||||
if (!prodContainerEl || !moduleCotnainer) return;
|
||||
|
||||
// ClearShow
|
||||
if (!prodContainerEl)
|
||||
return document
|
||||
.querySelector(".idm_picture__product.--show")
|
||||
?.classList?.remove("--show");
|
||||
if (prodContainerEl.classList.contains("--show"))
|
||||
return prodContainerEl.classList.remove("--show");
|
||||
// if(!prodContainerEl) return document.querySelector(".idm_picture__product.--show")?.classList?.remove("--show");
|
||||
// if(prodContainerEl.classList.contains("--show")) return prodContainerEl.classList.remove("--show");
|
||||
|
||||
const moduleContainer = prodContainerEl.closest(".idm_picture__module");
|
||||
if (!moduleContainer) return;
|
||||
// const moduleContainer = prodContainerEl.closest(".idm_picture__module");
|
||||
// if(!moduleContainer) return;
|
||||
|
||||
moduleContainer
|
||||
.querySelectorAll(".idm_picture__product.--show")
|
||||
.forEach((prodConEl) => prodConEl.classList.remove("--show"));
|
||||
prodContainerEl.classList.add("--show");
|
||||
// moduleContainer.querySelectorAll(".idm_picture__product.--show").forEach(prodConEl=>prodConEl.classList.remove("--show"));
|
||||
// prodContainerEl.classList.add("--show");
|
||||
const computedStyles = window.getComputedStyle(moduleCotnainer);
|
||||
const backgroundColor = computedStyles.getPropertyValue("--photo-mod-col-bg");
|
||||
const textColor = computedStyles.getPropertyValue("--photo-mod-col-text");
|
||||
|
||||
new Modal({
|
||||
element: prodContainerEl,
|
||||
classList: "--mobile --photo-prod-mobile",
|
||||
afterShow: (modal) => {
|
||||
modal.style.setProperty("--photo-prod-box-bg", backgroundColor || "#fff");
|
||||
modal.style.setProperty("--photo-prod-box-text", textColor || "#111");
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<style>
|
||||
.idm_picture__module {
|
||||
--photo-prod-box-bg: #fff;
|
||||
--photo-prod-box-text: #111;
|
||||
--photo-prod-box-bg: var(--photo-mod-col-bg, #fff);
|
||||
--photo-prod-box-text: var(--photo-mod-col-text, #111);
|
||||
|
||||
--photo-prod-point-shadow: rgba(255, 255, 255, 0.5);
|
||||
|
||||
--photo-prod-box-pad-top: 1rem;
|
||||
@@ -32,8 +33,7 @@
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
.idm_picture__product:hover,
|
||||
.idm_picture__product.--show {
|
||||
.idm_picture__product:hover {
|
||||
z-index: 20;
|
||||
}
|
||||
.idm_picture__img {
|
||||
@@ -114,15 +114,18 @@ PULSE ANIMATION
|
||||
|
||||
.product_info {
|
||||
background: var(--photo-prod-box-bg);
|
||||
flex-direction: column;
|
||||
padding: 1rem;
|
||||
gap: 1rem;
|
||||
display: none;
|
||||
max-width: var(--photo-prod-box-width);
|
||||
position: absolute;
|
||||
width: max-content;
|
||||
box-shadow: 0px 0px 10px 1px #000;
|
||||
}
|
||||
.product_info__container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
@media (min-width: 757px) {
|
||||
.product_info {
|
||||
padding: 1.5rem;
|
||||
@@ -294,19 +297,27 @@ PULSE ANIMATION
|
||||
}
|
||||
}
|
||||
|
||||
.idm_picture__product .product_info .product_name {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
.product_info
|
||||
.product_name {
|
||||
font-size: 1.6rem;
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
.idm_picture__product .product_info .product_name:hover {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
.product_info
|
||||
.product_name:hover {
|
||||
color: var(--primary-color, #000) !important;
|
||||
}
|
||||
|
||||
.idm_picture__product .product_info .product_prices {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
.product_info
|
||||
.product_prices {
|
||||
font-size: 1.6rem;
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
.idm_picture__product .product_info .price.--main {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
.product_info
|
||||
.price.--main {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -320,12 +331,6 @@ PULSE ANIMATION
|
||||
animation: idmShowUp 0.3s ease-in-out;
|
||||
}
|
||||
}
|
||||
@media (max-width: 978px) {
|
||||
.idm_picture__product.--show .product_info {
|
||||
display: flex;
|
||||
animation: idmShowUp 0.3s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes idmShowUp {
|
||||
from {
|
||||
@@ -356,38 +361,101 @@ PULSE ANIMATION
|
||||
}
|
||||
}
|
||||
|
||||
.idm_picture__module .label_icons {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .label_icons {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
position: static;
|
||||
}
|
||||
|
||||
.idm_picture__module .product_opinions {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .product_opinions {
|
||||
display: flex;
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
|
||||
.idm_picture__module .icon-star:not(.--active)::before {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
.icon-star:not(.--active)::before {
|
||||
content: "\f006";
|
||||
}
|
||||
.idm_picture__module .icon-star.--active {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .icon-star.--active {
|
||||
color: var(--opinions-star-active-color, #fac917);
|
||||
}
|
||||
|
||||
.idm_picture__module .product_opinions__score {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
.product_opinions__score {
|
||||
margin-left: 1rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.idm_picture__module .product_opinions__count::before {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
.product_opinions__count::before {
|
||||
content: "(";
|
||||
}
|
||||
.idm_picture__module .product_opinions__count::after {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
.product_opinions__count::after {
|
||||
content: ")";
|
||||
}
|
||||
|
||||
.idm_picture__module :is(.add_to_basket, .add_to_basket__link) {
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
:is(.add_to_basket, .add_to_basket__link) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
:is(.price.--omnibus.omnibus_price, .price.--max) {
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile)
|
||||
.--omnibus-higher
|
||||
:is(.price.--normal.--main, .price_percent) {
|
||||
color: var(--color-promo-price, #cd2323);
|
||||
}
|
||||
|
||||
.idm_picture__module .product_icon {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@media (max-width: 978px) {
|
||||
.modal.--photo-prod-mobile .product_info.--mod-init {
|
||||
position: static;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
box-shadow: none;
|
||||
flex-direction: column;
|
||||
}
|
||||
.modal.--photo-prod-mobile .modal__wrapper {
|
||||
border-radius: 10px 10px 0 0;
|
||||
background-color: var(--photo-prod-box-bg);
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
.modal.--photo-prod-mobile .modal__close {
|
||||
position: absolute;
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
.modal.--photo-prod-mobile
|
||||
.modal__close
|
||||
:is(.product_name, .omnibus_price, .price.--max) {
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
.modal.--photo-prod-mobile .product_icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 420px) and (max-width: 978px) {
|
||||
.modal.--photo-prod-mobile .product_info.--mod-init {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
}
|
||||
.modal.--photo-prod-mobile .product_info.--mod-init > *:not(.product_icon) {
|
||||
grid-column: "2/3";
|
||||
}
|
||||
.modal.--photo-prod-mobile .product_info.--mod-init > .product_icon {
|
||||
grid-row: "1/-1";
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
62
package-lock.json
generated
62
package-lock.json
generated
@@ -13,6 +13,7 @@
|
||||
"@mui/icons-material": "^7.3.6",
|
||||
"@mui/material": "^7.3.6",
|
||||
"react": "^19.2.0",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-hot-toast": "^2.6.0",
|
||||
"react-router-dom": "^7.11.0",
|
||||
@@ -1076,6 +1077,15 @@
|
||||
"url": "https://github.com/sponsors/nzakas"
|
||||
}
|
||||
},
|
||||
"node_modules/@icons/material": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
|
||||
"integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||
@@ -2999,6 +3009,18 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.23",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
|
||||
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash-es": {
|
||||
"version": "4.17.23",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz",
|
||||
"integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
@@ -3028,6 +3050,12 @@
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/material-colors": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
|
||||
"integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
@@ -3268,6 +3296,7 @@
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
@@ -3300,6 +3329,24 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-color": {
|
||||
"version": "2.19.3",
|
||||
"resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz",
|
||||
"integrity": "sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@icons/material": "^0.2.4",
|
||||
"lodash": "^4.17.15",
|
||||
"lodash-es": "^4.17.15",
|
||||
"material-colors": "^1.2.1",
|
||||
"prop-types": "^15.5.10",
|
||||
"reactcss": "^1.2.0",
|
||||
"tinycolor2": "^1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "19.2.3",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
|
||||
@@ -3404,6 +3451,15 @@
|
||||
"react-dom": ">=16.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/reactcss": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
|
||||
"integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.11",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
|
||||
@@ -3583,6 +3639,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/tinycolor2": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz",
|
||||
"integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tinyglobby": {
|
||||
"version": "0.2.15",
|
||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"@mui/icons-material": "^7.3.6",
|
||||
"@mui/material": "^7.3.6",
|
||||
"react": "^19.2.0",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-hot-toast": "^2.6.0",
|
||||
"react-router-dom": "^7.11.0",
|
||||
|
||||
@@ -3,7 +3,6 @@ import Home from "./pages/Home";
|
||||
import AppLayout from "./ui/AppLayout";
|
||||
import Instruction from "./pages/Instruction";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import { Alert } from "@mui/material";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
|
||||
@@ -23,7 +23,16 @@ export const DEFAULT_POINT = {
|
||||
direction: Object.keys(DIRECTIONS)[0],
|
||||
}; // Default point structure
|
||||
|
||||
export const URL_RADIO_DATA = [
|
||||
{ value: "single", label: "Jedno Zdjęcie" },
|
||||
{ value: "rwd", label: "Trzy Zdjęcia (RWD)" },
|
||||
export const DEFAULT_COLOR_PALLETE = [
|
||||
"#D9E3F0",
|
||||
"#F47373",
|
||||
"#697689",
|
||||
"#37D67A",
|
||||
"#2CCCE4",
|
||||
"#555555",
|
||||
"#dce775",
|
||||
"#ff8a65",
|
||||
"#ba68c8",
|
||||
"#111111",
|
||||
"#f2f2f2",
|
||||
];
|
||||
|
||||
@@ -17,6 +17,13 @@ export default function CodeBox() {
|
||||
}
|
||||
}, [state.urls, state.points, state.photoAlt, state.previewMode]); // reactive slices
|
||||
|
||||
if (
|
||||
import.meta.env.MODE === "production" &&
|
||||
window.location.href.includes("https://zooart6.yourtechnicaldomain.com/") &&
|
||||
!window.location.search.includes("dev=test")
|
||||
)
|
||||
return null;
|
||||
|
||||
const copyCode = () => {
|
||||
navigator.clipboard.writeText(code);
|
||||
toast.success("Skopiowano tekst!");
|
||||
|
||||
@@ -1,40 +1,18 @@
|
||||
import styled from "@emotion/styled";
|
||||
import { Button, Tab, Tabs } from "@mui/material";
|
||||
import { Tab, Tabs } from "@mui/material";
|
||||
import { BREAKPOINTS } from "../../../constants/rwd";
|
||||
import { useSharedState } from "../../../store/useSharedState";
|
||||
import { capitalizeFirstLetter } from "../../../utils/capitalizeFirstLetter";
|
||||
|
||||
const StyledPreviewTabsContainer = styled("div")({
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(3, 1fr)",
|
||||
gap: "0.1rem",
|
||||
// backgroundColor: "#060606",
|
||||
});
|
||||
|
||||
function PreviewRWDTabs() {
|
||||
const currentPreviewMode = useSharedState((state) => state.previewMode);
|
||||
const setPreviewMode = useSharedState((state) => state.setPreviewMode);
|
||||
const setField = useSharedState((state) => state.setField);
|
||||
|
||||
if (currentPreviewMode === "single") return null;
|
||||
|
||||
return (
|
||||
// <StyledPreviewTabsContainer>
|
||||
// {currentPreviewMode === "single"
|
||||
// ? null
|
||||
// : Object.keys(BREAKPOINTS).map((key) => (
|
||||
// <Button
|
||||
// key={key}
|
||||
// variant="contained"
|
||||
// disabled={currentPreviewMode === key}
|
||||
// onClick={() => setPreviewMode(key)}
|
||||
// >
|
||||
// {capitalizeFirstLetter(key)}
|
||||
// </Button>
|
||||
// ))}
|
||||
// </StyledPreviewTabsContainer>
|
||||
<Tabs
|
||||
value={currentPreviewMode}
|
||||
onChange={(_, newVal) => setPreviewMode(newVal)}
|
||||
onChange={(_, newVal) => setField("previewMode", newVal)}
|
||||
variant="fullWidth"
|
||||
sx={(theme) => ({
|
||||
backgroundColor: theme.palette.background.header,
|
||||
|
||||
@@ -7,10 +7,27 @@ function GeneratePreview({ preview = true }) {
|
||||
const urls = useSharedState((state) => state.urls);
|
||||
const uniqueId = Math.ceil(Math.random() * 100000 + 1);
|
||||
|
||||
const labels = useSharedState((state) => state.labels);
|
||||
const opinions = useSharedState((state) => state.opinions);
|
||||
const addToBasket = useSharedState((state) => state.addToBasket);
|
||||
|
||||
const bgColor = useSharedState((state) => state.bgColor);
|
||||
const textColor = useSharedState((state) => state.textColor);
|
||||
|
||||
if (preview && urls[previewMode] === "") return null;
|
||||
|
||||
return (
|
||||
<div className="idm_picture__module" id={`idm-picture-module-${uniqueId}`}>
|
||||
<div
|
||||
className="idm_picture__module"
|
||||
id={`idm-picture-module-${uniqueId}`}
|
||||
data-labels={labels && true}
|
||||
data-opinions={opinions && true}
|
||||
data-add-to-basket={addToBasket && true}
|
||||
style={{
|
||||
"--photo-mod-col-bg": bgColor,
|
||||
"--photo-mod-col-text": textColor,
|
||||
}}
|
||||
>
|
||||
{<GeneratePreviewImage preview={preview} urls={urls} />}
|
||||
{<GeneratePreviewPoints preview={preview} uniqueId={uniqueId} />}
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { useSharedState } from "../../../store/useSharedState";
|
||||
|
||||
function GeneratePreviewImage({ preview, urls }) {
|
||||
const imagePrefix =
|
||||
import.meta.env.MODE === "development"
|
||||
? `${import.meta.env.VITE_PUBLIC_URL}/`
|
||||
: "";
|
||||
const previewMode = useSharedState((state) => state.previewMode);
|
||||
const photoAlt = useSharedState((state) => state.photoAlt);
|
||||
|
||||
const imagePrefix =
|
||||
import.meta.env.MODE === "development" &&
|
||||
!urls[previewMode]?.includes("https://")
|
||||
? `${import.meta.env.VITE_PUBLIC_URL}/`
|
||||
: "";
|
||||
|
||||
if (preview)
|
||||
return (
|
||||
<img
|
||||
|
||||
@@ -12,6 +12,9 @@ function GeneratePreviewSinglePoint({
|
||||
const { positions, id } = useSharedState((state) => state.points[index]);
|
||||
const previewMode = useSharedState((state) => state.previewMode);
|
||||
const product = useSharedState((state) => state.products[id]);
|
||||
const labels = useSharedState((state) => state.labels);
|
||||
const opinions = useSharedState((state) => state.opinions);
|
||||
const addToBasket = useSharedState((state) => state.addToBasket);
|
||||
|
||||
const setSinglePointPosition = useSharedState(
|
||||
(state) => state.setSinglePointPosition,
|
||||
@@ -37,20 +40,45 @@ function GeneratePreviewSinglePoint({
|
||||
};
|
||||
};
|
||||
|
||||
// WARUNKI DLA STYLE/DATA ATRYBUTY
|
||||
const mainContainerStyles = () => {
|
||||
if (preview)
|
||||
return (
|
||||
<div
|
||||
className="idm_picture__product"
|
||||
style={{
|
||||
return {
|
||||
top: `${positions[previewMode].y}%`,
|
||||
left: `${positions[previewMode].x}%`,
|
||||
display: positions[previewMode].hide ? "none" : "block",
|
||||
}}
|
||||
>
|
||||
};
|
||||
|
||||
if (previewMode === "single")
|
||||
return { top: `${positions.single.y}%`, left: `${positions.single.x}%` };
|
||||
else
|
||||
return Object.keys(BREAKPOINTS).reduce((acc, key) => {
|
||||
acc[`--photo-prod-point-${key}-top`] = `${positions[key].y}%`;
|
||||
acc[`--photo-prod-point-${key}-left`] = `${positions[key].x}%`;
|
||||
acc[`--photo-prod-point-${key}-display`] = positions[key].hide
|
||||
? "none"
|
||||
: "block";
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
const productInfoDataAttributes = () => {
|
||||
if (preview || previewMode === "single")
|
||||
return generatePointDataAttribbutes(previewMode);
|
||||
else
|
||||
return {
|
||||
...generatePointDataAttribbutes("mobile"),
|
||||
...generatePointDataAttribbutes("tablet"),
|
||||
...generatePointDataAttribbutes("desktop"),
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="idm_picture__product" style={mainContainerStyles()}>
|
||||
<button
|
||||
className="idm_picture__product_point"
|
||||
aria-describedby={prodBoxUniqueId}
|
||||
aria-label="Product Info"
|
||||
tabIndex={-1}
|
||||
aria-hidden="true"
|
||||
onPointerDown={onPointerDown}
|
||||
>
|
||||
+
|
||||
@@ -59,56 +87,52 @@ function GeneratePreviewSinglePoint({
|
||||
className="product_info"
|
||||
id={prodBoxUniqueId}
|
||||
data-id={id}
|
||||
{...generatePointDataAttribbutes(previewMode)}
|
||||
{...productInfoDataAttributes()}
|
||||
>
|
||||
{preview && (
|
||||
<div class="product_info__container">
|
||||
{labels && (
|
||||
<strong class="label_icons">
|
||||
<span class="label --new">Nowość</span>
|
||||
</strong>
|
||||
)}
|
||||
{opinions && (
|
||||
<div class="product_opinions">
|
||||
<div class="product_opinions__stars">
|
||||
<i class="icon-star">*</i>
|
||||
<i class="icon-star">*</i>
|
||||
<i class="icon-star">*</i>
|
||||
<i class="icon-star">*</i>
|
||||
<i class="icon-star">*</i>
|
||||
</div>
|
||||
<span class="product_opinions__score">0 / 5.00 </span>
|
||||
<span class="product_opinions__count">0</span>
|
||||
</div>
|
||||
)}
|
||||
<a className="product_name" href="#">
|
||||
{product ? product?.name : `Produkt ${index + 1}`}
|
||||
</a>
|
||||
<span className="product_price">
|
||||
<div class="product_prices">
|
||||
<span class="price --normal --main">
|
||||
{product
|
||||
? product?.price?.price?.gross?.formatted
|
||||
: `Produkt ${index + 1} zł`}
|
||||
: `${index + 1} zł`}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="idm_picture__product"
|
||||
style={
|
||||
previewMode === "single"
|
||||
? { top: `${positions.single.y}%`, left: `${positions.single.x}%` }
|
||||
: Object.keys(BREAKPOINTS).reduce((acc, key) => {
|
||||
acc[`--photo-prod-point-${key}-top`] = `${positions[key].y}%`;
|
||||
acc[`--photo-prod-point-${key}-left`] = `${positions[key].x}%`;
|
||||
acc[`--photo-prod-point-${key}-display`] = positions[key].hide
|
||||
? "none"
|
||||
: "block";
|
||||
return acc;
|
||||
}, {})
|
||||
}
|
||||
>
|
||||
{addToBasket && (
|
||||
<button
|
||||
className="idm_picture__product_point"
|
||||
aria-describedby={prodBoxUniqueId}
|
||||
tabIndex={-1}
|
||||
aria-hidden="true"
|
||||
class="btn --solid --medium add_to_basket__button"
|
||||
tabindex="0"
|
||||
data-success="Dodany"
|
||||
data-error="Wystąpił błąd"
|
||||
data-text="Do koszyka"
|
||||
>
|
||||
+
|
||||
<span>Do koszyka</span>
|
||||
</button>
|
||||
<div
|
||||
className="product_info"
|
||||
id={prodBoxUniqueId}
|
||||
data-id={id}
|
||||
{...(previewMode === "single"
|
||||
? generatePointDataAttribbutes(previewMode)
|
||||
: {
|
||||
...generatePointDataAttribbutes("mobile"),
|
||||
...generatePointDataAttribbutes("tablet"),
|
||||
...generatePointDataAttribbutes("desktop"),
|
||||
})}
|
||||
></div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
function GenerateStyle() {
|
||||
return (
|
||||
<>
|
||||
<style>
|
||||
{`
|
||||
.idm_picture__module{
|
||||
--photo-prod-box-bg: #fff;
|
||||
--photo-prod-box-text: #111;
|
||||
--photo-prod-box-bg: var(--photo-mod-col-bg, #fff);
|
||||
--photo-prod-box-text: var(--photo-mod-col-text, #111);
|
||||
|
||||
--photo-prod-point-shadow: rgba(255,255,255,.5);
|
||||
|
||||
--photo-prod-box-pad-top: 1em;
|
||||
@@ -35,7 +37,7 @@ function GenerateStyle() {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
.idm_picture__product:hover, .idm_picture__product.--show{
|
||||
.idm_picture__product:hover{
|
||||
z-index: 20;
|
||||
}
|
||||
.idm_picture__img{
|
||||
@@ -116,15 +118,18 @@ PULSE ANIMATION
|
||||
|
||||
.product_info{
|
||||
background: var(--photo-prod-box-bg);
|
||||
flex-direction: column;
|
||||
padding: 1em;
|
||||
gap: 1em;
|
||||
display: none;
|
||||
max-width: var(--photo-prod-box-width);
|
||||
position: absolute;
|
||||
width: max-content;
|
||||
box-shadow: 0px 0px 10px 1px #000;
|
||||
}
|
||||
.product_info__container{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
}
|
||||
@media (min-width: 757px){
|
||||
.product_info{
|
||||
padding: 1.5em;
|
||||
@@ -296,19 +301,19 @@ PULSE ANIMATION
|
||||
}
|
||||
}
|
||||
|
||||
.idm_picture__product .product_info .product_name{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .product_info .product_name{
|
||||
font-size: 1.6em;
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
.idm_picture__product .product_info .product_name:hover{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .product_info .product_name:hover{
|
||||
color: var(--primary-color, #000)!important;
|
||||
}
|
||||
|
||||
.idm_picture__product .product_info .product_prices{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .product_info .product_prices{
|
||||
font-size: 1.6em;
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
.idm_picture__product .product_info .price.--main{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .product_info .price.--main{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -318,12 +323,6 @@ PULSE ANIMATION
|
||||
animation: idmShowUp 0.3s ease-in-out;
|
||||
}
|
||||
}
|
||||
@media(max-width: 978px){
|
||||
.idm_picture__product.--show .product_info{
|
||||
display: flex;
|
||||
animation: idmShowUp 0.3s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes idmShowUp{
|
||||
from{
|
||||
@@ -354,47 +353,154 @@ PULSE ANIMATION
|
||||
}
|
||||
}
|
||||
|
||||
.idm_picture__module .label_icons{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .label_icons{
|
||||
display: flex;
|
||||
gap: 0.5em;
|
||||
position: static;
|
||||
}
|
||||
|
||||
.idm_picture__module .product_opinions{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .product_opinions{
|
||||
display: flex;
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
|
||||
.idm_picture__module .icon-star:not(.--active)::before{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .icon-star:not(.--active)::before{
|
||||
content: "\f006";
|
||||
}
|
||||
.idm_picture__module .icon-star.--active{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .icon-star.--active{
|
||||
color: var(--opinions-star-active-color, #fac917);
|
||||
}
|
||||
|
||||
.idm_picture__module .product_opinions__score{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .product_opinions__score{
|
||||
margin-left: 1em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.idm_picture__module .product_opinions__count::before{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .product_opinions__count::before{
|
||||
content: "(";
|
||||
}
|
||||
.idm_picture__module .product_opinions__count::after{
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .product_opinions__count::after{
|
||||
content: ")";
|
||||
}
|
||||
|
||||
.idm_picture__module :is(.add_to_basket, .add_to_basket__link){
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) :is(.add_to_basket, .add_to_basket__link){
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) :is(.price.--omnibus.omnibus_price, .price.--max){
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
|
||||
:is(.idm_picture__module, .modal.--photo-prod-mobile) .--omnibus-higher :is(.price.--normal.--main, .price_percent){
|
||||
color: var(--color-promo-price, #cd2323);
|
||||
}
|
||||
|
||||
|
||||
.idm_picture__module .product_icon{
|
||||
display: none!important;
|
||||
}
|
||||
// MOBILE
|
||||
@media (max-width: 978px){
|
||||
.modal.--photo-prod-mobile .product_info.--mod-init{
|
||||
position: static;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
box-shadow: none;
|
||||
}
|
||||
.modal.--photo-prod-mobile .modal__wrapper{
|
||||
border-radius: 10px 10px 0 0;
|
||||
background-color: var(--photo-prod-box-bg);
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
.modal.--photo-prod-mobile .modal__close{
|
||||
position: absolute;
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
.modal.--photo-prod-mobile .modal__close :is(.product_name, .omnibus_price, .price.--max){
|
||||
color: var(--photo-prod-box-text);
|
||||
}
|
||||
.modal.--photo-prod-mobile .product_icon{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media(min-width: 400px) and (max-width: 978px){
|
||||
.modal.--photo-prod-mobile .product_info.--mod-init {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
}
|
||||
.modal.--photo-prod-mobile .product_info.--mod-init > *:not(.product_icon){
|
||||
grid-column: ~"2/3";
|
||||
}
|
||||
.modal.--photo-prod-mobile .product_info.--mod-init > .product_icon{
|
||||
grid-row: ~"1/-1"
|
||||
}
|
||||
}
|
||||
|
||||
`}
|
||||
</style>
|
||||
<style>
|
||||
{`
|
||||
|
||||
.idm_picture__product_point{
|
||||
cursor: grab;
|
||||
}
|
||||
.idm_picture__product .product_info .product_prices{
|
||||
font-size: 1.6em;
|
||||
color: #000;
|
||||
}
|
||||
.label_icons > *{
|
||||
font-size: 1em;
|
||||
color: #fff;
|
||||
background: #0090f6;
|
||||
font-weight: 600;
|
||||
padding: 4px 6px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
[class^="icon-"], [class*=" icon-"]{
|
||||
font-family: FontAwesome;
|
||||
}
|
||||
.icon-star:before {
|
||||
content: "\f005" / "";
|
||||
}
|
||||
.product_opinions{
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
.btn{
|
||||
background: none;
|
||||
padding: 0;
|
||||
border: 1px solid transparent;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
color: #E11D48;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
font-size: 1.2em;
|
||||
padding: 0.9em 1em;
|
||||
font-weight: normal;
|
||||
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.btn.--solid {
|
||||
background: #E11D48;
|
||||
border: 1px solid #E11D48;
|
||||
color: #fff;
|
||||
}
|
||||
.btn.--medium {
|
||||
font-size: 1.4em;
|
||||
padding: 1.25em 1.4em;
|
||||
}
|
||||
|
||||
`}
|
||||
</style>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +1,107 @@
|
||||
import { useState } from "react";
|
||||
import GenericBox from "../../ui/GenericBox";
|
||||
import { URL_RADIO_DATA } from "./../../constants/photo";
|
||||
import { useSharedState } from "../../store/useSharedState";
|
||||
import GenericRadioGroup from "./../../ui/GenericRadioGroup";
|
||||
import { Divider } from "@mui/material";
|
||||
import {
|
||||
Alert,
|
||||
Divider,
|
||||
FormControlLabel,
|
||||
FormGroup,
|
||||
Switch,
|
||||
} from "@mui/material";
|
||||
import ColorPickerInput from "../../ui/ColorPickerInput";
|
||||
import { DEFAULT_COLOR_PALLETE } from "../../constants/photo";
|
||||
|
||||
function PhotoGenericOptions() {
|
||||
const [urlPoint, setUrlPoint] = useState("single");
|
||||
const setPreviewMode = useSharedState((state) => state.setPreviewMode);
|
||||
const setField = useSharedState((state) => state.setField);
|
||||
const toggleField = useSharedState((state) => state.toggleField);
|
||||
|
||||
const handleUrlRadioChange = (event) => {
|
||||
setUrlPoint(event.target.value);
|
||||
setPreviewMode(event.target.value === "rwd" ? "desktop" : "single");
|
||||
const isRWD = useSharedState((state) => state.isRWD);
|
||||
const labels = useSharedState((state) => state.labels);
|
||||
const opinions = useSharedState((state) => state.opinions);
|
||||
const addToBasket = useSharedState((state) => state.addToBasket);
|
||||
const bgColor = useSharedState((state) => state.bgColor);
|
||||
const textColor = useSharedState((state) => state.textColor);
|
||||
|
||||
const handleUrlRadioChange = (e) => {
|
||||
toggleField("isRWD");
|
||||
setField("previewMode", e.target.checked ? "desktop" : "single");
|
||||
};
|
||||
|
||||
return (
|
||||
<GenericBox variant="inner" title="Opcje">
|
||||
<GenericRadioGroup
|
||||
// <GenericBox variant="inner" title="Opcje">
|
||||
<FormGroup sx={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
||||
{/* <GenericRadioGroup
|
||||
radioData={URL_RADIO_DATA}
|
||||
value={urlPoint}
|
||||
value={isRwd}
|
||||
onChange={handleUrlRadioChange}
|
||||
direction="row"
|
||||
/> */}
|
||||
<FormControlLabel
|
||||
control={<Switch checked={isRWD} onChange={handleUrlRadioChange} />}
|
||||
label="Czy wyświetlać inne zdjęcia dla innych szerokości ekranu (RWD)"
|
||||
/>
|
||||
<Divider />
|
||||
Labelki
|
||||
<Divider />
|
||||
Opinie
|
||||
<Divider />
|
||||
Dodaj do koszyka
|
||||
<Divider />
|
||||
</GenericBox>
|
||||
|
||||
<Divider sx={{ borderColor: "#ccc" }} />
|
||||
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch checked={labels} onChange={() => toggleField("labels")} />
|
||||
}
|
||||
label="Czy wyświetlać labele produktu (np Nowość, Promocja itp)"
|
||||
/>
|
||||
|
||||
<Divider sx={{ borderColor: "#ccc" }} />
|
||||
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch checked={opinions} onChange={() => toggleField("opinions")} />
|
||||
}
|
||||
label="Czy wyświetlać dane o opinii o produkcie"
|
||||
/>
|
||||
|
||||
<Divider sx={{ borderColor: "#ccc" }} />
|
||||
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
checked={addToBasket}
|
||||
onChange={() => toggleField("addToBasket")}
|
||||
/>
|
||||
}
|
||||
label="Czy wyświetlać przycisk dodania do koszyka na produkcie"
|
||||
/>
|
||||
|
||||
<Divider sx={{ borderColor: "#ccc" }} />
|
||||
|
||||
<div
|
||||
style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "2rem" }}
|
||||
>
|
||||
<ColorPickerInput
|
||||
color={bgColor}
|
||||
onChange={(newColor) => setField("bgColor", newColor)}
|
||||
label="Kolor Tła"
|
||||
palette={DEFAULT_COLOR_PALLETE}
|
||||
/>
|
||||
<ColorPickerInput
|
||||
color={textColor}
|
||||
onChange={(newColor) => setField("textColor", newColor)}
|
||||
label="Kolor Tekstu"
|
||||
palette={DEFAULT_COLOR_PALLETE}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Divider sx={{ borderColor: "#ccc" }} />
|
||||
|
||||
<Alert severity="warning">
|
||||
Uwaga!
|
||||
<br />
|
||||
Wygląd boxa produktowego na podglądzie może się różnić od tego
|
||||
wrzuconego na sklep. Aplikacja nie pobiera czcionek ani kolorów ze
|
||||
sklepu!
|
||||
<br />
|
||||
Podgląd wyświetla tylko jeden testowy label i nie wyświetla danych
|
||||
omnibusa.
|
||||
</Alert>
|
||||
</FormGroup>
|
||||
// {/* </GenericBox> */}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ function PhotoUrl() {
|
||||
const setUrl = useSharedState((state) => state.setUrl);
|
||||
|
||||
const photoAlt = useSharedState((state) => state.photoAlt);
|
||||
const setPhotoAlt = useSharedState((state) => state.setPhotoAlt);
|
||||
const setField = useSharedState((state) => state.setField);
|
||||
|
||||
const handleChangeURL = ({ event, type }) => {
|
||||
event.preventDefault();
|
||||
@@ -29,7 +29,7 @@ function PhotoUrl() {
|
||||
<Divider />
|
||||
<InputField
|
||||
name="Alt zdjęcia"
|
||||
onChange={(e) => setPhotoAlt(e.target.value)}
|
||||
onChange={(e) => setField("photoAlt", e.target.value)}
|
||||
value={photoAlt}
|
||||
/>
|
||||
</GenericBox>
|
||||
|
||||
22
src/main.jsx
22
src/main.jsx
@@ -1,21 +1,19 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import App from './App'
|
||||
import { ThemeProvider, CssBaseline } from '@mui/material';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import theme from './styles/theme';
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App";
|
||||
import { ThemeProvider, CssBaseline } from "@mui/material";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import theme from "./styles/theme";
|
||||
// import ThemeCssVars from './styles/ThemeCssVars';
|
||||
|
||||
|
||||
const BASENAME = import.meta.env.VITE_PUBLIC_URL || "/";
|
||||
|
||||
const path = window.location.pathname;
|
||||
if (path.endsWith('index.html')) {
|
||||
if (path.endsWith("index.html")) {
|
||||
window.location.replace(BASENAME);
|
||||
}
|
||||
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<BrowserRouter basename={BASENAME}>
|
||||
<ThemeProvider theme={theme}>
|
||||
@@ -24,5 +22,5 @@ ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
</ThemeProvider>
|
||||
</BrowserRouter>
|
||||
</React.StrictMode>
|
||||
)
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { create } from "zustand";
|
||||
import { persist } from "zustand/middleware";
|
||||
import { DEFAULT_POINT } from "./../constants/photo";
|
||||
|
||||
// export const createBox = () => ({});
|
||||
@@ -7,27 +8,54 @@ const defaultState = {
|
||||
points: [{ ...DEFAULT_POINT }],
|
||||
photoAlt: "Zdjęcie pokazowe",
|
||||
previewMode: "single", // desktop, tablet, mobile
|
||||
|
||||
isRWD: false,
|
||||
labels: false,
|
||||
opinions: false,
|
||||
addToBasket: false,
|
||||
|
||||
//colros
|
||||
bgColor: "#fff",
|
||||
textColor: "#060606",
|
||||
};
|
||||
|
||||
export const useSharedState = create((set, get) => ({
|
||||
export const useSharedState = create(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
//DATA
|
||||
...defaultState,
|
||||
products: {},
|
||||
|
||||
//SETTERS/UPDATERS
|
||||
setField: (key, value) =>
|
||||
set(() => ({
|
||||
[key]: value,
|
||||
})),
|
||||
|
||||
toggleField: (key) =>
|
||||
set((state) => ({
|
||||
[key]: !state[key],
|
||||
})),
|
||||
|
||||
// setPhotoAlt: (alt) => set({ photoAlt: alt }),
|
||||
// setPreviewMode: (mode) => set({ previewMode: mode }),
|
||||
|
||||
/* =========
|
||||
URLS
|
||||
========= */
|
||||
setUrl: (type, url) =>
|
||||
set((state) => ({ urls: { ...state.urls, [type]: url } })),
|
||||
|
||||
setPhotoAlt: (alt) => set({ photoAlt: alt }),
|
||||
setPoints: (points) => set({ points }),
|
||||
setPointsLength: (length) => set({ pointsLength: length }),
|
||||
setPreviewMode: (mode) => set({ previewMode: mode }),
|
||||
/* =========
|
||||
POINTS
|
||||
========= */
|
||||
|
||||
setPoints: (points) => set({ points }),
|
||||
// Update a single point by ID
|
||||
setSinglePoint: (id, newData) =>
|
||||
set((state) => ({
|
||||
points: state.points.map((p, index) =>
|
||||
index === id ? { ...p, ...newData } : p
|
||||
index === id ? { ...p, ...newData } : p,
|
||||
),
|
||||
})),
|
||||
|
||||
@@ -45,7 +73,7 @@ export const useSharedState = create((set, get) => ({
|
||||
},
|
||||
},
|
||||
}
|
||||
: p
|
||||
: p,
|
||||
),
|
||||
})),
|
||||
|
||||
@@ -61,8 +89,9 @@ export const useSharedState = create((set, get) => ({
|
||||
points: state.points.filter((p, index) => index !== id),
|
||||
})),
|
||||
|
||||
clearAll: () => set(() => ({ ...defaultState })),
|
||||
|
||||
/* =========
|
||||
PRODUCTS
|
||||
========= */
|
||||
addProduct: (prod) =>
|
||||
set((state) => ({
|
||||
products: {
|
||||
@@ -70,4 +99,25 @@ export const useSharedState = create((set, get) => ({
|
||||
[prod.id]: prod,
|
||||
},
|
||||
})),
|
||||
}));
|
||||
|
||||
/* =========
|
||||
RESET
|
||||
========= */
|
||||
clearAll: () => set(() => ({ ...defaultState })),
|
||||
}),
|
||||
{
|
||||
name: "photo-generic-options",
|
||||
|
||||
partialize: (state) => ({
|
||||
labels: state.labels,
|
||||
opinions: state.opinions,
|
||||
addToBasket: state.addToBasket,
|
||||
previewMode: state.previewMode,
|
||||
isRWD: state.isRWD,
|
||||
|
||||
bgColor: state.bgColor,
|
||||
textColor: state.textColor,
|
||||
}),
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
71
src/ui/ColorPickerInput.jsx
Normal file
71
src/ui/ColorPickerInput.jsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { BlockPicker } from "react-color";
|
||||
import { Box, ButtonBase, Typography } from "@mui/material";
|
||||
|
||||
function ColorPickerButton({ color, onChange, label = "Color", palette = [] }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const wrapperRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
function handleClickOutside(e) {
|
||||
if (!wrapperRef.current?.contains(e.target)) {
|
||||
setOpen(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (open) {
|
||||
document.addEventListener("mousedown", handleClickOutside);
|
||||
}
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", handleClickOutside);
|
||||
};
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
ref={wrapperRef}
|
||||
sx={{ position: "relative", display: "inline-block" }}
|
||||
>
|
||||
{label && (
|
||||
<Typography variant="caption" sx={{ display: "block", mb: 0.5 }}>
|
||||
{label}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: 32,
|
||||
borderRadius: 1,
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
backgroundColor: color,
|
||||
}}
|
||||
/>
|
||||
|
||||
{open && (
|
||||
<Box
|
||||
className="color-picker block-picker"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "100%",
|
||||
left: "50%",
|
||||
mt: 1,
|
||||
zIndex: 1300,
|
||||
transform: "translateX(-50%)",
|
||||
}}
|
||||
>
|
||||
<BlockPicker
|
||||
color={color}
|
||||
colors={palette}
|
||||
onChange={(c) => onChange(c.hex)}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default ColorPickerButton;
|
||||
Reference in New Issue
Block a user