Flask Mail added. Contact us page complete.
This commit is contained in:
Binary file not shown.
Binary file not shown.
18
app.py
18
app.py
@@ -37,6 +37,7 @@ from business_objects.product import Product_Filters
|
||||
from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session
|
||||
from flask_cors import CORS
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_mail import Mail, Message
|
||||
import stripe
|
||||
import json
|
||||
from dotenv import load_dotenv, find_dotenv
|
||||
@@ -87,6 +88,8 @@ oauth.register(
|
||||
)
|
||||
# session[app.ID_TOKEN_USER] = {'userinfo': {'sub': ''}}
|
||||
|
||||
mail = Mail(app)
|
||||
|
||||
|
||||
# METHODS
|
||||
|
||||
@@ -107,7 +110,9 @@ def contact():
|
||||
name = form.name.data
|
||||
msg = form.msg.data
|
||||
# send email
|
||||
pass
|
||||
mailItem = Message("PARTS Website Contact Us Message", recipients=[app.config['MAIL_DEFAULT_SENDER']])
|
||||
mailItem.body = f"Dear Lord Edward Middleton-Smith,\n\n{msg}\n\nKind regards,\n{name}\n{email}"
|
||||
mail.send(mailItem)
|
||||
return render_template('_page_contact.html', model=Model_View_Contact(db, get_info_user(), app, form))
|
||||
|
||||
|
||||
@@ -651,6 +656,17 @@ def get_info_user():
|
||||
except:
|
||||
return {'sub': ''}
|
||||
|
||||
"""
|
||||
@app.route('/send-email', methods=['GET'])
|
||||
def send_email():
|
||||
try:
|
||||
msg = Message("Flask Mail test", recipients=[app.config['MAIL_DEFAULT_SENDER']])
|
||||
msg.body = "Dear Lord Edward Middleton-Smith,\n\nThis is a test email sent from Flask.\n\nKind regards,\nBot"
|
||||
mail.send(msg)
|
||||
except:
|
||||
return "<html>Error</html>"
|
||||
return "<html>Email sent</html>"
|
||||
"""
|
||||
|
||||
# Onload
|
||||
if __name__ == '__main__':
|
||||
|
||||
12
config.py
12
config.py
@@ -25,7 +25,7 @@ class Config:
|
||||
ID_AUTH0_CLIENT_SECRET = os.getenv('ID_AUTH0_CLIENT_SECRET')
|
||||
DOMAIN_AUTH0 = os.getenv('DOMAIN_AUTH0')
|
||||
ID_TOKEN_USER = 'user'
|
||||
is_included_VAT = True
|
||||
# is_included_VAT = True
|
||||
"""
|
||||
KEY_IS_INCLUDED_VAT = 'is_included_VAT'
|
||||
code_currency = 1
|
||||
@@ -35,8 +35,14 @@ class Config:
|
||||
KEY_ID_CURRENCY = 'id_currency'
|
||||
KEY_ID_REGION_DELIVERY = 'id_region_delivery'
|
||||
"""
|
||||
id_currency = 1
|
||||
id_region_delivery = 1
|
||||
# id_currency = 1
|
||||
# id_region_delivery = 1
|
||||
MAIL_SERVER = 'smtp.gmail.com'
|
||||
MAIL_PORT = 587
|
||||
MAIL_USE_TLS = True
|
||||
MAIL_USERNAME = 'edward.middletonsmith@gmail.com'
|
||||
MAIL_PASSWORD = os.getenv('MAIL_PASSWORD')
|
||||
MAIL_DEFAULT_SENDER = 'edward.middletonsmith@gmail.com'
|
||||
|
||||
class DevelopmentConfig(Config):
|
||||
DEBUG = True
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -64,6 +64,7 @@ class Model_View_Base(ABC):
|
||||
HASH_PAGE_STORE_HOME = '/store'
|
||||
HASH_PAGE_STORE_PRODUCT = '/store/product'
|
||||
ID_BUTTON_HAMBURGER = 'btnHamburger'
|
||||
ID_FORM_CONTACT = 'formContact'
|
||||
ID_FORM_CURRENCY = 'formCurrency'
|
||||
ID_FORM_DELIVERY_REGION = 'formDeliveryRegion'
|
||||
ID_FORM_IS_INCLUDED_VAT = 'formIsIncludedVAT'
|
||||
|
||||
@@ -23,13 +23,16 @@ from lib import argument_validation as av
|
||||
from flask_wtf import FlaskForm
|
||||
from abc import abstractproperty
|
||||
|
||||
|
||||
# VARIABLE INSTANTIATION
|
||||
|
||||
|
||||
# CLASSES
|
||||
class Model_View_Contact(Model_View_Base):
|
||||
# Attributes
|
||||
ID_EMAIL = 'email'
|
||||
ID_MESSAGE = 'msg'
|
||||
ID_NAME = 'name'
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
return 'Contact'
|
||||
|
||||
@@ -16,6 +16,7 @@ mysqlclient
|
||||
# DOMAIN_AUTH0=dev-nwak2066ef6h8ixn.us.auth0.com
|
||||
# SQLALCHEMY_DATABASE_URI = 'mysql://username:password@localhost/dbname'
|
||||
# Replace 'username', 'password', 'localhost', and 'dbname' with your actual database credentials
|
||||
# MAIL_PASSWORD=uifv utsy yzxy hpnm
|
||||
|
||||
# run with:
|
||||
# python -m flask run
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
|
||||
#pageBody > .card:first-of-type{
|
||||
top: 0;
|
||||
flex-grow: 1;
|
||||
}
|
||||
#pageBody > .card:last-of-type {
|
||||
}
|
||||
#pageBody > .card:not(:first-of-type) {
|
||||
}
|
||||
|
||||
/*
|
||||
.content > a {
|
||||
display: flex;
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
|
||||
.page-body > * {
|
||||
height: 100%;
|
||||
}
|
||||
#pageBody > * :first-child{
|
||||
margin-top: 25vh;
|
||||
}
|
||||
#pageBody > * :last-child {
|
||||
margin-bottom: 35vh;
|
||||
}
|
||||
|
||||
.img-demo {
|
||||
max-width: 50%;
|
||||
min-width: 500px;
|
||||
|
||||
@@ -33,26 +33,34 @@ body {
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
h1, h2, h3, h4, h5, p, a, label {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 4vh;
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2.4vh;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 2vh;
|
||||
font-size: 18px;
|
||||
margin: 1vh;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.5vh;
|
||||
font-size: 13px;
|
||||
margin: 1vh;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25vh;
|
||||
font-size: 11px;
|
||||
margin: 1vh;
|
||||
}
|
||||
|
||||
@@ -136,12 +144,19 @@ h5 {
|
||||
|
||||
.page-body {
|
||||
height: 75vh !important;
|
||||
top: 15vh;
|
||||
bottom: 5vh;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.page-body > * {
|
||||
@@ -151,7 +166,6 @@ h5 {
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-self: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
@@ -160,15 +174,15 @@ h5 {
|
||||
align-self: center;
|
||||
padding-top: 1vh;
|
||||
padding-bottom: 1vh;
|
||||
color: white; /* var(--c_purple_dark); */
|
||||
color: var(--c_purple_dark);
|
||||
}
|
||||
#pageBody > * :first-child{
|
||||
margin-top: 25vh;
|
||||
#pageBody > .card {
|
||||
height: fit-content;
|
||||
margin-top: 1vh;
|
||||
}
|
||||
#pageBody > * :last-child {
|
||||
margin-bottom: 35vh;
|
||||
#pageBody > .card:last-of-type {
|
||||
margin-bottom: 1vh;
|
||||
}
|
||||
|
||||
/* Create two unequal columns that floats next to each other *
|
||||
/* Left column *
|
||||
.leftcolumn {
|
||||
@@ -245,7 +259,7 @@ img.header-logo {
|
||||
|
||||
/* Add a card effect for articles */
|
||||
.card {
|
||||
background-color: white;
|
||||
background-color: var(--c_purple_pastel);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex !important;
|
||||
@@ -254,7 +268,8 @@ img.header-logo {
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
border-radius: 4vh;
|
||||
min-width: fit-content;
|
||||
/* min-width: fit-content; */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card.subcard {
|
||||
@@ -305,14 +320,8 @@ img.header-logo {
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
/*
|
||||
background: var(--c_purple_light);
|
||||
border-top-right-radius: 2.5vh;
|
||||
border-top-left-radius: 2.5vh;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
*/
|
||||
height: 10vh !important;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.footer > h4, h5 {
|
||||
@@ -362,8 +371,8 @@ img.header-logo {
|
||||
|
||||
.container-input > input, .container-input > textarea {
|
||||
border: 2px solid var(--c_purple);
|
||||
max-width: 50%;
|
||||
min-width: 40%;
|
||||
max-width: 66%;
|
||||
min-width: 20%;
|
||||
padding: 1vh;
|
||||
}
|
||||
|
||||
@@ -422,7 +431,16 @@ button, .btn-submit, input[type="submit"] {
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
|
||||
border: 2px solid var(--c_purple_dark);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.hamburger:first-child {
|
||||
border-top-left-radius: 12px;
|
||||
border-top-right-radius: 12px;
|
||||
}
|
||||
.hamburger:last-child {
|
||||
border-bottom-left-radius: 12px;
|
||||
border-bottom-right-radius: 12px;
|
||||
}
|
||||
|
||||
.hamburger > * {
|
||||
|
||||
@@ -3,3 +3,19 @@ var _loading = true;
|
||||
function hookupPageContact() {
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
function stylePageContact() {
|
||||
let elementEmail = $(idEmail);
|
||||
let elementName = $(idName);
|
||||
let elementMessage = $(idMessage);
|
||||
|
||||
elementEmail.css({
|
||||
width: "50%"
|
||||
});
|
||||
elementName.css({
|
||||
width: "40%"
|
||||
});
|
||||
elementMessage.css({
|
||||
width: "66%"
|
||||
});
|
||||
}
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
{% block page_body %}
|
||||
<!-- Include Stylesheet -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/store_home.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/contact.css') }}">
|
||||
|
||||
<!-- HTML content -->
|
||||
<div class="card">
|
||||
<form id="{{ model.id_form_contact }}" class="container" action="{{ url_for('contact') }}" method="POST">
|
||||
<form id="{{ model.ID_FORM_CONTACT }}" class="container" action="{{ url_for('contact') }}" method="POST">
|
||||
<h2 class="label-title">Complete the form or find our details below.</h2>
|
||||
<!--
|
||||
<div class="container-input">
|
||||
@@ -75,9 +75,9 @@
|
||||
<a href="{{ model.url_GitHub }}" class="container-icon-label"><img class="img-icon" src="{{ url_for('static', filename='images/Logo_GitHub.png') }}"/><h4>GitHub</h4></a>
|
||||
</div>
|
||||
<div class="container">
|
||||
<h4>Unit 12c, Somers Road</h4>
|
||||
<h4>53 Alfred Green Close</h4>
|
||||
<h4>Rugby, Warwickshire</h4>
|
||||
<h4>CV22 7DH</h4>
|
||||
<h4>CV22 6DN</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -85,9 +85,13 @@
|
||||
<script src="{{ url_for('static', filename='js/contact.js') }}"></script>
|
||||
|
||||
<script>
|
||||
var hashPageCurrent = "{{ model.hash_page_contact }}";
|
||||
|
||||
var hashPageCurrent = "{{ model.HASH_PAGE_CONTACT }}";
|
||||
var idEmail = "#{{ model.ID_EMAIL }}";
|
||||
var idMessage = "#{{ model.ID_MESSAGE }}";
|
||||
var idName = "#{{ model.ID_NAME }}";
|
||||
|
||||
$(document).ready(function() {
|
||||
stylePageContact();
|
||||
hookupPageContact();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -59,13 +59,13 @@
|
||||
|
||||
|
||||
<div class="topnav">
|
||||
<div class="{{ model.FLAG_CONTAINER }}" style="width: 25vw; min-width: 15vw; max-width: 25vw;">
|
||||
<div class="{{ model.FLAG_CONTAINER }}" style="width: 18vw; min-width: 18vw; max-width: 25vw;">
|
||||
<img class="header-logo" src="{{ url_for('static', filename='images/Logo.png') }}" alt="PARTS logo">
|
||||
</div>
|
||||
<div class="{{ model.FLAG_CONTAINER }}" style="width: 60vw; min-width: 60vw; max-width: 60vw;">
|
||||
<div class="{{ model.FLAG_CONTAINER }}" style="width: 75vw; min-width: 65vw; max-width: 80vw;">
|
||||
<p class="company-name">Precision And Research Technology Systems</p>
|
||||
</div>
|
||||
<div class="{{ model.FLAG_CONTAINER }}" style="width: 15vw; min-width: 10vw; max-width: 15vw; justify-content: flex-end; "> <!-- padding-left: 25%; -->
|
||||
<div class="{{ model.FLAG_CONTAINER }}" style="width: 7vw; min-width: 7vw; max-width: 15vw; justify-content: flex-end; "> <!-- padding-left: 25%; -->
|
||||
<button id="{{ model.ID_BUTTON_HAMBURGER }}">=</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -139,7 +139,7 @@
|
||||
|
||||
|
||||
<div class="footer">
|
||||
<h4>Copyright (C) Precision And Research Technology Systems Limited. All rights reserved.</h4>
|
||||
<h4 style="padding-top: 1vh;">Copyright (C) Precision And Research Technology Systems Limited. All rights reserved.</h4>
|
||||
<h5>Company number 13587499</h5>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user