From fb007d65de96eacad80600697bbc81e62fc786db Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Thu, 11 May 2023 20:34:04 +0200 Subject: [PATCH] connect form fix (#92) * feddback form fix 1 --- api/_shared/formidablePromise.js | 14 +++++ api/feedback.js | 39 ++++++------ api/upload.mjs | 14 +---- .../Editor/TopicSelect/TopicSelect.tsx | 1 + src/components/Feed/Sidebar/Sidebar.tsx | 2 +- .../GrowingTextarea/GrowingTextarea.tsx | 2 +- src/pages/connect.page.tsx | 61 +++++++++++++++---- 7 files changed, 87 insertions(+), 46 deletions(-) create mode 100644 api/_shared/formidablePromise.js diff --git a/api/_shared/formidablePromise.js b/api/_shared/formidablePromise.js new file mode 100644 index 00000000..4b40f687 --- /dev/null +++ b/api/_shared/formidablePromise.js @@ -0,0 +1,14 @@ +import formidable from 'formidable' + +export const formidablePromise = async (request, options) => { + return new Promise((resolve, reject) => { + const form = formidable(options) + + form.parse(request, (err, fields, files) => { + if (err) { + return reject(err) + } + return resolve({ fields, files }) + }) + }) +} diff --git a/api/feedback.js b/api/feedback.js index deaf8931..c6674259 100644 --- a/api/feedback.js +++ b/api/feedback.js @@ -1,29 +1,28 @@ -const MG = require('mailgun.js') -const fd = require('form-data') -const mailgun = new MG(fd) +import { formidablePromise } from './_shared/formidablePromise' +const mailgun = require('mailgun-js')({ + apiKey: process.env.MAILGUN_API_KEY, + domain: process.env.MAILGUN_DOMAIN +}) -const mgOptions = { - key: process.env.MAILGUN_API_KEY, - domain: process.env.MAILGUN_DOMAIN, - username: 'discoursio' // FIXME -} +export default async function handler(req, res) { + const { contact, subject, message } = await formidablePromise(req) -const client = mailgun.client(mgOptions) + const text = `${contact}\n\n${message}` -const messageData = (subject, text) => { - return { + const data = { from: 'Discours Feedback Robot ', to: 'welcome@discours.io', subject, text } -} -export default async function handler(req, res) { - const { contact, subject, message } = req.query - try { - const data = messageData(`${contact}: ${subject}`, message) - client.messages.create(mgOptions.domain, data).then(console.log).catch(console.error) - } catch (error) { - res.status(400).json(error) - } + + mailgun.messages().send(data, (error) => { + if (error) { + console.log('Error:', error) + res.status(400).json(error) + } else { + console.log('Email sent successfully!') + res.status(200) + } + }) } diff --git a/api/upload.mjs b/api/upload.mjs index a6b45a8c..04ae86d2 100644 --- a/api/upload.mjs +++ b/api/upload.mjs @@ -4,6 +4,7 @@ import formidable from 'formidable' import { Writable } from 'stream' import path from 'path' import crypto from 'crypto' +import { formidablePromise } from './_shared/formidablePromise.js' const { STORJ_ACCESS_KEY, STORJ_SECRET_KEY, STORJ_END_POINT, STORJ_BUCKET_NAME, CDN_DOMAIN } = process.env @@ -15,19 +16,6 @@ const storjS3Client = new S3Client({ } }) -const formidablePromise = async (request, options) => { - return new Promise((resolve, reject) => { - const form = formidable(options) - - form.parse(request, (err, fields, files) => { - if (err) { - return reject(err) - } - return resolve({ fields, files }) - }) - }) -} - const fileConsumer = (acc) => { return new Writable({ write: (chunk, _enc, next) => { diff --git a/src/components/Editor/TopicSelect/TopicSelect.tsx b/src/components/Editor/TopicSelect/TopicSelect.tsx index ebab3d12..2642dffb 100644 --- a/src/components/Editor/TopicSelect/TopicSelect.tsx +++ b/src/components/Editor/TopicSelect/TopicSelect.tsx @@ -48,6 +48,7 @@ export const TopicSelect = (props: TopicSelectProps) => { const format = (item, type) => { if (type === 'option') { + // eslint-disable-next-line solid/components-return-once return item.label } diff --git a/src/components/Feed/Sidebar/Sidebar.tsx b/src/components/Feed/Sidebar/Sidebar.tsx index 354f218b..29521c53 100644 --- a/src/components/Feed/Sidebar/Sidebar.tsx +++ b/src/components/Feed/Sidebar/Sidebar.tsx @@ -1,4 +1,4 @@ -import { createSignal, For } from 'solid-js' +import { createSignal, For, Show } from 'solid-js' import type { Author } from '../../../graphql/types.gen' import { useAuthorsStore } from '../../../stores/zine/authors' import { Icon } from '../../_shared/Icon' diff --git a/src/components/_shared/GrowingTextarea/GrowingTextarea.tsx b/src/components/_shared/GrowingTextarea/GrowingTextarea.tsx index 77608afb..6b8b4efa 100644 --- a/src/components/_shared/GrowingTextarea/GrowingTextarea.tsx +++ b/src/components/_shared/GrowingTextarea/GrowingTextarea.tsx @@ -1,6 +1,6 @@ import { clsx } from 'clsx' import styles from './GrowingTextarea.module.scss' -import { createEffect, createSignal } from 'solid-js' +import { createSignal } from 'solid-js' type Props = { class?: string diff --git a/src/pages/connect.page.tsx b/src/pages/connect.page.tsx index 8eb6324e..92ff877d 100644 --- a/src/pages/connect.page.tsx +++ b/src/pages/connect.page.tsx @@ -1,6 +1,41 @@ import { PageLayout } from '../components/_shared/PageLayout' +import { createSignal } from 'solid-js' export const ConnectPage = () => { + const [state, setState] = createSignal<'initial' | 'loading' | 'success' | 'error'>('initial') + + const formRef: { current: HTMLFormElement } = { current: null } + const handleFormSubmit = async (e) => { + e.preventDefault() + setState('loading') + + // eslint-disable-next-line unicorn/prefer-spread + const postData = Array.from(formRef.current.elements).reduce((acc, element) => { + const formField = element as unknown as { name: string; value: string } + if (formField.name) { + acc[formField.name] = formField.value + } + + return acc + }, {} as Record) + + const requestOptions = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(postData) + } + + try { + await fetch('/api/feedback', requestOptions) + setState('success') + } catch (error) { + console.error('[handleFormSubmit]', error) + setState('error') + } + } + return (
@@ -15,26 +50,30 @@ export const ConnectPage = () => { скорее! Если укажете свою почту, мы обязательно ответим.

-
+ (formRef.current = el)}>
- + + + + + +
- +
-