Services page finished. Ready for deployment

This commit is contained in:
2024-04-28 16:48:16 +01:00
parent 7d4ef4b429
commit 4d2770d003
29 changed files with 213 additions and 135 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

6
app.py
View File

@@ -100,7 +100,7 @@ def home():
return render_template('_page_home.html', model=Model_View_Home(db, get_info_user(), app))
@app.route('/contact', methods=['GET', 'POST'])
@app.route('/contact', methods=['GET'])
def contact():
form = Form_Contact()
if form.validate_on_submit():
@@ -115,6 +115,10 @@ def contact():
mail.send(mailItem)
return render_template('_page_contact.html', model=Model_View_Contact(db, get_info_user(), app, form))
@app.route('/services', methods=['GET', 'POST'])
def services():
return render_template('_page_services.html', model=Model_View_Home(db, get_info_user(), app))
# Store
@app.route('/store', methods=['GET', 'POST'])

View File

@@ -44,6 +44,9 @@ class Config:
MAIL_PASSWORD = os.getenv('MAIL_PASSWORD')
MAIL_DEFAULT_SENDER = 'edward.middletonsmith@gmail.com'
RECAPTCHA_PUBLIC_KEY = os.getenv('RECAPTCHA_PUBLIC_KEY')
RECAPTCHA_PRIVATE_KEY = os.getenv('RECAPTCHA_PRIVATE_KEY')
class DevelopmentConfig(Config):
DEBUG = True
# Add development-specific configuration variables

View File

@@ -17,7 +17,7 @@ Defines Flask-WTF forms for handling user input.
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, SubmitField, BooleanField, IntegerField, SelectField
from wtforms.validators import InputRequired, NumberRange, Regexp, DataRequired
from flask_wtf.recaptcha import RecaptchaField
class Form_Contact(FlaskForm):
@@ -25,6 +25,7 @@ class Form_Contact(FlaskForm):
CC = BooleanField('Would you like to receive a copy of this email request?') # not in use
name = StringField('Name')
msg = TextAreaField('Message')
recaptcha = RecaptchaField()
submit = SubmitField('Submit')
class Form_Register(FlaskForm):

View File

@@ -17,9 +17,13 @@ mysqlclient
# 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
# RECAPTCHA_PUBLIC_KEY = ''
# RECAPTCHA_PRIVATE_KEY = ''
# run with:
# python -m flask run
# host network-wide with:
# python -m flask run --host=0.0.0.0
# not env var:
# auth0 recovery key: S92HY59VU5J9YDVYWCRHSKJ8

View File

@@ -8,6 +8,7 @@
#pageBody > .card:not(:first-of-type) {
}
/*
.content > a {
display: flex;

37
static/css/services.css Normal file
View File

@@ -0,0 +1,37 @@
#pageBody > .card {
padding-left: 5vw;
padding-right: 5vw;
max-width: 80vw;
}
#pageBody > .card:first-of-type{
}
#pageBody > .card:last-of-type {
padding-left: 5vw;
padding-right: 5vw;
}
#pageBody > .card:not(:first-of-type) {
}
table {
left: 5vw;
max-width: 70vw;
width: fit-content !important;
}
/*
tr th::after {
content: "";
position: absolute;
top: 65px;
left: 4%;
width: 92%;
border-bottom: 2px solid var(--c_purple_dark);
}
*/
/*
img {
max-height: 5vh;
max-width: 10vw;
}
*/

View File

