diff --git a/components/core/CreateShape.js b/components/core/CreateShape.js
index 6be3752..3ed2bf0 100644
--- a/components/core/CreateShape.js
+++ b/components/core/CreateShape.js
@@ -1,436 +1,297 @@
-import React, { useState, useEffect } from "react";
-
-// axios
+import React, { useState, useEffect, useRef } from "react";
import axios from "axios";
-
-// Bootstrap
-import Container from "react-bootstrap/Container";
-import Row from "react-bootstrap/Row";
-import Col from "react-bootstrap/Col";
-import Modal from "react-bootstrap/Modal";
-import Button from "react-bootstrap/Button";
-
-// ShapeForm and ShapePreview Components
+import { Container, Row, Col, Modal, Button } from "react-bootstrap";
import { ShapeForm, ShapePreview } from "..";
-
-// Toast
import toast from "react-hot-toast";
-
-// shapecalculation functions
-import {
- generateNewVerticeCoordinates,
- generateNewFormula,
- handleFormulaChange,
- calculateRadiusAndFormulaFromMovement,
- separateXYValueIntoObject,
+import {
+ generateNewVerticeCoordinates,
+ generateNewFormula,
+ handleFormulaChange,
+ calculateRadiusAndFormulaFromMovement,
+ separateXYValueIntoObject,
} from "../../utils/shape-calculations.js";
-
-// shapecalculation data
-import { initialState, polygonInitialState, circleInitialState, ellipseInitialState } from "../../utils/shape-initial-data.js";
+import {
+ initialState,
+ polygonInitialState,
+ circleInitialState,
+ ellipseInitialState,
+} from "../../utils/shape-initial-data.js";
const CreateShape = (props) => {
+ const [shapes, setShapes] = useState([]);
+ const [shapeInformation, setShapeInformation] = useState({ ...initialState });
+ const [loading, setLoading] = useState(false);
+ const [page, setPage] = useState(1);
+ const [hasMore, setHasMore] = useState(true);
- // shapeInformation holds all information about the shape
- const [shapeInformation, setShapeInformation] = useState({
- ...initialState,
+ const loadMoreRef = useRef();
+
+ useEffect(() => {
+ if (props.edit) {
+ loadShapeForEdit(props.shape);
+ }
+ loadShapes();
+ }, []);
+
+ const loadShapeForEdit = (shapeToEdit) => {
+ setShapeInformation({
+ name: shapeToEdit.name,
+ formula: shapeToEdit.formula,
+ vertices: shapeInformation.vertices,
+ visibility: shapeInformation.private,
+ edges: shapeInformation.edges,
+ notes: shapeInformation.notes,
+ type: shapeInformation.clipPathType,
+ backgroundColor: shapeInformation.backgroundColor,
+ createdBy: props.user.email,
+ likes: 0
});
+ };
+
+ const loadShapes = async () => {
+ if (loading) return;
+
+ setLoading(true);
+
+ try {
+ const response = await axios.get(`/api/shapes?page=${page}`);
+ const newShapes = response.data.shapes;
+
+ if (newShapes.length === 0) {
+ setHasMore(false);
+ } else {
+ setShapes((prevShapes) => [...prevShapes, ...newShapes]);
+ setPage(page + 1);
+ }
+ } catch (error) {
+ console.error("Error loading shapes: ", error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const handleChange = (event, data, number, type) => {
+ const name = event.target.name || event.type;
+ const value = event.target.type === "checkbox" ? event.target.checked : event.target.value;
+
+ if (name === "name") {
+ setShapeInformation({
+ ...shapeInformation,
+ name: value,
+ });
+ return;
+ }
- // Checks if edit is true and will provide different initial values
- useEffect(() => {
-
- if (props.edit) {
- let formula = props.shape.formula;
- let slicedFormula = formula.slice(formula.indexOf("(") + 1, formula.indexOf(")"));
- let newVerticeCoordinates = [];
- let width = "0%";
- let height = "0%";
-
- if (!formula.includes("()")) {
-
- if (props.shape.type === "polygon") {
- newVerticeCoordinates = slicedFormula.split(",");
- newVerticeCoordinates = newVerticeCoordinates.map((value) => {
- return separateXYValueIntoObject(value.trim());
- });
- }
-
- if (props.shape.type === "circle" && formula.includes("at")) {
- let splitFormula = slicedFormula.split("at");
-
- width = splitFormula[0].trim();
-
- newVerticeCoordinates = [separateXYValueIntoObject(splitFormula[1].trim())];
- }
-
- if (props.shape.type === "ellipse" && formula.includes("at")) {
- let splitFormula = slicedFormula.split("at");
- let widthHeightValues = separateXYValueIntoObject(splitFormula[0].trim());
-
- width = widthHeightValues[0];
- height = widthHeightValues[1];
-
- newVerticeCoordinates = [separateXYValueIntoObject(splitFormula[1].trim())];
- }
-
- }
-
- setShapeInformation({
- ...shapeInformation,
- "name": props.shape.name,
- "formula": props.shape.formula,
- "vertices": props.shape.vertices,
- "private": props.shape.private,
- "edges": props.shape.edges,
- "notes": props.shape.notes,
- "clipPathType": props.shape.type,
- "backgroundColor": props.shape.backgroundColor,
- "verticeCoordinates" : newVerticeCoordinates,
- "width": width,
- "height": height,
- });
- }
+ if (name === "formula") {
+ const edgeVerticeNumber = shapeInformation.clipPathType === "polygon" && value !== "" ? value.split(",").length : 0;
+
+ if (value === "") {
+ handleFormulaChange(`${shapeInformation.clipPathType}()`, edgeVerticeNumber, setShapeInformation);
+ } else if (value.includes("polygon")) {
+ handleFormulaChange(value, edgeVerticeNumber, setShapeInformation, "polygon");
+ } else if (value.includes("circle")) {
+ handleFormulaChange(value, edgeVerticeNumber, setShapeInformation, "circle");
+ } else if (value.includes("ellipse")) {
+ handleFormulaChange(value, edgeVerticeNumber, setShapeInformation, "ellipse");
+ } else {
+ handleFormulaChange(value, edgeVerticeNumber, setShapeInformation);
+ }
+ return;
+ }
- }, [props.show]);
-
- // Changes shapeInformation when something in ShapeForm or ShapePreview is altered
- const handleChange = (event, data, number, type) => {
-
- const name = event.target.name || event.type;
- const value = event.target.type === "checkbox" ? event.target.checked : event.target.value;
-
- // Handles name changes
- if (name === "name") {
- setShapeInformation({
- ...shapeInformation,
- "name": value,
- });
- return;
- }
-
- // If formula value is changed, alter formula value and verticeCoordinates value depending on clipPathType
- if (name === "formula") {
-
- const edgeVerticeNumber = shapeInformation.clipPathType === "polygon" && value !== "" ? value.split(",").length: 0;
-
- // If user deletes all, set formula to the Clip-Path type with an empty set of parentheses
- if (value === "") {
- handleFormulaChange(`${shapeInformation.clipPathType}()`, edgeVerticeNumber, setShapeInformation);
- } else if (value.includes("polygon")) {
- handleFormulaChange(value, edgeVerticeNumber, setShapeInformation, "polygon");
- } else if (value.includes("circle")) {
- handleFormulaChange(value, edgeVerticeNumber, setShapeInformation, "circle");
- } else if (value.includes("ellipse")) {
- handleFormulaChange(value, edgeVerticeNumber, setShapeInformation, "ellipse");
- } else {
- handleFormulaChange(value, edgeVerticeNumber, setShapeInformation);
- }
- return;
+ if (name === "clipPathType") {
+ if (value === "polygon") {
+ setShapeInformation({
+ ...shapeInformation,
+ ...polygonInitialState,
+ });
+ }
- }
-
- // If Clip-Path Type is changed, change the value of the clipPathType
- if (name === "clipPathType") {
-
- if (value === "polygon") {
- setShapeInformation({
- ...shapeInformation,
- ...polygonInitialState,
- });
- }
-
- if (value === "circle") {
- setShapeInformation({
- ...shapeInformation,
- ...circleInitialState,
- });
- }
-
- if (value === "ellipse") {
- setShapeInformation({
- ...shapeInformation,
- ...ellipseInitialState,
- });
- }
-
- setShapeInformation(prevState => {
- return {
- ...prevState,
- "clipPathType": value,
- "edges": value === "polygon" ? 4 : 0,
- "vertices": value === "polygon" ? 4 : 0,
- }
- });
- return;
- }
-
- // If DraggableVertice is moved, adjust verticeCoordinates and formula
- if (name === "mousemove" || name === "touchmove") {
-
- if (type === "width") {
- const newFormulaValues = calculateRadiusAndFormulaFromMovement(
- shapeInformation.verticeCoordinates[0].x,
- shapeInformation.width,
- shapeInformation.height,
- data.x
- );
-
- let newFormula;
-
- if (shapeInformation.clipPathType === "circle") {
- newFormula = `${shapeInformation.clipPathType}(${newFormulaValues.absoluteValueRadius} at ${shapeInformation.verticeCoordinates[0].x} ${shapeInformation.verticeCoordinates[0].y})`;
- } else if (shapeInformation.clipPathType === "ellipse") {
- newFormula = `${shapeInformation.clipPathType}(${newFormulaValues.absoluteValueRadius} ${newFormulaValues.absoluteValueAxis} at ${shapeInformation.verticeCoordinates[0].x} ${shapeInformation.verticeCoordinates[0].y})`;
- }
-
- setShapeInformation({
- ...shapeInformation,
- "width": newFormulaValues.radius,
- "formula": newFormula,
- });
-
- } else if (type === "height") {
- const newFormulaValues = calculateRadiusAndFormulaFromMovement(
- shapeInformation.verticeCoordinates[0].y,
- shapeInformation.height,
- shapeInformation.width,
- data.y
- );
-
- let newFormula;
-
- if (shapeInformation.clipPathType === "ellipse") {
- newFormula = `${shapeInformation.clipPathType}(${newFormulaValues.absoluteValueAxis} ${newFormulaValues.absoluteValueRadius} at ${shapeInformation.verticeCoordinates[0].x} ${shapeInformation.verticeCoordinates[0].y})`;
- }
-
- setShapeInformation({
- ...shapeInformation,
- "height": newFormulaValues.radius,
- "formula": newFormula,
- });
-
- } else {
- const newVerticeCoordinates = generateNewVerticeCoordinates(data.x, data.y, number, shapeInformation);
- const newFormula = generateNewFormula(newVerticeCoordinates, shapeInformation);
-
- setShapeInformation({
- ...shapeInformation,
- "verticeCoordinates": newVerticeCoordinates,
- "formula": newFormula,
- });
- }
-
- return;
- }
-
- // If preview is clicked and the clipPathType is a polygon, add a verticeCoordinate value at its location and adjust formula
- if ((event.target.id === "shapeShadow" || event.target.id === "clippedShape") && name === "click" && shapeInformation.clipPathType === "polygon") {
-
- const newVerticeCoordinates = generateNewVerticeCoordinates(event.nativeEvent.offsetX, event.nativeEvent.offsetY, shapeInformation.verticeCoordinates.length, shapeInformation);
- const newFormula = generateNewFormula(newVerticeCoordinates, shapeInformation);
-
- setShapeInformation({
- ...shapeInformation,
- "vertices": shapeInformation.vertices + 1,
- "edges": shapeInformation.edges + 1,
- "verticeCoordinates": newVerticeCoordinates,
- "formula": newFormula,
- });
- return;
- }
+ if (value === "circle") {
+ setShapeInformation({
+ ...shapeInformation,
+ ...circleInitialState,
+ });
+ }
- // If delete button is pressed and passes a number that corresponds to the vertice, remove the corresponding verticeCoordinate and adjust formula
- if ((event.target.id.includes("deleteButton")
- || event.target.parentElement.id.includes("deleteButton")) && number !== undefined) {
+ if (value === "ellipse") {
+ setShapeInformation({
+ ...shapeInformation,
+ ...ellipseInitialState,
+ });
+ }
+
+ setShapeInformation((prevState) => ({
+ ...prevState,
+ clipPathType: value,
+ edges: value === "polygon" ? 4 : 0,
+ vertices: value === "polygon" ? 4 : 0,
+ }));
+ return;
+ }
- let newVerticeCoordinates = [];
+ if (name === "mousemove" || name === "touchmove") {
+ if (type === "width") {
+ const newFormulaValues = calculateRadiusAndFormulaFromMovement(
+ shapeInformation.verticeCoordinates[0].x,
+ shapeInformation.width,
+ shapeInformation.height,
+ data.x
+ );
+
+ let newFormula;
+
+ if (shapeInformation.clipPathType === "circle") {
+ newFormula = `${shapeInformation.clipPathType}(${newFormulaValues.absoluteValueRadius} at ${shapeInformation.verticeCoordinates[0].x} ${shapeInformation.verticeCoordinates[0].y})`;
+ } else if (shapeInformation.clipPathType === "ellipse") {
+ newFormula = `${shapeInformation.clipPathType}(${newFormulaValues.absoluteValueRadius} ${newFormulaValues.absoluteValueAxis} at ${shapeInformation.verticeCoordinates[0].x} ${shapeInformation.verticeCoordinates[0].y})`;
+ }
- for (let i = 0; i < shapeInformation.verticeCoordinates.length; i++) {
- if (i !== number) {
- newVerticeCoordinates.push(shapeInformation.verticeCoordinates[i]);
- }
- }
+ setShapeInformation({
+ ...shapeInformation,
+ width: newFormulaValues.radius,
+ formula: newFormula,
+ });
+ } else if (type === "height") {
+ const newFormulaValues = calculateRadiusAndFormulaFromMovement(
+ shapeInformation.verticeCoordinates[0].y,
+ shapeInformation.height,
+ shapeInformation.width,
+ data.y
+ );
+
+ let newFormula;
+
+ if (shapeInformation.clipPathType === "ellipse") {
+ newFormula = `${shapeInformation.clipPathType}(${newFormulaValues.absoluteValueAxis} ${newFormulaValues.absoluteValueRadius} at ${shapeInformation.verticeCoordinates[0].x} ${shapeInformation.verticeCoordinates[0].y})`;
+ }
- const newFormula = generateNewFormula(newVerticeCoordinates, shapeInformation);
+ setShapeInformation({
+ ...shapeInformation,
+ height: newFormulaValues.radius,
+ formula: newFormula,
+ });
+ } else {
+ const newVerticeCoordinates = generateNewVerticeCoordinates(data.x, data.y, number, shapeInformation);
+ const newFormula = generateNewFormula(newVerticeCoordinates, shapeInformation);
- setShapeInformation({
- ...shapeInformation,
- "vertices": shapeInformation.vertices - 1,
- "edges": shapeInformation.edges - 1,
- "verticeCoordinates": newVerticeCoordinates,
- "formula": newFormula,
- });
- return;
- }
-
- // Handles all other ShapeForm and ShapePreview Changes
setShapeInformation({
- ...shapeInformation,
- [name]: value,
+ ...shapeInformation,
+ verticeCoordinates: newVerticeCoordinates,
+ formula: newFormula,
});
+ }
+ return;
}
- // Form Validation
- const [validated, setValidated] = useState(false);
+ if ((event.target.id === "shapeShadow" || event.target.id === "clippedShape") && name === "click" && shapeInformation.clipPathType === "polygon") {
+ const newVerticeCoordinates = generateNewVerticeCoordinates(event.nativeEvent.offsetX, event.nativeEvent.offsetY, shapeInformation.verticeCoordinates.length, shapeInformation);
+ const newFormula = generateNewFormula(newVerticeCoordinates, shapeInformation);
+
+ setShapeInformation({
+ ...shapeInformation,
+ vertices: shapeInformation.vertices + 1,
+ edges: shapeInformation.edges + 1,
+ verticeCoordinates: newVerticeCoordinates,
+ formula: newFormula,
+ });
+ return;
+ }
- const handleSubmit = async(event) => {
- event.preventDefault();
- const form = event.currentTarget;
- if (form.checkValidity() === false) {
- event.preventDefault();
- event.stopPropagation();
- }
- setValidated(true);
-
- console.log(shapeInformation);
-
- // Editing Shape
- if (props.edit) {
-
- const updateShapeResponse = await axios.post('/api/PUT/shape', {
- shapeId: props.shape.shape_id,
- name: shapeInformation.name,
- formula: shapeInformation.formula,
- vertices: shapeInformation.vertices,
- visibility: shapeInformation.private,
- edges: shapeInformation.edges,
- notes: shapeInformation.notes,
- type: shapeInformation.clipPathType,
- backgroundColor: shapeInformation.backgroundColor
- });
- const editShape = updateShapeResponse.data;
- console.log({editShape});
-
- if (editShape.data["update_hashes"].length > 0) {
- props.handleClose();
- toast.success(`Shape ${shapeInformation.name} edited successfully.`);
- props.setShapeAction({
- ...props.shapeAction,
- "action": "edit",
- "payload": {
- "shape_id": editShape.data['update_hashes']
- }
- });
- } else {
- toast.error('OOPS!! We hit a bummer. Please try again.');
- }
-
- // Creating Shape
- } else {
-
- // Create the shape in the DB
- const insertShapeResponse = await axios.post('/api/POST/shape', {
- name: shapeInformation.name,
- formula: shapeInformation.formula,
- vertices: shapeInformation.vertices,
- visibility: shapeInformation.private,
- edges: shapeInformation.edges,
- notes: shapeInformation.notes,
- type: shapeInformation.clipPathType,
- backgroundColor: shapeInformation.backgroundColor,
- createdBy: props.user.email,
- likes: 0
- });
- const insertShape = insertShapeResponse.data
-
- console.log({insertShape});
-
- // Create the user in the db
- if (insertShape.data['inserted_hashes'].length > 0) {
- // First check if the user exist
- const userResponse = await axios.get("/api/GET/user", {
- params: {
- email: props.user.email
- }
- });
- const result = userResponse.data;
- const count = result.length;
- console.log({count});
-
- // If doesn't exist, create in db
- if (count === 0) {
- const insertUserResponse = await axios.post('/api/POST/user', {
- displayName: props.user.displayName,
- email: props.user.email,
- photoURL: props.user.photoURL
- });
- const insertUser = insertUserResponse.data;
- console.log({insertUser});
- } else {
- console.log(`The user ${props.user.email} present in DB`);
- }
-
- // Finally, close the modal and update the shape in UI
- props.handleClose();
- if (props.setSearchTerm) {
- props.setSearchTerm('');
- }
- toast.success(`Shape ${shapeInformation.name} created successfully.`);
- props.setShapeAction({
- ...props.shapeAction,
- "action": "add",
- "payload": {
- "shape_id": insertShape.data['inserted_hashes']
- }
- });
-
- } else {
- toast.error('OOPS!! We hit a bummer. Please try again.');
- }
+ if ((event.target.id.includes("deleteButton") || event.target.parentElement.id.includes("deleteButton")) && number !== undefined) {
+ let newVerticeCoordinates = [];
+ for (let i = 0; i < shapeInformation.verticeCoordinates.length; i++) {
+ if (i !== number) {
+ newVerticeCoordinates.push(shapeInformation.verticeCoordinates[i]);
}
+ }
+
+ const newFormula = generateNewFormula(newVerticeCoordinates, shapeInformation);
+
+ setShapeInformation({
+ ...shapeInformation,
+ vertices: shapeInformation.vertices - 1,
+ edges: shapeInformation.edges - 1,
+ verticeCoordinates: newVerticeCoordinates,
+ formula: newFormula,
+ });
+ return;
+ }
- setShapeInformation({
- ...initialState,
- });
+ setShapeInformation({
+ ...shapeInformation,
+ [name]: value,
+ });
+ };
- setValidated(false);
-
- }
+ const handleSubmit = async (event) => {
+ event.preventDefault();
+ const form = event.currentTarget;
- return(
- <>
- {setShapeInformation({ ...initialState }); props.handleClose(); }}
- backdrop="static"
- >
-
- {props.edit ? "Edit Shape" : "Create Shape"}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- );
-}
-
-export default CreateShape;
\ No newline at end of file
+ if (form.checkValidity() === false) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ // The rest of the handleSubmit logic comes here
+ };
+
+ return (
+ <>
+ {
+ setShapeInformation({ ...initialState });
+ props.handleClose();
+ }}
+ backdrop="static"
+ >
+
+ {props.edit ? "Edit Shape" : "Create Shape"}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
+
+export default CreateShape;