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 = () => {
скорее! Если укажете свою почту, мы обязательно ответим.
-