Skip to content

Commit 331e367

Browse files
committed
added contact and language badges
1 parent c97f451 commit 331e367

File tree

14 files changed

+331
-31
lines changed

14 files changed

+331
-31
lines changed

astro.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,11 @@ import tailwindcss from "@tailwindcss/vite";
44
export default defineConfig({
55
vite: {
66
plugins: [tailwindcss()],
7+
server: {
8+
headers: {
9+
"Content-Security-Policy":
10+
"frame-ancestors 'self' https://challenges.cloudflare.com; frame-src 'self' https://challenges.cloudflare.com;",
11+
},
12+
},
713
},
814
});

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"@lucide/astro": "^0.561.0",
1313
"@tailwindcss/vite": "^4.1.18",
1414
"astro": "^5.16.6",
15+
"nodemailer": "^7.0.12",
1516
"tailwindcss": "^4.1.18"
1617
}
1718
}

pnpm-lock.yaml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/Footer.astro

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Github } from "@lucide/astro";
33
---
44

55
<footer
6-
class="mt-12 px-96 sm:px-8 md:px-16 lg:px-32 xl:px-64 w-screen h-80 flex justify-center items-center border-t border-t-(--background-lighter)"
6+
class="relative mt-12 px-96 sm:px-8 md:px-16 lg:px-32 xl:px-64 w-screen h-80 flex flex-col justify-center items-center border-t border-t-(--background-lighter)"
77
>
88
<div class="flex gap-32">
99
<div class="w-80 flex flex-col">
@@ -30,5 +30,19 @@ import { Github } from "@lucide/astro";
3030
<br />
3131
<a href="https://github.com/Nexoscript">GitHub</a>
3232
</div>
33+
<div class="flex flex-col">
34+
<p class="text-xl font-semibold">Legal</p>
35+
<br />
36+
<a href="https://eztxm.de/imprint">Imprint</a>
37+
</div>
3338
</div>
39+
<p id="copyright" class="absolute bottom-0 py-2"></p>
3440
</footer>
41+
42+
<script>
43+
const copyright = document.getElementById("copyright");
44+
if (copyright) {
45+
const year = new Date().getFullYear();
46+
copyright.innerHTML = `Nexoscript &copy; ${year === 2025 ? year : "2025-" + year} - All rights reserved`;
47+
}
48+
</script>

src/components/Header.astro

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
<input
3030
type="text"
3131
placeholder="Search..."
32-
class="px-4 py-2 border border-(--background-lighter) rounded-lg transition-filter duration-200 ease-in-out hover:bg-(--background) hover:brightness-250 focus:outline-0 focus:bg-(--background) focus:brightness-250"
32+
disabled="true"
33+
class="px-4 py-2 border border-(--background-lighter) rounded-lg transition-filter duration-200 ease-in-out cursor-not-allowed"
3334
/>
35+
<!-- hover:bg-(--background) hover:brightness-250 focus:outline-0 focus:bg-(--background) focus:brightness-250 -->
3436
</div>
3537
</header>

src/components/Member.astro

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
---
2-
import { Github, Paperclip, Youtube } from "@lucide/astro";
2+
import { Github, Paperclip, Twitch, Youtube } from "@lucide/astro";
33
4-
const { name, image, description, apply, github, youtube } = Astro.props;
4+
const { name, image, description, apply, github, youtube, twitch } =
5+
Astro.props;
56
---
67

78
<div
@@ -18,7 +19,7 @@ const { name, image, description, apply, github, youtube } = Astro.props;
1819
<>
1920
{github && (
2021
<button
21-
class="member-github-link px-4 py-2 flex items-center gap-2 border border-(--background-lightest) rounded-lg cursor-pointer transition-all duration-200 ease-in-out hover:bg-(--background) hover:brightness-125"
22+
class="member-github-link px-4 py-2 flex items-center gap-2 border border-(--background-lightest) rounded-lg cursor-pointer transition-all duration-200 ease-in-out hover:bg-(--background-lighter) hover:brightness-125"
2223
data-github={github}
2324
>
2425
<Github class="w-6 h-6" />
@@ -27,20 +28,29 @@ const { name, image, description, apply, github, youtube } = Astro.props;
2728
)}
2829
{youtube && (
2930
<button
30-
class="member-youtube-link px-4 py-2 flex items-center gap-2 border border-(--background-lightest) rounded-lg cursor-pointer transition-all duration-200 ease-in-out hover:bg-(--background) hover:brightness-125"
31+
class="member-youtube-link px-4 py-2 flex items-center gap-2 border border-(--background-lightest) rounded-lg cursor-pointer transition-all duration-200 ease-in-out hover:bg-(--background-lighter) hover:brightness-125"
3132
data-youtube={youtube}
3233
>
3334
<Youtube class="w-6 h-6" />
3435
<p>YouTube</p>
3536
</button>
3637
)}
38+
{twitch && (
39+
<button
40+
class="member-twitch-link px-4 py-2 flex items-center gap-2 border border-(--background-lightest) rounded-lg cursor-pointer transition-all duration-200 ease-in-out hover:bg-(--background-lighter) hover:brightness-125"
41+
data-twitch={twitch}
42+
>
43+
<Twitch class="w-6 h-6" />
44+
<p>Twitch</p>
45+
</button>
46+
)}
3747
</>
3848
)
3949
}
4050
{
4151
apply && (
4252
<button
43-
class="member-apply-link px-4 py-2 flex items-center gap-2 border border-(--background-lightest) rounded-lg cursor-pointer transition-all duration-200 ease-in-out hover:bg-(--background) hover:brightness-125"
53+
class="member-apply-link px-4 py-2 flex items-center gap-2 border border-(--background-lightest) rounded-lg cursor-pointer transition-all duration-200 ease-in-out hover:bg-(--background-lighter) hover:brightness-125"
4454
data-apply={apply}
4555
>
4656
<Paperclip class="w-6 h-6" />
@@ -75,4 +85,13 @@ const { name, image, description, apply, github, youtube } = Astro.props;
7585
}
7686
});
7787
});
88+
89+
document.querySelectorAll(".member-twitch-link").forEach((btn) => {
90+
btn.addEventListener("click", () => {
91+
const twitch = (btn as HTMLElement).dataset.twitch;
92+
if (twitch) {
93+
window.open(`https://twitch.tv/${twitch}`, "_blank");
94+
}
95+
});
96+
});
7897
</script>

