diff --git a/package.json b/package.json index 859a31a..61c186c 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "nanoid": "^4.0.2", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.22.0", "react-hook-form": "^7.45.1", "react-toastify": "^9.1.3", "tailwindcss": "^3.3.2", diff --git a/src/App.jsx b/src/App.jsx index ee39f78..158d46d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,14 +1,17 @@ import React from 'react'; -import { DndContext } from '@dnd-kit/core'; -import FormBuilder from './components/FormBuilder/FormBuilder'; +import { Routes, Route } from 'react-router-dom'; import { FormProvider } from './context/FormContext'; +import Home from './pages/Home'; +import BuilderPage from './pages/BuilderPage'; function App() { return ( -
- -
+ + } /> + } /> + } /> +
); } diff --git a/src/components/FormBuilder/FormBuilderHeader.jsx b/src/components/FormBuilder/FormBuilderHeader.jsx index 8b6e215..ba0d2f0 100644 --- a/src/components/FormBuilder/FormBuilderHeader.jsx +++ b/src/components/FormBuilder/FormBuilderHeader.jsx @@ -1,7 +1,8 @@ import React, { useState } from 'react'; import { useForm } from '../../context/FormContext'; import { toast } from 'react-toastify'; -import ComponentPreview from '../FormComponents/ComponentPreview'; +import { Link } from 'react-router-dom'; +import FormPreview from '../FormPreview/FormPreview'; const FormBuilderHeader = () => { @@ -12,6 +13,7 @@ const FormBuilderHeader = () => { importFormSchema, undo, redo, + saveFormToStorage, canUndo, canRedo } = useForm(); @@ -99,6 +101,10 @@ const FormBuilderHeader = () => { } }; + const handleSave = () => { + saveFormToStorage(); + }; + return (
@@ -112,6 +118,7 @@ const FormBuilderHeader = () => {
+ Home

{isEditingTitle ? ( { - + ))} + +
+ {tabs[activeTab] && (tabs[activeTab].components || []).map((child) => ( +
+ {renderComponent(child, path)} +
+ ))} +
+ + ); +}; + +const ColumnsContainer = ({ component, path, renderComponent }) => ( +
+ {(component.columns || []).map((column, idx) => ( +
+ {(column.components || []).map((child) => ( +
{renderComponent(child, path)}
+ ))} +
+ ))} +
+); + +const PanelContainer = ({ component, path, renderComponent }) => ( +
+ {component.title && ( +
+ {component.title} +
+ )} +
+ {(component.components || []).map((child) => ( +
{renderComponent(child, path)}
+ ))} +
+
+); + +const FormPreview = ({ form }) => { + const { register, handleSubmit, formState: { errors }, reset } = useForm(); + const [submitted, setSubmitted] = useState(false); + + const onSubmit = (data) => { + setSubmitted(true); + console.log('Form data:', data); // eslint-disable-line no-console + reset(); + }; + + const renderComponent = (component, parentPath = '') => { + const name = parentPath ? `${parentPath}.${component.key}` : component.key; + + switch (component.type) { + case 'textfield': + case 'email': + case 'phoneNumber': + return ( +
+ + + {component.description &&

{component.description}

} + {errors[name] &&

{errors[name].message}

} +
+ ); + case 'textarea': + return ( +
+ +