Update Home page links and enhance styling for improved user experience
This commit is contained in:
parent
1a43ad08e4
commit
6606dc2611
|
|
@ -29,8 +29,8 @@ public class Home {
|
||||||
//navbar links
|
//navbar links
|
||||||
model.addAttribute("links", List.of(
|
model.addAttribute("links", List.of(
|
||||||
new Link("About", "#about"),
|
new Link("About", "#about"),
|
||||||
new Link("Experience", "#experience"),
|
new Link("Experience", "#resume-details"),
|
||||||
new Link("Education", "#education"),
|
new Link("Education", "#resume-details"),
|
||||||
new Link("Projects", "#projects"),
|
new Link("Projects", "#projects"),
|
||||||
new Link("Contact", "#contact")
|
new Link("Contact", "#contact")
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -1,108 +1,96 @@
|
||||||
body {
|
body {
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
|
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||||
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
section {
|
section {
|
||||||
padding: 4rem 0;
|
padding: 5rem 0;
|
||||||
border-bottom: 1px solid var(--bs-secondary-bg-subtle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5 {
|
/* Reduced spacing for Hero */
|
||||||
letter-spacing: 0.02em;
|
.intro {
|
||||||
|
padding: 100px 0 60px 0;
|
||||||
|
background: radial-gradient(circle at top right, #f8f9ff 0%, #ffffff 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- NAVBAR ---------- */
|
.profile-img {
|
||||||
.navbar {
|
border: 8px solid #fff;
|
||||||
backdrop-filter: blur(6px);
|
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link {
|
/* Skill Badges */
|
||||||
|
.skill-badge {
|
||||||
|
background: #f0f2f5;
|
||||||
|
color: #475569;
|
||||||
|
padding: 0.4rem 0.8rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 500;
|
||||||
|
border: 1px solid rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Timeline UI to fix "weird" wide cards */
|
||||||
|
.timeline-card {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
border-left: 2px solid #e9ecef;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
transition: 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link::after {
|
.timeline-card::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: -7px;
|
||||||
bottom: -4px;
|
top: 4px;
|
||||||
width: 0;
|
width: 12px;
|
||||||
height: 2px;
|
height: 12px;
|
||||||
background-color: var(--bs-primary);
|
border-radius: 50%;
|
||||||
transition: width 0.3s ease;
|
background: var(--bs-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link:hover::after {
|
/* Section Headers */
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------- ICON LINKS ---------- */
|
|
||||||
.icon-link i {
|
|
||||||
font-size: 1.6rem;
|
|
||||||
transition: color 0.3s ease, transform 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-link:hover i {
|
|
||||||
color: var(--bs-primary);
|
|
||||||
transform: translateY(-3px);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------- INTRO / HERO ---------- */
|
|
||||||
.intro {
|
|
||||||
min-height: 70vh;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background: linear-gradient(180deg, var(--bs-light), #ffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro img {
|
|
||||||
border: 4px solid var(--bs-white);
|
|
||||||
}
|
|
||||||
|
|
||||||
.skill-badge {
|
|
||||||
background: var(--bs-secondary-bg);
|
|
||||||
border-radius: 2rem;
|
|
||||||
padding: 0.4rem 0.9rem;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------- CARDS (GLOBAL) ---------- */
|
|
||||||
.card,
|
|
||||||
.project-item,
|
|
||||||
.contact-box {
|
|
||||||
border-radius: 1rem;
|
|
||||||
border: 1px solid var(--bs-secondary-bg-subtle);
|
|
||||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
||||||
background: var(--bs-white);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card:hover,
|
|
||||||
.project-item:hover,
|
|
||||||
.contact-box:hover {
|
|
||||||
transform: translateY(-6px);
|
|
||||||
box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------- SECTION HEADERS ---------- */
|
|
||||||
.section-header {
|
.section-header {
|
||||||
text-align: center;
|
margin-bottom: 2.5rem;
|
||||||
margin-bottom: 3rem;
|
border-bottom: 2px solid #f0f0f0;
|
||||||
|
padding-bottom: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-header i {
|
/* Modern Project Cards */
|
||||||
font-size: 2rem;
|
.project-item {
|
||||||
color: var(--bs-primary);
|
border-radius: 12px;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid rgba(0,0,0,0.05);
|
||||||
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- FOOTER ---------- */
|
.project-item:hover {
|
||||||
footer a {
|
transform: translateY(-5px);
|
||||||
text-decoration: none;
|
box-shadow: 0 15px 35px rgba(0,0,0,0.1) !important;
|
||||||
transition: color 0.3s ease;
|
border-color: var(--bs-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
footer a:hover {
|
.w-fit {
|
||||||
color: var(--bs-primary);
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer i {
|
/* Form Controls */
|
||||||
font-size: 1.4rem;
|
.form-control {
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control:focus {
|
||||||
|
box-shadow: 0 0 0 4px rgba(13, 110, 253, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navbar blur effect */
|
||||||
|
.navbar {
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
background-color: rgba(255, 255, 255, 0.8) !important;
|
||||||
|
border-bottom: 1px solid rgba(0,0,0,0.05);
|
||||||
}
|
}
|
||||||
|
|
@ -1,104 +1,62 @@
|
||||||
body {
|
body {
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
|
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||||
|
background-color: #f9fbff; /* Very slight blue tint for a technical look */
|
||||||
}
|
}
|
||||||
|
|
||||||
section {
|
/* --- HERO --- */
|
||||||
padding: 5rem 0;
|
|
||||||
border-bottom: 1px solid var(--bs-secondary-bg-subtle);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5 {
|
|
||||||
letter-spacing: 0.02em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero {
|
.hero {
|
||||||
min-height: 65vh;
|
padding: 80px 0 40px;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-badge {
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--bs-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- DYNAMIC CONTENT TABS --- */
|
||||||
|
.nav-pills .nav-link {
|
||||||
|
color: #6c757d;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 0.8rem 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-pills .nav-link.active {
|
||||||
|
background-color: var(--bs-primary);
|
||||||
|
box-shadow: 0 4px 12px rgba(13, 110, 253, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-container {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid rgba(0,0,0,0.05);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 3rem;
|
||||||
|
min-height: 400px; /* Prevents jumping when switching tabs */
|
||||||
|
box-shadow: 0 10px 30px rgba(0,0,0,0.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* --- CAROUSEL --- */
|
||||||
|
.browser-frame {
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 20px 50px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.browser-bar {
|
||||||
|
background: #f1f1f1;
|
||||||
|
height: 30px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: center;
|
padding-left: 15px;
|
||||||
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero img {
|
.dot { height: 8px; width: 8px; border-radius: 50%; background: #ddd; }
|
||||||
transition: transform 0.4s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------- NAVBAR ---------- */
|
|
||||||
.navbar {
|
|
||||||
backdrop-filter: blur(6px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: -4px;
|
|
||||||
width: 0;
|
|
||||||
height: 2px;
|
|
||||||
background-color: var(--bs-primary);
|
|
||||||
transition: width 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link:hover::after {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: -4px;
|
|
||||||
width: 0;
|
|
||||||
height: 2px;
|
|
||||||
background-color: var(--bs-primary);
|
|
||||||
transition: width 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.icon-link i {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
transition: color 0.3s ease, transform 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-link:hover i {
|
|
||||||
color: var(--bs-primary);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.card,
|
|
||||||
.project-box {
|
|
||||||
border-radius: 1rem;
|
|
||||||
border: 1px solid var(--bs-secondary-bg-subtle);
|
|
||||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card:hover,
|
|
||||||
.project-box:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tech-chips {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tech-chip {
|
|
||||||
padding: 0.375rem 0.75rem;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-weight: 500;
|
|
||||||
border-radius: 999px;
|
|
||||||
background-color: #f1f3f5;
|
|
||||||
color: #495057;
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
@ -12,183 +12,135 @@
|
||||||
<link th:href="@{/assets/css/bootstrap.min.css}" rel="stylesheet">
|
<link th:href="@{/assets/css/bootstrap.min.css}" rel="stylesheet">
|
||||||
<link th:href="@{https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css}" rel="stylesheet">
|
<link th:href="@{https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css}" rel="stylesheet">
|
||||||
<link rel="stylesheet" th:href="@{/assets/css/home.css}">
|
<link rel="stylesheet" th:href="@{/assets/css/home.css}">
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<!-- NAVBAR -->
|
|
||||||
<div th:replace="~{fragments/navbar :: navbar}"></div>
|
<div th:replace="~{fragments/navbar :: navbar}"></div>
|
||||||
|
|
||||||
<!-- INTRO / HERO + ABOUT -->
|
|
||||||
<header id="about" class="intro">
|
<header id="about" class="intro">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row align-items-center gy-4">
|
<div class="row align-items-center gy-4">
|
||||||
|
|
||||||
<div class="col-md-4 text-center">
|
<div class="col-md-4 text-center">
|
||||||
<img th:src="@{/assets/images/profileImage.jpg}" class="rounded-circle mb-3" width="160"
|
<img th:src="@{/assets/images/profileImage.jpg}" class="profile-img mb-3" width="180" height="180" alt="Kiyan Mckop">
|
||||||
height="160" alt="Kiyan Mckop">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<h1 class="fw-bold">Kiyan Mckop</h1>
|
<h1 class="display-5 fw-bold">Kiyan Mckop</h1>
|
||||||
<p class="lead text-muted mb-3">
|
<p class="lead text-secondary mb-3">
|
||||||
Software Engineer specializing in Java, Spring Boot, and backend systems.
|
Software Engineer specializing in <span class="text-primary fw-semibold">Java, Spring Boot</span>, and backend systems.
|
||||||
</p>
|
</p>
|
||||||
|
<p class="text-muted">
|
||||||
<p>
|
Honours graduate in IT with experience building secure, maintainable enterprise software and internal ERP systems.
|
||||||
Honours graduate in Information Technology with experience building secure,
|
|
||||||
maintainable enterprise software and internal ERP systems.
|
|
||||||
</p>
|
</p>
|
||||||
|
<div class="d-flex flex-wrap gap-2 my-4">
|
||||||
<!-- Skills -->
|
|
||||||
<div class="d-flex flex-wrap gap-2 my-3">
|
|
||||||
<span class="skill-badge">Java</span>
|
<span class="skill-badge">Java</span>
|
||||||
<span class="skill-badge">Spring Boot</span>
|
<span class="skill-badge">Spring Boot</span>
|
||||||
<span class="skill-badge">REST APIs</span>
|
<span class="skill-badge">REST APIs</span>
|
||||||
<span class="skill-badge">SQL</span>
|
<span class="skill-badge">SQL</span>
|
||||||
<span class="skill-badge">Docker</span>
|
<span class="skill-badge">Docker</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="d-flex gap-4">
|
||||||
<!-- Actions -->
|
<a class="icon-link" th:href="@{/resume}" title="Resume"><i class="bi bi-file-earmark-person"></i></a>
|
||||||
<div class="d-flex gap-4 mt-3">
|
<a class="icon-link" th:href="@{/cv}" title="CV"><i class="bi bi-file-earmark-text"></i></a>
|
||||||
<a class="icon-link" th:href="@{/resume}" title="Resume">
|
<a class="icon-link" href="https://mckopserver.ddns.net" target="_blank" title="Server"><i class="bi bi-hdd-network"></i></a>
|
||||||
<i class="bi bi-file-earmark-person"></i>
|
|
||||||
</a>
|
|
||||||
<a class="icon-link" th:href="@{/cv}"
|
|
||||||
title="CV">
|
|
||||||
<i class="bi bi-file-earmark-text"></i>
|
|
||||||
</a>
|
|
||||||
<a class="icon-link" href="https://mckopserver.ddns.net" target="_blank" title="Server">
|
|
||||||
<i class="bi bi-hdd-network"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- EXPERIENCE -->
|
<section id="resume-details" class="bg-light">
|
||||||
<section id="experience">
|
<div class="container">
|
||||||
|
<div class="row g-5">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="fw-bold"><i class="bi bi-briefcase me-2"></i>Experience</h2>
|
||||||
|
</div>
|
||||||
|
<div class="card p-4 border-0 shadow-sm">
|
||||||
|
<div class="timeline-card">
|
||||||
|
<h5 class="fw-bold mb-0">Graduate Software Engineer</h5>
|
||||||
|
<p class="text-primary small mb-2">WBHO Construction · 2025</p>
|
||||||
|
<p class="small text-muted mb-0">Developed and maintained internal ERP software systems.</p>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-card">
|
||||||
|
<h5 class="fw-bold mb-0">Data Capturer</h5>
|
||||||
|
<p class="text-primary small mb-2">Wealth Associates · 2022</p>
|
||||||
|
<p class="small text-muted mb-0">Handled sensitive data with high accuracy and integrity.</p>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-card mb-0">
|
||||||
|
<h5 class="fw-bold mb-0">General Office Work</h5>
|
||||||
|
<p class="text-primary small mb-2">Wealth Associates · 2019</p>
|
||||||
|
<p class="small text-muted mb-0">Administrative and operational support.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="fw-bold"><i class="bi bi-mortarboard me-2"></i>Education</h2>
|
||||||
|
</div>
|
||||||
|
<div class="card p-4 border-0 shadow-sm">
|
||||||
|
<div class="timeline-card">
|
||||||
|
<h5 class="fw-bold mb-0">BSc Honours in IT</h5>
|
||||||
|
<p class="text-primary small mb-2">Software Engineering</p>
|
||||||
|
<p class="small text-muted mb-0">Graduated with Honours</p>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-card">
|
||||||
|
<h5 class="fw-bold mb-0">BSc in IT</h5>
|
||||||
|
<p class="text-primary small mb-2">Software Engineering</p>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-card mb-0">
|
||||||
|
<h5 class="fw-bold mb-0">Matric Certificate</h5>
|
||||||
|
<p class="text-primary small mb-2">IT | CAT | Business</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="projects" class="bg-white">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<i class="bi bi-briefcase"></i>
|
<h2 class="fw-bold"><i class="bi bi-code-slash me-2"></i>Projects</h2>
|
||||||
<h2 class="fw-bold mt-2">Work Experience</h2>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row g-4">
|
<div class="row g-4">
|
||||||
<div class="col-md-4" th:each="exp : ${null}">
|
|
||||||
<!-- Static cards retained -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- WBHO -->
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card h-100 p-3">
|
|
||||||
<h5>Graduate Software Engineer</h5>
|
|
||||||
<p class="text-muted">WBHO Construction · 2025</p>
|
|
||||||
<p>Developed and maintained internal ERP software systems.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card h-100 p-3">
|
|
||||||
<h5>Data Capturer</h5>
|
|
||||||
<p class="text-muted">Wealth Associates · 2022</p>
|
|
||||||
<p>Handled sensitive data with high accuracy and integrity.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card h-100 p-3">
|
|
||||||
<h5>General Office Work</h5>
|
|
||||||
<p class="text-muted">Wealth Associates · 2019</p>
|
|
||||||
<p>Administrative and operational support.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- EDUCATION -->
|
|
||||||
<section id="education" class="bg-light">
|
|
||||||
<div class="container">
|
|
||||||
<div class="section-header">
|
|
||||||
<i class="bi bi-mortarboard"></i>
|
|
||||||
<h2 class="fw-bold mt-2">Education</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-8">
|
|
||||||
<div class="card p-4 text-center">
|
|
||||||
<h5>BSc Honours in Information Technology</h5>
|
|
||||||
<p class="text-muted mb-1">Specialization: Software Engineering</p>
|
|
||||||
<p class="text-muted">Graduated with Honours</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-8">
|
|
||||||
<div class="card p-4 text-center">
|
|
||||||
<h5>BSc in Information Technology</h5>
|
|
||||||
<p class="text-muted mb-1">Specialization: Software Engineering</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-8">
|
|
||||||
<div class="card p-4 text-center">
|
|
||||||
<h5>Matric Certificate</h5>
|
|
||||||
<p class="text-muted mb-1">Major Subjects: IT | CAT |Business</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- PROJECTS -->
|
|
||||||
<section id="projects">
|
|
||||||
<div class="container">
|
|
||||||
<div class="section-header">
|
|
||||||
<i class="bi bi-code-slash"></i>
|
|
||||||
<h2 class="fw-bold mt-2">Projects</h2>
|
|
||||||
<p class="text-muted">Selected technical work</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row g-4 d-inline-flex justify-content-center align-items-center" style="width: 100%;">
|
|
||||||
<div class="col-md-6 col-lg-4" th:each="project : ${projects}">
|
<div class="col-md-6 col-lg-4" th:each="project : ${projects}">
|
||||||
<div class="project-item h-100 p-3 ">
|
<div class="project-item h-100 p-4 d-flex flex-column shadow-sm">
|
||||||
<h5 th:text="${project.name}"></h5>
|
<h5 class="fw-bold mb-1" th:text="${project.name}">Project Name</h5>
|
||||||
<p class="small text-muted" th:text="${project.default_branch}"></p>
|
<p class="text-muted small flex-grow-1">2025 - Present</p>
|
||||||
<p th:text="${project.description}"></p>
|
<!-- <code class="small text-primary mb-3" th:text="${project.default_branch}">main</code> -->
|
||||||
<a th:href="@{/project/{repo}(repo=${project.name})}">View Details</a>
|
<p class="text-muted small flex-grow-1" th:text="${project.description}">Description goes here...</p>
|
||||||
|
<a class="btn btn-outline-primary btn-sm mt-3 w-fit" th:href="@{/project/{repo}(repo=${project.name})}">
|
||||||
|
View Details <i class="bi bi-arrow-right ms-1"></i>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- CONTACT -->
|
|
||||||
<section id="contact" class="bg-light">
|
<section id="contact" class="bg-light">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="section-header">
|
|
||||||
<i class="bi bi-envelope"></i>
|
|
||||||
<h2 class="fw-bold mt-2">Contact</h2>
|
|
||||||
<p class="text-muted">Let’s work together</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="contact-box p-4">
|
<div class="section-header text-center border-0">
|
||||||
<form method="post" th:action="@{/contact}">
|
<h2 class="fw-bold"><i class="bi bi-envelope me-2"></i>Contact</h2>
|
||||||
<input class="form-control mb-3" name="name" placeholder="Name" required>
|
<p class="text-muted">Let’s work together</p>
|
||||||
<input type="email" class="form-control mb-3" name="email" placeholder="Email" required>
|
</div>
|
||||||
<textarea class="form-control mb-3" name="message" rows="4" placeholder="Message"
|
<div class="contact-box p-4 shadow-sm border-0">
|
||||||
required></textarea>
|
<form th:action="@{/contact}" th:attr="hx-post=@{/contact}" hx-target="#toast-container" hx-swap="beforeend" hx-on:htmx:after-request="this.reset()">
|
||||||
<button class="btn btn-primary w-100">Send Message</button>
|
<div class="mb-3">
|
||||||
|
<input class="form-control" name="name" placeholder="Name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<input type="email" class="form-control" name="email" placeholder="Email" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<textarea class="form-control" name="message" rows="4" placeholder="Your Message" required></textarea>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary w-100 py-2 fw-bold">Send Message</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -196,12 +148,20 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div th:fragment="alertSuccess" role="alert" class='alert alert-success' th:text="${alertMessage}">Thank you! Your message has been sent.</div>
|
<div id="toast-container" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
|
||||||
|
|
||||||
|
<div th:fragment="alertSuccess" th:if="${alertMessage}">
|
||||||
|
<div class="toast show align-items-center text-bg-success border-0" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="toast-body" th:text="${alertMessage}">
|
||||||
|
Message sent successfully!
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- FOOTER -->
|
|
||||||
<div th:replace="~{fragments/footer :: footer}"></div>
|
<div th:replace="~{fragments/footer :: footer}"></div>
|
||||||
|
|
||||||
<script th:src="@{/assets/js/bootstrap.bundle.min.js}"></script>
|
<script th:src="@{/assets/js/bootstrap.bundle.min.js}"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -2,15 +2,9 @@
|
||||||
<html lang="en" data-bs-theme="light" xmlns:th="http://www.thymeleaf.org">
|
<html lang="en" data-bs-theme="light" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<!-- ================= META ================= -->
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title th:text="${project.name} + ' | Project Details'">Project</title>
|
||||||
<title th:text="${project.name} + ' | Kiyan Mckop'">Project</title>
|
|
||||||
|
|
||||||
<!-- SEO -->
|
|
||||||
<meta name="description" th:content="${project.description}">
|
|
||||||
<meta name="author" content="Kiyan Mckop">
|
|
||||||
|
|
||||||
<link th:href="@{/assets/css/bootstrap.min.css}" rel="stylesheet">
|
<link th:href="@{/assets/css/bootstrap.min.css}" rel="stylesheet">
|
||||||
<link th:href="@{https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css}" rel="stylesheet">
|
<link th:href="@{https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css}" rel="stylesheet">
|
||||||
|
|
@ -19,115 +13,113 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<!-- ================= NAVBAR ================= -->
|
|
||||||
<div th:replace="~{fragments/navbar :: navbar}"></div>
|
<div th:replace="~{fragments/navbar :: navbar}"></div>
|
||||||
|
|
||||||
<!-- ================= HERO ================= -->
|
<header class="hero">
|
||||||
<header class="hero bg-light">
|
<div class="container">
|
||||||
<div class="container text-center">
|
<div class="row align-items-center">
|
||||||
<h1 class="fw-bold" th:text="${project.name}">Project Name</h1>
|
<div class="col-lg-7">
|
||||||
|
<span class="project-badge">Project Case Study</span>
|
||||||
|
<h1 class="display-4 fw-bold mt-2" th:text="${project.name}">Project Name</h1>
|
||||||
|
<p class="lead text-muted" th:text="${project.description}">Short description.</p>
|
||||||
|
|
||||||
<p class="lead text-muted mt-2" th:text="${project.description}">
|
<div class="d-flex gap-3 mt-4">
|
||||||
Project description
|
<!-- <a th:href="${project.githubUrl}" target="_blank" class="btn btn-dark px-4 py-2 rounded-pill">
|
||||||
</p>
|
<i class="bi bi-github me-2"></i> GitHub
|
||||||
|
</a> -->
|
||||||
<!-- Project Links -->
|
<a th:if="${project.liveUrl != null}" th:href="${project.liveUrl}" target="_blank" class="btn btn-outline-primary px-4 py-2 rounded-pill">
|
||||||
<div class="d-flex justify-content-center gap-4 mt-4">
|
<i class="bi bi-globe me-2"></i> Live Demo
|
||||||
<a th:href="${project.githubUrl}" target="_blank" class="icon-link" title="GitHub Repository">
|
</a>
|
||||||
<i class="bi bi-github"></i>
|
</div>
|
||||||
</a>
|
</div>
|
||||||
|
|
||||||
<a th:if="${project.liveUrl != null}" th:href="${project.liveUrl}" target="_blank" class="icon-link"
|
|
||||||
title="Live Application">
|
|
||||||
<i class="bi bi-box-arrow-up-right"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- ================= SCREENSHOTS ================= -->
|
<section class="py-4" th:if="${project.screenshots != null && !project.screenshots.isEmpty()}">
|
||||||
<section th:if="${project.screenshots != null && !project.screenshots.isEmpty()}">
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2 class="fw-bold text-center mb-5">Application Screenshots</h2>
|
<div class="browser-frame">
|
||||||
|
<div class="browser-bar">
|
||||||
<div id="projectCarousel" class="carousel slide" data-bs-ride="carousel">
|
<div class="dot"></div><div class="dot"></div><div class="dot"></div>
|
||||||
<div class="carousel-inner rounded-4 shadow-sm">
|
</div>
|
||||||
<div th:each="img, stat : ${project.screenshots}"
|
<div id="projectCarousel" class="carousel slide" data-bs-ride="carousel">
|
||||||
th:class="'carousel-item ' + (${stat.index} == 0 ? 'active' : '')">
|
<div class="carousel-inner">
|
||||||
<img th:src="${img}" class="d-block w-100" alt="Project Screenshot">
|
<div th:each="img, stat : ${project.screenshots}"
|
||||||
</div>
|
th:class="'carousel-item ' + (${stat.index} == 0 ? 'active' : '')">
|
||||||
|
<img th:src="${img}" class="d-block w-100" alt="Screenshot">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="carousel-control-prev" type="button" data-bs-target="#projectCarousel" data-bs-slide="prev">
|
||||||
|
<span class="carousel-control-prev-icon"></span>
|
||||||
|
</button>
|
||||||
|
<button class="carousel-control-next" type="button" data-bs-target="#projectCarousel" data-bs-slide="next">
|
||||||
|
<span class="carousel-control-next-icon"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<button class="carousel-control-prev" type="button" data-bs-target="#projectCarousel"
|
|
||||||
data-bs-slide="prev">
|
|
||||||
<span class="carousel-control-prev-icon"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button class="carousel-control-next" type="button" data-bs-target="#projectCarousel"
|
|
||||||
data-bs-slide="next">
|
|
||||||
<span class="carousel-control-next-icon"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- ================= OVERVIEW & STACK ================= -->
|
<section class="py-5">
|
||||||
<section id="project-overview" class="bg-light">
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row gy-4">
|
<ul class="nav nav-pills mb-4 gap-2 justify-content-center" id="projectTab" role="tablist">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link active" id="overview-tab" data-bs-toggle="pill" data-bs-target="#overview" type="button" role="tab">Overview</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="stack-tab" data-bs-toggle="pill" data-bs-target="#stack" type="button" role="tab">Tech Stack</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation" th:if="${project.documentationHtml != null}">
|
||||||
|
<button class="nav-link" id="docs-tab" data-bs-toggle="pill" data-bs-target="#docs" type="button" role="tab">Documentation</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation" th:if="${project.futureHtml != null}">
|
||||||
|
<button class="nav-link" id="future-tab" data-bs-toggle="pill" data-bs-target="#future" type="button" role="tab">Future Plans</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<!-- Overview -->
|
<div class="tab-content dynamic-container" id="projectTabContent">
|
||||||
<div class="col-lg-8">
|
<div class="tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
|
||||||
<h2 class="fw-bold">Project Overview</h2>
|
<h3 class="fw-bold mb-4">Project Overview</h3>
|
||||||
<div th:utext="${project.overviewHtml}"></div>
|
<div class="lh-lg" th:utext="${project.overviewHtml}"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Stack -->
|
<div class="tab-pane fade" id="stack" role="tabpanel" aria-labelledby="stack-tab">
|
||||||
<div class="col-lg-4">
|
<h3 class="fw-bold mb-4">Technology Stack</h3>
|
||||||
<div class="card h-100 shadow-sm">
|
<div class="stack-content" th:utext="${project.stackHtml}"></div>
|
||||||
<div class="card-body">
|
</div>
|
||||||
<div th:utext="${project.stackHtml}"></div>
|
|
||||||
|
<div class="tab-pane fade" id="docs" role="tabpanel" aria-labelledby="docs-tab" th:if="${project.documentationHtml != null}">
|
||||||
|
<h3 class="fw-bold mb-4">Technical Documentation</h3>
|
||||||
|
<div class="lh-lg" th:utext="${project.documentationHtml}"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane fade" id="future" role="tabpanel" aria-labelledby="future-tab" th:if="${project.futureHtml != null}">
|
||||||
|
<h3 class="fw-bold mb-4">The Roadmap</h3>
|
||||||
|
<div class="lh-lg" th:utext="${project.futureHtml}"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="demo-vid" class="bg-dark py-5 text-white">
|
||||||
|
<div class="container text-center">
|
||||||
|
<h2 class="fw-bold mb-5"><i class="bi bi-play-btn me-2"></i>Video Demonstration</h2>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-lg-10">
|
||||||
|
<div class="ratio ratio-16x9 rounded-4 shadow-lg overflow-hidden bg-secondary">
|
||||||
|
<div class="d-flex align-items-center justify-content-center h-100">
|
||||||
|
<div class="text-center">
|
||||||
|
<i class="bi bi-camera-video display-1 opacity-25"></i>
|
||||||
|
<p class="mt-3">Walkthrough Video Coming Soon</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- ================= DOCUMENTATION ================= -->
|
|
||||||
<section id="documentation" th:if="${project.documentationHtml != null}">
|
|
||||||
<div class="container">
|
|
||||||
<h2 class="fw-bold text-center mb-5">Documentation</h2>
|
|
||||||
<div th:utext="${project.documentationHtml}"></div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- ================= FUTURE PLANS ================= -->
|
|
||||||
<section id="future-plans" class="bg-light" th:if="${project.futureHtml != null}">
|
|
||||||
<div class="container">
|
|
||||||
<h2 class="fw-bold text-center mb-5">Future Plans</h2>
|
|
||||||
<div th:utext="${project.futureHtml}"></div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- ================= DEMO ================= -->
|
|
||||||
<section id="demo-vid">
|
|
||||||
<div class="container">
|
|
||||||
<h2 class="fw-bold text-center mb-5">Demo Video</h2>
|
|
||||||
|
|
||||||
<div class="ratio ratio-16x9 rounded-4 shadow-sm overflow-hidden text-center">
|
|
||||||
<span><em>Coming Soon</em></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- ================= FOOTER ================= -->
|
|
||||||
<div th:replace="~{fragments/footer :: footer}"></div>
|
<div th:replace="~{fragments/footer :: footer}"></div>
|
||||||
|
|
||||||
<script th:src="@{/assets/js/bootstrap.bundle.min.js}"></script>
|
<script th:src="@{/assets/js/bootstrap.bundle.min.js}"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Loading…
Reference in New Issue