working orders page
@ -22,8 +22,8 @@ app.config["SESSION_PERMANENT"] = False
|
||||
app.config["SESSION_USE_SIGNER"] = True
|
||||
app.config["SESSION_REDIS"] = redis.from_url("redis://192.168.50.107:6379")
|
||||
# upload directory
|
||||
app.config["UPLOAD_DIRECTORY"] = 'uploads/'
|
||||
# app.config["UPLOAD_DIRECTORY"] = '../frontend/public/Group_1'
|
||||
# app.config["UPLOAD_DIRECTORY"] = 'uploads/'
|
||||
app.config["UPLOAD_DIRECTORY"] = '../frontend/public/batch1'
|
||||
# app.config["REDIS_PASSWORD"] = os.environ["REDIS_PASSWORD"]
|
||||
|
||||
# File value limit
|
||||
|
||||
@ -16,6 +16,12 @@ def index():
|
||||
images.append(file)
|
||||
return render_template('index.html', images=images)
|
||||
|
||||
@app.route('/list')
|
||||
def orderList():
|
||||
orders = Orders.query.all()
|
||||
all_orders = list(map(lambda x : x.to_json(), orders))
|
||||
return render_template('orders.html', orders=all_orders)
|
||||
|
||||
@app.route('/upload', methods=["POST"])
|
||||
def upload():
|
||||
try:
|
||||
@ -60,6 +66,7 @@ def mail():
|
||||
# Handle Images
|
||||
@app.route('/serve-image/<filename>', methods=['GET'])
|
||||
def serve_image(filename):
|
||||
|
||||
return send_from_directory(app.config['UPLOAD_DIRECTORY'], filename)
|
||||
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
object-fit: cover;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
50
backend/templates/orders.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Kevos orders</title>
|
||||
<style>
|
||||
body{
|
||||
background-color:#FBFAF4;
|
||||
}
|
||||
table {
|
||||
font-family: arial, sans-serif;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
td, th {
|
||||
border: 1px solid black;
|
||||
text-align: left;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #dddddd;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
|
||||
<div class="orders-section">
|
||||
<table>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Email</th>
|
||||
<th>Order</th>
|
||||
</tr>
|
||||
{% for order in orders %}
|
||||
<tr>
|
||||
<td>{{ order.id }}</td>
|
||||
<td>{{ order.email }}</td>
|
||||
<td>{{ order.order }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 219 KiB |
|
Before Width: | Height: | Size: 867 KiB |
|
Before Width: | Height: | Size: 619 KiB |
|
Before Width: | Height: | Size: 732 KiB |
|
Before Width: | Height: | Size: 505 KiB |
@ -1,92 +0,0 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "files_list",
|
||||
"photo": "/files_list.json",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "design_8_update-01",
|
||||
"photo": "/design_8_update-01.png",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Mockup_97",
|
||||
"photo": "/Mockup_97.jpg",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "json_sorter",
|
||||
"photo": "/json_sorter.py",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "design_update",
|
||||
"photo": "/design_update.png",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "design_4-01",
|
||||
"photo": "/design_4-01.png",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "design_7_update-01",
|
||||
"photo": "/design_7_update-01.png",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "test_design_never_give_up-01",
|
||||
"photo": "/test_design_never_give_up-01.png",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "mockup_1",
|
||||
"photo": "/mockup_1.jpg",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
}
|
||||
]
|
||||
|
Before Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 979 KiB |
|
Before Width: | Height: | Size: 221 KiB |
|
Before Width: | Height: | Size: 263 KiB |
|
Before Width: | Height: | Size: 219 KiB |
@ -1,82 +0,0 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "files_list",
|
||||
"photo": "./files_list.json",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "design_8_update-01",
|
||||
"photo": "./design_8_update-01.png",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Mockup_97",
|
||||
"photo": "./Mockup_97.jpg",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "design_update",
|
||||
"photo": "./design_update.png",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "design_4-01",
|
||||
"photo": "./design_4-01.png",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "design_7_update-01",
|
||||
"photo": "./design_7_update-01.png",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "test_design_never_give_up-01",
|
||||
"photo": "./test_design_never_give_up-01.png",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "mockup_1",
|
||||
"photo": "./mockup_1.jpg",
|
||||
"price": 25,
|
||||
"size": "Youth-S/M/L/2XL | Adult-S/M/L/2XL",
|
||||
"inStock": "yes",
|
||||
"favorite": "no",
|
||||
"description": "It's not an option.."
|
||||
}
|
||||
]
|
||||
@ -16,12 +16,12 @@ export const sendEmail = async (formData: FormData) => {
|
||||
//only allow authenticated user as well
|
||||
|
||||
const senderEmail = formData.get('senderEmail');
|
||||
const message = formData.get('message');
|
||||
const order = formData.get('order');
|
||||
|
||||
if (!validateString(senderEmail, 500)){
|
||||
return{ error: "Invalid sender Email",};
|
||||
}
|
||||
if (!validateString(message, 5000)){
|
||||
if (!validateString(order, 5000)){
|
||||
return{ error: "Invalid message",};
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ export const sendEmail = async (formData: FormData) => {
|
||||
subject: "New Order",
|
||||
reply_to: senderEmail as string,
|
||||
// text: message as string,
|
||||
react: React.createElement(OrderFormEmail, {message: message as string, senderEmail: senderEmail as string}),
|
||||
react: React.createElement(OrderFormEmail, {order: order as string, senderEmail: senderEmail as string}),
|
||||
});
|
||||
} catch (error: unknown){
|
||||
return console.log(error)
|
||||
|
||||
@ -13,11 +13,11 @@ import {
|
||||
import { Tailwind } from "@react-email/tailwind";
|
||||
|
||||
type OrderFormEmailProps = {
|
||||
message: string;
|
||||
order: string;
|
||||
senderEmail: string;
|
||||
};
|
||||
|
||||
export default function OrderFormEmail({ message, senderEmail }: OrderFormEmailProps) {
|
||||
export default function OrderFormEmail({ order, senderEmail }: OrderFormEmailProps) {
|
||||
return (
|
||||
<Html>
|
||||
<Head />
|
||||
@ -27,7 +27,7 @@ export default function OrderFormEmail({ message, senderEmail }: OrderFormEmailP
|
||||
<Container>
|
||||
<Section className="bg-white border-black my-10 px-10 py-4 rounded-md">
|
||||
<Heading className="leading-tight">You received a new order from the order form.</Heading>
|
||||
<Text>{message}</Text>
|
||||
<Text>{order}</Text>
|
||||
<Hr />
|
||||
<Text>The sender's email is: {senderEmail}</Text>
|
||||
</Section>
|
||||
|
||||
@ -15,6 +15,9 @@ const Popp = Poppins({ weight: "400", subsets: ["latin"] });
|
||||
// improve to drag & drop side cart for more fun
|
||||
|
||||
export default function Home() {
|
||||
const [email, setEmail] = React.useState<string>("");
|
||||
const [order, setOrder] = React.useState<string>("");
|
||||
|
||||
const [isOpen, setIsOpen] = React.useState(false);
|
||||
const [showPortal, setShowPortal] = React.useState(false);
|
||||
const handleModal = () => {
|
||||
@ -69,6 +72,7 @@ export default function Home() {
|
||||
<input
|
||||
className="h-14 px-4 rounded-lg border-black bg-slate-600 lg:w-1/3 md:w-1/2 text-[#EEEEEE]"
|
||||
type="email"
|
||||
value={email}
|
||||
required
|
||||
maxLength={500}
|
||||
placeholder="Your email"
|
||||
@ -77,7 +81,8 @@ export default function Home() {
|
||||
|
||||
<textarea
|
||||
className="h-52 my-3 rounded-lg lg:w-1/3 md:w-1/2 bg-slate-600 p-4 text-[#EEEEEE]"
|
||||
name="message"
|
||||
name="order"
|
||||
value={order}
|
||||
placeholder="Your order"
|
||||
required
|
||||
maxLength={500}
|
||||
|
||||