diff --git a/cms/cms.js b/cms/cms.js index e46ab1b..0262b07 100644 --- a/cms/cms.js +++ b/cms/cms.js @@ -1,12 +1,13 @@ -import CMS from 'decap-cms-app'; -import { Widget as UuidWidget } from 'netlify-cms-widget-id'; -import { Widget as PermalinkWidget } from 'netlify-cms-widget-permalink'; - -import pages from './collections/pages'; -import posts from './collections/posts'; -import authors from './collections/authors'; -import settings from './collections/settings'; -import PagePreview from './previews/Page'; +import CMS from 'decap-cms-app' +import { Widget as UuidWidget } from 'netlify-cms-widget-id' +import { Widget as PermalinkWidget } from 'netlify-cms-widget-permalink' +import authors from './collections/authors' +import forms from './collections/forms' +import pages from './collections/pages' +import posts from './collections/posts' +import settings from './collections/settings' +import FormPreview from './previews/FormPreview' +import PagePreview from './previews/Page' const config = { config: { @@ -23,9 +24,14 @@ const config = { }, media_folder: '/static/img', public_folder: '/img', - collections: [pages, posts, authors, settings], + collections: [pages, posts, authors, forms, settings], }, -}; +} + + +CMS.registerPreviewStyle('../commons.css') +CMS.registerPreviewTemplate('pages', PagePreview) +CMS.registerPreviewTemplate('forms', FormPreview) const injectCustomStyle = () => { const style = document.createElement('style') @@ -39,10 +45,7 @@ const injectCustomStyle = () => { injectCustomStyle() -CMS.registerPreviewStyle('../commons.css'); -CMS.registerPreviewTemplate('pages', PagePreview); - -CMS.registerWidget(UuidWidget); -CMS.registerWidget(PermalinkWidget); +CMS.registerWidget(UuidWidget) +CMS.registerWidget(PermalinkWidget) -CMS.init(config); +CMS.init(config) diff --git a/cms/previews/FormPreview.js b/cms/previews/FormPreview.js new file mode 100644 index 0000000..c2beea2 --- /dev/null +++ b/cms/previews/FormPreview.js @@ -0,0 +1,37 @@ +import React from 'react' +import Form from '@/components/Form/Form' + +export default class PagePreview extends React.Component { + render() { + const blocks = this.props.widgetsFor('rows').toJS() + let blocksUpdated = [] + let hasBlocks = Array.isArray(blocks) + if (hasBlocks) { + blocksUpdated = blocks.map((block) => block.data) + } + + return ( +
+ {hasBlocks ? ( +
+
+
+ ) : ( +
+

Add first block to start creating your form

+
+ )} +
+ ) + } +} diff --git a/content/forms/example.md b/content/forms/example.md index 5cbb820..72a1b74 100644 --- a/content/forms/example.md +++ b/content/forms/example.md @@ -51,14 +51,5 @@ rows: - fields: - type: submit label: Take the first step - - type: button - button: - variant: default - content: Let's go to google!! - url: 'https://google.com' position: center - - position: bottom - fields: - - type: text - content: Yo yo yo --- diff --git a/jsconfig.json b/jsconfig.json index 8c39ffb..9a2681a 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -4,7 +4,7 @@ "paths": { "@/*": ["./src/*"], "~/*": ["./*"], - "img": ["./static/img/*"] + "img/*": ["./static/img/*"] } }, "exclude": ["node_modules"] diff --git a/src/blocks/Content.js b/src/blocks/Content.js index 92c603d..c13611c 100644 --- a/src/blocks/Content.js +++ b/src/blocks/Content.js @@ -1,5 +1,6 @@ import React from 'react' import Container from '@/components/UI/Container' +import Section from '@/components/UI/Section' import Text from '@/components/UI/Text' export default function Content({ data }) { diff --git a/src/components/Form/Form.js b/src/components/Form/Form.js new file mode 100644 index 0000000..0d7bed7 --- /dev/null +++ b/src/components/Form/Form.js @@ -0,0 +1,147 @@ +import React, { useState } from 'react' +import { useForm } from 'react-hook-form' +import ButtonField from './partials/ButtonField' +import Checkbox from './partials/Checkbox' +import ContentSection from './partials/ContentSection' +import Input from './partials/Input' +import Submit from './partials/Submit' +import TextArea from './partials/TextArea' +import { handleGoal, cn } from '@/lib/helper' + +const encode = (data) => { + return Object.keys(data) + .map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(data[key])) + .join('&') +} + +export default function Form({ data, white }) { + const [isSend, setIsSend] = useState(false) + const [isSending, setIsSending] = useState(false) + const { + register, + handleSubmit, + setValue, + reset, + formState: { errors: fieldErrors }, + } = useForm() + + const onSubmit = async (formData) => { + setIsSending(true) + if (data.settings.resolver === 'Form') { + fetch('/', { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: encode({ 'form-name': data.title, ...formData }), + }) + .then(() => { + setIsSend(true) + handleGoal(data.settings.event_id) + setTimeout(() => { + reset() + setIsSending(false) + }, 200) + }) + .catch((error) => setIsSending(false)) + } + + if (data.settings.resolver === 'ConvertKit') { + const res = await fetch('/api/subscribe', { + method: 'POST', + body: JSON.stringify(formData), + }) + const returned = JSON.parse(await res.json()) + if (returned.success === true) { + setIsSend(true) + handleGoal(data.settings.event_id) + setTimeout(() => { + reset() + }, 200) + } + setIsSending(false) + } + } + + return ( +
+
+
+ {data?.settings?.success_msg} +
+
+ + {data.rows && + data.rows.map((row, i) => ( +
+ {row.fields && + row.fields.map((field, i) => { + switch (field.type) { + case 'input': + return ( + + ) + case 'textarea': + return ( + +
+ {error?.message} +
+
+ ) +} diff --git a/src/components/UI/Button.js b/src/components/UI/Button.js index d5a7fd7..77b64b2 100644 --- a/src/components/UI/Button.js +++ b/src/components/UI/Button.js @@ -6,7 +6,7 @@ export default function Button({ className, button, children, ...props }) { let buttonStyle = 'group inline-block font-bold text-dark-500 dark:text-white' switch (button?.variant) { case 'button': - buttonStyle = `${buttonStyle} border-dark-500 border dark:border-white bg-dark-500 dark:bg-white text-white dark:text-black py-2 px-6 text-center dark:hover:bg-transparent hover:bg-transparent hover:text-dark-500 dark:hover:text-white transition-colors` + buttonStyle = `${buttonStyle} border-dark-500 border dark:border-white bg-dark-500 dark:bg-white text-black dark:text-black py-2 px-6 text-center dark:hover:bg-transparent hover:bg-transparent hover:text-dark-500 dark:hover:text-white transition-colors` break case 'outlined': buttonStyle = `${buttonStyle} border-dark-500 border dark:border-white py-2 px-6 text-center dark:hover:bg-white hover:bg-dark-500 hover:text-white dark:hover:text-black transition-colors`