Skip to content

Commit 8a123dc

Browse files
Merge pull request #612 from DeveloperAmrit/revamp-4
Revamped AOSSIE website
2 parents 8f344f8 + 41cb46e commit 8a123dc

File tree

100 files changed

+2452
-1368
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+2452
-1368
lines changed

package-lock.json

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

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"dev": "next dev",
77
"build": "next build",
88
"start": "next start",
9-
"lint": "next lint"
9+
"lint": "next lint",
10+
"disable-telemetry": "npx next telemetry disable"
1011
},
1112
"author": "AOSSIE",
1213
"license": "ISC",
@@ -18,14 +19,14 @@
1819
"@fortawesome/free-brands-svg-icons": "^6.2.1",
1920
"@fortawesome/free-regular-svg-icons": "^6.2.1",
2021
"@fortawesome/free-solid-svg-icons": "^6.2.1",
21-
"@fortawesome/react-fontawesome": "^0.2.0",
22+
"@fortawesome/react-fontawesome": "^3.1.1",
2223
"@headlessui/react": "^1.7.2",
2324
"@mapbox/rehype-prism": "^0.8.0",
2425
"@mdx-js/loader": "^2.3.0",
2526
"@mdx-js/react": "^2.3.0",
2627
"@mui/icons-material": "^6.4.1",
2728
"@mui/material": "^6.4.1",
28-
"@next/mdx": "^13.5.6",
29+
"@next/mdx": "^14.1.3",
2930
"@tailwindcss/typography": "^0.5.4",
3031
"@types/mdx": "^2.0.11",
3132
"autoprefixer": "^10.4.12",
@@ -34,7 +35,7 @@
3435
"fast-glob": "^3.2.11",
3536
"feed": "^4.2.2",
3637
"focus-visible": "^5.2.0",
37-
"framer-motion": "^12.0.6",
38+
"framer-motion": "^12.30.0",
3839
"next": "^14.1.3",
3940
"postcss-focus-visible": "^6.0.4",
4041
"react": "^18.2.0",

