diff --git a/README.md b/README.md
index 5d0aa92..84da4b4 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,7 @@ Użyte biblioteki
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
@@ -29,10 +30,8 @@ Jak zrobić Preview - 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
-za duże plusy - kwestia czcionki apliakcji pewnie
+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
diff --git a/package-lock.json b/package-lock.json
index 7a2af27..7e137a2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,6 +14,7 @@
"@mui/material": "^7.3.6",
"react": "^19.2.0",
"react-dom": "^19.2.0",
+ "react-hot-toast": "^2.6.0",
"react-router-dom": "^7.11.0",
"react-shadow": "^20.6.0",
"zustand": "^5.0.9"
@@ -2267,7 +2268,8 @@
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/debug": {
"version": "4.4.3",
@@ -2724,6 +2726,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/goober": {
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.18.tgz",
+ "integrity": "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "csstype": "^3.0.10"
+ }
+ },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -3302,6 +3313,23 @@
"react": "^19.2.3"
}
},
+ "node_modules/react-hot-toast": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.6.0.tgz",
+ "integrity": "sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg==",
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.1.3",
+ "goober": "^2.1.16"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": ">=16",
+ "react-dom": ">=16"
+ }
+ },
"node_modules/react-is": {
"version": "19.2.3",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz",
diff --git a/package.json b/package.json
index b204e82..c5ec98b 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"@mui/material": "^7.3.6",
"react": "^19.2.0",
"react-dom": "^19.2.0",
+ "react-hot-toast": "^2.6.0",
"react-router-dom": "^7.11.0",
"react-shadow": "^20.6.0",
"zustand": "^5.0.9"
diff --git a/src/App.jsx b/src/App.jsx
index 6f898bd..3d017fa 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -3,22 +3,22 @@ import Home from "./pages/Home";
import "./styles/index.css";
import AppLayout from "./ui/AppLayout";
import Instruction from "./pages/Instruction";
+import { Toaster } from "react-hot-toast";
function App() {
-
return (
- //
- //
- //
-
- }>
- }/>
-
- }>
- }/>
-
-
- )
+ <>
+
+
+ }>
+ } />
+
+ }>
+ } />
+
+
+ >
+ );
}
-export default App
\ No newline at end of file
+export default App;
diff --git a/src/constants/photo.js b/src/constants/photo.js
index 82a9dca..7fd733a 100644
--- a/src/constants/photo.js
+++ b/src/constants/photo.js
@@ -1,17 +1,29 @@
+import { BREAKPOINTS } from "./rwd";
+
// Constants for PhotoModule
-export const DIRECTIONS = ["tl", "tr", "bl", "br"]; // top-left, top-right, bottom-left, bottom-right
-export const DIRECTIONS_NAMES = {
- tl: "Góra Lewo",
- tr: "Góra Prawo",
- bl: "Dół Lewo",
- br: "Dół Prawo",
+
+// top-left, top-right, bottom-left, bottom-right
+export const DIRECTIONS = {
+ "t-l": "Góra Lewo",
+ "t-r": "Góra Prawo",
+ "b-l": "Dół Lewo",
+ "b-r": "Dół Prawo",
};
export const DEFAULT_POINT = {
x: 0,
y: 0,
+
+ positions: {
+ single: { x: 0, y: 0 },
+ // ...Object.BREAKPOINTS
+ desktop: { x: 0, y: 0 },
+ tablet: { x: 0, y: 0 },
+ mobile: { x: 0, y: 0 },
+ },
+
id: 0,
- direction: DIRECTIONS[0],
+ direction: Object.keys(DIRECTIONS)[0],
}; // Default point structure
export const URL_RADIO_DATA = [
diff --git a/src/constants/rwd.js b/src/constants/rwd.js
index b7405a0..eb9024d 100644
--- a/src/constants/rwd.js
+++ b/src/constants/rwd.js
@@ -1,5 +1,5 @@
export const BREAKPOINTS = {
- mobile: 0,
- tablet: 757,
desktop: 979,
+ tablet: 757,
+ mobile: 0,
};
diff --git a/src/features/htmlBuilder/components/CodeBox.jsx b/src/features/htmlBuilder/components/CodeBox.jsx
index a807707..1cf23c2 100644
--- a/src/features/htmlBuilder/components/CodeBox.jsx
+++ b/src/features/htmlBuilder/components/CodeBox.jsx
@@ -1,16 +1,62 @@
-import { TextareaAutosize } from "@mui/material";
+import { Button, TextareaAutosize } from "@mui/material";
import GenericBox from "../../../ui/GenericBox";
+import GeneratePreview from "../generated/GeneratePreview";
+import { useSharedState } from "../../../store/useSharedState";
+import { useEffect, useRef, useState } from "react";
+import toast from "react-hot-toast";
+
+export default function CodeBox() {
+ const state = useSharedState();
+ const hiddenRef = useRef(null);
+ const [code, setCode] = useState("");
+
+ // Whenever state changes, update the string
+ useEffect(() => {
+ if (hiddenRef.current) {
+ setCode(hiddenRef.current.innerHTML);
+ }
+ }, [state.urls, state.urlRadioPoint, state.points, state.photoAlt]); // reactive slices
+
+ const copyCode = () => {
+ navigator.clipboard.writeText("code");
+ toast.success("Skopiowano tekst!");
+ };
+
+ const clearCode = () => {
+ state.clearAll();
+ toast.success("Wyczyszczono kod");
+ };
-function CodeBox() {
return (
+ {/* Hidden live component */}
+
+
+
+
+
+
+
+
+
+
+ {/* Textarea showing the HTML */}
);
}
-
-export default CodeBox;
diff --git a/src/features/htmlBuilder/components/PreviewRWDTabs.jsx b/src/features/htmlBuilder/components/PreviewRWDTabs.jsx
index b43266e..997a375 100644
--- a/src/features/htmlBuilder/components/PreviewRWDTabs.jsx
+++ b/src/features/htmlBuilder/components/PreviewRWDTabs.jsx
@@ -2,6 +2,7 @@ import styled from "@emotion/styled";
import { Button } from "@mui/material";
import { BREAKPOINTS } from "../../../constants/rwd";
import { useSharedState } from "../../../store/useSharedState";
+import { capitalizeFirstLetter } from "../../../utils/capitalizeFirstLetter";
const StyledPreviewTabsContainer = styled("div")({
display: "grid",
@@ -16,16 +17,18 @@ function PreviewRWDTabs() {
return (
- {currentPreviewMode === "single" ? null : Object.keys(BREAKPOINTS).map((key) => (
-
- ))}
+ {currentPreviewMode === "single"
+ ? null
+ : Object.keys(BREAKPOINTS).map((key) => (
+
+ ))}
);
}
diff --git a/src/features/htmlBuilder/generated/GeneratePreview.jsx b/src/features/htmlBuilder/generated/GeneratePreview.jsx
index b551979..8949e39 100644
--- a/src/features/htmlBuilder/generated/GeneratePreview.jsx
+++ b/src/features/htmlBuilder/generated/GeneratePreview.jsx
@@ -12,59 +12,6 @@ function GeneratePreview({ preview = true }) {
);
}
diff --git a/src/features/htmlBuilder/generated/GeneratePreviewSinglePoint.jsx b/src/features/htmlBuilder/generated/GeneratePreviewSinglePoint.jsx
index 3c98c7e..ae76234 100644
--- a/src/features/htmlBuilder/generated/GeneratePreviewSinglePoint.jsx
+++ b/src/features/htmlBuilder/generated/GeneratePreviewSinglePoint.jsx
@@ -3,22 +3,27 @@ import { useSharedState } from "../../../store/useSharedState";
//
function GeneratePreviewSinglePoint({ index, preview, containerRef }) {
- const { x, y, id, direction } = useSharedState(
+ const { positions, id, direction } = useSharedState(
(state) => state.points[index]
);
- const setPoint = useSharedState((state) => state.setSinglePoint); // you need a setter in your store
+ const previewMode = useSharedState((state) => state.previewMode);
+
+ const setSinglePointPosition = useSharedState(
+ (state) => state.setSinglePointPosition
+ ); // you need a setter in your store
+
+ const [directionY, directionX] = direction.split("-");
const onPointerDown = (e) => {
e.preventDefault();
const container = containerRef.current;
- console.log(containerRef);
if (!container) return;
const rect = container.getBoundingClientRect();
const startX = e.clientX;
const startY = e.clientY;
- const initialX = x;
- const initialY = y;
+ const initialX = positions[previewMode].x;
+ const initialY = positions[previewMode].y;
const onPointerMove = (moveEvent) => {
const deltaX = ((moveEvent.clientX - startX) / rect.width) * 100;
@@ -28,7 +33,8 @@ function GeneratePreviewSinglePoint({ index, preview, containerRef }) {
const newX = Math.min(100, Math.max(0, initialX + deltaX));
const newY = Math.min(100, Math.max(0, initialY + deltaY));
- setPoint(index, { x: newX, y: newY });
+ setSinglePointPosition(index, previewMode, "x", newX);
+ setSinglePointPosition(index, previewMode, "y", newY);
};
const onPointerUp = () => {
@@ -40,17 +46,58 @@ function GeneratePreviewSinglePoint({ index, preview, containerRef }) {
window.addEventListener("pointerup", onPointerUp);
};
+ if (preview)
+ return (
+
+ );
+
return (