smtp initial setup, need to complete form to send order data
This commit is contained in:
parent
5a2af4ef1c
commit
03cae74a0e
@ -35,6 +35,32 @@ def upload():
|
||||
|
||||
return redirect('/')
|
||||
|
||||
@app.route("/mail", methods=["POST"])
|
||||
def mail():
|
||||
email = request.json["email"]
|
||||
password = request.json["password"]
|
||||
order = request.json["order"]
|
||||
|
||||
|
||||
if email is None:
|
||||
return jsonify({"error": "Unauthorized"}), 401
|
||||
|
||||
if not bcrypt.check_password_hash(user.password, password):
|
||||
return jsonify({"error": "Unauthorized"}), 401
|
||||
|
||||
# Cache session with redis
|
||||
session["user_id"] = user.id
|
||||
|
||||
return jsonify({
|
||||
"id": user.id,
|
||||
"email": user.email
|
||||
})
|
||||
|
||||
@app.route("/orders", methods=["GET"])
|
||||
def orders():
|
||||
|
||||
|
||||
|
||||
# Handle Images
|
||||
@app.route('/serve-image/<filename>', methods=['GET'])
|
||||
def serve_image(filename):
|
||||
|
||||
@ -24,6 +24,23 @@ class User(db.Model):
|
||||
id = db.Column(db.String(32), primary_key=True, unique=True, default=get_uuid)
|
||||
email = db.Column(db.String(345), unique=True)
|
||||
password = db.Column(db.Text, nullable=False)
|
||||
|
||||
class Orders(db.Model):
|
||||
__tablename__ ="orders"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(80), unique=False, nullable=False)
|
||||
email = db.Column(db.String(120), unique=False, nullable=False)
|
||||
order = db.Column(db.String(345), unique=False, nullable=False)
|
||||
|
||||
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"firstName":self.first_name,
|
||||
"lastName":self.last_name,
|
||||
"email": self.email,
|
||||
}
|
||||
|
||||
# class Category(db.Model):
|
||||
# __tablename__ = "categories"
|
||||
|
||||
Binary file not shown.
@ -14,21 +14,23 @@
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "^0.427.0",
|
||||
"next": "14.1.4",
|
||||
"react": "^18",
|
||||
"nodemailer": "^6.9.14",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"sharp": "^0.33.4",
|
||||
"tailwind-merge": "^2.5.0",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.1.4"
|
||||
"@types/node": "^20.14.15",
|
||||
"@types/nodemailer": "^6.4.15",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "14.1.4",
|
||||
"postcss": "^8.4.41",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
}
|
||||
|
||||
26
frontend/src/app/api/emails/route.ts
Normal file
26
frontend/src/app/api/emails/route.ts
Normal file
@ -0,0 +1,26 @@
|
||||
export async function POST() {
|
||||
const sender = {
|
||||
name: 'My App',
|
||||
address: 'no-reply@kevosattire.com',
|
||||
}
|
||||
|
||||
const recipients = [{
|
||||
name: 'John Doe',
|
||||
address: 'fernando.delgado@kevosattire.com',
|
||||
}]
|
||||
|
||||
try{
|
||||
const result = await sendEmail({
|
||||
sender,
|
||||
recipients,
|
||||
subject: "Thank you for placing an order with us!",
|
||||
message: "We will follow up with a Paypal invoice soon!"
|
||||
})
|
||||
|
||||
return Response.json({
|
||||
accepted: result.accepted,
|
||||
})
|
||||
} catch (error){
|
||||
return Response.json({message: 'Unable to send email at this time.'}, {status: 500})
|
||||
}
|
||||
}
|
||||
33
frontend/src/components/Form/Form.tsx
Normal file
33
frontend/src/components/Form/Form.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
"use client";
|
||||
import * as React from "react";
|
||||
|
||||
const Form = () => {
|
||||
const [result, setResult] = React.useState<Record<string, string>>({});
|
||||
const [loading, setLoading] = React.useState<boolean>(false);
|
||||
|
||||
const sendEmail = () => {
|
||||
setLoading(true);
|
||||
|
||||
fetch('/api/emails', {
|
||||
method: 'POST'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => setResult(data))
|
||||
.catch(error => setResult(error))
|
||||
.finally(() => setLoading(false))
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-4">
|
||||
<div className="my-4">{JSON.stringify(result)}</div>
|
||||
|
||||
{loading && <div className="my-4">Processing...</div>}
|
||||
|
||||
<button onClick={sendEmail} className="bg-blue-500 rounded p-3">
|
||||
Send email
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Form;
|
||||
30
frontend/src/lib/mail.utils.ts
Normal file
30
frontend/src/lib/mail.utils.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import nodemailer from "nodemailer";
|
||||
import Mail from "nodemailer/lib/mailer";
|
||||
import SMTPTransport from "nodemailer/lib/smtp-transport";
|
||||
|
||||
const transport = nodemailer.createTransport({
|
||||
host: process.env.MAIL_HOST,
|
||||
port: process.env.MAIL_PORT,
|
||||
secure: process.env.NODE_ENV !== 'development', //true
|
||||
auth: {
|
||||
user: process.env.MAIL_USER,
|
||||
pass: process.env.MAIL_PASSWORD
|
||||
},
|
||||
} as SMTPTransport.Options)
|
||||
|
||||
type SendEmailDto = {
|
||||
sender: Mail.Address,
|
||||
recipients: Mail.Address[],
|
||||
subject: string;
|
||||
message: string;
|
||||
}
|
||||
export const sendEmail = async (dto: SendEmailDto) => {
|
||||
const { sender, recipients, subject, message} = dto;
|
||||
|
||||
return await transport.sendMail({
|
||||
from: sender,
|
||||
to: recipients,
|
||||
html: message,
|
||||
text: message,
|
||||
})
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user