@@ -51,7 +51,7 @@ h2 {
h3 {
font-size: 18px;
margin: 1vh;
margin-top: 1vh;
}
h4 {
@@ -92,7 +92,7 @@ h5 {
width: 100%;
max-height: 15vh;
font-weight: normal;
font-size: 25px;
font-size: 20px;
}
/*
.topnav a {
@@ -224,13 +224,14 @@ img, video {
/* header image */
img.header-logo {
max-height: 15vh;
max-width: 20vw;
}
/* icon images */
.img-icon {
max-width: 5vh;
max-height: 5vh;
border-radius: 1vh;
max-width: 16vh;
max-height: 8vh;
border-radius: 0;
}
.container-icon-label {
@@ -270,6 +271,7 @@ img.header-logo {
border-radius: 4vh;
/* min-width: fit-content; */
position: relative;
height: fit-content;
}
.card.subcard {
@@ -464,3 +466,8 @@ button, .btn-submit, input[type="submit"] {
margin-top: 4.5px;
margin-bottom: 4.5px;
}
li {
text-align: left;
font-size: 18px;
}

BIN
static/images/C#_NET.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
static/images/CSS3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
static/images/Firebase.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
static/images/Flask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
static/images/HTML5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
static/images/Java.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

BIN
static/images/MVC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

BIN
static/images/MySQL.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
static/images/Node_js.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

BIN
static/images/REST.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
static/images/React.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
static/images/python.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 KiB

5
static/js/services.js Normal file
View File

@@ -0,0 +1,5 @@
var _loading = true;
function hookupPageServices() {
_loading = false;
}

View File

@@ -59,6 +59,14 @@ function hookupNavigation() {
});
});
let btnNavServices = $(idNavServices);
initialiseEventHandler(btnNavServices, flagInitialised, function() {
btnNavServices.on("click", function(event) {
event.stopPropagation();
goToPage(hashPageServices);
});
});
let btnNavContact = $(idNavContact);
initialiseEventHandler(btnNavContact, flagInitialised, function() {
btnNavContact.on("click", function(event) {

View File

@@ -61,6 +61,9 @@
<p class="error">{{ error }}</p>
{% endfor %}
</div>
<div class="container-input">
{{ model.form.recaptcha() }}
</div>
<div class="container-input">
{{ model.form.submit() }}
</div>
@@ -68,13 +71,13 @@
</div>
<div class="card">
<h3 class="label-title">Contact Details</h3>
<div class="container">
<h3 class="label-title" style="padding-bottom: 0;">Contact Details</h3>
<div class="container" style="padding-top: 0;">
<h4>edward.middletonsmith@gmail.com</h4>
<a href="{{ model.url_LinkedIn }}" class="container-icon-label"><img class="img-icon" src="{{ url_for('static', filename='images/Logo_LinkedIn.png') }}"/><h4>LinkedIn</h4></a>
<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">
<div class="container" style="padding-top: 0;">
<h4>53 Alfred Green Close</h4>
<h4>Rugby, Warwickshire</h4>
<h4>CV22 6DN</h4>

View File

@@ -6,139 +6,142 @@
{% block page_body %}
<!-- Include Stylesheet -->
<link rel="stylesheet" href="{{ url_for('static', filename='css/home.css') }}" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/services.css') }}" />
<!-- HTML content -->
<div>
<p>Your software engineering solution</p>
<button class="button-contact">Get in touch</button>
<div class="{{ model.FLAG_CARD }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<h2>Web & Desktop Application Development</h2>
<ul>
<li>Deliver custom web and desktop apps tailored to your unique business needs</li>
<li>Leverage the latest technologies for seamless, high-performance solutions</li>
<li>Intuitive UX design to delight your users and boost productivity</li>
</ul>
<h2>Cloud Migration & Architecture Design</h2>
<ul>
<li>Expertise to guide your cloud journey and optimize your architecture</li>
<li>Ensure scalability, security and cost-efficiency in the cloud</li>
<li>Unlock the power of cloud-native services to accelerate innovation</li>
</ul>
</div>
</div>
<div class="{{ model.FLAG_CARD }}">
<!--
<table>
<thead>
<!--
<tr>
<th>Cloud / Backend</th>
<th></th>
<th>Web</th>
<th></th>
</tr>
--
<tr>
<th>Database</th>
<th>Server / Application</th>
<th>Web</th>
<th>Frameworks</th>
</tr>
</thead>
<tbody>
<tr>
<td>MySQL</td>
<td>Python</td>
<td>HTML</td>
<td>React</td>
</tr>
<tr>
<td>MS SQL Server</td>
<td>C# .NET</td>
<td>CSS</td>
<td>Flask</td>
</tr>
<tr>
<td>Firebase</td>
<td>Node.js</td>
<td>JavaScript</td>
<td>MVC</td>
</tr>
<tr>
<td></td>
<td>Java</td>
<td></td>
<td>REST</td>
</tr>
</tbody>
</table>
-->
<table>
<thead>
<!--
<tr>
<th>Cloud / Backend</th>
<th></th>
<th>Web</th>
<th></th>
</tr>
-->
<tr>
<th>Database</th>
<th>Server / Application</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.mysql.com/" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/MySQL.png')}}" alt="MySQL"></img></a></td>
<td><a href="https://www.python.org/" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/python.png')}}" alt="python"></img></a></td>
</tr>
<tr>
<td><a href="https://www.microsoft.com/en-us/sql-server/sql-server-2019" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/MS_SQL_Server.svg')}}" alt="MS SQL Server"></img></a></td>
<td><a href="https://dotnet.microsoft.com/en-us/languages/csharp" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/C#_NET.png')}}" alt="C# .NET"></img></a></td>
</tr>
<tr>
<td><a href="https://firebase.google.com/" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/Firebase.png')}}" alt="Firebase"></img></a></td>
<td><a href="https://nodejs.org/en" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/Node_js.png')}}" alt="Node.js"></img></a></td>
</tr>
<tr>
<td></td>
<td><a href="https://www.java.com/en/" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/Java.png')}}" alt="Java"></img></a></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Web</th>
<th>Frameworks</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.w3.org/html/" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/HTML5.png')}}" alt="HTML5"></img></a></td>
<td><a href="https://react.dev/" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/React.png')}}" alt="React"></img></a></td>
</tr>
<tr>
<td><a href="https://www.w3.org/Style/CSS/" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/CSS3.jpg')}}" alt="CSS3"></img></a></td>
<td><a href="https://flask.palletsprojects.com/en/3.0.x/" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/Flask.png')}}" alt="Flask"></img></a></td>
</tr>
<tr>
<td><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/JavaScript.png')}}" alt="JavaScript"></img></a></td>
<td><a href="https://dotnet.microsoft.com/en-us/apps/aspnet/mvc" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/MVC.png')}}" alt="MVC"></img></a></td>
</tr>
<tr>
<td></td>
<td><a href="https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm" target="_blank"><img class="img-icon" src="{{ url_for('static', filename='images/REST.png')}}" alt="REST"></img></a></td>
</tr>
</tbody>
</table>
</div>
<!-- Include JavaScript -->
<script src="{{ url_for('static', filename='js/home.js') }}"></script>
<script src="{{ url_for('static', filename='js/services.js') }}"></script>
<script>
var hashPageCurrent = "{{ model.HASH_PAGE_SERVICES }}";
$(document).ready(function() {
hookupPageHome();
hookupPageServices();
});
</script>
{% endblock %}
<div class="{{ model.FLAG_CARD }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<h2>Web App & Database Design</h2>
<p>Crafting seamless digital experiences with expertly designed web applications and robust database solutions.</p>
</div>
<div class="{{ model.FLAG_CONTAINER }}">
<!-- image
<img class="img-demo" src="{{ url_for('static', filename='images/webapp_db_design.jpg')}}" alt="Web app and database design image">
-->
<!-- MP4 video --
<video controls class="img-demo" name="Web app and database design">
<source src="{{ url_for('static', filename='images/webapp_db_design.mp4')}}" type="video/mp4">
Your browser does not support the video format mp4.
</video>
-->
<!-- gif --
<img class="img-demo" src="{{ url_for('static', filename='images/webapp_db_design.gif')}}" alt="Web app and database design gif">
-->
</div>
</div>
<div class="{{ model.FLAG_CARD }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<h2>Programming services (C++, Python, etc.)</h2>
<p>Empowering businesses with efficient automation, web manipulation, and cutting-edge AI/ML solutions for complex tasks.</p>
</div>
<div class="{{ model.FLAG_CONTAINER }}">
<!-- image --
<img class="img-demo" src="{{ url_for('static', filename='images/webapp_db_design.jpg')}}" alt="Web app and database design image">
-->
<!-- MP4 video -->
<video controls class="img-demo" name="Programming services">
<source src="{{ url_for('static', filename='images/programming_services.mp4')}}" type="video/mp4">
Your browser does not support the video format mp4.
</video>
<!-- gif --
<img class="img-demo" src="{{ url_for('static', filename='images/webapp_db_design.gif')}}" alt="Web app and database design gif">
-->
</div>
</div>
<div class="{{ model.FLAG_CARD }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<h2>MS Office Data Analysis & Automation</h2>
<p>Unleashing the power of MS Office for streamlined data analysis, automation, and enhanced productivity across Excel, PowerPoint, and Outlook.</p>
</div>
<div class="{{ model.FLAG_CONTAINER }}">
<!-- image --
<img class="img-demo" src="{{ url_for('static', filename='images/webapp_db_design.jpg')}}" alt="Web app and database design image">
-->
<!-- MP4 video -->
<video controls class="img-demo" name="MS Office automation">
<source src="{{ url_for('static', filename='images/ms_automation.mp4')}}" type="video/mp4">
Your browser does not support the video format mp4.
</video>
<!-- gif --
<img class="img-demo" src="{{ url_for('static', filename='images/webapp_db_design.gif')}}" alt="Web app and database design gif">
-->
</div>
</div>
<div class="{{ model.FLAG_CARD }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<h2>Mechatronics Design</h2>
<p>Integrating mechanical and electronic components seamlessly for innovative mechatronic solutions, elevating your product design.</p>
</div>
<div class="{{ model.FLAG_CONTAINER }}">
<!-- image --
<img class="img-demo" src="{{ url_for('static', filename='images/webapp_db_design.jpg')}}" alt="Web app and database design image">
-->
<!-- MP4 video --
<video controls class="img-demo">
<source src="{{ url_for('static', filename='images/programming_services.mp4')}}" type="video/mp4">
Your browser does not support the video format mp4.
</video>
-->
<!-- gif -->
<img class="img-demo" src="{{ url_for('static', filename='images/mechatronics_design.gif')}}" alt="Mechatronics design gif">
</div>
</div>
<div class="{{ model.FLAG_CARD }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<h2>CAD, DFM, DFAM</h2>
<p>Transforming concepts into reality with precision CAD designs, Design for Manufacturing (DFM), and Design for Additive Manufacturing (DFAM) expertise.</p>
</div>
<div class="{{ model.FLAG_CONTAINER }}">
<!-- image --
<img class="img-demo" src="{{ url_for('static', filename='images/webapp_db_design.jpg')}}" alt="Web app and database design image">
-->
<!-- MP4 video --
<video controls class="img-demo">
<source src="{{ url_for('static', filename='images/programming_services.mp4')}}" type="video/mp4">
Your browser does not support the video format mp4.
</video>
-->
<!-- gif -->
<img class="img-demo" src="{{ url_for('static', filename='images/CAD.gif')}}" alt="Computer aided design gif">
</div>
</div>
<div class="{{ model.FLAG_CARD }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<h2>Photopolymerisation, Materials Science, AM Advice</h2>
<p>Navigating the forefront of materials science and additive manufacturing, providing expert advice on photopolymerisation and innovative AM solutions.</p>
</div>
<div class="{{ model.FLAG_CONTAINER }}">
<!-- image --
<img class="img-demo" src="{{ url_for('static', filename='images/webapp_db_design.jpg')}}" alt="Web app and database design image">
-->
<!-- MP4 video --
<video controls class="img-demo">
<source src="{{ url_for('static', filename='images/programming_services.mp4')}}" type="video/mp4">
Your browser does not support the video format mp4.
</video>
-->
<!-- gif --
<img class="img-demo" src="{{ url_for('static', filename='images/webapp_db_design.gif')}}" alt="Web app and database design gif">
-->
</div>
</div>

View File

@@ -8,6 +8,7 @@
<!-- Scripts -->
<script src="{{ url_for('static', filename='js/shared.js') }}"></script>
<script src="https://code.jquery.com/jquery-3.7.1.js"></script> <!-- Include jQuery from a CDN -->
<script src="https://www.google.com/recaptcha/enterprise.js?render=6Lf8Q8cpAAAAAFAawGu4-ma60bvbEixNVTVvRzKe"></script> <!-- reCaptcha Integration -->
<script>
var attrTextCollapsed = "{{ model.ATTR_TEXT_COLLAPSED }}";
@@ -59,7 +60,7 @@
<div class="topnav">
<div class="{{ model.FLAG_CONTAINER }}" style="width: 18vw; min-width: 18vw; max-width: 25vw;">
<div class="{{ model.FLAG_CONTAINER }}" style="width: 18vw; min-width: 18vw; max-width: 20vw;">
<img class="header-logo" src="{{ url_for('static', filename='images/Logo.png') }}" alt="PARTS logo">
</div>
<div class="{{ model.FLAG_CONTAINER }}" style="width: 75vw; min-width: 65vw; max-width: 80vw;">
@@ -70,7 +71,7 @@
</div>
</div>
<div id="{{ model.ID_OVERLAY_HAMBURGER }}" class="{{ model.FLAG_OVERLAY}} {{ model.FLAG_HAMBURGER }} {{ model.FLAG_EXPANDED}}" style="height: {{ 27 * 3 }}px"> <!-- {- { 4.5 * 3 }}vh -->
<div id="{{ model.ID_OVERLAY_HAMBURGER }}" class="{{ model.FLAG_OVERLAY}} {{ model.FLAG_HAMBURGER }} {{ model.FLAG_COLLAPSED }}" style="height: {{ 27 * 3 }}px"> <!-- {- { 4.5 * 3 }}vh -->
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a id="{{ model.ID_NAV_HOME }}">Home</a> <!-- href="{{ url_for('home') }}" -->
</div>