connect form fix (#92)

* feddback form fix 1
This commit is contained in:
Igor Lobanov 2023-05-11 20:34:04 +02:00 committed by GitHub
parent 384fe16671
commit fb007d65de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 87 additions and 46 deletions

View File

@ -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 })
})
})
}

View File

@ -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 <robot@discours.io>',
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) {
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)
}
})
}

View File

@ -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) => {

View File

@ -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
}

View File

@ -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'

View File

@ -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

View File

@ -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<string, string>)
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 (
<PageLayout>
<article class="wide-container container--static-page">
@ -15,26 +50,30 @@ export const ConnectPage = () => {
скорее! Если укажете свою почту, мы&nbsp;обязательно ответим.
</p>
<form action="/api/feedback">
<form onSubmit={handleFormSubmit} ref={(el) => (formRef.current = el)}>
<div class="pretty-form__item">
<select id="subject">
<option value="">Сотрудничество</option>
<option value="">Посоветовать тему</option>
<option value="">Сообщить об ошибке</option>
<option value="">Предложить проект</option>
<option value="">Волонтерство</option>
<option value="">Другое</option>
<select name="subject">
<option value="Сотрудничество" selected>
Сотрудничество
</option>
<option value="Посоветовать тему">Посоветовать тему</option>
<option value="Сообщить об ошибке">Сообщить об ошибке</option>
<option value="Предложить проект">Предложить проект</option>
<option value="Волонтерство">Волонтерство</option>
<option value="Другое">Другое</option>
</select>
</div>
<div class="pretty-form__item">
<input type="text" id="contact-email" placeholder="Email для обратной связи" />
<input type="email" name="contact" placeholder="Email для обратной связи" />
<label for="contact-email">Email для обратной связи</label>
</div>
<div class="pretty-form__item">
<textarea id="message" placeholder="Текст сообщения" />
<textarea name="message" placeholder="Текст сообщения" />
<label for="message">Текст сообщения</label>
</div>
<button class="button">Отправить письмо</button>
<button class="button" disabled={state() !== 'initial'} type="submit">
Отправить письмо
</button>
</form>
</div>
</div>