This commit is contained in:
2026-01-20 13:16:32 +01:00
parent e6a9465195
commit 70d32c7d56
14 changed files with 439 additions and 63 deletions

View File

@@ -133,7 +133,7 @@ async function idmPictureModuleProducts(containerEL) {
},
body: JSON.stringify({
query: `{${productsId.reduce(
(acc, val, index) => acc + `${idmGetSingleProdGraphQL(val)}`,
(acc, val) => acc + `${idmGetSingleProdGraphQL(val)}`,
""
)}}`,
}),
@@ -143,8 +143,8 @@ async function idmPictureModuleProducts(containerEL) {
const products = Object.values(data?.data)?.map((prod) => prod.product);
allProdEl.forEach((prodEl) => {
const prodData = products.find((p) => p.id === +prodEl.dataset.id);
if (!prodData) return;
const prodData = products.find((p) => p?.id === +prodEl?.dataset?.id);
if (!prodData) return prodEl.closest(".idm_picture__product")?.remove();
prodEl.classList.add("--mod-init");
prodEl.innerHTML = `

View File

@@ -132,7 +132,6 @@ PULSE ANIMATION
z-index: -1;
}
.product_info{
bottom: var(--photo-prod-box-dir-t, auto);
top: var(--photo-prod-box-dir-b, auto);
@@ -148,6 +147,115 @@ PULSE ANIMATION
left: var(--photo-prod-box-dir-l-before, auto);
}
.product_info[data-dir-single-x="l"] {
--photo-prod-box-dir-l: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-l-before: 0;
}
.product_info[data-dir-single-x="r"] {
--photo-prod-box-dir-r: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-r-before: 0;
}
.product_info[data-dir-single-y="t"] {
--photo-prod-box-dir-t: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-t-before: 0;
}
.product_info[data-dir-single-y="b"] {
--photo-prod-box-dir-b: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-b-before: 0;
}
.product_info[data-dir-single-x="l"][data-dir-single-y="t"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-tl);
}
.product_info[data-dir-single-x="r"][data-dir-single-y="t"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-tr);
}
.product_info[data-dir-single-x="l"][data-dir-single-y="b"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-bl);
}
.product_info[data-dir-single-x="r"][data-dir-single-y="b"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-br);
}
@media (max-width: 756px) {
.product_info[data-dir-mobile-x="l"] {
--photo-prod-box-dir-l: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-l-before: 0;
}
.product_info[data-dir-mobile-x="r"] {
--photo-prod-box-dir-r: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-r-before: 0;
}
.product_info[data-dir-mobile-y="t"] {
--photo-prod-box-dir-t: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-t-before: 0;
}
.product_info[data-dir-mobile-y="b"] {
--photo-prod-box-dir-b: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-b-before: 0;
}
.product_info[data-dir-mobile-x="l"][data-dir-mobile-y="b"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-bl);
}
}
@media (min-width: 757px) and (max-width: 978px) {
.product_info[data-dir-tablet-x="l"] {
--photo-prod-box-dir-l: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-l-before: 0;
}
.product_info[data-dir-tablet-x="r"] {
--photo-prod-box-dir-r: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-r-before: 0;
}
.product_info[data-dir-tablet-y="t"] {
--photo-prod-box-dir-t: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-t-before: 0;
}
.product_info[data-dir-tablet-y="b"] {
--photo-prod-box-dir-b: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-b-before: 0;
}
.product_info[data-dir-tablet-x="r"][data-dir-tablet-y="b"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-br);
}
}
@media (min-width: 979px) {
.product_info[data-dir-desktop-x="l"] {
--photo-prod-box-dir-l: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-l-before: 0;
}
.product_info[data-dir-desktop-x="r"] {
--photo-prod-box-dir-r: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-r-before: 0;
}
.product_info[data-dir-desktop-y="t"] {
--photo-prod-box-dir-t: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-t-before: 0;
}
.product_info[data-dir-desktop-y="b"] {
--photo-prod-box-dir-b: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-b-before: 0;
}
.product_info[data-dir-desktop-x="l"][data-dir-desktop-y="t"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-tl);
}
}
.idm_picture__product .product_info .product_name{
font-size: 1.6rem;
color: var(--photo-prod-box-text);
@@ -162,17 +270,15 @@ PULSE ANIMATION
}
@media(min-width: 979px){
.idm_picture__product:hover .product_info{
:is(.idm_picture__product:hover, .idm_picture__product:has(.idm_picture__product_point:focus-within)) .product_info{
display: flex;
animation: idmShowUp 0.3s ease-in-out;
/* opacity: 1; */
}
}
@media(max-width: 978px){
.idm_picture__product.--show .product_info{
display: flex;
animation: idmShowUp 0.3s ease-in-out;
/* opacity: 1; */
}
}

BIN
public/instruction.pdf Normal file

Binary file not shown.

View File

@@ -1,7 +1,6 @@
import { BREAKPOINTS } from "../../../constants/rwd";
import { useDragMove } from "../../../hooks/useDragMove";
import { usePrepareRWDStyle } from "../../../hooks/usePrepareRWDStyle";
import { useSharedState } from "../../../store/useSharedState";
import { dragMove } from "../../../utils/dragMove";
// Problemy - unikalne id elementu pod SEO
function GeneratePreviewSinglePoint({
@@ -12,12 +11,13 @@ function GeneratePreviewSinglePoint({
}) {
const { positions, id } = useSharedState((state) => state.points[index]);
const previewMode = useSharedState((state) => state.previewMode);
const product = useSharedState((state) => state.products[id]);
const setSinglePointPosition = useSharedState(
(state) => state.setSinglePointPosition
(state) => state.setSinglePointPosition,
); // you need a setter in your store
const onPointerDown = useDragMove({
const onPointerDown = dragMove({
ref: containerRef,
x: positions[previewMode].x,
y: positions[previewMode].y,
@@ -27,19 +27,14 @@ function GeneratePreviewSinglePoint({
const prodBoxUniqueId = `prod-id-${id}-${uniqueId}`;
const generatePointStyles = (mode) => {
const generatePointDataAttribbutes = (mode) => {
const [dirY, dirX] = positions[mode].direction.split("-");
return `#${prodBoxUniqueId}{
--photo-prod-box-dir-${dirY}: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-${dirX}: calc(100% + var(--photo-box-offset));
const dataAttributeName = preview ? "single" : mode;
--photo-prod-box-dir-${dirY}-before: 0;
--photo-prod-box-dir-${dirX}-before: 0;
--photo-prod-box-radius: var(--photo-prod-box-radius-${
dirY + dirX
});
}`;
return {
[`data-dir-${dataAttributeName}-x`]: dirX,
[`data-dir-${dataAttributeName}-y`]: dirY,
};
};
if (preview)
@@ -56,18 +51,25 @@ function GeneratePreviewSinglePoint({
className="idm_picture__product_point"
aria-describedby={prodBoxUniqueId}
aria-label="Product Info"
tabIndex="-1"
onPointerDown={onPointerDown}
>
+
</button>
<div className="product_info" id={prodBoxUniqueId} data-id={id}>
<div
className="product_info"
id={prodBoxUniqueId}
data-id={id}
{...generatePointDataAttribbutes(previewMode)}
>
<a className="product_name" href="#">
Produkt {index + 1}
{product ? product?.name : `Produkt ${index + 1}`}
</a>
<span className="product_price">XX,XX </span>
<span className="product_price">
{product
? product?.price?.price?.gross?.formatted
: `Produkt ${index + 1}`}
</span>
</div>
<style>{generatePointStyles(previewMode)}</style>
</div>
);
@@ -90,23 +92,23 @@ function GeneratePreviewSinglePoint({
<button
className="idm_picture__product_point"
aria-describedby={prodBoxUniqueId}
aria-label="Product Info"
tabIndex="-1"
tabIndex={-1}
aria-hidden="true"
>
+
</button>
<div className="product_info" id={prodBoxUniqueId} data-id={id}></div>
<style>
{previewMode === "single" ? (
<style>{generatePointStyles("single")}</style>
) : (
usePrepareRWDStyle({
desktopStyle: generatePointStyles("desktop"),
mobileStyle: generatePointStyles("mobile"),
tabletStyle: generatePointStyles("tablet"),
})
)}
</style>
<div
className="product_info"
id={prodBoxUniqueId}
data-id={id}
{...(previewMode === "single"
? generatePointDataAttribbutes(previewMode)
: {
...generatePointDataAttribbutes("mobile"),
...generatePointDataAttribbutes("tablet"),
...generatePointDataAttribbutes("desktop"),
})}
></div>
</div>
);
}

View File

@@ -135,7 +135,6 @@ PULSE ANIMATION
z-index: -1;
}
.product_info{
bottom: var(--photo-prod-box-dir-t, auto);
top: var(--photo-prod-box-dir-b, auto);
@@ -151,6 +150,115 @@ PULSE ANIMATION
left: var(--photo-prod-box-dir-l-before, auto);
}
.product_info[data-dir-single-x="l"] {
--photo-prod-box-dir-l: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-l-before: 0;
}
.product_info[data-dir-single-x="r"] {
--photo-prod-box-dir-r: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-r-before: 0;
}
.product_info[data-dir-single-y="t"] {
--photo-prod-box-dir-t: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-t-before: 0;
}
.product_info[data-dir-single-y="b"] {
--photo-prod-box-dir-b: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-b-before: 0;
}
.product_info[data-dir-single-x="l"][data-dir-single-y="t"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-tl);
}
.product_info[data-dir-single-x="r"][data-dir-single-y="t"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-tr);
}
.product_info[data-dir-single-x="l"][data-dir-single-y="b"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-bl);
}
.product_info[data-dir-single-x="r"][data-dir-single-y="b"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-br);
}
@media (max-width: 756px) {
.product_info[data-dir-mobile-x="l"] {
--photo-prod-box-dir-l: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-l-before: 0;
}
.product_info[data-dir-mobile-x="r"] {
--photo-prod-box-dir-r: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-r-before: 0;
}
.product_info[data-dir-mobile-y="t"] {
--photo-prod-box-dir-t: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-t-before: 0;
}
.product_info[data-dir-mobile-y="b"] {
--photo-prod-box-dir-b: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-b-before: 0;
}
.product_info[data-dir-mobile-x="l"][data-dir-mobile-y="b"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-bl);
}
}
@media (min-width: 757px) and (max-width: 978px) {
.product_info[data-dir-tablet-x="l"] {
--photo-prod-box-dir-l: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-l-before: 0;
}
.product_info[data-dir-tablet-x="r"] {
--photo-prod-box-dir-r: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-r-before: 0;
}
.product_info[data-dir-tablet-y="t"] {
--photo-prod-box-dir-t: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-t-before: 0;
}
.product_info[data-dir-tablet-y="b"] {
--photo-prod-box-dir-b: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-b-before: 0;
}
.product_info[data-dir-tablet-x="r"][data-dir-tablet-y="b"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-br);
}
}
@media (min-width: 979px) {
.product_info[data-dir-desktop-x="l"] {
--photo-prod-box-dir-l: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-l-before: 0;
}
.product_info[data-dir-desktop-x="r"] {
--photo-prod-box-dir-r: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-r-before: 0;
}
.product_info[data-dir-desktop-y="t"] {
--photo-prod-box-dir-t: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-t-before: 0;
}
.product_info[data-dir-desktop-y="b"] {
--photo-prod-box-dir-b: calc(100% + var(--photo-box-offset));
--photo-prod-box-dir-b-before: 0;
}
.product_info[data-dir-desktop-x="l"][data-dir-desktop-y="t"] {
--photo-prod-box-radius: var(--photo-prod-box-radius-tl);
}
}
.idm_picture__product .product_info .product_name{
font-size: 1.6em;
color: var(--photo-prod-box-text);
@@ -165,17 +273,15 @@ PULSE ANIMATION
}
@media(min-width: 979px){
.idm_picture__product:hover .product_info{
:is(.idm_picture__product:hover, .idm_picture__product:has(.idm_picture__product_point:focus-within)) .product_info{
display: flex;
animation: idmShowUp 0.3s ease-in-out;
/* opacity: 1; */
}
}
@media(max-width: 978px){
.idm_picture__product.--show .product_info{
display: flex;
animation: idmShowUp 0.3s ease-in-out;
/* opacity: 1; */
}
}

View File

@@ -4,12 +4,18 @@ import { useSharedState } from "../../store/useSharedState";
import PhotoPointPosition from "./PhotoPointPosition";
import PhotoPointCheckbox from "./PhotoPointCheckbox";
import PhotoPointDirection from "./PhotoPointDirection";
import { getProductOnce } from "../../services/productService";
function PhotoSinglePoint({ index }) {
const setSinglePoint = useSharedState((state) => state.setSinglePoint);
const removeSinglePoint = useSharedState((state) => state.removeSinglePoint);
const id = useSharedState((state) => state.points[index].id);
const handleChange = (id) => {
setSinglePoint(index, { id });
getProductOnce(id);
};
return (
<GenericBox
variant="inner"
@@ -21,7 +27,7 @@ function PhotoSinglePoint({ index }) {
type="text"
name="id produktu"
value={id}
onChange={(e) => setSinglePoint(index, { id: e.target.value })}
onChange={(e) => handleChange(e.target.value)}
/>
<PhotoPointPosition index={index} />
<PhotoPointDirection index={index} />

View File

@@ -0,0 +1,81 @@
export const PRICE = (priceType = "gross") => `price {
rebateCodeActive
price {
${priceType} {
value
formatted
}
}
omnibusPrice {
${priceType} {
value
formatted
}
}
omnibusPriceDetails {
unit {
${priceType} {
value
formatted
}
}
youSavePercent
omnibusPriceIsHigherThanSellingPrice
newPriceEffectiveUntil {
formatted
}
}
max {
${priceType} {
value
formatted
}
}
unit {
${priceType} {
value
formatted
}
}
unitConvertedPrice {
${priceType} {
value
formatted
}
}
youSavePercent
beforeRebate {
${priceType} {
value
formatted
}
}
beforeRebateDetails {
youSavePercent
unit {
${priceType} {
value
formatted
}
}
}
advancePrice {
${priceType} {
value
formatted
}
}
suggested {
${priceType} {
value
formatted
}
}
rebateNumber {
number
${priceType} {
value
formatted
}
}
}`;

View File

@@ -0,0 +1,33 @@
import { PRICE } from "./price.query";
export const PRODUCT = (
prodId,
priceType = "gross"
) => `product(productId: ${prodId}) {
product {
id
name
link
${PRICE(priceType)}
}
}`;
export async function getProduct(id) {
try {
const res = await fetch("/graphql/v1/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ query: `{${PRODUCT(id)}}` }),
});
const data = await res.json();
const product = data?.data?.product?.product;
if (!product) throw new Error("Nie znaleziono Produktu");
return product;
} catch (err) {
console.error(err);
return false;
}
}

View File

@@ -1,9 +1,22 @@
function Instruction() {
return (
<div>
Tu miała być instrukcja
</div>
)
<iframe
src={`${import.meta.env.VITE_PUBLIC_URL}/instruction.pdf`}
style={{ width: "100%", height: "100vh" }}
></iframe>
);
}
export default Instruction
export default Instruction;
/*
<object
type="application/pdf"
src={link}
style={{ width: "100%", height: "100vh" }}
>
<p>
PDF cannot be displayed. <a href={link}>Download PDF</a>
</p>
</object>
*/

View File

@@ -0,0 +1,20 @@
import { getProduct } from "../graphql/product.query";
import { useSharedState } from "../store/useSharedState";
export async function getProductOnce(id) {
if (import.meta.env.MODE === "development") return false;
try {
const { products, addProduct } = useSharedState.getState();
if (products[id]) return true;
const product = await getProduct(id);
if (!product) throw new Error("Nie znaleziono produktu");
addProduct(product);
return true;
} catch (err) {
console.error(err);
}
}

View File

@@ -12,6 +12,7 @@ const defaultState = {
export const useSharedState = create((set, get) => ({
//DATA
...defaultState,
products: {},
//SETTERS/UPDATERS
setUrl: (type, url) =>
@@ -61,4 +62,12 @@ export const useSharedState = create((set, get) => ({
})),
clearAll: () => set(() => ({ ...defaultState })),
addProduct: (prod) =>
set((state) => ({
products: {
...state.products,
[prod.id]: prod,
},
})),
}));

View File

@@ -13,7 +13,7 @@ const StyledAppLayout = styled("div")(({ showSidebar }) => ({
const StyledMain = styled("main")({
padding: "4rem",
margin: "0 auto",
maxWidth: "1200px",
maxWidth: "1800px",
width: "100%",
height: "100%",
});

View File

@@ -1,5 +1,5 @@
// onPointerDown
export function useDragMove({ ref, x, y, changeXFn, changeYFn }) {
export function dragMove({ ref, x, y, changeXFn, changeYFn }) {
return function (e) {
e.preventDefault();
const container = ref.current;

View File

@@ -1,6 +1,6 @@
import { BREAKPOINTS } from "../constants/rwd";
export function usePrepareRWDStyle({ mobileStyle, desktopStyle, tabletStyle }) {
export function prepareRWDStyle({ mobileStyle, desktopStyle, tabletStyle }) {
return `
@media(max-width: ${BREAKPOINTS.tablet - 1}px){
${mobileStyle}