diff --git a/.gitignore b/.gitignore index a547bf3..18b5c9b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ yarn-error.log* pnpm-debug.log* lerna-debug.log* +test.html node_modules dist dist-ssr diff --git a/IdoSellAddOn/script.js b/IdoSellAddOn/script.js index e6df9d0..41d3c8b 100644 --- a/IdoSellAddOn/script.js +++ b/IdoSellAddOn/script.js @@ -1,4 +1,14 @@ -function idmObserveEachOnce(elements, callback, options = {}) { +const idmPhotoModuleLiteralsPM = { + [`Okazja`]: "Okazja", + [`Promocja`]: "Promocja", + [`Zobacz produkt`]: "Zobacz produkt", + [`Dodany`]: "Dodany", + [`Wystąpił błąd`]: "Wystąpił błąd", + [`Do koszyka`]: "Do koszyka", +}; + +// LAZY LOAD +function idmObserveEachOncePM(elements, callback, options = {}) { const observer = new IntersectionObserver( (entries, obs) => { entries.forEach((entry) => { @@ -11,21 +21,27 @@ function idmObserveEachOnce(elements, callback, options = {}) { { threshold: 0.1, ...options, - } + }, ); elements.forEach((el) => observer.observe(el)); return observer; } -idmObserveEachOnce( +idmObserveEachOncePM( document.querySelectorAll(".idm_picture__module"), (entry) => { - idmPictureModuleProducts(entry.target); - } + idmPictureModuleProductsPM(entry.target); + }, ); -function idmGetSingleProdGraphQL(prodId) { +// GRAPHQL QUERY +function idmGetSingleProdGraphQLPM({ + prodId, + opinions = false, + labels = false, + addToBasket = false, +}) { const IDM_PRICE_QUERY = (priceType) => `price { rebateCodeActive price { @@ -114,18 +130,85 @@ function idmGetSingleProdGraphQL(prodId) { id name link + type + ${labels ? "zones" : ""} + ${ + opinions + ? ` + opinion{ + rating + count + }` + : "" + } ${IDM_PRICE_QUERY(app_shop.vars.priceType)} + ${ + addToBasket + ? ` + sizes{ + id + name + code + amount + availability{ + visible + status + } + ${IDM_PRICE_QUERY(app_shop.vars.priceType)} + } + ` + : "" + } } }`; } -async function idmPictureModuleProducts(containerEL) { + +function idmHandleAddToBasketPM(e) { + const formEl = e.target.closest( + `${this.isClosestForm ? "div" : "form"}.add_to_basket`, + ); + if (!formEl) return; +} + +function idmMarkupAddToBasketPM(prodData) { + if (!prodData) return ""; + + const totalAmount = prodData?.sizes?.[0]?.amount || 0; + const prodStatus = prodData?.sizes?.[0]?.availability?.status || "disable"; + + if ( + prodData.type !== "product" || + totalAmount === 0 || + prodStatus === "disable" + ) + return `${idmPhotoModuleLiteralsPM["Zobacz produkt"]}`; + + return `
+ + + + + +
`; +} + +// POBIERANIE I WSTAWIANIE PRODUKTOW +async function idmPictureModuleProductsPM(containerEL) { try { + // TABLICA ID const allProdEl = containerEL.querySelectorAll(".product_info[data-id]"); const productsId = []; allProdEl.forEach((prodEl) => { if (prodEl.dataset?.id) productsId.push(prodEl.dataset?.id); }); + const isLabels = containerEL.dataset.labels === "true"; + const isOpinions = containerEL.dataset.opinions === "true"; + const isAddToBasket = containerEL.dataset.addToBasket === "true"; + + // POBIERANIE PRODUKTOW const res = await fetch("/graphql/v1/", { method: "POST", headers: { @@ -133,8 +216,15 @@ async function idmPictureModuleProducts(containerEL) { }, body: JSON.stringify({ query: `{${productsId.reduce( - (acc, val) => acc + `${idmGetSingleProdGraphQL(val)}`, - "" + (acc, val, index) => + acc + + `${idmGetSingleProdGraphQLPM({ + prodId: val, + labels: isLabels, + opinions: isOpinions, + addToBasket: isAddToBasket, + })}`, + "", )}}`, }), }); @@ -142,16 +232,54 @@ async function idmPictureModuleProducts(containerEL) { const data = await res.json(); const products = Object.values(data?.data)?.map((prod) => prod.product); + // WSTAWIANIE PRODUKTOW allProdEl.forEach((prodEl) => { - const prodData = products.find((p) => p?.id === +prodEl?.dataset?.id); - if (!prodData) return prodEl.closest(".idm_picture__product")?.remove(); + const prodData = products.find((p) => p.id === +prodEl.dataset.id); + if (!prodData) return prodEl.remove(); prodEl.classList.add("--mod-init"); + + // LABELKI + let labelsHTML = ""; + + if (isLabels) { + if (prodData.price?.omnibusPrice?.[app_shop.vars.priceType]?.value) { + if ( + prodData.price?.omnibusPriceDetails + ?.omnibusPriceIsHigherThanSellingPrice + ) + labelsHTML += `${idmPhotoModuleLiteralsPM["Promocja"]}`; + else + labelsHTML += `${idmPhotoModuleLiteralsPM["Okazja"]}`; + } + + prodData.zones?.forEach((zone) => { + labelsHTML += `${zone[0].toUpperCase() + zone.slice(1)}`; + }); + } + + // OPINIE + let opinionsHTML = ""; + if (isOpinions) { + opinionsHTML = ` +
+ + + + + +
+ ${prodData.opinion.rating} / 5.00 + ${prodData.opinion.count} + `; + } + prodEl.innerHTML = ` + ${isLabels ? `${labelsHTML}` : ""} + ${isOpinions ? `
${opinionsHTML}
` : ""} ${prodData.name} - ${ - prodData.price?.price?.[app_shop.vars.priceType]?.formatted - } + ${prodData.price?.price?.[app_shop.vars.priceType]?.formatted} + ${isAddToBasket ? idmMarkupAddToBasketPM(prodData) : ""} `; }); @@ -161,10 +289,17 @@ async function idmPictureModuleProducts(containerEL) { } } +// OTWIERANIE NA MOBILE 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"); - if (!prodContainerEl) return; + + // ClearShow + if (!prodContainerEl) + return document + .querySelector(".idm_picture__product.--show") + ?.classList?.remove("--show"); if (prodContainerEl.classList.contains("--show")) return prodContainerEl.classList.remove("--show"); diff --git a/README.md b/README.md index 264ebae..9b03dc3 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,22 @@ Problemy na które trzeba zwrócić uwagę: - 1. w .env trzeba dodać poprawny basename przy publikacji i przed użyciem komendy build -2. (stare już poprawione) po użyciu komendy build w dist/index.html trzeba dodać . przed linkami do css i js -3. (stare już poprawione) trzeba się upewnić że link do zdjęć będzie poprawny -4. (stare już poprawione) po wejściu na apkę trzeba usunąć z linku /index.html żeby zadziałała z routerem Da się dodać taką apkę do ulubionych linków w panelu idosella ALE - 1. Trzeba dodać ją z nowego panelu 2. Sam link będzie działał ze starego panelu Użyte biblioteki - 1. MUI 2. React Router 3. zustand 4. react shadow 5. react-hot-toast -Dodać contentEditable -przepisać działanie tej listy. Może przygotować gotowy komponent od listy w zustand - -Podpięcie GraphQL - -Jak zrobić Preview - CodeBox - -1. Potrzeba generowania kodu HTML dla preview i codebox -2. Do Preview powinno się dać dodać jakieś funkcje pozwalające zmieniać zustand -3. zmiany w codebox powinny też pozwalać na zmianę zustand'a(może lepiej najpierw generować kod w codebox a później wklejać go do preview? tylko co później z podpinaniem funkcji do np punktów żeby dało się je przesuwać myszką? i pobieranie i używanie danych z GraphQL w Preview?) - -Trzy położenia punktów(+ wycentrowanie położenia boxa produktowego) -xd przez shadow roota stylowanie komponentów z MUI nie działa w preview -poprawić rerenderowanie szczególnie inputow - problem rem em w shadow root - - +Dodać contentEditable Zmiana szerokości kod|preview + +link do instrukcji: +https://docs.google.com/document/d/1pEofWs_tWnTiAyeUEfkG7LUhdyjbsSYI1P1H_B61hWg/edit?tab=t.0 \ No newline at end of file diff --git a/src/styles/theme.js b/src/styles/theme.js index 54b52cc..ba6a398 100644 --- a/src/styles/theme.js +++ b/src/styles/theme.js @@ -1,81 +1,80 @@ -import { createTheme } from '@mui/material/styles'; - +import { createTheme } from "@mui/material/styles"; const theme = createTheme({ palette: { primary: { - main: '#C7FC70', - light: '#F3F9EA', - dark: '#0B4430', - contrastText: '#060606', + main: "#C7FC70", + light: "#F3F9EA", + dark: "#0B4430", + contrastText: "#060606", }, - secondary:{ + secondary: { main: "#A7B2BA", - dark: '#545454', - light: '#F2F2F2', - contrastText: '#060606', + dark: "#545454", + light: "#F2F2F2", + contrastText: "#060606", }, error: { - main: '#d32f2f', + main: "#d32f2f", }, background: { - default: '#eee', + default: "#eee", paper: "#fff", header: "#060606", }, - text:{ - primary: "#060606" + text: { + primary: "#060606", }, - divider: '#060606', + divider: "#060606", }, typography: { fontSize: 16, - fontFamily: 'Arial, sans-serif', + fontFamily: "Arial, sans-serif", h1: { - fontSize: '2.5rem', + fontSize: "2.5rem", fontWeight: 700, lineHeight: 1.2, }, h2: { - fontSize: '2rem', + fontSize: "2rem", fontWeight: 600, lineHeight: 1.3, }, h3: { - fontSize: '1.5rem', + fontSize: "1.5rem", fontWeight: 600, lineHeight: 1.4, }, h4: { - fontSize: '1.25rem', + fontSize: "1.25rem", fontWeight: 500, lineHeight: 1.4, }, h5: { - fontSize: '1.1rem', + fontSize: "1.1rem", fontWeight: 500, lineHeight: 1.5, }, h6: { - fontSize: '1rem', + fontSize: "1rem", fontWeight: 500, lineHeight: 1.5, }, body1: { - fontSize: '1rem', + fontSize: "1rem", lineHeight: 1.5, }, body2: { - fontSize: '0.875rem', + fontSize: "0.875rem", lineHeight: 1.5, }, subtitle1: { - fontSize: '1rem', + fontSize: "1rem", fontWeight: 500, lineHeight: 1.5, }, subtitle2: { - fontSize: '0.875rem', + fontSize: "0.875rem", fontWeight: 500, lineHeight: 1.5, }, @@ -84,7 +83,7 @@ const theme = createTheme({ MuiInputLabel: { styleOverrides: { root: ({ theme }) => ({ - '&.Mui-focused': { + "&.Mui-focused": { color: theme.palette.primary.dark, }, }), @@ -93,17 +92,16 @@ const theme = createTheme({ MuiButton: { variants: [ { - props: { variant: 'contained', color: 'primary' }, + props: { variant: "contained", color: "primary" }, style: { - '&:hover': { - color: '#fff', + "&:hover": { + color: "#fff", }, }, }, ], }, }, - }); -export default theme; \ No newline at end of file +export default theme;