Skip to content

Commit 9cc6593

Browse files
committed
feat: add multi-link support and new contribution items
1 parent 6fd0988 commit 9cc6593

File tree

4 files changed

+141
-15
lines changed

4 files changed

+141
-15
lines changed

public/Kotlin_Icon.png

195 KB
Loading

public/swiftui-256x256_2x.png

169 KB
Loading

src/App.tsx

Lines changed: 87 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -806,14 +806,20 @@ const ContributionsPage = () => {
806806
</div>
807807

808808
<div className="contributions-list">
809-
{currentItems.map((item: ContributionItem) => (
810-
<a
811-
key={item.id}
812-
href={item.redirectionLink}
813-
target="_blank"
814-
rel="noopener noreferrer"
815-
className="contribution-card-link"
816-
>
809+
{currentItems.map((item: ContributionItem) => {
810+
const hasManyLinks = item.redirectionLinks.length > 1;
811+
812+
const getLinkLabel = (url: string) => {
813+
try {
814+
const hostname = new URL(url).hostname.replace('www.', '');
815+
if (hostname.includes('youtube')) return 'YouTube';
816+
if (hostname.includes('github')) return 'GitHub';
817+
const parts = hostname.split('.');
818+
return parts.length > 1 ? parts.slice(0, -1).join('.') : hostname;
819+
} catch { return 'Link'; }
820+
};
821+
822+
const cardContent = (
817823
<GlassCard hover className="contribution-card">
818824
<div className="contribution-image-wrapper">
819825
<img src={`/${item.imageUrl}`} alt={item.title} className="contribution-image" />
@@ -828,13 +834,48 @@ const ContributionsPage = () => {
828834
<h3 className="contribution-title">{item.title}</h3>
829835
<p className="contribution-card-subtitle">{item.subtitle}</p>
830836
<p className="contribution-description">{item.description}</p>
831-
<span className="contribution-read-more">
832-
Read More <ArrowRight size={16} />
833-
</span>
837+
{hasManyLinks ? (
838+
<div className="contribution-links">
839+
{item.redirectionLinks.map((link, idx) => (
840+
<a
841+
key={idx}
842+
href={link}
843+
target="_blank"
844+
rel="noopener noreferrer"
845+
className="contribution-link-btn"
846+
onClick={(e) => e.stopPropagation()}
847+
>
848+
<Link size={14} />
849+
{getLinkLabel(link)}
850+
<ArrowRight size={14} />
851+
</a>
852+
))}
853+
</div>
854+
) : (
855+
<span className="contribution-read-more">
856+
Read More <ArrowRight size={16} />
857+
</span>
858+
)}
834859
</div>
835860
</GlassCard>
836-
</a>
837-
))}
861+
);
862+
863+
if (hasManyLinks) {
864+
return <div key={item.id} className="contribution-card-link">{cardContent}</div>;
865+
}
866+
867+
return (
868+
<a
869+
key={item.id}
870+
href={item.redirectionLinks[0]}
871+
target="_blank"
872+
rel="noopener noreferrer"
873+
className="contribution-card-link"
874+
>
875+
{cardContent}
876+
</a>
877+
);
878+
})}
838879
</div>
839880

840881
{totalPages > 1 && (
@@ -2224,6 +2265,39 @@ const App = () => {
22242265
color: #22d3ee;
22252266
}
22262267
2268+
/* Multi-link buttons */
2269+
.contribution-links {
2270+
display: flex;
2271+
flex-wrap: wrap;
2272+
gap: 0.6rem;
2273+
margin-top: auto;
2274+
padding-top: 0.75rem;
2275+
}
2276+
2277+
.contribution-link-btn {
2278+
display: inline-flex;
2279+
align-items: center;
2280+
gap: 0.4rem;
2281+
padding: 0.45rem 1rem;
2282+
border-radius: 10px;
2283+
border: 1px solid rgba(6, 182, 212, 0.3);
2284+
background: rgba(6, 182, 212, 0.08);
2285+
color: #06b6d4;
2286+
font-size: 0.82rem;
2287+
font-weight: 600;
2288+
text-decoration: none;
2289+
transition: all 0.3s ease;
2290+
white-space: nowrap;
2291+
}
2292+
2293+
.contribution-link-btn:hover {
2294+
background: rgba(6, 182, 212, 0.2);
2295+
border-color: rgba(6, 182, 212, 0.5);
2296+
box-shadow: 0 4px 15px rgba(6, 182, 212, 0.15);
2297+
color: #22d3ee;
2298+
transform: translateY(-1px);
2299+
}
2300+
22272301
/* Pagination */
22282302
.pagination-controls {
22292303
display: flex;

src/contributionsData.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export interface ContributionItem {
66
date: string;
77
description: string;
88
imageUrl: string;
9-
redirectionLink: string;
9+
redirectionLinks: string[]; // Supports multiple links
1010
}
1111

1212
// ============================================================
@@ -16,6 +16,57 @@ export interface ContributionItem {
1616
// ============================================================
1717

1818
export const contributions: ContributionItem[] = [
19+
{
20+
id: 5,
21+
title: "Hello, SwiftUI",
22+
subtitle: "Get to know Xcode, Swift, and SwiftUI",
23+
date: "March 24, 2026",
24+
description:
25+
"You will build Chat Prototype, a chat conversation using text views. The text and colors in the project are just suggestions, so feel free to make it your own by changing the words and style.",
26+
imageUrl: "swiftui-256x256_2x.png",
27+
redirectionLinks: [
28+
"https://developer.apple.com/tutorials/develop-in-swift/hello-swiftui",
29+
],
30+
},
31+
{
32+
id: 4,
33+
title: "Flutter Learning Resources",
34+
subtitle: "A catalog of tutorials, samples, and workshops",
35+
date: "March 24, 2026",
36+
description:
37+
"An extensive collection of curated learning materials including guided Codelabs, feature-rich demo applications, instructor-led workshops, and quick-solution recipes for common development challenges.",
38+
imageUrl: "Flutter_learning_resources_dashatar.png",
39+
redirectionLinks: [
40+
"https://docs.flutter.dev/learn/learning-resources",
41+
],
42+
},
43+
{
44+
id: 3,
45+
title: "Take Kotlin Tour",
46+
subtitle:
47+
"Kotlin is a modern language that's concise, multiplatform, and interoperable with Java and other languages.",
48+
date: "March 24, 2026",
49+
description:
50+
"Understand the fundamentals of Kotlin and Jetpack Compose, Build basic Android apps, Use Jetpack libraries and modern Android development practices, Create adaptive layouts optimized for different display sizes",
51+
imageUrl: "Kotlin_Icon.png",
52+
redirectionLinks: [
53+
"https://developer.android.com/courses/android-basics-compose/course",
54+
"https://kotlinlang.org/docs/getting-started.html",
55+
],
56+
},
57+
{
58+
id: 2,
59+
title: "Flutter Tutorial",
60+
subtitle: "Build pixel-perfect applications from scratch",
61+
date: "March 24, 2026",
62+
description:
63+
"A comprehensive guide to building Flutter apps for mobile, desktop, and web. Starting from a blank canvas, you'll build several small applications to master critical framework features. Note: Requires a Flutter environment and basic Dart knowledge.",
64+
imageUrl: "Flutter_tutorial.png",
65+
redirectionLinks: [
66+
"https://docs.flutter.dev/learn/pathway/tutorial",
67+
"https://www.youtube.com/playlist?list=PL4cUxeGkcC9jLYyp2Aoh6hcWuxFDX6PBJ",
68+
],
69+
},
1970
{
2071
id: 1,
2172
title: "A Swift Tour",
@@ -24,7 +75,8 @@ export const contributions: ContributionItem[] = [
2475
description:
2576
"Get started with Apple's powerful and intuitive programming language. This guide provides a comprehensive overview of Swift's core features, from simple values and control flow to functions, closures, and object-oriented patterns. Perfect for developers looking to master the fundamentals of pure Swift through practical, hands-on examples.",
2677
imageUrl: "swift-256x256_2x.png",
27-
redirectionLink:
78+
redirectionLinks: [
2879
"https://docs.swift.org/swift-book/documentation/the-swift-programming-language/guidedtour/",
80+
],
2981
},
3082
];

0 commit comments

Comments
 (0)