src/app/about/page.jsx

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
'use client'
2+
3+
import { useState, useEffect } from 'react';
4+
import Image from 'next/image';
5+
import { Container } from '@/components/shared/Container';
6+
import { Banner } from '@/components/shared/Banner';
7+
import { Timeline } from '@/components/about/Timeline';
8+
import { Team } from '@/components/about/Team';
9+
import React from 'react';
10+
import { Line } from 'react-chartjs-2';
11+
import { Chart as ChartJS, LineElement, CategoryScale, LinearScale, PointElement } from 'chart.js';
12+
import { motion } from 'framer-motion';
13+
14+
ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement);
15+
16+
export default function About() {
17+
const [stats, setStats] = useState({
18+
years: 8,
19+
projects: 80,
20+
contributors: 70,
21+
graphData: {
22+
labels: ['2016', '2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024'],
23+
data: [4, 8, 12, 9, 9, 11, 8, 6, 18]
24+
}
25+
});
26+
27+
// Detect dark mode preference on page load and fetch stats
28+
useEffect(() => {
29+
const fetchStats = async () => {
30+
try {
31+
const res = await fetch('/api/stats');
32+
const data = await res.json();
33+
if (!data.error) {
34+
setStats(data);
35+
}
36+
} catch (error) {
37+
console.error('Failed to fetch stats:', error);
38+
}
39+
};
40+
41+
fetchStats();
42+
}, []);
43+
44+
const data = {
45+
labels: ['2016', '2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025'], // Include '0' on the x-axis
46+
datasets: [
47+
{
48+
label: 'Number of Completed Projects',
49+
data: [4, 8, 12, 9, 9, 11, 8, 6, 18, 22], // Start data points from '2017', leave '0' as null
50+
fill: false,
51+
borderColor: '#32a852',
52+
tension: 0.4,
53+
},
54+
],
55+
};
56+
57+
const options = {
58+
responsive: true,
59+
maintainAspectRatio: false,
60+
plugins: {
61+
legend: {
62+
display: false,
63+
},
64+
},
65+
scales: {
66+
x: {
67+
type: 'category',
68+
grid: {
69+
display: true,
70+
color: '#FFCC00',
71+
},
72+
ticks: {
73+
callback: (value, index) => data.labels[index], // Match x-axis labels
74+
},
75+
},
76+
y: {
77+
beginAtZero: true, // Start y-axis from 0
78+
ticks: {
79+
stepSize: 5, // Increment y-axis labels by 5
80+
},
81+
grid: {
82+
display: true,
83+
color: '#FFCC00',
84+
},
85+
},
86+
},
87+
};
88+
89+
return (
90+
<>
91+
<Container className="mt-4 sm:mt-16 mb-20">
92+
<div className="max-w-4xl mx-auto px-4 text-center">
93+
<div className="my-8">
94+
<motion.h1
95+
className="text-4xl md:text-5xl font-mono font-black text-[#32a852]"
96+
initial={{ opacity: 0, y: -20 }}
97+
animate={{ opacity: 1, y: 0 }}
98+
transition={{ duration: 0.8 }}
99+
>
100+
ABOUT US
101+
</motion.h1>
102+
<motion.p
103+
className="text-base md:text-lg leading-relaxed text-zinc-600 dark:text-zinc-400 font-mono mt-5 mb-10 text-center"
104+
initial={{ opacity: 0 }}
105+
animate={{ opacity: 1 }}
106+
transition={{ duration: 0.8, delay: 0.2 }}
107+
>
108+
<span className="text-[#32a852] font-bold">AOSSIE</span> (Australian Open
109+
Source Software Innovation and Education) is a not-for-profit
110+
umbrella organization for open-source projects. We believe the
111+
open-source philosophy provides a resource-efficient channel to
112+
transfer knowledge and achieve innovation and education.
113+
</motion.p>
114+
</div>
115+
116+
<div className="my-8 space-y-12">
117+
<motion.div
118+
className="w-full h-[300px] md:h-[400px]"
119+
initial={{ opacity: 0, scale: 0.95 }}
120+
whileInView={{ opacity: 1, scale: 1 }}
121+
viewport={{ once: true }}
122+
transition={{ duration: 0.5 }}
123+
>
124+
<Line data={data} options={options} />
125+
</motion.div>
126+
127+
<motion.div
128+
className="flex flex-wrap justify-around gap-6 mt-8"
129+
initial="hidden"
130+
whileInView="show"
131+
viewport={{ once: true }}
132+
variants={{
133+
hidden: { opacity: 0 },
134+
show: {
135+
opacity: 1,
136+
transition: {
137+
staggerChildren: 0.2
138+
}
139+
}
140+
}}
141+
>
142+
{/* Stats Cards */}
143+
{[
144+
{ value: stats.years, label: 'years completed' },
145+
{ value: stats.projects, label: 'projects completed' },
146+
{ value: `${stats.contributors}+`, label: 'contributors' }
147+
].map((item, index) => (
148+
<motion.div
149+
key={index}
150+
variants={{
151+
hidden: { opacity: 0, y: 20 },
152+
show: { opacity: 1, y: 0 }
153+
}}
154+
className="bg-white dark:bg-zinc-800 p-6 rounded-xl shadow-lg w-full sm:w-48 lg:w-56 cursor-pointer transform hover:scale-105 transition-transform duration-300"
155+
>
156+
<div className="text-4xl font-bold text-[#32a852]">{item.value}</div>
157+
<div className="text-lg text-zinc-600 dark:text-zinc-400 mt-1">{item.label}</div>
158+
</motion.div>
159+
))}
160+
</motion.div>
161+
</div>
162+
</div>
163+
164+
<motion.div
165+
className="mt-20"
166+
initial={{ opacity: 0 }}
167+
whileInView={{ opacity: 1 }}
168+
viewport={{ once: true }}
169+
transition={{ duration: 0.8 }}
170+
>
171+
<Timeline />
172+
</motion.div>
173+
174+
<motion.div
175+
className="mt-24 mb-24"
176+
initial={{ opacity: 0 }}
177+
whileInView={{ opacity: 1 }}
178+
viewport={{ once: true }}
179+
transition={{ duration: 0.8 }}
180+
>
181+
<Team />
182+
</motion.div>
183+
</Container>
184+
</>
185+
);
186+
}

