feat: add api requests

This commit is contained in:
2025-07-07 15:45:25 +03:00
parent f20785993a
commit 9b39cf285d
8 changed files with 144 additions and 5 deletions

View File

@@ -0,0 +1,9 @@
export async function GET(request: Request) {
return new Response('Heartbeat is OK!', {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
},
});
}

View File

@@ -0,0 +1,66 @@
import nodemailer from 'nodemailer';
import { TBaseForm } from '@shared/api/api.types';
import { CORE } from '@shared/config/core';
async function sendMail(data: TBaseForm) {
const { name, phone, message, form } = data;
const formattedBody = `
<html lang="ru-RU">
<body>
<p>Сообщение с сайта "Экспертиза и Оценка"</p>
<p>Форма отправки: ${form}</p>
<p>Имя отправителя: ${name ?? 'не указано'}</p>
<p>Номер телефона: ${phone}</p>
<p>Сообщение: ${message ?? 'отсутствует'}</p>
</body>
</html>
`;
const transporter = nodemailer.createTransport({
service: 'Yandex',
auth: {
user: CORE.MAIL_USER,
pass: CORE.MAIL_PASS,
},
});
return await transporter.sendMail({
from: CORE.MAIL_FROM,
to: CORE.MAIL_TO,
subject: 'Заявка с сайта Ocenka-Sochi',
html: formattedBody,
});
}
export async function POST(request: Request) {
try {
const payload = await request.json();
if (payload.secure !== CORE.MAIL_SECURE_KEY) {
await Promise.reject('Request failure!');
}
const sendResult = await sendMail({ ...payload });
const data = { message: 'Form accepted' };
const headers = new Headers({
'Content-Type': 'application/json',
});
const options = {
status: 200,
statusText: 'OK',
headers: headers,
};
if (sendResult?.messageId) {
return new Response(JSON.stringify(data), options);
} else {
await Promise.reject('Sending request failure!');
}
} catch (error) {
return new Response(`Api error: ${error}`, {
status: 400,
});
}
}

View File

@@ -0,0 +1,35 @@
import { API_ROUTES } from '@shared/config/routes';
import { TBaseForm } from '@shared/api/api.types';
import { CORE } from '@shared/config/core';
type TRequest = TBaseForm;
const sendFormFn = async ({ ...props }: TRequest) => {
try {
const response = await fetch('/api' + API_ROUTES.SEND_FORM, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
...props,
secure: CORE.MAIL_SECURE_KEY,
}),
});
if (response.ok) {
return response;
} else {
if (response.status === 400) throw new Error(`400 Bad request`);
if (response.status === 401) throw new Error(`401 Unauthorized`);
if (response.status === 500) throw new Error('500 Internal server error');
throw new Error(`${response.status} - Network response failure`);
}
} catch (e) {
console.error(e);
}
};
export { sendFormFn };

View File

@@ -0,0 +1,6 @@
export type TBaseForm = {
form: string;
name?: string;
phone: string;
message?: string;
};

View File

@@ -0,0 +1,7 @@
export const CORE = {
MAIL_USER: process.env.NEXT_PUBLIC_MAIL_USER,
MAIL_PASS: process.env.NEXT_PUBLIC_MAIL_PASS,
MAIL_FROM: process.env.NEXT_PUBLIC_MAIL_FROM,
MAIL_TO: process.env.NEXT_PUBLIC_MAIL_TO,
MAIL_SECURE_KEY: process.env.NEXT_PUBLIC_MAIL_SECURE_KEY,
} as const;

View File

@@ -0,0 +1,4 @@
export const API_ROUTES = {
SEND_FORM: '/sendform',
HEARTBEAT: '/heartbeat',
} as const;