Add Portfolio project

This commit is contained in:
2025-10-25 19:09:18 +02:00
parent 50e97e8a51
commit bd757d5ceb
30 changed files with 560 additions and 17 deletions

View File

@@ -0,0 +1,5 @@
apply plugin: 'java'
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}

1
Portfolio/build.gradle Normal file
View File

@@ -0,0 +1 @@
apply plugin: 'base'

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,12 @@
<svg id="icon" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<defs>
<style>
.cls-1 {
fill: none;
}
</style>
</defs>
<polygon points="14 21.414 9 16.413 10.413 15 14 18.586 21.585 11 23 12.415 14 21.414"/>
<path d="M16,2A14,14,0,1,0,30,16,14,14,0,0,0,16,2Zm0,26A12,12,0,1,1,28,16,12,12,0,0,1,16,28Z"/>
<rect id="_Transparent_Rectangle_" data-name="&lt;Transparent Rectangle&gt;" class="cls-1" width="32" height="32"/>
</svg>

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

186
Portfolio/index.html Normal file
View File

@@ -0,0 +1,186 @@
<!DOCTYPE html>
<html>
<head>
<title>John Ahlroos - Portfolio</title>
<link rel="stylesheet" href="./style.css"/>
<script src="./script.js"></script>
</head>
<body>
<!-- Navigation Bar -->
<nav>
<div id="home">
<div class="profile_name">
<span>John Ahlroos</span>
<div class="contact_info">
<img src="html_finalprojimages/envelope.png" alt="https://icons8.com/icon/124377/circled-envelope"/>
john@nomail.com
</div>
<div style="clear:both;"></div>
<div class="contact_info">
<img src="html_finalprojimages/phone.png" alt="https://icons8.com/icon/124377/circled-envelope"/>
+13456764598
</div>
</div>
<div class="topdiv">
<a class="topmenu topmenu:hover" href="#about-me">About Me</a>
<a class="topmenu topmenu:hover" href="#skills">Skills</a>
<a class="topmenu topmenu:hover" href="#projects">Projects</a>
<a class="topmenu topmenu:hover" href="#recommendations">Recommendations</a>
</div>
</div>
</nav>
<!-- About Me -->
<section id="about-me" class="container">
<div>
<img src="html_finalprojimages/profile.webp" class="profile_image"/>
</div>
<div>
<h1>
Hi, I'm John Ahlroos! <img src="html_finalprojimages/waving-hand.png" width="60px"/>
</h1>
<p>
I am a full stack developer with 20 years of experience in both Back-End and Web development.
I haver worked on numerous different software stacks ranging from the most basic websites to large
cloud deployments with 100+ microservices.
My favourite development stack is Java Spring Boot combined with HTMX as the front-end.
</p>
</div>
</section>
<!-- Skills -->
<section id="skills">
<h2>Skills</h2>
<div style="clear:both;"></div>
<div class="all_skills">
<div class="skill">
<img src="html_finalprojimages/html5.png"/>
<h6>HTML</h6>
<p>15 years experience</p>
</div>
<div class="skill">
<img src="html_finalprojimages/js.jpeg"/>
<h6>JavaScript</h6>
<p>15 years experience</p>
</div>
<div class="skill">
<img src="html_finalprojimages/java.png"/>
<h6>Java</h6>
<p>15 years experience</p>
</div>
<div class="skill">
<img src="html_finalprojimages/react.png"/>
<h6>React</h6>
<p>2 years experience</p>
</div>
<div class="skill">
<img src="html_finalprojimages/node.png"/>
<h6>Node</h6>
<p>1 years experience</p>
</div>
</div>
</section>
<!-- Projects -->
<section class="projects" id="projects">
<h2>
Projects
</h2>
<div style="clear:both;"></div>
<div id="projects-container" class="projects-container">
<div class="project-card">
<h3>Software development blog</h3>
<ul>
<li>A blog providing the latest news in web development</li>
</ul>
</div>
<hr>
<div class="project-card">
<h3>Step Counter</h3>
<ul>
<li>A step counter which measures steps taken on the Moon. Only works in Zero-gravity.</li>
</ul>
</div>
<hr>
<div class="project-card">
<h3>Family secret recipes book</h3>
<ul>
<li>The secret recipes only known to my family - until now!</li>
</ul>
</div>
</div>
</section>
<div style="clear:both;"></div>
<!-- Recommendations -->
<section id="recommendations">
<h2>Recommendations</h2>
<div style="clear:both;"></div>
<div class="all_recommendations" id="all_recommendations">
<div class="recommendation">
<span>&#8220;</span>
I've been fortunate to get to know John well over the past
5 years, both personally and professionally. It's obvious to me that he has the key attributes necessary
to land a dream project. He could be a change-maker just
through her insurmountable spirit alone but the fact that he has the intelligence to match makes him a
formidable force and one to watch for the future.
<span>&#8221;</span>
</div>
<div class="recommendation">
<span>&#8220;</span>
I cannot recommend John more highly - he's an extremely capable and talented Web Developer,
not to mention an A+ human. From the moment he joined BigTech over 5 years ago, John stood out
for his work ethic, attitude, and intelligence. He was a stand-out IC and then a talented and respected leader,
and any company would be lucky to have him. I'd work with him again in a heartbeat.
<span>&#8221;</span>
</div>
<div class="recommendation">
<span>&#8220;</span>
John was an invaluable asset to the team and one of the highest performing consultants I worked with
during my tenure at Resume Worded. He independently managed multiple work streams where he demonstrated
strong project management skills, deep research and analytical capabilities and scenario-driven strategic
thinking. I know he will go on to lead and achieve great things in his career.
<span>&#8221;</span>
</div>
</div>
</section>
<!-- Recommendation Form -->
<section id="contact">
<div class="flex_center">
<fieldset>
<legend class="introduction">Leave a Recommendation</legend>
<input type="text" placeholder="Name (Optional)"> <br/>
<textarea id="new_recommendation" cols="500" rows="10" placeholder="Message"></textarea>
<div class="flex_center">
<button id="recommend_btn" onclick="addRecommendation()">Submit</button>
</div>
</fieldset>
</div>
</section>
<div class="iconbutton">
<a href="#home">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="white" width="63px">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 11.25l-3-3m0 0l-3 3m3-3v7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</a>
</div>
<div class="popup" id="popup" class="flex_center">
<img src="html_finalprojimages/checkmark--outline.svg"/>
<h3>Thanks for leaving a recommendation bro!</h3>
<button onclick="showPopup(false)">Ok</button>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

