Fix(Restructure): \n 1. Restructure project as normal production website. \n 2. Add link to live BathroomWarehouse store site. \n 3. Add webp thumbnails for each project.

This commit is contained in:
2025-03-05 05:55:26 +00:00
parent 9550f09140
commit 6bb1f74395
5 changed files with 429 additions and 307 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -9,264 +9,8 @@
<!-- Security --> <!-- Security -->
<meta http-equiv="X-Frame-Options" content="SAMEORIGIN"> <meta http-equiv="X-Frame-Options" content="SAMEORIGIN">
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate"> <meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate">
<style> <!-- Stylesheet -->
/* Modern CSS reset and variables */ <link rel="stylesheet" href="styles/styles.css">
:root {
/* Claude dark blue / grey theme
--text-color: #1a202c;
--primary-color: #2d3748;
--secondary-color: #4a5568;
--accent-color: #4299e1;
--background-color: #f7fafc;
*/
/* Purple theme
- https://coolors.co/palette/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff
--text-color: #10002B; /* very dark * /
--primary-color: #240046; /* medium dark * /
--secondary-color: #3C096C; /* dark * /
--accent-color: #C77DFF; /* light * /
--background-color: #E0AAFF; /* very light * /
*/
/* Red theme
- https://coolors.co/palette/2b0000-4f0000-740000-980000-b50000-d30000-eb1d1d-f50f0f-ff0000
- https://coolors.co/palette/9c191b-ac1c1e-bd1f21-d02224-dd2c2f-e35053-e66063-ec8385-f1a7a9-f6cacc
*/
--text-color: #2B0000;
--primary-color: #740000;
--secondary-color: #B50000;
--accent-color: #E35053;
--background-color: #F6CACC;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: var(--background-color);
}
/* Header styles */
header {
background-color: var(--primary-color);
color: white;
padding: 2rem 1rem;
text-align: center;
}
header h1 {
color: white;
}
nav {
background-color: var(--secondary-color);
padding: 1rem;
position: sticky;
top: 0;
z-index: 100;
}
nav ul {
list-style: none;
display: flex;
justify-content: center;
gap: 2rem;
}
nav a {
color: white;
text-decoration: none;
font-weight: 500;
transition: color 0.3s;
}
nav a:hover {
color: var(--accent-color);
}
/* Google Translate styles
- Hide poorly styled iframes
*/
iframe.skiptranslate {
display: none !important;
}
body {
top: 0px !important;
}
/* Main content styles */
main {
max-width: 1200px;
margin: 0 auto;
padding: 2rem 1rem;
}
section {
margin-bottom: 3rem;
}
h1, h2, h3 {
color: var(--primary-color);
margin-bottom: 1rem;
}
ul, li {
list-style-position: outside;
}
.expertise-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.expertise-card {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 2rem;
}
.projects-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-top: 2rem;
}
.project-card {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.expertise-card h3,
.project-card h3,
.experience-card h3 {
color: var(--secondary-color);
}
.button {
display: inline-block;
padding: 0.5rem 1rem;
background-color: var(--accent-color);
color: white;
text-decoration: none;
border-radius: 4px;
transition: background-color 0.3s;
}
.button:hover {
background-color: #2b6cb0;
}
.experience-card {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 2rem;
margin-top: 2rem;
}
.experience-card h3 {
margin-bottom: 0;
}
.experience-date {
color: var(--primary-color);
font-size: 0.9rem;
width: 50%;
min-width: 50%;
-webkit-text-fill-color: inherit;
text-decoration: none;
pointer-events: none;
}
.experience-card:last-child {
margin-bottom: 0;
}
.experience-company-and-date {
display: flex;
justify-content: space-between;
align-items: center;
text-align: left;
width: 100%;
margin-bottom: 0.25rem;
}
.experience-description {
margin: 0.5rem 0;
}
.experience-additional-entry {
list-style-type: disc;
width: 100%;
}
.experience-header {
display: flex;
align-items: center;
}
.experience-additional-entry .experience-company-and-date {
display: flex;
width: 100%;
}
.experience-additional-entry .experience-job-title,
.experience-additional-entry .experience-company,
.experience-additional-entry .experience-date {
font-weight: bold;
margin: 0;
width: fit-content;
}
.experience-additional-entry .experience-company {
margin-left: 5px;
margin-right: auto;
}
.experience-additional-entry .experience-date {
font-weight: normal;
margin-left: auto;
}
.experience-additional-entry:not(:first-of-type) .experience-job-title::after {
content: " at ";
font-weight: normal;
}
.experience-additional-entry .experience-company::after {
content: " ";
}
.experience-additional-entry .experience-description:last-of-type {
margin-top: 0;
margin-bottom: 1rem;
}
/* Footer styles */
footer {
background-color: var(--primary-color);
color: white;
text-align: center;
padding: 2rem 1rem;
margin-top: 4rem;
}
footer a {
color: white;
}
/* Responsive design */
@media (max-width: 768px) {
nav ul {
flex-direction: column;
align-items: center;
gap: 1rem;
}
.expertise-grid,
.projects-grid {
grid-template-columns: 1fr;
}
}
</style>
</head> </head>
<body> <body>
<header> <header>
@@ -317,8 +61,26 @@
<li>Automated order fulfillment</li> <li>Automated order fulfillment</li>
</ul> </ul>
<p style="margin-bottom: 1rem"><strong>Technologies:</strong> Python, MySQL / MariaDB, Docker</p> <p style="margin-bottom: 1rem"><strong>Technologies:</strong> Python, MySQL / MariaDB, Docker</p>
<a href="https://auth.sandbox.teddy.org.uk?target=https%3A%2F%2Ferp.sandbox.partsenterprise.partsltd.co.uk" class="button">Demo ERP</a> <div class="project-links">
<a href="https://store.sandbox.partsenterprise.partsltd.co.uk" class="button">Demo Store</a> <a href="https://auth.sandbox.teddy.org.uk?target=https%3A%2F%2Ferp.sandbox.partsenterprise.partsltd.co.uk" class="button" data-project="project_demo_partsenterprise_erp">Demo ERP</a>
<!-- <a href="https://store.sandbox.partsenterprise.partsltd.co.uk" class="button" data-project="project_demo_partsenterprise_store">Demo Store</a> -->
<a href="https://bathroomwarehouse.uk" class="button" data-project="project_demo_live_partsenterprise_store">Live Store</a>
</div>
<div class="project-thumbnails">
<!--
<div class="project-thumbnail" data-project="project_demo_partsenterprise_erp">
<img src="content/images/PARTSEnterprise_store_live-page-home.webp" alt="Live PARTS Enterprise ERP">
</div>
-->
<!--
<div class="project-thumbnail" data-project="project_demo_partsenterprise_store">
<img src="content/images/PARTSEnterprise_store_live-page-home.webp" alt="Demo PARTS Enterprise Store">
</div>
-->
<div class="project-thumbnail" data-project="project_demo_live_partsenterprise_store">
<img src="content/images/PARTSEnterprise_store_live-page-home.webp" alt="Live PARTS Enterprise Store">
</div>
</div>
</div> </div>
<div class="project-card"> <div class="project-card">
<h3>partsERP Core Framework</h3> <h3>partsERP Core Framework</h3>
@@ -331,8 +93,15 @@
<li>Database abstraction layer and unit test coverage</li> <li>Database abstraction layer and unit test coverage</li>
</ul> </ul>
<p style="margin-bottom: 1rem"><strong>Technologies:</strong> Python - Flask, MySQL / MariaDB, JavaScript</p> <p style="margin-bottom: 1rem"><strong>Technologies:</strong> Python - Flask, MySQL / MariaDB, JavaScript</p>
<a href="https://github.com/Teddy-1024/demo_partsERP.git" class="button">View on GitHub</a> <div class="project-links">
<a href="https://auth.sandbox.teddy.org.uk?target=https%3A%2F%2Fsandbox.partsERP.teddy.org.uk/" class="button">Demo Site</a> <a href="https://github.com/Teddy-1024/demo_partsERP.git" class="button" data-project="project_demo_partserp">View on GitHub</a>
<a href="https://auth.sandbox.teddy.org.uk?target=https%3A%2F%2Fsandbox.partsERP.teddy.org.uk/" class="button" data-project="project_demo_partserp">Demo Site</a>
</div>
<div class="project-thumbnails">
<div class="project-thumbnail" data-project="project_demo_partserp">
<img src="content/images/partsERP-page-product_category.webp" alt="Demo PARTS ERP Site">
</div>
</div>
</div> </div>
<div class="project-card"> <div class="project-card">
<h3>Financial Data Reconciliation Tool</h3> <h3>Financial Data Reconciliation Tool</h3>
@@ -344,8 +113,17 @@
<li>Automated error detection</li> <li>Automated error detection</li>
<li>Audit trail generation</li> <li>Audit trail generation</li>
</ul> </ul>
<div class="project-links">
<p style="margin-bottom: 1rem"><strong>Technologies:</strong> VBA, Excel Object Model</p> <p style="margin-bottom: 1rem"><strong>Technologies:</strong> VBA, Excel Object Model</p>
<a href="https://github.com/Teddy-1024/demo_VBA.git" class="button">View on GitHub</a> <a href="https://github.com/Teddy-1024/demo_VBA.git" class="button" data-project="">View on GitHub</a>
</div>
<div class="project-thumbnails">
<!--
<div class="project-thumbnail" data-project="">
<img src="content/images/partsERP-page-product_category.webp" alt="Demo PARTS ERP Site">
</div>
-->
</div>
</div> </div>
</div> </div>
</section> </section>
@@ -433,51 +211,14 @@
<p>For ERP services, please visit my <a href="https://www.partsltd.co.uk/">company website</a>.</p> <p>For ERP services, please visit my <a href="https://www.partsltd.co.uk/">company website</a>.</p>
</footer> </footer>
<!-- Scripts -->
<script type="text/javascript" src="scripts/scripts.js"></script>
<script type="text/javascript" src="https://translate.google.com/translate_a/element.js?cb=initGoogleTranslateElement"></script>
<script> <script>
// Smooth scrolling for navigation links window.onload = function() {
document.querySelectorAll('nav a').forEach(anchor => { hookupPage();
anchor.addEventListener('click', function(e) { };
e.preventDefault();
const section = document.querySelector(this.getAttribute('href'));
section.scrollIntoView({
behavior: 'smooth'
});
});
});
// Add active state to nav items on scroll
window.addEventListener('scroll', function() {
const sections = document.querySelectorAll('section');
const navLinks = document.querySelectorAll('nav a');
let current = '';
sections.forEach(section => {
const sectionTop = section.offsetTop;
if (pageYOffset >= sectionTop - 60) {
current = section.getAttribute('id');
}
});
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href').substring(1) === current) {
link.classList.add('active');
}
});
});
</script> </script>
<!-- Google Translate Script -->
<script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({
pageLanguage: 'en',
// layout: google.translate.TranslateElement.InlineLayout.SIMPLE
layout: google.translate.TranslateElement.InlineLayout.VERTICAL
}, 'google_translate_element');
}
</script>
<script type="text/javascript" src="https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
</body> </body>
</html> </html>

