├── components ├── ui │ ├── Gallery │ │ ├── index.ts │ │ └── Gallery.tsx │ ├── line-shadow-text.tsx │ ├── aurora-text.tsx │ ├── blur-fade.tsx │ ├── shine-border.tsx │ └── select.tsx ├── auth │ └── LoginWithGithub.tsx ├── Loader.tsx └── main │ ├── Footer.tsx │ ├── Pagination.tsx │ ├── Navbar.tsx │ ├── OrganizationCard.tsx │ └── GsocGuide.tsx ├── app ├── favicon.ico ├── (dashboard) │ ├── roadmap │ │ └── page.tsx │ ├── issues │ │ └── page.tsx │ ├── layout.tsx │ ├── starred │ │ └── page.tsx │ └── organizations │ │ ├── [org] │ │ └── page.tsx │ │ └── page.tsx ├── api │ ├── all-years │ │ └── route.ts │ ├── one-org-data │ │ └── route.ts │ └── orgs-data │ │ └── route.ts └── (root) │ ├── layout.tsx │ └── page.tsx ├── public ├── image.png └── gsoc-orgs-with-years-git - Copy.csv ├── fonts └── font.ts ├── postcss.config.mjs ├── lib └── utils.ts ├── db ├── db.ts └── Connect.ts ├── utils ├── cn.ts └── technologies.ts ├── next.config.ts ├── models ├── user.model.ts └── starred.model.ts ├── components.json ├── hooks └── use-mobile.tsx ├── .gitignore ├── eslint.config.mjs ├── tsconfig.json ├── README.md ├── package.json ├── styles └── globals.css └── tailwind.config.ts /components/ui/Gallery/index.ts: -------------------------------------------------------------------------------- 1 | export { Gallery } from "./Gallery"; 2 | 3 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayushsharma74/HackToGSoC/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /public/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayushsharma74/HackToGSoC/HEAD/public/image.png -------------------------------------------------------------------------------- /public/gsoc-orgs-with-years-git - Copy.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayushsharma74/HackToGSoC/HEAD/public/gsoc-orgs-with-years-git - Copy.csv -------------------------------------------------------------------------------- /fonts/font.ts: -------------------------------------------------------------------------------- 1 | import { Jura } from "next/font/google"; 2 | 3 | export const jura = Jura({ 4 | weight: "400", 5 | style: "normal", 6 | subsets: ["latin"], 7 | }); -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /db/db.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from "@prisma/client"; 2 | 3 | declare global { 4 | var prisma: PrismaClient | undefined; 5 | } 6 | 7 | export const db = global.prisma || new PrismaClient() 8 | 9 | -------------------------------------------------------------------------------- /utils/cn.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /app/(dashboard)/roadmap/page.tsx: -------------------------------------------------------------------------------- 1 | import GSOCGuide from '@/components/main/GsocGuide' 2 | import React from 'react' 3 | 4 | const Roadmap = () => { 5 | return ( 6 | 7 | ) 8 | } 9 | 10 | export default Roadmap -------------------------------------------------------------------------------- /components/auth/LoginWithGithub.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | import React from 'react' 3 | 4 | const LoginWithGithub = () => { 5 | return ( 6 |
7 |

Login with github

8 |
9 | ) 10 | } 11 | 12 | export default LoginWithGithub -------------------------------------------------------------------------------- /app/(dashboard)/issues/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | 4 | 5 | const page = () => { 6 | return ( 7 |
8 |

9 | Under Development.... 10 |

11 |
12 | ) 13 | } 14 | 15 | export default page -------------------------------------------------------------------------------- /next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | /* config options here */ 5 | images: { 6 | remotePatterns: [ 7 | { 8 | protocol: 'https', 9 | hostname: '*', 10 | port: '', 11 | pathname: '/**', 12 | }, 13 | ], 14 | }, 15 | }; 16 | 17 | export default nextConfig; 18 | -------------------------------------------------------------------------------- /db/Connect.ts: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | const {MONGODB_URI} = process.env 3 | 4 | export const connectDB = async () => { 5 | try { 6 | const {connection} = await mongoose.connect(MONGODB_URI as string) 7 | console.log("MongoDb connected", connection.port); 8 | if (connection.readyState === 1) { 9 | return Promise.resolve(true); 10 | } 11 | } catch (error) { 12 | console.log(error) 13 | return Promise.reject(error) 14 | } 15 | } -------------------------------------------------------------------------------- /models/user.model.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema } from "mongoose" 2 | 3 | 4 | interface UserDocument { 5 | name: string, 6 | email: string, 7 | password: string 8 | } 9 | 10 | const userSchema = new Schema({ 11 | name: { 12 | type: String 13 | }, 14 | email: { 15 | type: String 16 | }, 17 | password: { 18 | type: String 19 | } 20 | }) 21 | 22 | export const User = mongoose.models?.User || mongoose.model('User', userSchema) -------------------------------------------------------------------------------- /models/starred.model.ts: -------------------------------------------------------------------------------- 1 | import mongoose, {ObjectId, Schema} from "mongoose"; 2 | 3 | interface StarredDocument { 4 | orgs: string 5 | starredBy: ObjectId 6 | } 7 | 8 | 9 | const StarredSchmema = new Schema({ 10 | orgs : [{ 11 | type: String 12 | }], 13 | starredBy: { 14 | type: mongoose.Types.ObjectId, 15 | ref: 'user' 16 | } 17 | }) 18 | 19 | const Starred = mongoose.models.Starred || mongoose.model('Starred', StarredSchmema) 20 | export default Starred -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "styles/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /hooks/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env* 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | const compat = new FlatCompat({ 9 | baseDirectory: __dirname, 10 | }); 11 | 12 | const eslintConfig = [ 13 | ...compat.extends("next/core-web-vitals", "next/typescript"), 14 | { 15 | rules: { 16 | "@typescript-eslint/no-unused-vars": "off", 17 | "@typescript-eslint/no-explicit-any": "off", 18 | "@typescript-eslint/no-non-null-assertion": "off" 19 | } 20 | } 21 | ]; 22 | 23 | export default eslintConfig; 24 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HackToGSoC Organizations Dashboard 2 | 3 | Welcome to the HackToGSoC Organizations Dashboard! This platform showcases organizations participating in HackToGSoC. 4 | 5 | ## Features 6 | - **List of Organizations**: Browse through various organizations involved in the event. 7 | - **Contribution Guidelines**: Get the organization's guidelines for contributing to their open-source projects. 8 | - **Repositories**: Access a list of repositories available for contributions. 9 | 10 | ## How to Contribute 11 | 1. Browse the list of organizations. 12 | 2. Check their repositories and guidelines. 13 | 3. Fork, contribute, and make a pull request to participate in HackToGSoC! 14 | 15 | For more details, visit the [HackToGSoC website](https://hacktogsoc.vercel.app/organizations). 16 | -------------------------------------------------------------------------------- /components/Loader.tsx: -------------------------------------------------------------------------------- 1 | export function Loader() { 2 | return ( 3 |
16 | ); 17 | } -------------------------------------------------------------------------------- /app/api/all-years/route.ts: -------------------------------------------------------------------------------- 1 | // app/api/all-years/route.ts 2 | import { NextRequest, NextResponse } from 'next/server'; 3 | import fs from 'fs'; 4 | import path from 'path'; 5 | 6 | export async function GET(req: NextRequest) { 7 | try { 8 | const jsonDirectory = path.join(process.cwd(), 'public', 'gsoc_orgs_json'); 9 | const filenames = fs.readdirSync(jsonDirectory); 10 | 11 | const years = filenames 12 | .filter(filename => filename.endsWith('.json') && /^\d{4}\.json$/.test(filename)) 13 | .map(filename => parseInt(filename.slice(0, 4))) 14 | .sort((a, b) => a - b); // Sort the years in ascending order 15 | 16 | return NextResponse.json({ years }); 17 | } catch (error: any) { 18 | console.error("Failed to read years:", error); 19 | return NextResponse.json({ error: "Failed to load available years." }, { status: 500 }); 20 | } 21 | } -------------------------------------------------------------------------------- /app/(dashboard)/layout.tsx: -------------------------------------------------------------------------------- 1 | import "@/styles/globals.css" 2 | import { jura } from "@/fonts/font"; 3 | import Navbar from "@/components/main/Navbar"; 4 | import { Metadata } from "next"; 5 | import Footer from "@/components/main/Footer"; 6 | import { Analytics } from "@vercel/analytics/react"; 7 | 8 | export const metadata: Metadata = { 9 | title: "HackToGSoC | Dashboard", 10 | description: "An app to simplify gsoc contributions", 11 | }; 12 | 13 | export default function RootLayout({ 14 | children, 15 | }: Readonly<{ 16 | children: React.ReactNode; 17 | }>) { 18 | return ( 19 | 20 | 21 | 22 | 23 |
24 | 25 | {children} 26 |
27 |
28 | 29 | 30 | ); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /app/api/one-org-data/route.ts: -------------------------------------------------------------------------------- 1 | import { NextRequest, NextResponse } from "next/server"; 2 | import fs from "fs" 3 | import path from "path"; 4 | import { parse } from "csv-parse/sync"; 5 | 6 | 7 | export async function GET(req: NextRequest ){ 8 | const { searchParams } = new URL(req.url); 9 | const title = searchParams.get("title") 10 | const filePath = path.join(process.cwd(), 'public', 'combined_projects.json'); 11 | const fileContent = fs.readFileSync(filePath, 'utf-8'); 12 | const data = JSON.parse(fileContent); 13 | const projects = [] 14 | console.log(data); 15 | 16 | let Description: string | null = null; 17 | 18 | 19 | 20 | 21 | if(!title){ 22 | return NextResponse.json({error: "Title parameter is required"},{status:400}); 23 | } 24 | 25 | for (const item of data) { 26 | if (item.name.toLowerCase() === title.toLowerCase()) { 27 | Description = item.description; 28 | projects.push(item.projects); 29 | break; 30 | } 31 | } 32 | 33 | if(Description){ 34 | console.log(Description); 35 | return NextResponse.json({ Description , projects}); 36 | }else{ 37 | return NextResponse.json({ Description: "No Description found for the given title."}, {status:404}); 38 | } 39 | } -------------------------------------------------------------------------------- /components/ui/Gallery/Gallery.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactHTMLElement } from "react" 2 | import { cn } from "@/utils/cn" 3 | 4 | export const Gallery: React.FC> = ({ 5 | className, 6 | ...props 7 | }) => { 8 | const gallery = React.useRef(null) 9 | 10 | React.useEffect(() => { 11 | if (props.children && gallery.current) { 12 | const main = gallery.current; 13 | const items = main.children; 14 | main.style.gridTemplateRows = "10px 1fr"; 15 | main.style.gridTemplateColumns = "repeat(auto-fill, minmax(20rem, 1fr))"; 16 | for (let i = 0; i < items.length; i++){ 17 | const h = items[i].clientHeight; 18 | const rowSpan = Math.ceil(h / 10); 19 | // (items[i] as HTMLElement).style.gridRowEnd = `span ${rowSpan}`; 20 | (items[i] as HTMLElement).style.gridRowEnd = `span ${rowSpan}`; 21 | 22 | } 23 | } 24 | 25 | }, [props.children]) 26 | return ( 27 |
33 | {props.children} 34 |
35 | ) 36 | } -------------------------------------------------------------------------------- /app/(root)/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Geist, Geist_Mono } from "next/font/google"; 3 | import "@/styles/globals.css"; 4 | import Navbar from "@/components/main/Navbar"; 5 | import Footer from "@/components/main/Footer"; 6 | import { Jura } from "next/font/google"; 7 | import { Analytics } from "@vercel/analytics/react" 8 | 9 | 10 | const jura = Jura({ 11 | weight: "400", 12 | style: "normal", 13 | subsets: ["latin"], 14 | }); 15 | 16 | const geistSans = Geist({ 17 | variable: "--font-geist-sans", 18 | subsets: ["latin"], 19 | }); 20 | 21 | const geistMono = Geist_Mono({ 22 | variable: "--font-geist-mono", 23 | subsets: ["latin"], 24 | }); 25 | 26 | export const metadata: Metadata = { 27 | title: "HackToGSoC", 28 | description: "An app to simplify gsoc contributions", 29 | }; 30 | 31 | export default async function RootLayout({ 32 | children, 33 | }: Readonly<{ 34 | children: React.ReactNode; 35 | }>) { 36 | return ( 37 | 38 | 39 | 42 | 43 | 44 | {children} 45 | 46 |