28
Portfolio/script.js Normal file
View File

@@ -0,0 +1,28 @@
function addRecommendation() {
// Get the message of the new recommendation
let recommendation = document.getElementById("new_recommendation");
// If the user has left a recommendation, display a pop-up
if (recommendation.value != null && recommendation.value.trim() != "") {
console.log("New recommendation added");
//Call showPopup here
showPopup(true);
// Create a new 'recommendation' element and set it's value to the user's message
var element = document.createElement("div");
element.setAttribute("class","recommendation");
element.innerHTML = "\<span\>&#8220;\</span\>" + recommendation.value + "\<span\>&#8221;\</span\>";
// Add this element to the end of the list of recommendations
document.getElementById("all_recommendations").appendChild(element);
// Reset the value of the textarea
recommendation.value = "";
}
}
function showPopup(bool) {
if (bool) {
document.getElementById('popup').style.visibility = 'visible'
} else {
document.getElementById('popup').style.visibility = 'hidden'
}
}

326
Portfolio/style.css Normal file
View File

@@ -0,0 +1,326 @@
body {
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
}
/* Navigation Bar */
#home {
background-color: #7600bc;
padding-bottom: 1cm;
margin-left:-1cm;
margin-right:-1cm;
margin-top:-1cm;
padding-top: 2cm;
padding-bottom: 2cm;
height: 5mm;
}
.topmenu {
color: lightgray;
margin: 10px;
padding: 20px;
font-size: 20px;
text-decoration:none;
}
.topmenu:hover {
color: white;
font-weight: bold;
text-decoration: underline;
}
.topdiv {
float: right;
padding-right: 1cm;
}
.profile_name {
float: left;
padding-left: 3cm;
margin-top: -20px;
font-size: 2em;
color: #eee;
font-family: 'sans-serif';
}
.profile_name .contact_info {
font-size: 15px;
font-style: italic;
display: flex;
align-items: center;
flex-direction: row;
}
.contact_info img {
width:25px;
margin-right: 10px;
float:left;
}
/* Titles */
h2 {
text-align: justify;
font-size: 50px;
text-align: center;
float: left;
color: #7600bc;
margin: 30px;
margin-left: 60px;
margin-top: 40px;
margin-bottom: 0px;
}
.introduction {
text-align: justify;
font-size: 30px;
text-align: center;
float: left;
margin-top: 30px;
margin-bottom: 20px;
animation-duration: 5s;
position: relative;
}
/* Used in the About Me sections */
.container {
display: flex;
}
/* About Me */
.about-me {
display: flex;
align-items: center;
}
#about-me h1 {
font-size: 65px;
margin-top: 90px;
color: #7600bc;
}
#about-me p {
font-size: 25px;
color: rgb(128, 128, 128);
margin-top: -1cm;
}
.profile_image {
width: 550px;
height: fit-content;
vertical-align: middle;
margin: 5px;
}
/* Skills */
.all_skills {
display: flex;
flex-direction: row;
flex-flow: wrap;
}
.skill {
border: 1px solid gray;
display: block;
border-radius: 6px;
text-align: center;
margin: 50px;
padding: 10px;
width: 2in;
font-size: 20px;
box-shadow: 0 3px 10px gray;
}
.skill img {
height: 100px;
align-items: center;
}
.skills h6 {
align-items: center;
font-size: 20px;
margin-block-start: 8px;
margin-block-end: 5px;
font-weight: bold;
}
.skills p {
align-items: center;
font-size: 15px;
color: gray;
margin-block-start: 5px;
margin-block-end: 5px;
}
.flex_center {
display: flex;
align-items: center;
justify-content: center;
}
/* Projects */
.projects-container {
margin-top: 30px;
margin-left: 60px;
}
.projects-container hr {
border: 1px solid lightgray;
width: 75%;
margin-left: 5cm;
}
.project-card {
margin: 0 15px 15px 30px;
padding-bottom: 5px;
}
.project-card h3 {
font-size: 25px;
margin-left: 30px;
}
.project-card li {
font-size: 20px;
margin-left: 30px;
}
/* Recommendations */
.all_recommendations {
display: flex;
align-items: center;
margin-left: 1in;
flex-direction: row;
flex-flow: wrap;
padding: 20px;
}
.recommendation {
font-style: italic;
text-align: left;
width: 26.875rem;
padding: 1rem;
background-color: #fff;
border-radius: 11px;
box-shadow: 0 3px 10px var(--primary-shadow);
padding: 20px;
margin: 10px;
border:1px solid gray;
font-size: 18px;
height:170px
}
.recommendation span {
color: #7600bc;
font-size: 20px;
font-family: 'Times New Roman', Times, serif;
}
/* Scroll to Top Button */
.iconbutton{
width: 48px;
height: 48px;
border-radius: 100%;
background-color: #7600bc;
display: flex;
align-items: center;
justify-content: center;
position: fixed;
right: 3%;
bottom: 3%;
cursor: pointer;
}
/* Form Pop-up */
.popup {
width:400px;
background-color: #e8bcf0;
border-radius: 3mm;
top: 50%;
left:50%;
transform: translate(-50%,-50%);
text-align: center;
position: fixed;
/* padding: 30px; */
visibility: hidden;
}
.popup img {
padding-top: 20px;
}
.popup button {
background-color: #fff;
border: 1px solid #7600bc;
color: #7600bc;
display: block;
border-radius: 6px;
text-align: center;
margin: 50px;
padding: 10px;
width: 2in;
font-size: 20px;
margin-left: 25%;
}
.popup button:hover {
background-color: #fff;
border: 2px solid #7600bc;
color: #7600bc;
display: block;
font-weight: bolder;
text-align: center;
cursor: pointer;
margin-left: 25%;
}
/* Recommendation Form */
input, textarea {
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
margin: 10px;
width:100%;
}
fieldset {
display: flexbox;
align-content: center;
justify-content: center;
padding: 25px;
margin-left: 50px;
margin-right: 50px;
border: thin solid white;
width: 50%;
}
/* Buttons */
button {
background-color: #fff;
border: 1px solid #7600bc;
color: #7600bc;
display: block;
border-radius: 6px;
text-align: center;
margin: 50px;
padding: 10px;
width: 2in;
font-size: 20px;
}
button:hover {
background-color: #7600bc;
border: 1px solid #7600bc;
color: #fff;
display: block;
border-radius: 6px;
text-align: center;
cursor: pointer;
}

View File

@@ -5,19 +5,3 @@ allprojects {
mavenCentral()
}
}
subprojects {
apply plugin: 'java'
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
dependencies {
testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
test {
useJUnitPlatform()
}
}

View File

@@ -1,2 +1,3 @@
rootProject.name = 'java-developer-course'
include('PetCareScheduler')
include 'PetCareScheduler'
include 'Portfolio'