src/components/Project.astro

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,46 @@
11
---
22
import { Github } from "@lucide/astro";
33
4-
const { name, description, path } = Astro.props;
4+
const { name, languages, description, path } = Astro.props;
5+
6+
function getColor(language: string) {
7+
switch (language.toLowerCase()) {
8+
case "java":
9+
return "#b07219";
10+
case "go":
11+
return "#00add8";
12+
case "c++":
13+
return "#f34b7d";
14+
case "astro":
15+
return "#9933ff";
16+
default:
17+
return "#999999";
18+
}
19+
}
520
---
621

722
<div
823
class="relative w-full sm:w-full md:w-[calc(50%-0.75rem)] lg:w-[calc(25%-0.75rem)] p-8 flex flex-col gap-4 bg-(--background-light) border border-(--background-lightest) rounded-lg"
924
>
10-
<p class="text-xl font-semibold">{name}</p>
25+
<div class="flex gap-2">
26+
<p class="text-xl font-semibold">{name}</p>
27+
{
28+
languages.map((language: string) => (
29+
<p
30+
class="px-2 rounded-lg text-white"
31+
style={`background-color: ${getColor(language)}`}
32+
>
33+
{language}
34+
</p>
35+
))
36+
}
37+
</div>
1138
<div class="mb-16">
12-
<p>Description:</p>
1339
<p>{description}</p>
1440
</div>
1541
<div class="absolute bottom-8">
1642
<button
17-
class="project-github-link px-4 py-2 flex items-center gap-2 border border-(--background-lightest) rounded-lg cursor-pointer transition-all duration-200 ease-in-out hover:bg-(--background) hover:brightness-125"
43+
class="project-github-link px-4 py-2 flex items-center gap-2 border border-(--background-lightest) rounded-lg cursor-pointer transition-all duration-200 ease-in-out hover:bg-(--background-lighter) hover:brightness-125"
1844
data-path={path}
1945
>
2046
<Github class="w-6 h-6" />

src/layouts/Layout.astro

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@ import Footer from "../components/Footer.astro";
1111
<meta name="viewport" content="width=device-width" />
1212
<link rel="icon" type="image/ico" href="/favicon.ico" />
1313
<meta name="generator" content={Astro.generator} />
14+
<meta
15+
http-equiv="Content-Security-Policy"
16+
content="frame-src 'self' https://challenges.cloudflare.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://challenges.cloudflare.com; child-src 'self' https://challenges.cloudflare.com;"
17+
/>
1418
<title>Nexoscript</title>
1519
</head>
1620
<body class="w-screen min-h-screen flex flex-col gap-8 bg-(--background)">
17-
<Header client:load />
21+
<Header />
1822
<main class="px-96 sm:px-8 md:px-16 lg:px-32 xl:px-64 flex flex-col gap-6">
1923
<slot />
2024
</main>
21-
<Footer client:load />
25+
<Footer />
2226
</body>
2327
</html>

src/pages/contact/api.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import nodemailer from "nodemailer";
2+
3+
export async function POST({ request }) {
4+
const { name, email, message, token } = await request.json();
5+
6+
const verify = await fetch(
7+
"https://challenges.cloudflare.com/turnstile/v0/siteverify",
8+
{
9+
method: "POST",
10+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
11+
body: new URLSearchParams({
12+
secret: process.env.TURNSTILE_SECRET,
13+
response: token,
14+
}),
15+
}
16+
).then((r) => r.json());
17+
18+
if (!verify.success) return new Response("Captcha failed", { status: 403 });
19+
20+
const transporter = nodemailer.createTransport({
21+
host: "smtp.example.com",
22+
port: 587,
23+
secure: false,
24+
auth: {
25+
user: process.env.SMTP_USER,
26+
pass: process.env.SMTP_PASS,
27+
},
28+
});
29+
30+
await transporter.sendMail({
31+
from: `"Nexoscript Contact" <${process.env.SMTP_USER}>`,
32+
33+
subject: `Contact from ${name}`,
34+
text: `Email: ${email}\n\n${message}`,
35+
});
36+
37+
return new Response(JSON.stringify({ success: true }), { status: 200 });
38+
}

src/pages/index.astro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
import Layout from "../layouts/Layout.astro";
33
import About from "../sections/About.astro";
4+
import Contact from "../sections/Contact.astro";
45
import Projects from "../sections/Projects.astro";
56
import Team from "../sections/Team.astro";
67
---
@@ -9,4 +10,5 @@ import Team from "../sections/Team.astro";
910
<About />
1011
<Projects />
1112
<Team />
13+
<Contact />
1214
</Layout>

0 commit comments

Comments
 (0)