src/app/api/stats/route.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { NextResponse } from 'next/server';
2+
import projects from '@/helper/projects';
3+
4+
export async function GET() {
5+
try {
6+
const startYear = 2016;
7+
const currentYear = new Date().getFullYear();
8+
const yearsOfAossie = currentYear - startYear;
9+
10+
// Count projects from the helper file as requested
11+
const completedProjectsCount = projects.length;
12+
13+
// Fetch GitHub Data
14+
// Note: Unauthenticated requests are limited to 60 per hour per IP.
15+
const orgs = ['AOSSIE-Org'];
16+
const headers = {
17+
'Accept': 'application/vnd.github.v3+json',
18+
// Add 'Authorization': `token ${process.env.GITHUB_TOKEN}` if you have one
19+
};
20+
21+
// 1. Fetch Repositories
22+
const reposPromises = orgs.map(async (org) => {
23+
const res = await fetch(`https://api.github.com/orgs/${org}/repos?per_page=100&type=public`, { headers, next: { revalidate: 3600 } });
24+
if (!res.ok) {
25+
console.error(`Failed to fetch repos for ${org}: ${res.statusText}`);
26+
return [];
27+
}
28+
return res.json();
29+
});
30+
31+
const reposArrays = await Promise.all(reposPromises);
32+
const repos = reposArrays.flat();
33+
34+
// 2. Process for Graph (Repos per year)
35+
// The user wants "Number of repos in (green) over the past years".
36+
// We will group by 'created_at'.
37+
const repoCountsByYear = {};
38+
const yearsSet = new Set();
39+
40+
// Initialize years from startYear to currentYear to ensure continuous axis
41+
for (let y = startYear; y <= currentYear; y++) {
42+
repoCountsByYear[y] = 0;
43+
yearsSet.add(y);
44+
}
45+
46+
repos.forEach(repo => {
47+
const year = new Date(repo.created_at).getFullYear();
48+
if (year >= startYear) {
49+
repoCountsByYear[year] = (repoCountsByYear[year] || 0) + 1;
50+
}
51+
});
52+
53+
const labels = Object.keys(repoCountsByYear).sort((a, b) => parseInt(a) - parseInt(b));
54+
const data = labels.map(year => repoCountsByYear[year]);
55+
56+
57+
// 3. Count Contributors
58+
// Fetching contributors for ALL repos consumes too much rate limit (N requests).
59+
// We will proactively fetch contributors for the top 6 most starred/popular repos to get a good estimate.
60+
// Sorting repos by stargazers_count
61+
const topRepos = repos.sort((a, b) => b.stargazers_count - a.stargazers_count).slice(0, 6);
62+
63+
const contributorIds = new Set();
64+
65+
const contributorPromises = topRepos.map(async (repo) => {
66+
try {
67+
const contribRes = await fetch(repo.contributors_url + '?per_page=100', { headers, next: { revalidate: 3600 } });
68+
if (contribRes.ok) {
69+
const contributors = await contribRes.json();
70+
if (Array.isArray(contributors)) {
71+
contributors.forEach(c => contributorIds.add(c.id));
72+
}
73+
}
74+
} catch (e) {
75+
console.error(`Failed to fetch contributors for ${repo.name}`, e);
76+
}
77+
});
78+
79+
await Promise.all(contributorPromises);
80+
81+
// Fallback if APIs fail or return 0 (which is unlikely for top repos)
82+
const contributorCount = contributorIds.size > 0 ? contributorIds.size : 70;
83+
84+
return NextResponse.json({
85+
years: yearsOfAossie,
86+
projects: completedProjectsCount,
87+
contributors: contributorCount,
88+
graphData: {
89+
labels,
90+
data
91+
}
92+
});
93+
94+
} catch (error) {
95+
console.error('API Error:', error);
96+
return NextResponse.json({ error: error.message }, { status: 500 });
97+
}
98+
}

