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 ( +
+ +
+ {preview && ( + <> + + Produkt {index + 1} + + XX,XX zł + + )} +
+
+ ); + return (