This commit is contained in:
2026-01-21 14:26:16 +01:00
parent 70d32c7d56
commit d8d4d6452f
4 changed files with 185 additions and 70 deletions

1
.gitignore vendored
View File

@@ -7,6 +7,7 @@ yarn-error.log*
pnpm-debug.log* pnpm-debug.log*
lerna-debug.log* lerna-debug.log*
test.html
node_modules node_modules
dist dist
dist-ssr dist-ssr

View File

@@ -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( const observer = new IntersectionObserver(
(entries, obs) => { (entries, obs) => {
entries.forEach((entry) => { entries.forEach((entry) => {
@@ -11,21 +21,27 @@ function idmObserveEachOnce(elements, callback, options = {}) {
{ {
threshold: 0.1, threshold: 0.1,
...options, ...options,
} },
); );
elements.forEach((el) => observer.observe(el)); elements.forEach((el) => observer.observe(el));
return observer; return observer;
} }
idmObserveEachOnce( idmObserveEachOncePM(
document.querySelectorAll(".idm_picture__module"), document.querySelectorAll(".idm_picture__module"),
(entry) => { (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 { const IDM_PRICE_QUERY = (priceType) => `price {
rebateCodeActive rebateCodeActive
price { price {
@@ -114,18 +130,85 @@ function idmGetSingleProdGraphQL(prodId) {
id id
name name
link link
type
${labels ? "zones" : ""}
${
opinions
? `
opinion{
rating
count
}`
: ""
}
${IDM_PRICE_QUERY(app_shop.vars.priceType)} ${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 `<a class="btn --solid --medium add_to_basket__link" href="${prodData.href}">${idmPhotoModuleLiteralsPM["Zobacz produkt"]}</a>`;
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="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>`;
}
// POBIERANIE I WSTAWIANIE PRODUKTOW
async function idmPictureModuleProductsPM(containerEL) {
try { try {
// TABLICA ID
const allProdEl = containerEL.querySelectorAll(".product_info[data-id]"); const allProdEl = containerEL.querySelectorAll(".product_info[data-id]");
const productsId = []; const productsId = [];
allProdEl.forEach((prodEl) => { allProdEl.forEach((prodEl) => {
if (prodEl.dataset?.id) productsId.push(prodEl.dataset?.id); 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/", { const res = await fetch("/graphql/v1/", {
method: "POST", method: "POST",
headers: { headers: {
@@ -133,8 +216,15 @@ async function idmPictureModuleProducts(containerEL) {
}, },
body: JSON.stringify({ body: JSON.stringify({
query: `{${productsId.reduce( 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 data = await res.json();
const products = Object.values(data?.data)?.map((prod) => prod.product); const products = Object.values(data?.data)?.map((prod) => prod.product);
// WSTAWIANIE PRODUKTOW
allProdEl.forEach((prodEl) => { allProdEl.forEach((prodEl) => {
const prodData = products.find((p) => p?.id === +prodEl?.dataset?.id); const prodData = products.find((p) => p.id === +prodEl.dataset.id);
if (!prodData) return prodEl.closest(".idm_picture__product")?.remove(); if (!prodData) return prodEl.remove();
prodEl.classList.add("--mod-init"); 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 += `<span class="label --promo --omnibus">${idmPhotoModuleLiteralsPM["Promocja"]}</span>`;
else
labelsHTML += `<span class="label --bargain --omnibus">${idmPhotoModuleLiteralsPM["Okazja"]}</span>`;
}
prodData.zones?.forEach((zone) => {
labelsHTML += `<span class="label --${zone}">${zone[0].toUpperCase() + zone.slice(1)}</span>`;
});
}
// OPINIE
let opinionsHTML = "";
if (isOpinions) {
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>
</div>
<span class="product_opinions__score">${prodData.opinion.rating} / 5.00 </span>
<span class="product_opinions__count">${prodData.opinion.count}</span>
`;
}
prodEl.innerHTML = ` prodEl.innerHTML = `
${isLabels ? `<strong class="label_icons">${labelsHTML}</strong>` : ""}
${isOpinions ? `<div class="product_opinions">${opinionsHTML}</div>` : ""}
<a class="product_name" href="${prodData.link}">${prodData.name}</a> <a class="product_name" href="${prodData.link}">${prodData.name}</a>
<span class="product_price">${ <span class="product_price">${prodData.price?.price?.[app_shop.vars.priceType]?.formatted}</span>
prodData.price?.price?.[app_shop.vars.priceType]?.formatted ${isAddToBasket ? idmMarkupAddToBasketPM(prodData) : ""}
}</span>
`; `;
}); });
@@ -161,10 +289,17 @@ async function idmPictureModuleProducts(containerEL) {
} }
} }
// OTWIERANIE NA MOBILE
document.body.addEventListener("click", (e) => { document.body.addEventListener("click", (e) => {
if (app_shop.vars.view === 3 || app_shop.vars.view === 4) return; if (app_shop.vars.view === 3 || app_shop.vars.view === 4) return;
const prodContainerEl = e.target.closest(".idm_picture__product"); 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")) if (prodContainerEl.classList.contains("--show"))
return prodContainerEl.classList.remove("--show"); return prodContainerEl.classList.remove("--show");

View File

@@ -1,41 +1,22 @@
Problemy na które trzeba zwrócić uwagę: Problemy na które trzeba zwrócić uwagę:
1. w .env trzeba dodać poprawny basename przy publikacji i przed użyciem komendy build 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 Da się dodać taką apkę do ulubionych linków w panelu idosella ALE
1. Trzeba dodać ją z nowego panelu 1. Trzeba dodać ją z nowego panelu
2. Sam link będzie działał ze starego panelu 2. Sam link będzie działał ze starego panelu
Użyte biblioteki Użyte biblioteki
1. MUI 1. MUI
2. React Router 2. React Router
3. zustand 3. zustand
4. react shadow 4. react shadow
5. react-hot-toast 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 problem rem em w shadow root
Dodać contentEditable
Zmiana szerokości kod|preview Zmiana szerokości kod|preview
link do instrukcji:
https://docs.google.com/document/d/1pEofWs_tWnTiAyeUEfkG7LUhdyjbsSYI1P1H_B61hWg/edit?tab=t.0

View File

@@ -1,81 +1,80 @@
import { createTheme } from '@mui/material/styles'; import { createTheme } from "@mui/material/styles";
const theme = createTheme({ const theme = createTheme({
palette: { palette: {
primary: { primary: {
main: '#C7FC70', main: "#C7FC70",
light: '#F3F9EA', light: "#F3F9EA",
dark: '#0B4430', dark: "#0B4430",
contrastText: '#060606', contrastText: "#060606",
}, },
secondary: { secondary: {
main: "#A7B2BA", main: "#A7B2BA",
dark: '#545454', dark: "#545454",
light: '#F2F2F2', light: "#F2F2F2",
contrastText: '#060606', contrastText: "#060606",
}, },
error: { error: {
main: '#d32f2f', main: "#d32f2f",
}, },
background: { background: {
default: '#eee', default: "#eee",
paper: "#fff", paper: "#fff",
header: "#060606", header: "#060606",
}, },
text: { text: {
primary: "#060606" primary: "#060606",
}, },
divider: '#060606', divider: "#060606",
}, },
typography: { typography: {
fontSize: 16, fontSize: 16,
fontFamily: 'Arial, sans-serif', fontFamily: "Arial, sans-serif",
h1: { h1: {
fontSize: '2.5rem', fontSize: "2.5rem",
fontWeight: 700, fontWeight: 700,
lineHeight: 1.2, lineHeight: 1.2,
}, },
h2: { h2: {
fontSize: '2rem', fontSize: "2rem",
fontWeight: 600, fontWeight: 600,
lineHeight: 1.3, lineHeight: 1.3,
}, },
h3: { h3: {
fontSize: '1.5rem', fontSize: "1.5rem",
fontWeight: 600, fontWeight: 600,
lineHeight: 1.4, lineHeight: 1.4,
}, },
h4: { h4: {
fontSize: '1.25rem', fontSize: "1.25rem",
fontWeight: 500, fontWeight: 500,
lineHeight: 1.4, lineHeight: 1.4,
}, },
h5: { h5: {
fontSize: '1.1rem', fontSize: "1.1rem",
fontWeight: 500, fontWeight: 500,
lineHeight: 1.5, lineHeight: 1.5,
}, },
h6: { h6: {
fontSize: '1rem', fontSize: "1rem",
fontWeight: 500, fontWeight: 500,
lineHeight: 1.5, lineHeight: 1.5,
}, },
body1: { body1: {
fontSize: '1rem', fontSize: "1rem",
lineHeight: 1.5, lineHeight: 1.5,
}, },
body2: { body2: {
fontSize: '0.875rem', fontSize: "0.875rem",
lineHeight: 1.5, lineHeight: 1.5,
}, },
subtitle1: { subtitle1: {
fontSize: '1rem', fontSize: "1rem",
fontWeight: 500, fontWeight: 500,
lineHeight: 1.5, lineHeight: 1.5,
}, },
subtitle2: { subtitle2: {
fontSize: '0.875rem', fontSize: "0.875rem",
fontWeight: 500, fontWeight: 500,
lineHeight: 1.5, lineHeight: 1.5,
}, },
@@ -84,7 +83,7 @@ const theme = createTheme({
MuiInputLabel: { MuiInputLabel: {
styleOverrides: { styleOverrides: {
root: ({ theme }) => ({ root: ({ theme }) => ({
'&.Mui-focused': { "&.Mui-focused": {
color: theme.palette.primary.dark, color: theme.palette.primary.dark,
}, },
}), }),
@@ -93,17 +92,16 @@ const theme = createTheme({
MuiButton: { MuiButton: {
variants: [ variants: [
{ {
props: { variant: 'contained', color: 'primary' }, props: { variant: "contained", color: "primary" },
style: { style: {
'&:hover': { "&:hover": {
color: '#fff', color: "#fff",
}, },
}, },
}, },
], ],
}, },
}, },
}); });
export default theme; export default theme;