src/app/apply/page.jsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import Image from 'next/image'
2+
import Link from 'next/link'
3+
4+
import { Container } from '@/components/shared/Container'
5+
import { TimelineElement } from '@/components/about/TimelineElement'
6+
import { ApplyHeader } from '@/components/apply/ApplyHeader'
7+
import GSoC from '@/images/logo.svg'
8+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
9+
import { faDiscord, faGitlab } from '@fortawesome/free-brands-svg-icons'
10+
import { faLightbulb, faComments, faPaperPlane } from '@fortawesome/free-solid-svg-icons'
11+
12+
export const metadata = {
13+
title: 'Application Timeline',
14+
description: 'How to apply for GSOC',
15+
}
16+
17+
export default function Apply() {
18+
return (
19+
<>
20+
<ApplyHeader>
21+
<ol className="relative border-l-2 border-gray-200 dark:border-gray-700">
22+
<TimelineElement
23+
title="Join us on Discord"
24+
description="Join the AOSSIE community on Discord and connect with other developers, mentors, and organizers. Our Discord server is a great place to ask questions, share ideas, and get support throughout the Google Summer of Code application process. From proposal writing tips to coding advice, our community is here to help you succeed. Don't go through the process alone, join us on Discord now!"
25+
button="Join Discord"
26+
link="https://discord.gg/hjUhu33uAn"
27+
/>
28+
<TimelineElement
29+
title="Start Contributing"
30+
description="Contribute to the project and make your mark on open-source development with AOSSIE. By making a Pull Request (PR) to one of our existing projects, you'll have the opportunity to showcase your skills and demonstrate your understanding of the project. This will also give you an opportunity to work with the mentors and get familiar with the project before the official GSoC coding period starts. This is a great way to get started and increase your chances of being selected for the program."
31+
button="Contribute"
32+
link="https://gitlab.com/aossie"
33+
/>
34+
<TimelineElement
35+
title="Write a Draft Application"
36+
description="Select an Idea and write a draft application that expands this idea with your own proposals and showcases how you will execute and complete your project. This is your chance to demonstrate your understanding of the project, your skills, and your passion for open-source development. Our mentors will provide feedback and help you refine your proposal, increasing your chances of being selected for the program."
37+
button="Choose an Idea"
38+
link="/ideas"
39+
/>
40+
<TimelineElement
41+
title="Discuss with Mentors"
42+
description="Share your draft application with our mentors and get feedback on your proposal. Our mentors are experienced developers who have been through the GSoC process before and can provide valuable insights to help you improve your application. Discussing your proposal with mentors also demonstrates your commitment to the project and your willingness to learn and improve."
43+
button="Mentors List"
44+
link="https://github.com/orgs/AOSSIE-Org/people"
45+
/>
46+
<TimelineElement
47+
title="Submit Application"
48+
description="Submit your final application to Google Summer of Code before the deadline. Make sure to double-check your application and ensure that you have included all the necessary information. Good luck!"
49+
button="Apply Now"
50+
link="https://summerofcode.withgoogle.com/"
51+
/>
52+
</ol>
53+
</ApplyHeader>
54+
</>
55+
)
56+
}

src/pages/ideas/2022/agora-blockchain.mdx renamed to src/app/ideas/2022/agora-blockchain/page.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { IdeaLayout } from '@/components/IdeaLayout'
1+
import { IdeaLayout } from '@/components/ideas/IdeaLayout'
22

33
export const meta = {
44
title: 'Agora Blockchain',
55
description:
66
'First version of Blockchain based Agora web application, with basic features like user registration, election creation, voting and result calculation.',
77
}
88

9-
export default (props) => <IdeaLayout meta={meta} {...props} />
9+
export default ({ children }) => <IdeaLayout meta={meta}>{children}</IdeaLayout>
1010

1111
### Project Duration: 175 hrs
1212

0 commit comments

Comments
 (0)