83
scripts/scripts.js Normal file
View File

@@ -0,0 +1,83 @@
var activeFlag = 'active';
function hookupPage() {
console.log("Hooking up home page...");
hookupNav();
hookupScroll();
hookupProjectThumbnails();
}
function hookupNav() {
console.log("Hooking up nav...");
document.querySelectorAll('nav a').forEach(anchor => {
console.log("Hooking up nav anchor...");
anchor.addEventListener('click', function(e) {
e.preventDefault();
const section = document.querySelector(this.getAttribute('href'));
section.scrollIntoView({
behavior: 'smooth'
});
});
});
}
function hookupScroll() {
console.log("Hooking up scroll...");
window.addEventListener('scroll', function() {
const sections = document.querySelectorAll('section');
const navLinks = document.querySelectorAll('nav a');
let current = '';
sections.forEach(section => {
const sectionTop = section.offsetTop;
if (scrollY >= sectionTop - 60) {
current = section.getAttribute('id');
}
});
navLinks.forEach(link => {
link.classList.remove(activeFlag);
if (link.getAttribute('href').substring(1) === current) {
link.classList.add(activeFlag);
}
});
});
}
function hookupProjectThumbnails() {
console.log("Hooking up project thumbnails...");
let demoButtonSelector = '.project-links .button';
document.querySelectorAll(demoButtonSelector).forEach(demoButton => {
console.log("Hooking up project thumbnail...");
let projectName = getProjectNameFromDemoButton(demoButton);
console.log({projectName});
demoButton.addEventListener('mouseover', function() {
let projectName = getProjectNameFromDemoButton(this);
let thumbnailContainer = getProjectThumbnailContainer(projectName);
thumbnailContainer.classList.add(activeFlag);
});
demoButton.addEventListener('mouseout', function() {
let projectName = getProjectNameFromDemoButton(this);
let thumbnailContainer = getProjectThumbnailContainer(projectName);
thumbnailContainer.classList.remove(activeFlag);
});
});
}
function getProjectNameFromDemoButton(demoButton) {
let projectName = demoButton.getAttribute('data-project');
console.log({projectName});
return projectName;
}
function getProjectThumbnailContainer(projectName) {
let container = document.querySelector(`div.project-thumbnail[data-project="${projectName}"]`);
console.log({container});
return container;
}
// Google Translate
function initGoogleTranslateElement() {
new google.translate.TranslateElement({
pageLanguage: 'en',
// layout: google.translate.TranslateElement.InlineLayout.SIMPLE
layout: google.translate.TranslateElement.InlineLayout.VERTICAL
}, 'google_translate_element');
}

