Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 48 additions & 22 deletions components/FormContainer.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React, { useState } from 'react';
import FormField from './FormField';
import FormPreview from './FormPreview';

export default function FormContainer() {
const [formContent, setFormContent] = useState([]);
const [option, setOption] = useState("");
const [showPreview, setShowPreview] = useState(false);

const addFormField = () => {
const field = {
Expand Down Expand Up @@ -64,31 +66,55 @@ export default function FormContainer() {
setFormContent(formField);
}

const togglePreview = () => {
setShowPreview(!showPreview);
};

return (
<div className="bg-white shadow-lg rounded-md p-5 my-12">
{formContent.map((field) => (
<FormField
key={field.id}
field={field}
option={option}
onTypeChange={editFieldType}
onTitleChange={editFieldTitle}
onDelete={deleteField}
onAddOption={addOption}
onDeleteOption={deleteOption}
setOption={setOption}
/>
))}
<div className="relative w-full p-4">
<div className="absolute inset-x-0 bottom-0 h-12 flex justify-center">
<button
onClick={addFormField}
className='inline-flex bg-gray-800 hover:bg-gray-200 items-center px-3 py-1 text-slate-50 rounded-md'
>
Añadir campo
</button>
<div className="flex flex-col md:flex-row gap-6 w-full">
<div className={`${showPreview ? 'md:w-1/2' : 'w-full'}`}>
<div className="bg-white shadow-lg rounded-md p-5 my-12">
<div className="flex justify-between mb-4">
<h3 className="text-xl font-bold">Form Editor</h3>
<button
onClick={togglePreview}
className='inline-flex bg-indigo-600 hover:bg-indigo-700 items-center px-3 py-1 text-white rounded-md'
>
{showPreview ? 'Hide Preview' : 'Show Preview'}
</button>
</div>

{formContent.map((field) => (
<FormField
key={field.id}
field={field}
option={option}
onTypeChange={editFieldType}
onTitleChange={editFieldTitle}
onDelete={deleteField}
onAddOption={addOption}
onDeleteOption={deleteOption}
setOption={setOption}
/>
))}
<div className="relative w-full p-4">
<div className="absolute inset-x-0 bottom-0 h-12 flex justify-center">
<button
onClick={addFormField}
className='inline-flex bg-gray-800 hover:bg-gray-200 items-center px-3 py-1 text-slate-50 rounded-md'
>
Add field
</button>
</div>
</div>
</div>
</div>

{showPreview && (
<div className="md:w-1/2">
<FormPreview formContent={formContent} />
</div>
)}
</div>
);
}
14 changes: 7 additions & 7 deletions components/FormField.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ export default function FormField({
</div>
</div>
<div className="my-2">
{field.type === "text" && <input type="text" placeholder="Este es el input de texto" readOnly/>}
{field.type === "number" && <input type="number" placeholder="" readOnly/>}
{field.type === "date" && <input type="date" placeholder="" readOnly/>}
{field.type === "text" && <input type="text" placeholder="This is the text input" readOnly/>}
{field.type === "number" && <input type="number" placeholder="This is the number input" readOnly/>}
{field.type === "date" && <input type="date" placeholder="This is the date input" readOnly/>}

{(field.type === "checkbox" || field.type === "radio") && (
<div className="flex flex-col space-y-2">
Expand All @@ -53,7 +53,7 @@ export default function FormField({
className="text-red-600 hover:text-red-900"
onClick={() => onDeleteOption(field.id, opt)}
>
Eliminar opcion
Delete option
</button>
</div>
))}
Expand All @@ -67,7 +67,7 @@ export default function FormField({
className="text-blue-900 hover:text-blue-600"
onClick={() => onAddOption(field.id, option)}
>
Añadir opción
Add option
</button>
</div>
</div>
Expand Down Expand Up @@ -101,7 +101,7 @@ export default function FormField({
className="text-blue-900 hover:text-blue-600"
onClick={() => onAddOption(field.id, option)}
>
Añadir opción
Add option
</button>
</div>
</div>
Expand All @@ -112,7 +112,7 @@ export default function FormField({
className="bg-red-700 hover:bg-red-200 text-neutral-100 rounded-md px-3 py-1"
onClick={() => onDelete(field.id)}
>
Eliminar campo
Delete field
</button>
</div>
</>
Expand Down
102 changes: 102 additions & 0 deletions components/FormPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React from 'react';

export default function FormPreview({ formContent }) {
return (
<div className="bg-white shadow-lg rounded-md p-5 my-12">
<h3 className="text-xl font-bold mb-4">Form Preview</h3>
<form>
{formContent.map((field) => (
<div key={field.id} className="mb-4">
<label htmlFor={field.id} className="block text-sm font-medium mb-2">
{field.title}
</label>

{field.type === "text" && (
<input
type="text"
id={field.id}
name={field.id}
className="w-full p-2 border rounded-md"
/>
)}

{field.type === "number" && (
<input
type="number"
id={field.id}
name={field.id}
className="w-full p-2 border rounded-md"
/>
)}

{field.type === "date" && (
<input
type="date"
id={field.id}
name={field.id}
className="w-full p-2 border rounded-md"
/>
)}

{field.type === "checkbox" && (
<div className="space-y-2">
{field.options.map((opt) => (
<div key={opt} className="flex items-center">
<input
type="checkbox"
id={`${field.id}_${opt}`}
name={field.id}
value={opt}
className="mr-2"
/>
<label htmlFor={`${field.id}_${opt}`}>{opt}</label>
</div>
))}
</div>
)}

{field.type === "radio" && (
<div className="space-y-2">
{field.options.map((opt) => (
<div key={opt} className="flex items-center">
<input
type="radio"
id={`${field.id}_${opt}`}
name={field.id}
value={opt}
className="mr-2"
/>
<label htmlFor={`${field.id}_${opt}`}>{opt}</label>
</div>
))}
</div>
)}

{field.type === "select" && (
<select
id={field.id}
name={field.id}
className="w-full p-2 border rounded-md"
>
<option value="">Select an option</option>
{field.options.map((opt) => (
<option key={opt} value={opt}>{opt}</option>
))}
</select>
)}
</div>
))}

{formContent.length > 0 && (
<button
Comment on lines +9 to +91

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible runtime error: File: components/FormPreview.js Line: 9

  • The code assumes that the 'options' property exists on all fields of type 'checkbox', 'radio', and 'select'. If 'options' is undefined or missing, accessing 'field.options.map' will cause a runtime error.
  • This can occur if a form field of those types is added but the options property is not set, as the field creation logic in FormContainer does not set 'options' by default.
  • Example scenarios where this can break: changing a field type to 'checkbox', 'radio', or 'select' before options are added, or if a field is created without options.

type="submit"
className="mt-4 bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-md"
onClick={(e) => e.preventDefault()}
>
Submit
</button>
)}
</form>
</div>
);
}
15 changes: 1 addition & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"dev": "next dev -p 3001",
"build": "next build",
"start": "next start",
"lint": "next lint"
Expand Down
12 changes: 6 additions & 6 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ export default function Home() {
return (
<>
<Head>
<title>Adestos Forms</title>
<meta name="description" content="Crea tu formulario" />
<title>Forms</title>
<meta name="description" content="Create your form" />
</Head>
<div className="container mx-auto px-4 w-2/4 h-full">
<div className="flex flex-col w-6/12 space-x-7 my-7">
<h1 className="text-4xl font-bold">Adestos-Forms</h1>
<h2 className="text-2xl font-bold">Crea tu formulario</h2>
<div className="container mx-auto px-4 w-full md:w-5/6 lg:w-3/4 h-full">
<div className="flex flex-col w-full md:w-6/12 space-y-2 my-7">
<h1 className="text-4xl font-bold">Forms</h1>
<h2 className="text-2xl font-bold">Create your form</h2>
</div>
<FormContainer />
</div>
Expand Down