From 7d4ef4b429176ba6258312250833dc63e4250de8 Mon Sep 17 00:00:00 2001 From: teddy Date: Wed, 24 Apr 2024 19:51:31 +0100 Subject: [PATCH] Flask Mail added. Contact us page complete. --- __pycache__/app.cpython-311.pyc | Bin 31544 -> 32062 bytes __pycache__/config.cpython-311.pyc | Bin 1925 -> 2085 bytes app.py | 18 ++++- config.py | 12 +++- .../model_view_base.cpython-311.pyc | Bin 5511 -> 5550 bytes .../model_view_contact.cpython-311.pyc | Bin 1993 -> 2069 bytes models/model_view_base.py | 1 + models/model_view_contact.py | 5 +- requirements.txt | 1 + static/css/contact.css | 10 +++ static/css/home.css | 11 +++ static/css/shared.css | 66 +++++++++++------- static/js/contact.js | 16 +++++ templates/_page_contact.html | 16 +++-- templates/layout.html | 8 +-- 15 files changed, 125 insertions(+), 39 deletions(-) diff --git a/__pycache__/app.cpython-311.pyc b/__pycache__/app.cpython-311.pyc index a2994b7ee42e3d68ad1f6a2ecf38dc43956db96b..5d9b7c48c72e00e142138f4441fe81ddff4829df 100644 GIT binary patch delta 6082 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 O%k?t)-`OS$ruBbD+ECd5 delta 5640 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 diff --git a/__pycache__/config.cpython-311.pyc b/__pycache__/config.cpython-311.pyc index bed9d752c47cfe318144d8d9c2dfe1e69f63d8a7..7adbb68442921aaa235217583a6c941c558259a4 100644 GIT binary patch delta 525 zcmZqWUn;=2oR^o20SG3WXr|3#-^jO~k@3sqeT;i;I2lqnqWDrcqxe&}q6AX7qXd~4 zQdzUuK#D;ig=ZNf1H)<{hJYv`pc>&6-e3kzzRCSeg`QP>#knN~dg-}|nK^pN`MH_i zObiSmRr0AR<%vZpdbyb?DLJVn`FX{;nI#zxaAmi6eH}f0;sYFmgTwuUT>LaeCUY`R z@Z$!H2D=7@xdz?hgedV33c1AtW`+j4#)tR>L-hiAL4JaWbTEM)3o&KnhndgC_Un z?M#K7Aukz$>iskYCl@kLFyzlHj?c_X&M8evO^FY447tUfnG&B|T2z#pmt1*E2*@c) zP0!5Fi%&_-$t+7Ps+{c4QouNU@&T4w`5R(V4gMdPI9NG82r&qYG0F*>qng9R* diff --git a/app.py b/app.py index 24eb2953..67edba02 100644 --- a/app.py +++ b/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 "Error" + return "Email sent" +""" # Onload if __name__ == '__main__': diff --git a/config.py b/config.py index e7978608..25d29489 100644 --- a/config.py +++ b/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 diff --git a/models/__pycache__/model_view_base.cpython-311.pyc b/models/__pycache__/model_view_base.cpython-311.pyc index c2ad9d7a45a5a902466ca4401c02dc886bd821aa..7668a70adb38812a2be9a039081fcff5bbcb5060 100644 GIT binary patch delta 545 zcmZqIUZ>5woR^o20SH#@&`8_2k(ZT;QDd?&(`Ty`{V2m!qZES{hGjt6)gUEc5M|uK zkj9u|*uoKIl48`t5M`QT3?$7u7%CW}%!3&;O*Y#ww=(i@r{x#rI_Kw=Bqo<^KEQI8 zkuhX*A6p?Kqtzr12}YaAk{r@(CO{L594A|G$S_7s4(CW?G~2w7<1mwe1xVZyL|B0c z>&X+jeWh$cOgj)^4x4k}6yW!CiFfl4@{M=)_X}}!4%y5rD9k8e z3RG9*2qOGIM9^ddAyIiZAhVbeNH`RMLxcw;1tR1@67wdf2t8#HQ*Q8|>><1p=t?FL zCq}!;t|DPlMj(YCtHJtyaoFVMr5P%#kBAm;BcN=#xAB!xs2(nQT&usDtG;is1PDV42K z2^IOwnPvSBkMIBu(e#K3JyfaupKRll&ldk70crF@cz*7hMH^3e#!C48o4!Iz#P_ zY%+^`4}&U^=&!?!s~l!i45q{|z=Oo-fg=bj*0p07AVCM6YoRc+sz~x|Y1)k1o=(^f z2R1v_YBfV&-84l$fHmJbM}W|lb4W^H*BG_AQjoVYt{1SvZV%+*tW45~0%C!osg%nV zW7RY(x?z;dDv&u=HGv^b_=h;~D54)lgC2Qa>6Z7Ny-)RJV451fC4U6Z;HA9fTTX4% ev>ijAA;+}kJDXhu2)qe@^R)8L&F4R!kNp9-40H$p diff --git a/models/__pycache__/model_view_contact.cpython-311.pyc b/models/__pycache__/model_view_contact.cpython-311.pyc index 20fb1aef3ba507dacfc9ade84abc9f01c1e63071..01d67098498b6501b4eb89f5dd2d961603078696 100644 GIT binary patch delta 545 zcmZvXJxBvF6vvbH?s`_wYOPhP*n%P+LYFQMMJ#$~t92%m#h3uh~daYS3HMvTv#froI)y582YQ-uk!5=$j`tIQD&9g5BVT8q%_}q}l&~bso z*k7k4LN(!w<{4HtVVL!lwlyYdxsFh!R%s$cBjRdmG$d_e5|a{B5;8@n1sa+_LWWDd zc?s516EMk6)sz+%IkTTVsB`V?DzfsK>?RKimA49o%$mgmLT_dA7T0%aeV5SY0Uegc za%Y+l;08h^r`Tweh~pq+!ta^#%gf*6bXh9lEpsHqhYNnsQz+`LKMqIToccHzao5;} zM&wtuG#q6w+DvRvcFQe2vrj!;t>czMmS~bK1j>s8BXHss{Ka|vO}@VWlk(iY01wrH AZU6uP delta 488 zcmbO#aFU;QIWI340}v#zzE2I^$h(^{!Vbu5XPC~A$`Hkv!Vtxj%ACU3!mtb|x*DVq z45C;%7}6M1m|8fZSivl2Ad9Vop@K1rJ(xk0<(80deoAUid{|~`dAxIeUP)qd$z(gG zQ;dq6Ihl`2YJ+rX0f`?C z3{N?DJK1~KuX9LT;*gjz`7Emx8$VD+lVkE*R<*E#qWpr?qLRuYKA;%b#YG^~Z}G;* zC+8#<7bmCY .card:first-of-type{ + top: 0; + flex-grow: 1; +} +#pageBody > .card:last-of-type { +} +#pageBody > .card:not(:first-of-type) { +} + /* .content > a { display: flex; diff --git a/static/css/home.css b/static/css/home.css index 36bdc651..b02945af 100644 --- a/static/css/home.css +++ b/static/css/home.css @@ -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; diff --git a/static/css/shared.css b/static/css/shared.css index dfe81c2f..bcf5f251 100644 --- a/static/css/shared.css +++ b/static/css/shared.css @@ -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 > * { diff --git a/static/js/contact.js b/static/js/contact.js index f0cff237..14aa627c 100644 --- a/static/js/contact.js +++ b/static/js/contact.js @@ -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%" + }); +} \ No newline at end of file diff --git a/templates/_page_contact.html b/templates/_page_contact.html index d2d1e34c..c67db85c 100644 --- a/templates/_page_contact.html +++ b/templates/_page_contact.html @@ -4,11 +4,11 @@ {% block page_body %} - +

-
+

Complete the form or find our details below.

+
@@ -139,7 +139,7 @@