Updated Visuals
@@ -0,0 +1,22 @@
|
|||||||
|
# Multi-stage build for Vue 3 portfolio
|
||||||
|
# Build stage
|
||||||
|
FROM node:20-alpine AS build
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Copy source and build
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Runtime stage (no nginx as requested)
|
||||||
|
FROM node:20-alpine AS runtime
|
||||||
|
WORKDIR /app
|
||||||
|
# Install a tiny static file server
|
||||||
|
RUN npm install -g serve@14
|
||||||
|
# Copy only built assets
|
||||||
|
COPY --from=build /app/dist ./dist
|
||||||
|
# No EXPOSE (internal port 80 via serve)
|
||||||
|
CMD ["serve", "-s", "dist", "-l", "80"]
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
version: "3.9"
|
||||||
|
services:
|
||||||
|
portfolio:
|
||||||
|
build: .
|
||||||
|
container_name: vue_portfolio
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- cloudflare
|
||||||
|
networks:
|
||||||
|
cloudflare:
|
||||||
|
external: true
|
||||||
|
Before Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 653 KiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 804 KiB |
|
After Width: | Height: | Size: 226 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 161 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 496 B |
@@ -51,27 +51,21 @@
|
|||||||
<p class="text-base lg:text-lg mt-8 py-8 text-justify">
|
<p class="text-base lg:text-lg mt-8 py-8 text-justify">
|
||||||
I am a Software Engineering student from Portugal with 4+ years of
|
I am a Software Engineering student from Portugal with 4+ years of
|
||||||
experience from my internships and Self Learning + Personal Projects.
|
experience from my internships and Self Learning + Personal Projects.
|
||||||
I am passionate about technology and always eager to learn more. I am
|
I am passionate about technology and always eager to learn more.
|
||||||
currently pursuing my Bachelor's on Software Engineering after having
|
Outside University I've been studying Backend Development with Go to
|
||||||
completed a CTeSP in programming, where I gained a solid foundation in
|
build lightning fast and efficient RESTful APIs I've also been
|
||||||
C, .NET, PHP, Java, and MySQL. In my free time I've taken a few online
|
studying Frontend Development with Vue.js to build modern and
|
||||||
courses on Unity 3D, Swift/SwiftUI, Cypress, Git, React, Golang. I've
|
responsive web applications.
|
||||||
also had the pleasure to be a QA/QC Intern at VOID Software in Leiria
|
|
||||||
for five months. There, I contributed to the testing and quality
|
|
||||||
assurance of several projects, using Cypress and Cucumber to automate
|
|
||||||
and streamline the testing process and Git to manage the source code
|
|
||||||
and collaborate with the development team. I am always looking for new
|
|
||||||
challenges and opportunities to grow as a developer.
|
|
||||||
</p>
|
</p>
|
||||||
<div class="grid grid-cols-3 gap-4 max-w-lg pt-8">
|
<div class="grid grid-cols-3 gap-4 max-w-lg pt-8">
|
||||||
<div
|
<!-- <div
|
||||||
class="text-center rounded-xl bg-gray-900 shadow-lg border border-[#1f1641] p-3"
|
class="text-center rounded-xl bg-gray-900 shadow-lg border border-[#1f1641] p-3"
|
||||||
>
|
>
|
||||||
<h3 class="text-white font-bold text-xl sm:text-2xl lg:text-3xl">
|
<h3 class="text-white font-bold text-xl sm:text-2xl lg:text-3xl">
|
||||||
+200
|
+200
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-sm sm:text-base text-gray-300">Happy Clients</p>
|
<p class="text-sm sm:text-base text-gray-300">Happy Clients</p>
|
||||||
</div>
|
</div> -->
|
||||||
<div
|
<div
|
||||||
class="text-center rounded-xl bg-gray-900 shadow-lg border border-[#1f1641] p-3"
|
class="text-center rounded-xl bg-gray-900 shadow-lg border border-[#1f1641] p-3"
|
||||||
>
|
>
|
||||||
@@ -84,7 +78,7 @@
|
|||||||
class="text-center rounded-xl bg-gray-900 shadow-lg border border-[#1f1641] p-3"
|
class="text-center rounded-xl bg-gray-900 shadow-lg border border-[#1f1641] p-3"
|
||||||
>
|
>
|
||||||
<h3 class="text-white font-bold text-xl sm:text-2xl lg:text-3xl">
|
<h3 class="text-white font-bold text-xl sm:text-2xl lg:text-3xl">
|
||||||
+300
|
+20
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-sm sm:text-base text-gray-300">Projects</p>
|
<p class="text-sm sm:text-base text-gray-300">Projects</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -158,7 +158,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="z-1 w-[100%!important] px-6 md:px-7 py-3 rounded-full sm:w-max flex justify-center text-white bg-primary border-2 border-transparent"
|
class="z-1 cursor-pointer w-[100%!important] px-6 md:px-7 py-3 rounded-full sm:w-max flex justify-center text-white bg-primary border-2 border-transparent"
|
||||||
>
|
>
|
||||||
Send Message
|
Send Message
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -96,7 +96,7 @@
|
|||||||
class="absolute z-0 top-1/2 -translate-y-1/2 w-5/6 right-0 h-[calc(80%+20px)] bg-gradient-to-tr opacity-25 from-[#570cac] to-primary blur-2xl"
|
class="absolute z-0 top-1/2 -translate-y-1/2 w-5/6 right-0 h-[calc(80%+20px)] bg-gradient-to-tr opacity-25 from-[#570cac] to-primary blur-2xl"
|
||||||
></div>
|
></div>
|
||||||
<div
|
<div
|
||||||
class="absolute h-full z-10 p-2 -translate-y-1/2 top-1/2 lg:right-3 md:right-40 sm:right-16 rounded-full shadow-lg border border-primary"
|
class="absolute h-full aspect-square z-10 p-2 -translate-y-1/2 top-1/2 lg:right-3 md:right-40 sm:right-16 rounded-full shadow-lg border border-primary"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="@/assets/profile_image.jpg"
|
src="@/assets/profile_image.jpg"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<h2 class="text-4xl font-bold text-white">My Projects</h2>
|
<h2 class="text-4xl font-bold text-white">My Projects</h2>
|
||||||
<div class="flex space-x-4 mb-4 mt-5 md:mt-0">
|
<div class="flex space-x-4 mb-4 mt-5 md:mt-0">
|
||||||
<button
|
<button
|
||||||
class="hover:text-primary z-10"
|
class="hover:text-primary z-10 cursor-pointer"
|
||||||
v-for="cat in ['All', 'Academic', 'Personal']"
|
v-for="cat in ['All', 'Academic', 'Personal']"
|
||||||
:key="cat"
|
:key="cat"
|
||||||
@click="() => (selectedCategory = cat)"
|
@click="() => (selectedCategory = cat)"
|
||||||
@@ -29,14 +29,14 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="overlay items-center justify-center absolute top-0 left-0 w-full h-full bg-[#181818] bg-opacity-0 hidden group-hover:flex group-hover:bg-opacity-80 transition-all duration-50"
|
class="overlay items-center justify-center absolute top-0 left-0 w-full h-full backdrop-blur-none hidden group-hover:flex group-hover:backdrop-blur-sm transition-all duration-50"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
v-if="p.webURL"
|
v-if="p.webURL"
|
||||||
:href="p.webURL"
|
:href="p.webURL"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
class="h-14 w-14 mr-2 border-2 relative rounded-full border-[#ADB7BE] hover:border-white group/link"
|
class="h-14 w-14 mr-2 border-2 relative rounded-full border-gray-900 hover:border-white group/link"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
class="h-10 w-10 text-[#ADB7BE] absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer group-hover/link:text-white"
|
class="h-10 w-10 text-gray-900 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer group-hover/link:text-white"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<span
|
<span
|
||||||
v-else
|
v-else
|
||||||
class="h-14 w-14 mr-2 border-2 relative rounded-full border-gray-600 opacity-40 cursor-not-allowed flex items-center justify-center"
|
class="h-14 w-14 mr-2 border-2 relative rounded-full border-gray-900 opacity-40 cursor-not-allowed flex items-center justify-center"
|
||||||
aria-disabled="true"
|
aria-disabled="true"
|
||||||
title="Live demo unavailable"
|
title="Live demo unavailable"
|
||||||
>
|
>
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
class="h-10 w-10 text-[#ADB7BE] absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer group-hover/link:text-white"
|
class="h-10 w-10 text-gray-900 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer group-hover/link:text-white"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
:href="p.gitURL"
|
:href="p.gitURL"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
class="h-14 w-14 mr-2 border-2 relative rounded-full border-[#ADB7BE] hover:border-white group/link"
|
class="h-14 w-14 mr-2 border-2 relative rounded-full border-gray-900 hover:border-white group/link"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
stroke-width="1.5"
|
stroke-width="1.5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
class="h-10 w-10 text-[#ADB7BE] absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer"
|
class="h-10 w-10 text-gray-900 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<span
|
<span
|
||||||
v-else
|
v-else
|
||||||
class="h-14 w-14 mr-2 border-2 relative rounded-full border-gray-600 opacity-40 cursor-not-allowed flex items-center justify-center"
|
class="h-14 w-14 mr-2 border-2 relative rounded-full border-gray-900 opacity-40 cursor-not-allowed flex items-center justify-center"
|
||||||
aria-disabled="true"
|
aria-disabled="true"
|
||||||
title="Live demo unavailable"
|
title="Live demo unavailable"
|
||||||
>
|
>
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
stroke-width="1.5"
|
stroke-width="1.5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
class="h-10 w-10 text-[#ADB7BE] absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer"
|
class="h-10 w-10 text-gray-900 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
@@ -173,7 +173,7 @@ const projects = ref([
|
|||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
category: "Academic",
|
category: "Academic",
|
||||||
image: "src/assets/test.jpg",
|
image: "src/assets/stuffandgo_web.jpg",
|
||||||
title: "Stuff&Go Web Store",
|
title: "Stuff&Go Web Store",
|
||||||
description: "Supermarket e-commerce platform",
|
description: "Supermarket e-commerce platform",
|
||||||
technologies: ["PHP", "JavaScript", "MySQL"],
|
technologies: ["PHP", "JavaScript", "MySQL"],
|
||||||
@@ -183,7 +183,7 @@ const projects = ref([
|
|||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
category: "Academic",
|
category: "Academic",
|
||||||
image: "src/assets/test.jpg",
|
image: "src/assets/stuffngo_mobile.jpg",
|
||||||
title: "Stuff&Go Mobile App",
|
title: "Stuff&Go Mobile App",
|
||||||
description: "Mobile application for supermarket shopping.",
|
description: "Mobile application for supermarket shopping.",
|
||||||
technologies: ["Java", "MQTT", "Android"],
|
technologies: ["Java", "MQTT", "Android"],
|
||||||
@@ -203,7 +203,7 @@ const projects = ref([
|
|||||||
{
|
{
|
||||||
id: 4,
|
id: 4,
|
||||||
category: "Academic",
|
category: "Academic",
|
||||||
image: "src/assets/test.jpg",
|
image: "src/assets/sgi.png",
|
||||||
title: "La Redoute Product Page UI",
|
title: "La Redoute Product Page UI",
|
||||||
description: "UI design for a La Redoute product page.",
|
description: "UI design for a La Redoute product page.",
|
||||||
technologies: ["HTML", "Bootstrap", "Three.js"],
|
technologies: ["HTML", "Bootstrap", "Three.js"],
|
||||||
@@ -233,7 +233,7 @@ const projects = ref([
|
|||||||
{
|
{
|
||||||
id: 7,
|
id: 7,
|
||||||
category: "Personal",
|
category: "Personal",
|
||||||
image: "src/assets/velox_web.png",
|
image: "src/assets/velox_web.jpg",
|
||||||
title: "Velox Web Framework",
|
title: "Velox Web Framework",
|
||||||
description: "Fullstack laravel like web framework built with Go.",
|
description: "Fullstack laravel like web framework built with Go.",
|
||||||
technologies: ["Go"],
|
technologies: ["Go"],
|
||||||
@@ -243,7 +243,7 @@ const projects = ref([
|
|||||||
{
|
{
|
||||||
id: 8,
|
id: 8,
|
||||||
category: "Personal",
|
category: "Personal",
|
||||||
image: "src/assets/profile_image.jpg",
|
image: "src/assets/portfolio.png",
|
||||||
title: "My Portfolio",
|
title: "My Portfolio",
|
||||||
description: "Showcase of my projects and skills built in Vue 3.",
|
description: "Showcase of my projects and skills built in Vue 3.",
|
||||||
technologies: ["Vue.js", "Tailwind CSS"],
|
technologies: ["Vue.js", "Tailwind CSS"],
|
||||||
@@ -253,7 +253,7 @@ const projects = ref([
|
|||||||
{
|
{
|
||||||
id: 9,
|
id: 9,
|
||||||
category: "Personal",
|
category: "Personal",
|
||||||
image: "src/assets/Lk.jpg",
|
image: "src/assets/Lk.png",
|
||||||
title: "LK Results Website",
|
title: "LK Results Website",
|
||||||
description: "Landing Page for my Company.",
|
description: "Landing Page for my Company.",
|
||||||
technologies: ["React.js", "Typescript"],
|
technologies: ["React.js", "Typescript"],
|
||||||
|
|||||||
@@ -55,5 +55,11 @@ const services = ref([
|
|||||||
description:
|
description:
|
||||||
"Building mobile applications with a focus on user experience and performance.",
|
"Building mobile applications with a focus on user experience and performance.",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
icon: "https://img.icons8.com/ios-filled/100/ffffff/web-design.png",
|
||||||
|
name: "Web Design",
|
||||||
|
description: "Mockup and prototyping of user interfaces.",
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||