From 09c14785e791e69e2cbd8163417835c20fb380e8 Mon Sep 17 00:00:00 2001 From: "pawel.gaca" Date: Tue, 27 Jan 2026 10:39:21 +0100 Subject: [PATCH] opinie, dodaj do koszyka, labelki --- IdoSellAddOn/script.js | 66 +- src/constants/photo.js | 5 - .../htmlBuilder/components/PreviewRWDTabs.jsx | 28 +- .../htmlBuilder/generated/GeneratePreview.jsx | 12 +- .../generated/GeneratePreviewSinglePoint.jsx | 140 ++-- .../htmlBuilder/generated/GenerateStyle.jsx | 738 ++++++++++-------- .../photoModule/PhotoGenericOptions.jsx | 91 ++- src/features/photoModule/PhotoUrl.jsx | 4 +- src/store/useSharedState.js | 151 ++-- 9 files changed, 682 insertions(+), 553 deletions(-) diff --git a/IdoSellAddOn/script.js b/IdoSellAddOn/script.js index 9603297..8629540 100644 --- a/IdoSellAddOn/script.js +++ b/IdoSellAddOn/script.js @@ -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 @@ -239,7 +239,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 = `${buttonEl.dataset.error}`; buttonEl.classList.add("--error"); @@ -267,20 +267,10 @@ function idmMarkupAddToBasketPM(prodData) { return `
- - - -
`; @@ -291,9 +281,7 @@ function idmMarkupPricePM({ prodData, addToBasket }) { let priceMarkup; if (!addToBasket) - priceMarkup = `
${ - prodData.price?.price?.[app_shop.vars.priceType]?.formatted - }
`; + priceMarkup = `
${prodData.price?.price?.[app_shop.vars.priceType]?.formatted}
`; else { const currentSize = prodData?.sizes?.[0] || prodData; @@ -313,9 +301,7 @@ function idmMarkupPricePM({ prodData, addToBasket }) { const maxPercent = currentSize?.price?.youSavePercent; priceMarkup = ` -
+
${price} ${ omnibusPrice && typeof omnibusPercent === "number" @@ -382,7 +368,7 @@ async function idmPictureModuleProductsPM(containerEL) { opinions: isOpinions, addToBasket: isAddToBasket, })}`, - "" + "", )}}`, }), }); @@ -423,35 +409,19 @@ async function idmPictureModuleProductsPM(containerEL) { if (isOpinions) { opinionsHTML = `
- - - - - + + + + +
- ${ - prodData.opinion.rating - } / 5.00 + ${prodData.opinion.rating} / 5.00 ${prodData.opinion.count} `; } prodEl.innerHTML = ` ${isLabels ? `${labelsHTML}` : ""} - ${ - isOpinions - ? `
${opinionsHTML}
` - : "" - } + ${isOpinions ? `
${opinionsHTML}
` : ""} ${prodData.name} ${idmMarkupPricePM({ prodData, addToBasket: isAddToBasket })} ${isAddToBasket ? idmMarkupAddToBasketPM(prodData) : ""} @@ -464,7 +434,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); } diff --git a/src/constants/photo.js b/src/constants/photo.js index 4375c5d..233127d 100644 --- a/src/constants/photo.js +++ b/src/constants/photo.js @@ -22,8 +22,3 @@ export const DEFAULT_POINT = { id: 0, 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)" }, -]; diff --git a/src/features/htmlBuilder/components/PreviewRWDTabs.jsx b/src/features/htmlBuilder/components/PreviewRWDTabs.jsx index a706008..798e1ac 100644 --- a/src/features/htmlBuilder/components/PreviewRWDTabs.jsx +++ b/src/features/htmlBuilder/components/PreviewRWDTabs.jsx @@ -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 ( - // - // {currentPreviewMode === "single" - // ? null - // : Object.keys(BREAKPOINTS).map((key) => ( - // - // ))} - // setPreviewMode(newVal)} + onChange={(_, newVal) => setField("previewMode", newVal)} variant="fullWidth" sx={(theme) => ({ backgroundColor: theme.palette.background.header, diff --git a/src/features/htmlBuilder/generated/GeneratePreview.jsx b/src/features/htmlBuilder/generated/GeneratePreview.jsx index 3d4160a..ad12fc8 100644 --- a/src/features/htmlBuilder/generated/GeneratePreview.jsx +++ b/src/features/htmlBuilder/generated/GeneratePreview.jsx @@ -7,10 +7,20 @@ 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); + if (preview && urls[previewMode] === "") return null; return ( -
+
{} {}
diff --git a/src/features/htmlBuilder/generated/GeneratePreviewSinglePoint.jsx b/src/features/htmlBuilder/generated/GeneratePreviewSinglePoint.jsx index 72d7390..649d1fe 100644 --- a/src/features/htmlBuilder/generated/GeneratePreviewSinglePoint.jsx +++ b/src/features/htmlBuilder/generated/GeneratePreviewSinglePoint.jsx @@ -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,63 +40,46 @@ function GeneratePreviewSinglePoint({ }; }; - if (preview) - return ( -
- -
- - {product ? product?.name : `Produkt ${index + 1}`} - - - {product - ? product?.price?.price?.gross?.formatted - : `Produkt ${index + 1} zł`} - -
-
- ); + // WARUNKI DLA STYLE/DATA ATRYBUTY + const mainContainerStyles = () => { + if (preview) + 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 ( -
{ - 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; - }, {}) - } - > +
@@ -101,14 +87,52 @@ function GeneratePreviewSinglePoint({ className="product_info" id={prodBoxUniqueId} data-id={id} - {...(previewMode === "single" - ? generatePointDataAttribbutes(previewMode) - : { - ...generatePointDataAttribbutes("mobile"), - ...generatePointDataAttribbutes("tablet"), - ...generatePointDataAttribbutes("desktop"), - })} - >
+ {...productInfoDataAttributes()} + > + {preview && ( + <> + {labels && ( + + Nowość + + )} + {opinions && ( +
+
+ * + * + * + * + * +
+ 0 / 5.00 + 0 +
+ )} + + {product ? product?.name : `Produkt ${index + 1}`} + +
+ + {product + ? product?.price?.price?.gross?.formatted + : `${index + 1} zł`} + +
+ {addToBasket && ( + + )} + + )} +
); } diff --git a/src/features/htmlBuilder/generated/GenerateStyle.jsx b/src/features/htmlBuilder/generated/GenerateStyle.jsx index c65b35a..f2dc998 100644 --- a/src/features/htmlBuilder/generated/GenerateStyle.jsx +++ b/src/features/htmlBuilder/generated/GenerateStyle.jsx @@ -1,400 +1,460 @@ function GenerateStyle() { return ( - + + `} + + ); } diff --git a/src/features/photoModule/PhotoGenericOptions.jsx b/src/features/photoModule/PhotoGenericOptions.jsx index 1a3c05a..719fff1 100644 --- a/src/features/photoModule/PhotoGenericOptions.jsx +++ b/src/features/photoModule/PhotoGenericOptions.jsx @@ -1,35 +1,84 @@ -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"; 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 handleUrlRadioChange = (e) => { + toggleField("isRWD"); + setField("previewMode", e.target.checked ? "desktop" : "single"); }; return ( - - + + {/* */} + } + label="Czy wyświetlać inne zdjęcia dla innych szerokości ekranu (RWD)" /> - - Labelki - - Opinie - - Dodaj do koszyka - - + + + + toggleField("labels")} /> + } + label="Czy wyświetlać labele produktu (np Nowość, Promocja itp)" + /> + + + + toggleField("opinions")} /> + } + label="Czy wyświetlać dane o opinii o produkcie" + /> + + + + toggleField("addToBasket")} + /> + } + label="Czy wyświetlać przycisk dodania do koszyka na produkcie" + /> + + + + + Uwaga! +
+ 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! +
+ Podgląd wyświetla tylko jeden testowy label i nie wyświetla danych + omnibusa. +
+ + // {/* */} ); } diff --git a/src/features/photoModule/PhotoUrl.jsx b/src/features/photoModule/PhotoUrl.jsx index aec4b4d..21682ac 100644 --- a/src/features/photoModule/PhotoUrl.jsx +++ b/src/features/photoModule/PhotoUrl.jsx @@ -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() { setPhotoAlt(e.target.value)} + onChange={(e) => setField("photoAlt", e.target.value)} value={photoAlt} /> diff --git a/src/store/useSharedState.js b/src/store/useSharedState.js index 5cf41bc..7df4e6e 100644 --- a/src/store/useSharedState.js +++ b/src/store/useSharedState.js @@ -1,4 +1,5 @@ import { create } from "zustand"; +import { persist } from "zustand/middleware"; import { DEFAULT_POINT } from "./../constants/photo"; // export const createBox = () => ({}); @@ -7,67 +8,109 @@ const defaultState = { points: [{ ...DEFAULT_POINT }], photoAlt: "Zdjęcie pokazowe", previewMode: "single", // desktop, tablet, mobile + + isRWD: false, + labels: false, + opinions: false, + addToBasket: false, }; -export const useSharedState = create((set, get) => ({ - //DATA - ...defaultState, - products: {}, +export const useSharedState = create( + persist( + (set, get) => ({ + //DATA + ...defaultState, + products: {}, - //SETTERS/UPDATERS - setUrl: (type, url) => - set((state) => ({ urls: { ...state.urls, [type]: url } })), + //SETTERS/UPDATERS + setField: (key, value) => + set(() => ({ + [key]: value, + })), - setPhotoAlt: (alt) => set({ photoAlt: alt }), - setPoints: (points) => set({ points }), - setPointsLength: (length) => set({ pointsLength: length }), - setPreviewMode: (mode) => set({ previewMode: mode }), + toggleField: (key) => + set((state) => ({ + [key]: !state[key], + })), - // Update a single point by ID - setSinglePoint: (id, newData) => - set((state) => ({ - points: state.points.map((p, index) => - index === id ? { ...p, ...newData } : p - ), - })), + // setPhotoAlt: (alt) => set({ photoAlt: alt }), + // setPreviewMode: (mode) => set({ previewMode: mode }), - setSinglePointPosition: (id, brName, positionName, newValue) => - set((state) => ({ - points: state.points.map((p, index) => - index === id - ? { - ...p, - positions: { - ...p.positions, - [brName]: { - ...p.positions[brName], - [positionName]: newValue, - }, - }, - } - : p - ), - })), + /* ========= + URLS + ========= */ + setUrl: (type, url) => + set((state) => ({ urls: { ...state.urls, [type]: url } })), - // Add a point AND increment pointsLength - addSinglePoint: (point) => - set((state) => ({ - points: [...state.points, point], - })), + /* ========= + POINTS + ========= */ - // Remove a point AND decrement pointsLength - removeSinglePoint: (id) => - set((state) => ({ - points: state.points.filter((p, index) => index !== id), - })), + 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, + ), + })), - clearAll: () => set(() => ({ ...defaultState })), + setSinglePointPosition: (id, brName, positionName, newValue) => + set((state) => ({ + points: state.points.map((p, index) => + index === id + ? { + ...p, + positions: { + ...p.positions, + [brName]: { + ...p.positions[brName], + [positionName]: newValue, + }, + }, + } + : p, + ), + })), - addProduct: (prod) => - set((state) => ({ - products: { - ...state.products, - [prod.id]: prod, - }, - })), -})); + // Add a point AND increment pointsLength + addSinglePoint: (point) => + set((state) => ({ + points: [...state.points, point], + })), + + // Remove a point AND decrement pointsLength + removeSinglePoint: (id) => + set((state) => ({ + points: state.points.filter((p, index) => index !== id), + })), + + /* ========= + PRODUCTS + ========= */ + addProduct: (prod) => + set((state) => ({ + products: { + ...state.products, + [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, + }), + }, + ), +);