298
styles/styles.css Normal file
View File

@@ -0,0 +1,298 @@
/* Modern CSS reset and variables */
:root {
/* Claude dark blue / grey theme
--text-color: #1a202c;
--primary-color: #2d3748;
--secondary-color: #4a5568;
--accent-color: #4299e1;
--background-color: #f7fafc;
*/
/* Purple theme
- https://coolors.co/palette/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff
--text-color: #10002B; /* very dark * /
--primary-color: #240046; /* medium dark * /
--secondary-color: #3C096C; /* dark * /
--accent-color: #C77DFF; /* light * /
--background-color: #E0AAFF; /* very light * /
*/
/* Red theme
- https://coolors.co/palette/2b0000-4f0000-740000-980000-b50000-d30000-eb1d1d-f50f0f-ff0000
- https://coolors.co/palette/9c191b-ac1c1e-bd1f21-d02224-dd2c2f-e35053-e66063-ec8385-f1a7a9-f6cacc
*/
--text-color: #2B0000;
--primary-color: #740000;
--secondary-color: #B50000;
--accent-color: #E35053;
--background-color: #F6CACC;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: var(--background-color);
}
/* Header styles */
header {
background-color: var(--primary-color);
color: white;
padding: 2rem 1rem;
text-align: center;
}
header h1 {
color: white;
}
nav {
background-color: var(--secondary-color);
padding: 1rem;
position: sticky;
top: 0;
z-index: 100;
}
nav ul {
list-style: none;
display: flex;
justify-content: center;
gap: 2rem;
}
nav a {
color: white;
text-decoration: none;
font-weight: 500;
transition: color 0.3s;
}
nav a:hover {
color: var(--accent-color);
}
/* Google Translate styles
- Hide poorly styled iframes
*/
iframe.skiptranslate {
display: none !important;
}
body {
top: 0px !important;
}
/* Main content styles */
main {
max-width: 1200px;
margin: 0 auto;
padding: 2rem 1rem;
}
section {
margin-bottom: 3rem;
}
h1, h2, h3 {
color: var(--primary-color);
margin-bottom: 1rem;
}
ul, li {
list-style-position: outside;
}
.expertise-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.expertise-card {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 2rem;
}
/* Projects */
.projects-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-top: 2rem;
}
.project-card {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
position: relative;
}
.expertise-card h3,
.project-card h3,
.experience-card h3 {
color: var(--secondary-color);
}
.button {
display: inline-block;
padding: 0.5rem 1rem;
background-color: var(--accent-color);
color: white;
text-decoration: none;
border-radius: 4px;
transition: background-color 0.3s;
}
.button:hover {
background-color: #2b6cb0;
}
/*
.project-thumbnails {
position: relative;
}
.project-thumbnail {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 0;
overflow: hidden;
transition: height 0.3s ease;
}
.project-thumbnail img {
width: 100%;
display: block;
}
/* .project-card .button:hover + .project-thumbnail */
/*
.project-card .button.project_demo_partsenterprise_erp:hover + .project-thumbnail.project_demo_partsenterprise_erp,
.project-card .button.project_demo_partsenterprise_store:hover + .project-thumbnail.project_demo_partsenterprise_store,
.project-card .button.project_demo_live_partsenterprise_store:hover + .project-thumbnail.project_demo_live_partsenterprise_store,
.project-card .button.project_demo_partserp:hover + .project-thumbnail.project_demo_partserp
*/
/*
.project-links .button.project_demo_partsenterprise_erp:hover ~ .project-thumbnails .project_demo_partsenterprise_erp,
.project-links .button.project_demo_partsenterprise_store:hover ~ .project-thumbnails .project_demo_partsenterprise_store,
.project-links .button.project_demo_live_partsenterprise_store:hover ~ .project-thumbnails .project_demo_live_partsenterprise_store,
.project-links .button.project_demo_partserp:hover ~ .project-thumbnails .project_demo_partserp
* /
.project-thumbnail.active
{
height: 200px; /* Adjust the height as needed * /
}
*/
/* Experience */
.experience-card {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 2rem;
margin-top: 2rem;
}
.experience-card h3 {
margin-bottom: 0;
}
.experience-date {
color: var(--primary-color);
font-size: 0.9rem;
width: 50%;
min-width: 50%;
-webkit-text-fill-color: inherit;
text-decoration: none;
pointer-events: none;
}
.experience-card:last-child {
margin-bottom: 0;
}
.experience-company-and-date {
display: flex;
justify-content: space-between;
align-items: center;
text-align: left;
width: 100%;
margin-bottom: 0.25rem;
}
.experience-description {
margin: 0.5rem 0;
}
.experience-additional-entry {
list-style-type: disc;
width: 100%;
}
.experience-header {
display: flex;
align-items: center;
}
.experience-additional-entry .experience-company-and-date {
display: flex;
width: 100%;
}
.experience-additional-entry .experience-job-title,
.experience-additional-entry .experience-company,
.experience-additional-entry .experience-date {
font-weight: bold;
margin: 0;
width: fit-content;
}
.experience-additional-entry .experience-company {
margin-left: 5px;
margin-right: auto;
}
.experience-additional-entry .experience-date {
font-weight: normal;
margin-left: auto;
}
.experience-additional-entry:not(:first-of-type) .experience-job-title::after {
content: " at ";
font-weight: normal;
}
.experience-additional-entry .experience-company::after {
content: " ";
}
.experience-additional-entry .experience-description:last-of-type {
margin-top: 0;
margin-bottom: 1rem;
}
/* Footer styles */
footer {
background-color: var(--primary-color);
color: white;
text-align: center;
padding: 2rem 1rem;
margin-top: 4rem;
}
footer a {
color: white;
}
/* Responsive design */
@media (max-width: 768px) {
nav ul {
flex-direction: column;
align-items: center;
gap: 1rem;
}
.expertise-grid,
.projects-grid {
grid-template-columns: 1fr;
}
}