From e284a36fa8bbd37a48bc7bb4f69b7605fe2d1ff4 Mon Sep 17 00:00:00 2001 From: Tapas Adhikary Date: Sun, 13 Jun 2021 00:20:13 +0530 Subject: [PATCH 1/6] feat: Tested the basic fetch call using the HarperDB. Now hooked a local JSON for building UI --- components/core/App.js | 34 ++++++++++ components/index.js | 1 + data/shapes.js | 146 +++++++++++++++++++++++++++++++++++++++++ pages/index.js | 19 +++--- utils/HarperFetch.js | 12 ++++ 5 files changed, 203 insertions(+), 9 deletions(-) create mode 100644 components/core/App.js create mode 100644 components/index.js create mode 100644 data/shapes.js create mode 100644 utils/HarperFetch.js diff --git a/components/core/App.js b/components/core/App.js new file mode 100644 index 0000000..83edd92 --- /dev/null +++ b/components/core/App.js @@ -0,0 +1,34 @@ +import React, { useEffect, useState } from "react"; + +import { harperFetch } from "../../utils/HarperFetch"; + +import { shapes } from '../../data/shapes'; + +const App = (props) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + + useEffect(async () => { + setData([]); + setLoading(true); + + // fetching the shape data + /*const shapes = await harperFetch({ + operation: "sql", + sql: "SELECT * FROM tryshape.shapes", + });*/ + + console.log(shapes); + + await setData(shapes); + setLoading(false); + }, []); + + return( +
+ Test +
+ ) +}; + +export default App; diff --git a/components/index.js b/components/index.js new file mode 100644 index 0000000..6d884b7 --- /dev/null +++ b/components/index.js @@ -0,0 +1 @@ +export { default as App } from "./core/App"; \ No newline at end of file diff --git a/data/shapes.js b/data/shapes.js new file mode 100644 index 0000000..58e930d --- /dev/null +++ b/data/shapes.js @@ -0,0 +1,146 @@ +const shapes = [ + { + name: "Circle", + type: "circle", + formula: "circle(50% at 50% 50%)", + vertices: 0, + edges: 0, + notes: "A circle is a round shaped figure that has no corners or edges. In geometry, a circle can be defined as a closed, two-dimensional curved shape.", + }, + { + name: "Square", + type: "polygon", + formula: "polygon(10% 10%, 90% 10%, 90% 90%, 10% 90%)", + vertices: 4, + edges: 4, + notes: "A square is closed, two-dimensional shape with 4 equal sides. A square is a quadrilateral.", + }, + { + name: "Rectangle", + type: "polygon", + formula: "polygon(10% 25%, 90% 25%, 90% 75%, 10% 75%)", + vertices: 4, + edges: 4, + notes: "A Rectangle is a four sided-polygon, having all the internal angles equal to 90 degrees. The two sides at each corner or vertex, meet at right angles. The opposite sides of the rectangle are equal in length which makes it different from a square.", + }, + { + name: "Rhombus", + type: "polygon", + formula: "polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)", + vertices: 4, + edges: 4, + notes: "A rhombus is a quadrilateral whose four sides all have the same length. A square and a rhombus both have sides equal in length. But square has all its angles equal to 90 degrees, but a rhombus only has its opposite angles equal.", + }, + { + name: "Ellipse", + type: "ellipse", + formula: "ellipse(25% 40% at 50% 50%);", + vertices: 0, + edges: 0, + notes: "An ellipse is a shape that looks like an oval or a flattened circle.", + }, + { + name: "Triangle", + type: "polygon", + formula: "polygon(50% 0%, 0% 100%, 100% 100%)", + vertices: 3, + edges: 3, + notes: " a triangle is a three-sided polygon that consists of three edges and three vertices. The most important property of a triangle is that the sum of the internal angles of a triangle is equal to 180 degrees.", + }, + { + name: "Parallelogram", + type: "polygon", + formula: "polygon(25% 0%, 100% 0%, 75% 100%, 0% 100%)", + vertices: 4, + edges: 4, + notes: "A parallelogram is a quadrilateral that has its opposite sides parallel and equal to each other. It has its interior opposite angles equal. Also, the angles on the same side of transversal sum up to 180 degrees or supplementary to each other.", + }, + { + name: "Trapezoid", + type: "polygon", + formula: "polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%)", + vertices: 4, + edges: 4, + notes: "A trapezoid(also called, trapezium) is a quadrilateral with at least one pair of parallel sides. No other features matter. The parallel sides may be vertical , horizontal , or slanting .", + }, + { + name: "Pentagon", + type: "polygon", + formula: "polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%)", + vertices: 5, + edges: 5, + notes: "A pentagon is a geometrical shape, which has five sides and five angles. Here, “Penta” denotes five and “gon” denotes angle. An equilateral pentagon is a polygon with five sides of equal length.", + }, + { + name: "Hexagon", + type: "polygon", + formula: + "polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%)", + vertices: 6, + edges: 6, + notes: "A hexagon can be defined as a polygon with six sides. The two-dimensional shape has 6 sides, 6 vertices and 6 angles.", + }, + { + name: "Heptagon", + type: "polygon", + formula: + "polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 0% 60%, 10% 20%)", + vertices: 7, + edges: 7, + notes: "Heptagon is a polygon ( a closed shape made up of line segments) made up of 7 sides and 7 angles. The word heptagon is made up of two words, hepta meaning seven and gon meaning sides.", + }, + { + name: "Octagon", + type: "polygon", + formula: + "polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%)", + vertices: 8, + edges: 8, + notes: "An octagon is a polygon made up of 8 sides. It has eight angles. Octagon = Octa + gon where octa means eight and gon means sides. ", + }, + { + name: "Nonagon", + type: "polygon", + formula: + "polygon(50% 0%, 83% 12%, 100% 43%, 94% 78%, 68% 100%, 32% 100%, 6% 78%, 0% 43%, 17% 12%)", + vertices: 9, + edges: 9, + notes: "A nonagon or enneagon is a nine-sided polygon or 9-gon.", + }, + { + name: "Decagon", + type: "polygon", + formula: + "polygon(50% 0%, 80% 10%, 100% 35%, 100% 70%, 80% 90%, 50% 100%, 20% 90%, 0% 70%, 0% 35%, 20% 10%)", + vertices: 10, + edges: 10, + notes: "A decagon is a ten-sided polygon or 10-gon. The total sum of the interior angles of a simple decagon is 1440°. A self-intersecting regular decagon is known as a decagram.", + }, + { + name: "Cross", + type: "polygon", + formula: + "polygon(30% 0%, 70% 0%, 70% 30%, 100% 30%, 100% 60%, 70% 60%, 70% 100%, 30% 100%, 30% 60%, 0% 60%, 0% 30%, 30% 30%)", + vertices: 12, + edges: 12, + notes: "A cross is a geometrical figure consisting of two intersecting lines or bars, usually perpendicular to each other. The lines usually run vertically and horizontally.", + }, + { + name: "Star", + type: "polygon", + formula: "polygon(10% 100%,50% 0%,90% 100%,0% 40%,100% 40%)", + vertices: 5, + edges: 5, + notes: "A regular star pentagon, has five corner vertices and intersecting edges.", + }, + { + name: "Tag", + type: "polygon", + formula: "polygon(68% 0%,0% 0%,0% 100%,68% 100%,100% 50%)", + vertices: 5, + edges: 5, + notes: "A custom structure that usually represents a Tag.", + }, +]; + +export { shapes }; diff --git a/pages/index.js b/pages/index.js index 5272e9b..0f35788 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,11 +1,12 @@ -import styled from 'styled-components'; +import React from "react"; +import { App } from "../components"; -export default () => ( -
- My First Next.js Page -
-); +const index = (props) => { + return ( +
+ +
+ ); +}; -const Title = styled.h1` - color: #3700ff; -`; \ No newline at end of file +export default index; \ No newline at end of file diff --git a/utils/HarperFetch.js b/utils/HarperFetch.js new file mode 100644 index 0000000..7801f0f --- /dev/null +++ b/utils/HarperFetch.js @@ -0,0 +1,12 @@ +export const harperFetch = async (body) => { + const request = await fetch(process.env.NEXT_PUBLIC_DB_URL, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Basic ${process.env.NEXT_PUBLIC_DB_AUTHORIZATION}`, + }, + body: JSON.stringify(body), + }); + + return request.json(); +}; From 071351920c0c8d527ca4435ca10bf49da6e0350b Mon Sep 17 00:00:00 2001 From: Tapas Adhikary Date: Mon, 14 Jun 2021 09:29:31 +0530 Subject: [PATCH 2/6] feat: Now tested the shapes using the dummy data. --- components/core/App.js | 130 +++++++++++++++++++++++++-- components/utils/StyledComponents.js | 86 ++++++++++++++++++ package.json | 3 + pages/_app.js | 6 ++ styles/global.css | 39 ++++++++ yarn.lock | 23 ++++- 6 files changed, 277 insertions(+), 10 deletions(-) create mode 100644 components/utils/StyledComponents.js create mode 100644 pages/_app.js create mode 100644 styles/global.css diff --git a/components/core/App.js b/components/core/App.js index 83edd92..1f92ddb 100644 --- a/components/core/App.js +++ b/components/core/App.js @@ -1,8 +1,24 @@ import React, { useEffect, useState } from "react"; - +import dynamic from 'next/dynamic'; import { harperFetch } from "../../utils/HarperFetch"; -import { shapes } from '../../data/shapes'; +import { shapes } from "../../data/shapes"; + +const Shape = dynamic(import('react-clip-path'), { ssr: false }) +import Switch from "react-switch"; + +import { + ShapeCards, + ShapeCard, + ShapeName, + ShapePallete, + ShapeDetailsItems, + ShapeActions, + ShapeHeader, + CopyIcon, + DownloadIcon, + LikeIcon, +} from "../utils/StyledComponents"; const App = (props) => { const [data, setData] = useState([]); @@ -19,16 +35,114 @@ const App = (props) => { });*/ console.log(shapes); + let modifiedShapes = shapes.map((shape, index) => { + shape.showAdvanced = false; + return shape; + }); + console.log(modifiedShapes); - await setData(shapes); + await setData(modifiedShapes); setLoading(false); }, []); - return( -
- Test -
- ) + const handleSwicth = (shapeName) => { + console.log(shapeName); + + + let modifiedShapes = data.map((shape, index) => { + if (shape.name === shapeName) { + return { + ...shape, + showAdvanced: !shape.showAdvanced + } + } + return shape; + }); + console.log(modifiedShapes); + setData(...[modifiedShapes]); + } + + const getShapeFileName = (name) => { + return name.split(" ").join("-"); + }; + + async function performCopy(event, formula) { + event.preventDefault(); + try { + await navigator.clipboard.writeText(formula); + console.log("The clip-path formula copied to clipboard"); + } catch (err) { + console.error("Failed to copy: ", err); + } + } + + return ( + +

Available Shapes({shapes.length})

+ + {data.map((shape, index) => ( + + + + {shape.name} + + + + {" "} + + + saveAsPng( + event, + `${getShapeFileName(shape.name)}-id`, + getShapeFileName(shape.name) + ) + } + /> + + + + + + + + {shape.showAdvanced && ( + + + Clip-Path:{" "} + + {shape.formula} + + {" "} + + performCopy(event, shape.formula)} + /> + + + )} + + + ))} + +
+ ); }; export default App; diff --git a/components/utils/StyledComponents.js b/components/utils/StyledComponents.js new file mode 100644 index 0000000..c8cdcd0 --- /dev/null +++ b/components/utils/StyledComponents.js @@ -0,0 +1,86 @@ +import styled from "styled-components"; +import { FiCopy, FiDownload, FiHeart } from 'react-icons/fi'; + +const ShapeCards = styled.div` + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; +`; + +const ShapeCard = styled.div` + height: 100%; + border: 1px solid #ececec; + border-radius: 4px; + padding: 5px; + margin: 5px; + background-color: #ebebeb; +`; + +const ShapeActions = styled.div` + float: right; +`; + +const ShapeName = styled.span` + font-weight: bold; + font-size: 20px; +`; + +const Playground = styled.div` + width: 100%; +`; + +const ShapeDetails = styled.ul` + background-color: #ebebeb; + border-radius: 4px; + padding: 10px; + width: 100%; +`; + +const ShapeDetailsItems = styled.li` + word-wrap: break-word; +`; + +const ShapePallete = styled.div` + margin-top: 5px; +`; + +const ShapeHeader = styled.div` + padding: 5px; + margin: 5px; +`; + +const CopyIcon = styled(FiCopy)` + cursor: pointer; + &:hover { + color: #f71b76; + } +`; + +const DownloadIcon = styled(FiDownload)` + cursor: pointer; + &:hover { + color: #f71b76; + } +`; + +const LikeIcon = styled(FiHeart)` + cursor: pointer; + &:hover { + color: #f71b6f; + } +`; + +export { + ShapeCards, + ShapeCard, + ShapeName, + Playground, + ShapeDetails, + ShapeDetailsItems, + ShapePallete, + CopyIcon, + DownloadIcon, + LikeIcon, + ShapeActions, + ShapeHeader }; \ No newline at end of file diff --git a/package.json b/package.json index 6bc2ddc..b6bc68b 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,10 @@ "dependencies": { "next": "^10.0.0", "react": "17.0.1", + "react-clip-path": "^0.0.6", "react-dom": "17.0.1", + "react-icons": "^4.2.0", + "react-switch": "^6.0.0", "styled-components": "^5.3.0" }, "devDependencies": { diff --git a/pages/_app.js b/pages/_app.js new file mode 100644 index 0000000..12ccda8 --- /dev/null +++ b/pages/_app.js @@ -0,0 +1,6 @@ + +import '../styles/global.css'; + +export default function App({ Component, pageProps }) { + return ; +} diff --git a/styles/global.css b/styles/global.css new file mode 100644 index 0000000..c2308ae --- /dev/null +++ b/styles/global.css @@ -0,0 +1,39 @@ +html, +body { + padding: 0; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, + Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + line-height: 1.6; + font-size: 18px; +} + +* { + box-sizing: border-box; +} + +a { + color: #0070f3; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +img { + max-width: 100%; + display: block; +} + +li { + list-style: none; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; + font-size: 87.5%; + color: #e83e8c; + word-wrap: break-word; +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 3effb4c..e7bf10f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1500,7 +1500,7 @@ process@0.11.10, process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -prop-types@15.7.2: +prop-types@15.7.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -1576,6 +1576,13 @@ raw-body@2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" +react-clip-path@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/react-clip-path/-/react-clip-path-0.0.6.tgz#d9181cf89166d472470207fc2bb4ca059feed207" + integrity sha512-q3uU3GfqKBMzGzSsMYy1g550ctosfGm8+leNJlQTxA2oSqdzrid0lbLEaXrsP7uU01mT6HjYrFxQO6b5uqwHFg== + dependencies: + styled-components "^5.2.1" + react-dom@17.0.1: version "17.0.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6" @@ -1585,6 +1592,11 @@ react-dom@17.0.1: object-assign "^4.1.1" scheduler "^0.20.1" +react-icons@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.2.0.tgz#6dda80c8a8f338ff96a1851424d63083282630d0" + integrity sha512-rmzEDFt+AVXRzD7zDE21gcxyBizD/3NqjbX6cmViAgdqfJ2UiLer8927/QhhrXQV7dEj/1EGuOTPp7JnLYVJKQ== + react-is@16.13.1, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -1595,6 +1607,13 @@ react-refresh@0.8.3: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== +react-switch@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/react-switch/-/react-switch-6.0.0.tgz#bd4a2dea08f211b8a32e55e8314fd44bc1ec947e" + integrity sha512-QV3/6eRK5/5epdQzIqvDAHRoGLbCv/wDpHUi6yBMXY1Xco5XGuIZxvB49PHoV1v/SpEgOCJLD/Zo43iic+aEIw== + dependencies: + prop-types "^15.7.2" + react@17.0.1: version "17.0.1" resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127" @@ -1821,7 +1840,7 @@ strip-ansi@6.0.0: dependencies: ansi-regex "^5.0.0" -styled-components@^5.3.0: +styled-components@^5.2.1, styled-components@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.0.tgz#e47c3d3e9ddfff539f118a3dd0fd4f8f4fb25727" integrity sha512-bPJKwZCHjJPf/hwTJl6TbkSZg/3evha+XPEizrZUGb535jLImwDUdjTNxXqjjaASt2M4qO4AVfoHJNe3XB/tpQ== From 47287702f8e06fa407d451a60ef3130e9aa71a86 Mon Sep 17 00:00:00 2001 From: Tapas Adhikary Date: Mon, 14 Jun 2021 10:45:57 +0530 Subject: [PATCH 3/6] feat: Added the Toaster component. Now showing a success message on copying the clip-path value --- components/core/App.js | 154 ++++++++++++++------------- components/utils/StyledComponents.js | 14 ++- package.json | 1 + pages/_app.js | 11 +- pages/index.js | 4 +- yarn.lock | 12 +++ 6 files changed, 117 insertions(+), 79 deletions(-) diff --git a/components/core/App.js b/components/core/App.js index 1f92ddb..f368d2b 100644 --- a/components/core/App.js +++ b/components/core/App.js @@ -1,10 +1,12 @@ import React, { useEffect, useState } from "react"; -import dynamic from 'next/dynamic'; +import dynamic from "next/dynamic"; import { harperFetch } from "../../utils/HarperFetch"; import { shapes } from "../../data/shapes"; -const Shape = dynamic(import('react-clip-path'), { ssr: false }) +import toast from "react-hot-toast"; + +const Shape = dynamic(import("react-clip-path"), { ssr: false }); import Switch from "react-switch"; import { @@ -13,8 +15,9 @@ import { ShapeName, ShapePallete, ShapeDetailsItems, + ShapeCardSwitch, ShapeActions, - ShapeHeader, + ShapeCardHeader, CopyIcon, DownloadIcon, LikeIcon, @@ -47,20 +50,19 @@ const App = (props) => { const handleSwicth = (shapeName) => { console.log(shapeName); - let modifiedShapes = data.map((shape, index) => { if (shape.name === shapeName) { return { ...shape, - showAdvanced: !shape.showAdvanced - } + showAdvanced: !shape.showAdvanced, + }; } return shape; }); console.log(modifiedShapes); setData(...[modifiedShapes]); - } + }; const getShapeFileName = (name) => { return name.split(" ").join("-"); @@ -70,6 +72,7 @@ const App = (props) => { event.preventDefault(); try { await navigator.clipboard.writeText(formula); + toast.success("Successfully Copied!"); console.log("The clip-path formula copied to clipboard"); } catch (err) { console.error("Failed to copy: ", err); @@ -77,71 +80,78 @@ const App = (props) => { } return ( - -

Available Shapes({shapes.length})

- - {data.map((shape, index) => ( - - - - {shape.name} - - - - {" "} - - - saveAsPng( - event, - `${getShapeFileName(shape.name)}-id`, - getShapeFileName(shape.name) - ) - } - /> - - - - - - - - {shape.showAdvanced && ( - - - Clip-Path:{" "} - - {shape.formula} - - {" "} - - performCopy(event, shape.formula)} - /> - - - )} - - - ))} - -
+ <> + {loading ? ( +

Loading...

+ ) : ( + + + {data.map((shape, index) => ( + + + + {shape.name} + + + + {" "} + + + saveAsPng( + event, + `${getShapeFileName(shape.name)}-id`, + getShapeFileName(shape.name) + ) + } + /> + + + + + + + + + + {shape.showAdvanced && ( + + + Clip-Path:{" "} + + {shape.formula} + + {" "} + + performCopy(event, shape.formula)} + /> + + + )} + + + ))} + + + )} + ); }; diff --git a/components/utils/StyledComponents.js b/components/utils/StyledComponents.js index c8cdcd0..9c98d73 100644 --- a/components/utils/StyledComponents.js +++ b/components/utils/StyledComponents.js @@ -9,7 +9,8 @@ const ShapeCards = styled.div` `; const ShapeCard = styled.div` - height: 100%; + width: 400px; + min-height: 456px; border: 1px solid #ececec; border-radius: 4px; padding: 5px; @@ -45,11 +46,15 @@ const ShapePallete = styled.div` margin-top: 5px; `; -const ShapeHeader = styled.div` +const ShapeCardHeader = styled.div` padding: 5px; margin: 5px; `; +const ShapeCardSwitch = styled.div` + margin: 5px auto auto 9px; +`; + const CopyIcon = styled(FiCopy)` cursor: pointer; &:hover { @@ -77,10 +82,11 @@ export { ShapeName, Playground, ShapeDetails, - ShapeDetailsItems, + ShapeDetailsItems, + ShapeCardSwitch, ShapePallete, CopyIcon, DownloadIcon, LikeIcon, ShapeActions, - ShapeHeader }; \ No newline at end of file + ShapeCardHeader }; \ No newline at end of file diff --git a/package.json b/package.json index b6bc68b..d186957 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "react": "17.0.1", "react-clip-path": "^0.0.6", "react-dom": "17.0.1", + "react-hot-toast": "^2.0.0", "react-icons": "^4.2.0", "react-switch": "^6.0.0", "styled-components": "^5.3.0" diff --git a/pages/_app.js b/pages/_app.js index 12ccda8..2121428 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,6 +1,15 @@ +// styles import '../styles/global.css'; +// toaster +import { Toaster } from "react-hot-toast"; + export default function App({ Component, pageProps }) { - return ; + return ( + <> + + + + ); } diff --git a/pages/index.js b/pages/index.js index 0f35788..eb27a4d 100644 --- a/pages/index.js +++ b/pages/index.js @@ -3,9 +3,9 @@ import { App } from "../components"; const index = (props) => { return ( -
+
-
+ ); }; diff --git a/yarn.lock b/yarn.lock index e7bf10f..919dc6d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -882,6 +882,11 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +goober@^2.0.35: + version "2.0.37" + resolved "https://registry.yarnpkg.com/goober/-/goober-2.0.37.tgz#5598c41f4c19bc1fca2c926e876a58a685faffb8" + integrity sha512-wgj5C7IJX2+MyHZ4TgOA+hLL1mCDW+jGorQ5KCMLF1ofE9gQkfbo1s8txIrzIsAX65XRTm0qaipolId2KMYUkw== + graceful-fs@^4.1.2: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" @@ -1592,6 +1597,13 @@ react-dom@17.0.1: object-assign "^4.1.1" scheduler "^0.20.1" +react-hot-toast@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/react-hot-toast/-/react-hot-toast-2.0.0.tgz#6e83b2937a20b040acb2d5fd08bcf32561b7832a" + integrity sha512-J0J2rcSvKetlziVquwESgk85pV9JB0Dz3RJIZcAEv7CWU2y2z8BQqxmZHZUxjPKIBGPqXAocZch4Kj4oUdX4+w== + dependencies: + goober "^2.0.35" + react-icons@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.2.0.tgz#6dda80c8a8f338ff96a1851424d63083282630d0" From 30f0f81f014a82282ac39625e20278376580f5bd Mon Sep 17 00:00:00 2001 From: Tapas Adhikary Date: Mon, 14 Jun 2021 10:57:19 +0530 Subject: [PATCH 4/6] feat: Added a loading spinner --- components/core/App.js | 24 ++++++++++++++++++++---- package.json | 1 + yarn.lock | 7 +++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/components/core/App.js b/components/core/App.js index f368d2b..4749236 100644 --- a/components/core/App.js +++ b/components/core/App.js @@ -1,14 +1,24 @@ import React, { useEffect, useState } from "react"; import dynamic from "next/dynamic"; + +// harperDb fetch call import { harperFetch } from "../../utils/HarperFetch"; -import { shapes } from "../../data/shapes"; +// Dummy Shape Data +// import { shapes } from "../../data/shapes"; +// Toast import toast from "react-hot-toast"; +// Clip-Path const Shape = dynamic(import("react-clip-path"), { ssr: false }); + +// Switch import Switch from "react-switch"; +// loader +import Loader from "react-loader-spinner"; + import { ShapeCards, ShapeCard, @@ -32,10 +42,10 @@ const App = (props) => { setLoading(true); // fetching the shape data - /*const shapes = await harperFetch({ + const shapes = await harperFetch({ operation: "sql", sql: "SELECT * FROM tryshape.shapes", - });*/ + }); console.log(shapes); let modifiedShapes = shapes.map((shape, index) => { @@ -82,7 +92,13 @@ const App = (props) => { return ( <> {loading ? ( -

Loading...

+ ) : ( diff --git a/package.json b/package.json index d186957..7889cdc 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "react-dom": "17.0.1", "react-hot-toast": "^2.0.0", "react-icons": "^4.2.0", + "react-loader-spinner": "^4.0.0", "react-switch": "^6.0.0", "styled-components": "^5.3.0" }, diff --git a/yarn.lock b/yarn.lock index 919dc6d..510c4c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1614,6 +1614,13 @@ react-is@16.13.1, react-is@^16.7.0, react-is@^16.8.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-loader-spinner@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/react-loader-spinner/-/react-loader-spinner-4.0.0.tgz#43d9e71b0574219f64216933c28ef5faa12262f6" + integrity sha512-RU2vpEej6G4ECei0h3q6bgLU10of9Lw5O+4AwF/mtkrX5oY20Sh/AxoPJ7etbrs/7Q3u4jN5qwCwGLRKCHpk6g== + dependencies: + prop-types "^15.7.2" + react-refresh@0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" From 958887974aa696cb513d905af735700abe171170 Mon Sep 17 00:00:00 2001 From: Tapas Adhikary Date: Mon, 14 Jun 2021 11:26:27 +0530 Subject: [PATCH 5/6] feat: Refactored the code further to move the Shape listing in a separate util component --- components/core/App.js | 127 ++------------------------------ components/index.js | 4 +- components/utils/ShapeList.js | 133 ++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 122 deletions(-) create mode 100644 components/utils/ShapeList.js diff --git a/components/core/App.js b/components/core/App.js index 4749236..0869b81 100644 --- a/components/core/App.js +++ b/components/core/App.js @@ -6,36 +6,15 @@ import { harperFetch } from "../../utils/HarperFetch"; // Dummy Shape Data // import { shapes } from "../../data/shapes"; - -// Toast -import toast from "react-hot-toast"; - -// Clip-Path -const Shape = dynamic(import("react-clip-path"), { ssr: false }); - -// Switch -import Switch from "react-switch"; - // loader import Loader from "react-loader-spinner"; -import { - ShapeCards, - ShapeCard, - ShapeName, - ShapePallete, - ShapeDetailsItems, - ShapeCardSwitch, - ShapeActions, - ShapeCardHeader, - CopyIcon, - DownloadIcon, - LikeIcon, -} from "../utils/StyledComponents"; +// ShapeListing +import { ShapeList } from '..'; const App = (props) => { const [data, setData] = useState([]); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); useEffect(async () => { setData([]); @@ -46,48 +25,19 @@ const App = (props) => { operation: "sql", sql: "SELECT * FROM tryshape.shapes", }); - console.log(shapes); let modifiedShapes = shapes.map((shape, index) => { shape.showAdvanced = false; return shape; }); + console.log(modifiedShapes); await setData(modifiedShapes); setLoading(false); }, []); - const handleSwicth = (shapeName) => { - console.log(shapeName); - - let modifiedShapes = data.map((shape, index) => { - if (shape.name === shapeName) { - return { - ...shape, - showAdvanced: !shape.showAdvanced, - }; - } - return shape; - }); - console.log(modifiedShapes); - setData(...[modifiedShapes]); - }; - - const getShapeFileName = (name) => { - return name.split(" ").join("-"); - }; - - async function performCopy(event, formula) { - event.preventDefault(); - try { - await navigator.clipboard.writeText(formula); - toast.success("Successfully Copied!"); - console.log("The clip-path formula copied to clipboard"); - } catch (err) { - console.error("Failed to copy: ", err); - } - } + return ( <> @@ -100,72 +50,7 @@ const App = (props) => { width={300} /> ) : ( - - - {data.map((shape, index) => ( - - - - {shape.name} - - - - {" "} - - - saveAsPng( - event, - `${getShapeFileName(shape.name)}-id`, - getShapeFileName(shape.name) - ) - } - /> - - - - - - - - - - {shape.showAdvanced && ( - - - Clip-Path:{" "} - - {shape.formula} - - {" "} - - performCopy(event, shape.formula)} - /> - - - )} - - - ))} - - + )} ); diff --git a/components/index.js b/components/index.js index 6d884b7..b259ebd 100644 --- a/components/index.js +++ b/components/index.js @@ -1 +1,3 @@ -export { default as App } from "./core/App"; \ No newline at end of file +export { default as App } from "./core/App"; + +export { default as ShapeList } from './utils/ShapeList'; \ No newline at end of file diff --git a/components/utils/ShapeList.js b/components/utils/ShapeList.js new file mode 100644 index 0000000..54cf3d8 --- /dev/null +++ b/components/utils/ShapeList.js @@ -0,0 +1,133 @@ +import React, { useState } from "react"; +import dynamic from "next/dynamic"; + +// Toast +import toast from "react-hot-toast"; + +// Clip-Path +const Shape = dynamic(import("react-clip-path"), { ssr: false }); + +// Switch +import Switch from "react-switch"; + +// Shape Listing Styled-Componentns +import { + ShapeCards, + ShapeCard, + ShapeName, + ShapePallete, + ShapeDetailsItems, + ShapeCardSwitch, + ShapeActions, + ShapeCardHeader, + CopyIcon, + DownloadIcon, + LikeIcon, + } from './StyledComponents'; + +const ShapeList = ({ data }) => { + + const [shapes, setShapes] = useState(data); + + const handleSwicth = (shapeName) => { + console.log(shapeName); + + let modifiedShapes = shapes.map((shape, index) => { + if (shape.name === shapeName) { + return { + ...shape, + showAdvanced: !shape.showAdvanced, + }; + } + return shape; + }); + console.log(modifiedShapes); + setShapes(...[modifiedShapes]); + }; + + const getShapeFileName = (name) => { + return name.split(" ").join("-"); + }; + + async function performCopy(event, formula) { + event.preventDefault(); + try { + await navigator.clipboard.writeText(formula); + toast.success("Successfully Copied!"); + console.log("The clip-path formula copied to clipboard"); + } catch (err) { + console.error("Failed to copy: ", err); + } + } + + return ( + + + {shapes.map((shape, index) => ( + + + + {shape.name} + + + + {" "} + + + saveAsPng( + event, + `${getShapeFileName(shape.name)}-id`, + getShapeFileName(shape.name) + ) + } + /> + + + + + + + + + + {shape.showAdvanced && ( + + + Clip-Path:{" "} + + {shape.formula} + + {" "} + + performCopy(event, shape.formula)} + /> + + + )} + + + ))} + + + ); +}; + +export default ShapeList; From 8e483c2d224d006afbd7b41d9ef04d58f408da24 Mon Sep 17 00:00:00 2001 From: Tapas Adhikary Date: Mon, 14 Jun 2021 11:29:27 +0530 Subject: [PATCH 6/6] fix: Fixed the missing Html tag warning in the _document.js file --- pages/_document.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pages/_document.js b/pages/_document.js index 4baa7dd..ca99567 100644 --- a/pages/_document.js +++ b/pages/_document.js @@ -1,4 +1,4 @@ -import Document, { Head, Main, NextScript } from 'next/document'; +import Document, { Html, Head, Main, NextScript } from 'next/document'; // Import styled components ServerStyleSheet import { ServerStyleSheet } from 'styled-components'; @@ -21,7 +21,7 @@ export default class MyDocument extends Document { render() { return ( - + {/* Step 5: Output the styles in the head */} {this.props.styleTags} @@ -30,7 +30,7 @@ export default class MyDocument extends Document {
- + ); } } \ No newline at end of file