Skip to content

Commit f977505

Browse files
committed
refactor: Refactors and improves landing page UI
Refactors the landing page to improve the user interface and overall structure. Removes unused dependencies and components, streamlines the layout, and updates styling for better responsiveness and visual appeal. The primary goal is to enhance user experience and optimize the codebase for maintainability.
1 parent 4a521ab commit f977505

29 files changed

+287
-953
lines changed

package.json

-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@lottiefiles/react-lottie-player": "^3.6.0",
1211
"@react-three/drei": "^9.121.1",
1312
"@react-three/fiber": "^9.1.1",
1413
"lucide-react": "^0.486.0",
1514
"next": "15.2.4",
1615
"next-intl": "^4.0.2",
17-
"postcss": "^8.5.3",
1816
"react": "18.3.1",
1917
"react-dom": "18.3.1",
2018
"react-stacked-center-carousel": "^1.0.14",

postcss.config.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ const config = {
33
"@tailwindcss/postcss": {},
44
},
55
};
6-
export default config;
6+
export default config;

src/app/[locale]/layout.tsx

+5-6
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ import { ReactNode } from "react";
33
import { NextIntlClientProvider } from "next-intl";
44
import { getLocale, getMessages, getTranslations } from "next-intl/server";
55

6-
export async function generateMetadata({
7-
params,
8-
}: {
9-
params: { locale: string };
10-
}) {
11-
const { locale } = await params;
6+
type Params = Promise<{ locale: string }>;
7+
8+
export async function generateMetadata(props: { params: Params }) {
9+
const params = await props.params;
10+
const { locale } = params;
1211
const t = await getTranslations({ locale, namespace: "Metadata" });
1312

1413
return {

src/app/[locale]/page.tsx

+42-32
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import InfoCard from "@/components/InfoCard";
1212
import { LanguageIcon } from "@/components/LanguageIcon";
1313
import ProfileInfo from "@/components/ProfileInfo";
1414
import { ProjectCard } from "@/components/ProjectCard";
15-
import { Tooltip } from "@/components/ToolTip";
1615
import { formations } from "@/utils/formations";
1716
import { projects } from "@/utils/projects";
1817
import { techs } from "@/utils/techs";
@@ -53,21 +52,27 @@ export default async function Home() {
5352
</Container>
5453
</section>
5554

56-
{/* <section>
55+
<section className="mb-16">
5756
<Container>
5857
<InfoCard>
59-
<h2>{t("aboutMe.title")}</h2>
60-
<p>{t("aboutMe.description")}</p>
58+
<h2 className="mb-6 text-3xl font-bold text-white md:mb-1">
59+
{t("aboutMe.title")}
60+
</h2>
61+
<p className="text-justify text-[1rem] text-white md:text-[1.2rem]">
62+
{t("aboutMe.description")}
63+
</p>
6164
</InfoCard>
6265
</Container>
63-
</section> */}
66+
</section>
6467

65-
{/* <Container>
68+
<Container>
6669
<InfoCard>
67-
<section className={styles.education}>
68-
<h3>{t('academicFormation.title')}</h3>
69-
<div className={styles.educationContent}>
70-
{formations.map(formation => (
70+
<section>
71+
<h3 className="mb-2 text-3xl font-bold text-white">
72+
{t("academicFormation.title")}
73+
</h3>
74+
<div className="grid-rols-1 grid grid-cols-1 gap-x-0 gap-y-0 md:grid-cols-2">
75+
{formations.map((formation) => (
7176
<Info
7277
key={formation.description}
7378
title={{
@@ -80,14 +85,16 @@ export default async function Home() {
8085
</div>
8186
</section>
8287
</InfoCard>
83-
</Container> */}
88+
</Container>
8489

85-
{/* <section className={styles.projects}>
90+
<section className="mt-16">
8691
<Container>
8792
<InfoCard>
88-
<h4>{t('projects.title')}</h4>
93+
<h4 className="mb-2 text-3xl font-bold text-white">
94+
{t("projects.title")}
95+
</h4>
8996

90-
{projects.map(project => (
97+
{projects.map((project) => (
9198
<Suspense key={project.title} fallback={null}>
9299
<ProjectCard
93100
hasMockup={project.hasMockup}
@@ -104,32 +111,35 @@ export default async function Home() {
104111
))}
105112
</InfoCard>
106113
</Container>
107-
</section> */}
114+
</section>
108115

109-
{/* <section className={styles.techs}>
110-
<h5>{t('techs.title')}</h5>
116+
<section className="my-16">
117+
<h5 className="mb-10 text-center text-3xl font-bold text-white md:mb-10 md:text-5xl">
118+
{t("techs.title")}
119+
</h5>
111120

112-
<div>
113-
{techs.map(tech => (
114-
<Tooltip key={tech.title} text={tech.title}>
115-
<Image
116-
src={tech.img}
117-
width="40"
118-
height="40"
119-
alt={tech.title}
120-
loading="lazy"
121-
/>
122-
</Tooltip>
121+
<div className="flex flex-wrap items-start justify-around gap-1.5 px-1 py-2.5">
122+
{techs.map((tech) => (
123+
<Image
124+
src={tech.img}
125+
width="40"
126+
height="40"
127+
alt={tech.title}
128+
loading="lazy"
129+
key={tech.title}
130+
/>
123131
))}
124132
</div>
125-
</section> */}
133+
</section>
126134

127-
{/* <footer className={styles.footer}>
128-
<h5>Copyright © Rafael Santana · {year} </h5>
135+
<footer className="flex flex-col items-center justify-center py-10">
136+
<h5 className="text-[1rem] font-bold text-white">
137+
Copyright © Rafael Santana · {year}{" "}
138+
</h5>
129139
<Suspense>
130140
<ChangeColor />
131141
</Suspense>
132-
</footer> */}
142+
</footer>
133143

134144
<BackToTheTop />
135145
</main>

src/app/api/icon/[color]/route.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import { NextRequest, NextResponse } from 'next/server';
2-
3-
export async function GET(request: NextRequest, { params }: { params: any }) {
4-
const { color } = params;
1+
import { NextRequest, NextResponse } from "next/server";
52

3+
export async function GET(
4+
request: NextRequest,
5+
{ params }: { params: Promise<{ color: string }> },
6+
) {
7+
const { color } = await params;
68
if (!color) {
79
return NextResponse.json(
8-
{ error: 'color parameter is required' },
10+
{ error: "color parameter is required" },
911
{ status: 400 },
1012
);
1113
}

src/app/globals.css

+144-4
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,159 @@
44
--color-picton-blue: #3bbbe8;
55
--color-jet: #363636;
66
--color-chinese-black: #141414;
7+
--color-overlay-black: #00000099;
78
}
89

910
@layer utilities {
1011
* {
1112
scrollbar-width: auto;
1213
scrollbar-color: var(--color-picton-blue) var(--color-jet);
1314
}
15+
16+
.color-input-wrapper::-webkit-color-swatch-wrapper {
17+
padding: 0;
18+
}
19+
20+
.color-input-swatch::-webkit-color-swatch {
21+
border: none;
22+
}
23+
24+
.bg-custom {
25+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2000 1500'%3E%3Cdefs%3E%3CradialGradient id='a' gradientUnits='objectBoundingBox'%3E%3Cstop offset='0' stop-color='%23101010'/%3E%3Cstop offset='1' stop-color='%23141414'/%3E%3C/radialGradient%3E%3ClinearGradient id='b' gradientUnits='userSpaceOnUse' x1='0' y1='750' x2='1550' y2='750'%3E%3Cstop offset='0' stop-color='%23121212'/%3E%3Cstop offset='1' stop-color='%23141414'/%3E%3C/linearGradient%3E%3Cpath id='s' fill='url(%23b)' d='M1549.2 51.6c-5.4 99.1-20.2 197.6-44.2 293.6c-24.1 96-57.4 189.4-99.3 278.6c-41.9 89.2-92.4 174.1-150.3 253.3c-58 79.2-123.4 152.6-195.1 219c-71.7 66.4-149.6 125.8-232.2 177.2c-82.7 51.4-170.1 94.7-260.7 129.1c-90.6 34.4-184.4 60-279.5 76.3C192.6 1495 96.1 1502 0 1500c96.1-2.1 191.8-13.3 285.4-33.6c93.6-20.2 185-49.5 272.5-87.2c87.6-37.7 171.3-83.8 249.6-137.3c78.4-53.5 151.5-114.5 217.9-181.7c66.5-67.2 126.4-140.7 178.6-218.9c52.3-78.3 96.9-161.4 133-247.9c36.1-86.5 63.8-176.2 82.6-267.6c18.8-91.4 28.6-184.4 29.6-277.4c0.3-27.6 23.2-48.7 50.8-48.4s49.5 21.8 49.2 49.5c0 0.7 0 1.3-0.1 2L1549.2 51.6z'/%3E%3Cg id='g'%3E%3Cuse href='%23s' transform='scale(0.12) rotate(60)'/%3E%3Cuse href='%23s' transform='scale(0.2) rotate(10)'/%3E%3Cuse href='%23s' transform='scale(0.25) rotate(40)'/%3E%3Cuse href='%23s' transform='scale(0.3) rotate(-20)'/%3E%3Cuse href='%23s' transform='scale(0.4) rotate(-30)'/%3E%3Cuse href='%23s' transform='scale(0.5) rotate(20)'/%3E%3Cuse href='%23s' transform='scale(0.6) rotate(60)'/%3E%3Cuse href='%23s' transform='scale(0.7) rotate(10)'/%3E%3Cuse href='%23s' transform='scale(0.835) rotate(-40)'/%3E%3Cuse href='%23s' transform='scale(0.9) rotate(40)'/%3E%3Cuse href='%23s' transform='scale(1.05) rotate(25)'/%3E%3Cuse href='%23s' transform='scale(1.2) rotate(8)'/%3E%3Cuse href='%23s' transform='scale(1.333) rotate(-60)'/%3E%3Cuse href='%23s' transform='scale(1.45) rotate(-30)'/%3E%3Cuse href='%23s' transform='scale(1.6) rotate(10)'/%3E%3C/g%3E%3C/defs%3E%3Cg transform='rotate(0 0 0)'%3E%3Cg transform='rotate(0 0 0)'%3E%3Ccircle fill='url(%23a)' r='3000'/%3E%3Cg opacity='0.5'%3E%3Ccircle fill='url(%23a)' r='2000'/%3E%3Ccircle fill='url(%23a)' r='1800'/%3E%3Ccircle fill='url(%23a)' r='1700'/%3E%3Ccircle fill='url(%23a)' r='1651'/%3E%3Ccircle fill='url(%23a)' r='1450'/%3E%3Ccircle fill='url(%23a)' r='1250'/%3E%3Ccircle fill='url(%23a)' r='1175'/%3E%3Ccircle fill='url(%23a)' r='900'/%3E%3Ccircle fill='url(%23a)' r='750'/%3E%3Ccircle fill='url(%23a)' r='500'/%3E%3Ccircle fill='url(%23a)' r='380'/%3E%3Ccircle fill='url(%23a)' r='250'/%3E%3C/g%3E%3Cg transform='rotate(0 0 0)'%3E%3Cuse href='%23g' transform='rotate(10)'/%3E%3Cuse href='%23g' transform='rotate(120)'/%3E%3Cuse href='%23g' transform='rotate(240)'/%3E%3C/g%3E%3Ccircle fill-opacity='0.1' fill='url(%23a)' r='3000'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
26+
}
27+
28+
::selection {
29+
background: var(--color-picton-blue);
30+
}
1431
}
1532

16-
.bg-custom {
17-
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2000 1500'%3E%3Cdefs%3E%3CradialGradient id='a' gradientUnits='objectBoundingBox'%3E%3Cstop offset='0' stop-color='%23101010'/%3E%3Cstop offset='1' stop-color='%23141414'/%3E%3C/radialGradient%3E%3ClinearGradient id='b' gradientUnits='userSpaceOnUse' x1='0' y1='750' x2='1550' y2='750'%3E%3Cstop offset='0' stop-color='%23121212'/%3E%3Cstop offset='1' stop-color='%23141414'/%3E%3C/linearGradient%3E%3Cpath id='s' fill='url(%23b)' d='M1549.2 51.6c-5.4 99.1-20.2 197.6-44.2 293.6c-24.1 96-57.4 189.4-99.3 278.6c-41.9 89.2-92.4 174.1-150.3 253.3c-58 79.2-123.4 152.6-195.1 219c-71.7 66.4-149.6 125.8-232.2 177.2c-82.7 51.4-170.1 94.7-260.7 129.1c-90.6 34.4-184.4 60-279.5 76.3C192.6 1495 96.1 1502 0 1500c96.1-2.1 191.8-13.3 285.4-33.6c93.6-20.2 185-49.5 272.5-87.2c87.6-37.7 171.3-83.8 249.6-137.3c78.4-53.5 151.5-114.5 217.9-181.7c66.5-67.2 126.4-140.7 178.6-218.9c52.3-78.3 96.9-161.4 133-247.9c36.1-86.5 63.8-176.2 82.6-267.6c18.8-91.4 28.6-184.4 29.6-277.4c0.3-27.6 23.2-48.7 50.8-48.4s49.5 21.8 49.2 49.5c0 0.7 0 1.3-0.1 2L1549.2 51.6z'/%3E%3Cg id='g'%3E%3Cuse href='%23s' transform='scale(0.12) rotate(60)'/%3E%3Cuse href='%23s' transform='scale(0.2) rotate(10)'/%3E%3Cuse href='%23s' transform='scale(0.25) rotate(40)'/%3E%3Cuse href='%23s' transform='scale(0.3) rotate(-20)'/%3E%3Cuse href='%23s' transform='scale(0.4) rotate(-30)'/%3E%3Cuse href='%23s' transform='scale(0.5) rotate(20)'/%3E%3Cuse href='%23s' transform='scale(0.6) rotate(60)'/%3E%3Cuse href='%23s' transform='scale(0.7) rotate(10)'/%3E%3Cuse href='%23s' transform='scale(0.835) rotate(-40)'/%3E%3Cuse href='%23s' transform='scale(0.9) rotate(40)'/%3E%3Cuse href='%23s' transform='scale(1.05) rotate(25)'/%3E%3Cuse href='%23s' transform='scale(1.2) rotate(8)'/%3E%3Cuse href='%23s' transform='scale(1.333) rotate(-60)'/%3E%3Cuse href='%23s' transform='scale(1.45) rotate(-30)'/%3E%3Cuse href='%23s' transform='scale(1.6) rotate(10)'/%3E%3C/g%3E%3C/defs%3E%3Cg transform='rotate(0 0 0)'%3E%3Cg transform='rotate(0 0 0)'%3E%3Ccircle fill='url(%23a)' r='3000'/%3E%3Cg opacity='0.5'%3E%3Ccircle fill='url(%23a)' r='2000'/%3E%3Ccircle fill='url(%23a)' r='1800'/%3E%3Ccircle fill='url(%23a)' r='1700'/%3E%3Ccircle fill='url(%23a)' r='1651'/%3E%3Ccircle fill='url(%23a)' r='1450'/%3E%3Ccircle fill='url(%23a)' r='1250'/%3E%3Ccircle fill='url(%23a)' r='1175'/%3E%3Ccircle fill='url(%23a)' r='900'/%3E%3Ccircle fill='url(%23a)' r='750'/%3E%3Ccircle fill='url(%23a)' r='500'/%3E%3Ccircle fill='url(%23a)' r='380'/%3E%3Ccircle fill='url(%23a)' r='250'/%3E%3C/g%3E%3Cg transform='rotate(0 0 0)'%3E%3Cuse href='%23g' transform='rotate(10)'/%3E%3Cuse href='%23g' transform='rotate(120)'/%3E%3Cuse href='%23g' transform='rotate(240)'/%3E%3C/g%3E%3Ccircle fill-opacity='0.1' fill='url(%23a)' r='3000'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
33+
@layer utilities {
34+
.cardOverlay {
35+
-webkit-user-select: none;
36+
-moz-user-select: none;
37+
user-select: none;
38+
}
39+
40+
.card .card-button {
41+
position: absolute;
42+
top: 43%;
43+
box-shadow: none;
44+
border-radius: 0.5rem;
45+
width: 3.6rem;
46+
height: 3.6rem;
47+
background-color: transparent;
48+
}
49+
50+
.card .card-button.right {
51+
right: 0%;
52+
}
53+
54+
.react-stacked-center-carousel {
55+
padding: 2rem 0;
56+
min-height: 5rem;
57+
display: flex;
58+
justify-content: center;
59+
align-items: center;
60+
}
61+
62+
.card-card {
63+
transition: all 300ms ease;
64+
cursor: pointer;
65+
width: 100%;
66+
border-radius: 1.5rem;
67+
position: relative;
68+
background-color: transparent;
69+
}
70+
71+
.card-card:hover {
72+
transform: scale(1.05);
73+
}
74+
75+
.react-stacked-center-carousel-slide-0 .card-card {
76+
cursor: default;
77+
}
78+
79+
.react-stacked-center-carousel-slide-0 .card-card:hover {
80+
transform: none;
81+
}
82+
83+
.fill {
84+
width: 100%;
85+
height: 100%;
86+
}
87+
88+
.card-card .card-overlay {
89+
user-select: none;
90+
position: absolute;
91+
background-color: var(--color-overlay-black);
92+
transition: all 300ms ease;
93+
}
94+
95+
.card-overlay-mockup {
96+
border-radius: 2rem;
97+
}
98+
99+
.react-stacked-center-carousel-slide-0 .card-overlay {
100+
background-color: var(--color-overlay-black) !important;
101+
}
102+
103+
.card-card .cover-image {
104+
object-fit: cover;
105+
}
106+
107+
.card-card .cover {
108+
position: absolute;
109+
transition: opacity 300ms ease;
110+
}
111+
.react-stacked-center-carousel-slide-0 .card-card .cover {
112+
transition:
113+
opacity 300ms ease,
114+
z-index 0ms 300ms;
115+
}
116+
117+
.card-card .cover.on {
118+
opacity: 1;
119+
z-index: 1;
120+
}
121+
122+
.card-card .cover.off {
123+
opacity: 0;
124+
z-index: -1;
125+
}
126+
127+
.card-card .detail {
128+
display: flex;
129+
}
130+
131+
.card-card .video {
132+
width: 20%;
133+
}
134+
135+
.card-card .description {
136+
display: flex;
137+
flex-direction: column;
138+
}
18139
}
19140

20-
::selection {
21-
background: var(--color-picton-blue);
141+
@layer utilities {
142+
.text-vertical {
143+
position: absolute;
144+
font-family: var(--font-montserrat);
145+
font-weight: bold;
146+
writing-mode: vertical-rl;
147+
text-orientation: upright;
148+
text-transform: uppercase;
149+
color: var(--color-chinese-black);
150+
-webkit-text-stroke: 1.5px var(--color-picton-blue);
151+
}
152+
153+
.text-vertical::after {
154+
content: attr(data-text);
155+
color: var(--color-chinese-black);
156+
position: absolute;
157+
top: 0;
158+
left: 0;
159+
-webkit-text-stroke: 0 var(--color-chinese-black);
160+
font-family: var(--font-montserrat) !important;
161+
}
22162
}

src/app/not-found.tsx

-57
This file was deleted.

0 commit comments

Comments
 (0)