Skip to content

Commit 7843a2d

Browse files
dtinthclaude[bot]
andcommitted
เพิ่มหน้าแสดงผลงานโปรเจกต์จาก Stupido Hackettino #9
- สร้าง ProjectsSection component พร้อมระบบ parse markdown สำหรับรูปภาพและลิงก์ - เพิ่ม Team interface พร้อมเอกสารประกอบใน teams.ts - อัปเดตเมนูนำทางแทนที่ "Registration" ด้วย "Projects" - แสดงทั้งหมด 14 โปรเจกต์พร้อมรูปภาพ คำอธิบาย ลิงก์ และบทวิจารณ์ของมโนราห์ - ใช้ระบบไอคอนที่เหมาะสมสำหรับลิงก์ (GitHub, Demo, Canva, Slides) Co-Authored-By: Claude <209825114+claude[bot]@users.noreply.github.com>
1 parent 592704a commit 7843a2d

4 files changed

Lines changed: 387 additions & 4 deletions

File tree

src/components/Header.astro

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ import logotype from "../assets/logotype.svg?url";
106106
<a href="#what-to-bring" class="nav-pill mr-2"> What to Bring </a>
107107
<a href="#code-of-conduct" class="nav-pill mr-2"> Code of Conduct </a>
108108
<a href="#sponsors" class="nav-pill mr-4"> Sponsors </a>
109-
<a href="#registration" class="nav-pill-solid">
110-
<span>Registration</span>
109+
<a href="#projects" class="nav-pill-solid">
110+
<span>Projects</span>
111111
<div
112112
class="ml-2 w-6 h-6 bg-blue-600 rounded-full flex items-center justify-center"
113113
>
@@ -200,10 +200,10 @@ import logotype from "../assets/logotype.svg?url";
200200

201201
<div class="mt-8">
202202
<a
203-
href="#registration"
203+
href="#projects"
204204
class="sponsor-button inline-flex items-center w-full justify-center px-6 py-3 rounded-full text-white font-semibold shadow-lg"
205205
>
206-
<span>Registration</span>
206+
<span>Projects</span>
207207
<svg
208208
class="ml-2 w-4 h-4"
209209
fill="none"
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
import { teams } from "../data/teams";
3+
4+
// Function to extract image URL from markdown format ![alt](url)
5+
function extractImageUrl(imageMarkdown: string): string {
6+
const match = imageMarkdown.match(/!\[.*?\]\((.*?)\)/);
7+
return match ? match[1] : "";
8+
}
9+
10+
// Function to parse links from markdown format [Label](url)
11+
function parseLinks(linksMarkdown: string): Array<{label: string, url: string, icon: string}> {
12+
if (!linksMarkdown.trim()) return [];
13+
14+
const linkPattern = /\[([^\]]+)\]\(([^)]+)\)/g;
15+
const links: Array<{label: string, url: string, icon: string}> = [];
16+
let match;
17+
18+
while ((match = linkPattern.exec(linksMarkdown)) !== null) {
19+
const label = match[1];
20+
const url = match[2];
21+
22+
// Map link types to icons
23+
let icon = "mdi:link"; // default
24+
if (label.toLowerCase().includes("github")) {
25+
icon = "mdi:github";
26+
} else if (label.toLowerCase().includes("demo")) {
27+
icon = "mdi:play-circle";
28+
} else if (label.toLowerCase().includes("canva")) {
29+
icon = "mdi:palette";
30+
} else if (label.toLowerCase().includes("slides")) {
31+
icon = "mdi:presentation";
32+
}
33+
34+
links.push({ label, url, icon });
35+
}
36+
37+
return links;
38+
}
39+
---
40+
41+
<section id="projects" class="w-full bg-black pt-24 pb-16">
42+
<div class="max-w-6xl mx-auto px-8">
43+
<h2
44+
class="text-4xl md:text-7xl text-white mb-6 text-center tracking-wide font-display scroll-animate fade-down"
45+
>
46+
PROJECTS
47+
</h2>
48+
49+
<div
50+
class="inline-block text-white px-6 py-3 rounded-lg mb-12 text-xl md:text-2xl font-medium transform -rotate-2 bg-[#19806f] scroll-animate bounce-up stagger-1 mx-auto block text-center"
51+
style="font-family: 'K2D', sans-serif;"
52+
>
53+
ผลงานแห่งความเพี้ยน 🎨
54+
</div>
55+
56+
<div class="grid md:grid-cols-2 gap-8 max-w-6xl mx-auto">
57+
{
58+
teams.map((team, index) => {
59+
const imageUrl = extractImageUrl(team.project.image);
60+
const links = parseLinks(team.project.links);
61+
62+
return (
63+
<div
64+
class={`bg-gray-900 rounded-xl border border-gray-800 hover:border-[#19806f] transition-all duration-300 overflow-hidden scroll-animate fade-up stagger-${index + 2}`}
65+
>
66+
{/* Project Image */}
67+
{imageUrl && (
68+
<div class="aspect-[1200/630] overflow-hidden">
69+
<img
70+
src={imageUrl}
71+
alt={team.project.name}
72+
class="w-full h-full object-cover hover:scale-105 transition-transform duration-300"
73+
/>
74+
</div>
75+
)}
76+
77+
{/* Content */}
78+
<div class="p-6">
79+
{/* Project Name & Team */}
80+
<div class="mb-4">
81+
<h3
82+
class="text-xl font-bold text-white mb-2"
83+
style="font-family: 'K2D', sans-serif;"
84+
>
85+
{team.project.name}
86+
</h3>
87+
<p class="text-[#19806f] font-medium text-sm">
88+
by {team.name}
89+
</p>
90+
</div>
91+
92+
{/* Description */}
93+
<p class="text-gray-300 leading-relaxed mb-4 text-sm">
94+
{team.project.description.length > 200
95+
? team.project.description.substring(0, 200) + "..."
96+
: team.project.description
97+
}
98+
</p>
99+
100+
{/* Links */}
101+
{links.length > 0 && (
102+
<div class="flex flex-wrap gap-3 mb-4">
103+
{links.map((link) => (
104+
<a
105+
href={link.url}
106+
target="_blank"
107+
rel="noopener noreferrer"
108+
class="inline-flex items-center gap-2 px-3 py-2 bg-gray-800 hover:bg-[#19806f] text-white text-sm rounded-lg transition-colors"
109+
>
110+
<iconify-icon icon={link.icon} class="text-lg"></iconify-icon>
111+
{link.label}
112+
</a>
113+
))}
114+
</div>
115+
)}
116+
117+
{/* Manorah Commentary */}
118+
<div class="border-t border-gray-800 pt-4 mt-4">
119+
<div class="flex items-start gap-3">
120+
<iconify-icon
121+
icon="mdi:drama-masks"
122+
class="text-[#19806f] text-xl mt-1 flex-shrink-0"
123+
></iconify-icon>
124+
<div>
125+
<h4 class="text-[#19806f] font-semibold text-sm mb-2" style="font-family: 'K2D', sans-serif;">
126+
มโนราห์ว่าไง
127+
</h4>
128+
<p class="text-gray-300 text-sm leading-relaxed italic">
129+
{team.manorah}
130+
</p>
131+
</div>
132+
</div>
133+
</div>
134+
</div>
135+
</div>
136+
);
137+
})
138+
}
139+
</div>
140+
</div>
141+
</section>

0 commit comments

Comments
 (0)