├── .npmrc ├── apps ├── web │ ├── src │ │ ├── components │ │ │ ├── login │ │ │ │ └── LoginForm.tsx │ │ │ ├── ui │ │ │ │ ├── ErrMsg.tsx │ │ │ │ ├── divider.tsx │ │ │ │ ├── skeleton.tsx │ │ │ │ ├── overlay.tsx │ │ │ │ ├── client-side-tweet.tsx │ │ │ │ ├── ActiveTag.tsx │ │ │ │ ├── IconWrapper.tsx │ │ │ │ ├── SpinnerElm.tsx │ │ │ │ ├── textarea.tsx │ │ │ │ ├── NumberTickerDisplay.tsx │ │ │ │ ├── GlowingBtn.tsx │ │ │ │ ├── label.tsx │ │ │ │ ├── input.tsx │ │ │ │ ├── checkbox.tsx │ │ │ │ ├── custom-button.tsx │ │ │ │ ├── badge.tsx │ │ │ │ ├── radio-group.tsx │ │ │ │ ├── header.tsx │ │ │ │ ├── number-ticker.tsx │ │ │ │ ├── shine-borders.tsx │ │ │ │ ├── button.tsx │ │ │ │ ├── card.tsx │ │ │ │ ├── accordion.tsx │ │ │ │ ├── marquee.tsx │ │ │ │ └── Filter.tsx │ │ │ ├── legal │ │ │ │ ├── LegalContent.tsx │ │ │ │ ├── LegalFooter.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── LegalPageLayout.tsx │ │ │ │ ├── LegalSection.tsx │ │ │ │ ├── LegalPageHeader.tsx │ │ │ │ ├── LegalCard.tsx │ │ │ │ └── ContactInfo.tsx │ │ │ ├── oss-programs │ │ │ │ ├── index.ts │ │ │ │ ├── SearchInput.tsx │ │ │ │ ├── ProgramCard.tsx │ │ │ │ ├── ProgramHeader.tsx │ │ │ │ └── ProgramMetadata.tsx │ │ │ ├── providers │ │ │ │ └── SessionProvider.tsx │ │ │ ├── landing-page │ │ │ │ └── QueryCount.tsx │ │ │ ├── sheet │ │ │ │ ├── SheetContentRenderer.tsx │ │ │ │ ├── OpensoxProBadge.tsx │ │ │ │ └── ProgressBar.tsx │ │ │ ├── blogs │ │ │ │ └── BlogHeader.tsx │ │ │ ├── newsletters │ │ │ │ ├── NewsletterSkeleton.tsx │ │ │ │ ├── NewsletterList.tsx │ │ │ │ ├── PremiumUpgradePrompt.tsx │ │ │ │ └── NewsletterCard.tsx │ │ │ ├── checkout │ │ │ │ └── CheckoutWrapper.tsx │ │ │ ├── sidebar │ │ │ │ └── SidebarItem.tsx │ │ │ ├── dashboard │ │ │ │ ├── ProfilePic.tsx │ │ │ │ ├── DashboardContainer.tsx │ │ │ │ └── DashboardHeader.tsx │ │ │ ├── landing-sections │ │ │ │ └── CTA.tsx │ │ │ └── faq │ │ │ │ ├── faqData.ts │ │ │ │ └── FaqSection.tsx │ │ ├── types │ │ │ ├── index.ts │ │ │ ├── projects.ts │ │ │ ├── next-auth.d.ts │ │ │ └── filter.ts │ │ ├── app │ │ │ ├── fonts │ │ │ │ ├── GeistVF.woff │ │ │ │ ├── GeistMonoVF.woff │ │ │ │ ├── DMMono-Medium.ttf │ │ │ │ ├── DMMono-Regular.ttf │ │ │ │ ├── Mona-Sans-Medium.ttf │ │ │ │ ├── Mona-Sans-Regular.ttf │ │ │ │ └── DMMono-MediumItalic.ttf │ │ │ ├── api │ │ │ │ ├── auth │ │ │ │ │ └── [...nextauth] │ │ │ │ │ │ └── route.ts │ │ │ │ └── sheet │ │ │ │ │ └── modules │ │ │ │ │ └── route.ts │ │ │ ├── (main) │ │ │ │ ├── login │ │ │ │ │ ├── layout.tsx │ │ │ │ │ └── page.tsx │ │ │ │ ├── (landing) │ │ │ │ │ ├── layout.tsx │ │ │ │ │ └── page.tsx │ │ │ │ ├── dashboard │ │ │ │ │ ├── page.tsx │ │ │ │ │ ├── oss-programs │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── projects │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── home │ │ │ │ │ │ └── page.tsx │ │ │ │ │ └── account │ │ │ │ │ │ └── page.tsx │ │ │ │ └── sheet │ │ │ │ │ └── [moduleId] │ │ │ │ │ └── sheet-content.module.css │ │ │ ├── theme-provider.tsx │ │ │ ├── SessionWrapper.tsx │ │ │ ├── checkout │ │ │ │ └── page.tsx │ │ │ ├── PostHogPageView.tsx │ │ │ └── globals.css │ │ ├── data │ │ │ ├── sheet │ │ │ │ ├── index.ts │ │ │ │ ├── content │ │ │ │ │ ├── module-29.md │ │ │ │ │ ├── module-30.md │ │ │ │ │ ├── module-8.md │ │ │ │ │ ├── module-31.md │ │ │ │ │ ├── module-17.md │ │ │ │ │ ├── module-19.md │ │ │ │ │ ├── module-21.md │ │ │ │ │ ├── module-18.md │ │ │ │ │ ├── module-20.md │ │ │ │ │ ├── module-26.md │ │ │ │ │ ├── module-28.md │ │ │ │ │ ├── module-27.md │ │ │ │ │ ├── module-10.md │ │ │ │ │ ├── module-11.md │ │ │ │ │ ├── module-12.md │ │ │ │ │ ├── module-13.md │ │ │ │ │ ├── module-15.md │ │ │ │ │ ├── module-22.md │ │ │ │ │ ├── module-16.md │ │ │ │ │ ├── module-23.md │ │ │ │ │ ├── module-24.md │ │ │ │ │ ├── module-25.md │ │ │ │ │ ├── module-7.md │ │ │ │ │ ├── module-4.md │ │ │ │ │ └── module-14.md │ │ │ │ ├── types.ts │ │ │ │ └── sheet.ts │ │ │ └── oss-programs │ │ │ │ ├── types.ts │ │ │ │ └── programs │ │ │ │ └── iiit-kalyani-winter-of-code.ts │ │ ├── assets │ │ │ └── images │ │ │ │ ├── user_dp.webp │ │ │ │ └── module-1.webp │ │ ├── lib │ │ │ ├── trpc.ts │ │ │ ├── utils.ts │ │ │ ├── ox-constants.ts │ │ │ ├── auth │ │ │ │ └── protected-routes.ts │ │ │ ├── trpc-server.ts │ │ │ └── razorpay.ts │ │ ├── store │ │ │ ├── useLoadingStore.ts │ │ │ ├── useProjectTitleStore.ts │ │ │ ├── useProjectsFoundStore.ts │ │ │ ├── useFilterStore.ts │ │ │ ├── useProjectsDataStore.ts │ │ │ ├── useFilterInputStore.ts │ │ │ ├── useRenderProjectsStore.ts │ │ │ ├── useShowSidebar.ts │ │ │ └── useSubscriptionStore.ts │ │ ├── hooks │ │ │ ├── useGetProjects.ts │ │ │ ├── useNewsletterFilters.ts │ │ │ ├── useSubscription.ts │ │ │ └── useRazorpay.ts │ │ ├── utils │ │ │ └── queries.ts │ │ ├── middleware.ts │ │ ├── providers │ │ │ └── trpc-provider.tsx │ │ └── content │ │ │ └── newsletters │ │ │ └── 2024-01-welcome.md │ ├── public │ │ ├── ajeetunc.webp │ │ ├── images │ │ │ ├── dm.webp │ │ │ ├── doc.webp │ │ │ ├── lv-1.webp │ │ │ ├── ptm.webp │ │ │ ├── module-1.webp │ │ │ ├── os-image.ico │ │ │ ├── sheet-1.webp │ │ │ ├── sheet-2.webp │ │ │ └── opensox_og.webp │ │ └── assets │ │ │ ├── filter.webp │ │ │ ├── search.webp │ │ │ ├── contribute.webp │ │ │ ├── logo.svg │ │ │ ├── icons │ │ │ └── cal.svg │ │ │ ├── layer1.svg │ │ │ └── logo_var2.svg │ ├── postcss.config.mjs │ ├── types │ │ ├── sanitize-html.d.ts │ │ └── zeptomail.d.ts │ ├── .eslintrc.json │ ├── components.json │ ├── next.config.js │ ├── .gitignore │ ├── tsconfig.json │ ├── README.md │ └── package.json ├── api │ ├── prisma │ │ └── migrations │ │ │ ├── 20251030121123_add_payment_constraints │ │ │ └── migration.sql │ │ │ ├── 20250113181752_bigint_qc │ │ │ └── migration.sql │ │ │ ├── 20251114063002_add_completed_steps │ │ │ └── migration.sql │ │ │ ├── migration_lock.toml │ │ │ ├── 20241216100538_init │ │ │ └── migration.sql │ │ │ ├── 20250113182224_add_user_and_ac │ │ │ └── migration.sql │ │ │ ├── 20251021101502_add_ox_premium │ │ │ └── migration.sql │ │ │ └── 20251031113043_add_payment_status_enum │ │ │ └── migration.sql │ ├── src │ │ ├── routers │ │ │ ├── queries.ts │ │ │ ├── _app.ts │ │ │ ├── user.ts │ │ │ └── projects.ts │ │ ├── types │ │ │ └── zeptomail.d.ts │ │ ├── clients │ │ │ └── razorpay.ts │ │ ├── context.ts │ │ ├── utils │ │ │ └── auth.ts │ │ ├── constants │ │ │ └── subscription.ts │ │ ├── trpc.ts │ │ └── services │ │ │ ├── query.service.ts │ │ │ └── user.service.ts │ ├── .env.example │ ├── package.json │ └── tsconfig.json └── docs │ ├── app │ ├── favicon.ico │ ├── fonts │ │ ├── GeistVF.woff │ │ └── GeistMonoVF.woff │ ├── globals.css │ └── layout.tsx │ ├── next.config.mjs │ ├── .eslintrc.js │ ├── tsconfig.json │ ├── public │ ├── vercel.svg │ ├── file-text.svg │ ├── window.svg │ └── next.svg │ ├── .gitignore │ ├── package.json │ └── README.md ├── pnpm-workspace.yaml ├── railway.toml ├── packages ├── shared │ ├── types │ │ ├── index.ts │ │ ├── filter.ts │ │ └── projects.ts │ ├── package.json │ └── tsconfig.json ├── eslint-config │ ├── README.md │ ├── package.json │ ├── library.js │ ├── next.js │ └── react-internal.js ├── ui │ ├── tsconfig.json │ ├── tsconfig.lint.json │ ├── src │ │ ├── code.tsx │ │ ├── button.tsx │ │ └── card.tsx │ ├── turbo │ │ └── generators │ │ │ ├── templates │ │ │ └── component.hbs │ │ │ └── config.ts │ ├── .eslintrc.js │ └── package.json └── typescript-config │ ├── package.json │ ├── react-library.json │ ├── nextjs.json │ └── base.json ├── .gitmodules ├── vercel.json ├── package.json ├── .cursor └── rules │ └── general_rules.mdc ├── .gitignore ├── turbo.json ├── .github ├── ISSUE_TEMPLATE │ ├── general.yml │ ├── feature_request.yml │ └── bug_report.yml └── PULL_REQUEST_TEMPLATE │ └── pull_request_template.md ├── .dockerignore └── Dockerfile /.npmrc: -------------------------------------------------------------------------------- 1 | # package-manager=pnpm@latest 2 | -------------------------------------------------------------------------------- /apps/web/src/components/login/LoginForm.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'apps/*' 3 | - 'packages/*' -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20251030121123_add_payment_constraints/migration.sql: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /railway.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | builder = "DOCKERFILE" 3 | dockerfilePath = "Dockerfile" -------------------------------------------------------------------------------- /apps/web/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./filter" 2 | export * from "./projects" 3 | -------------------------------------------------------------------------------- /packages/shared/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './filter'; 2 | export * from './projects' -------------------------------------------------------------------------------- /apps/docs/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/docs/app/favicon.ico -------------------------------------------------------------------------------- /apps/web/public/ajeetunc.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/ajeetunc.webp -------------------------------------------------------------------------------- /apps/docs/app/fonts/GeistVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/docs/app/fonts/GeistVF.woff -------------------------------------------------------------------------------- /apps/web/public/images/dm.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/images/dm.webp -------------------------------------------------------------------------------- /apps/web/public/images/doc.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/images/doc.webp -------------------------------------------------------------------------------- /apps/web/public/images/lv-1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/images/lv-1.webp -------------------------------------------------------------------------------- /apps/web/public/images/ptm.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/images/ptm.webp -------------------------------------------------------------------------------- /packages/eslint-config/README.md: -------------------------------------------------------------------------------- 1 | # `@turbo/eslint-config` 2 | 3 | Collection of internal eslint configurations. 4 | -------------------------------------------------------------------------------- /apps/web/public/assets/filter.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/assets/filter.webp -------------------------------------------------------------------------------- /apps/web/public/assets/search.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/assets/search.webp -------------------------------------------------------------------------------- /apps/docs/app/fonts/GeistMonoVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/docs/app/fonts/GeistMonoVF.woff -------------------------------------------------------------------------------- /apps/web/public/images/module-1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/images/module-1.webp -------------------------------------------------------------------------------- /apps/web/public/images/os-image.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/images/os-image.ico -------------------------------------------------------------------------------- /apps/web/public/images/sheet-1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/images/sheet-1.webp -------------------------------------------------------------------------------- /apps/web/public/images/sheet-2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/images/sheet-2.webp -------------------------------------------------------------------------------- /apps/web/src/app/fonts/GeistVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/src/app/fonts/GeistVF.woff -------------------------------------------------------------------------------- /apps/web/src/data/sheet/index.ts: -------------------------------------------------------------------------------- 1 | export type { SheetModule } from "./types"; 2 | export { getSheetModules } from "./sheet"; 3 | -------------------------------------------------------------------------------- /apps/docs/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /apps/web/public/assets/contribute.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/assets/contribute.webp -------------------------------------------------------------------------------- /apps/web/public/images/opensox_og.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/public/images/opensox_og.webp -------------------------------------------------------------------------------- /apps/web/src/app/fonts/GeistMonoVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/src/app/fonts/GeistMonoVF.woff -------------------------------------------------------------------------------- /apps/web/src/assets/images/user_dp.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/src/assets/images/user_dp.webp -------------------------------------------------------------------------------- /apps/web/src/app/fonts/DMMono-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/src/app/fonts/DMMono-Medium.ttf -------------------------------------------------------------------------------- /apps/web/src/app/fonts/DMMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/src/app/fonts/DMMono-Regular.ttf -------------------------------------------------------------------------------- /apps/web/src/assets/images/module-1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/src/assets/images/module-1.webp -------------------------------------------------------------------------------- /apps/web/src/app/fonts/Mona-Sans-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/src/app/fonts/Mona-Sans-Medium.ttf -------------------------------------------------------------------------------- /apps/web/src/app/fonts/Mona-Sans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/src/app/fonts/Mona-Sans-Regular.ttf -------------------------------------------------------------------------------- /apps/web/src/app/fonts/DMMono-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apsinghdev/opensox/HEAD/apps/web/src/app/fonts/DMMono-MediumItalic.ttf -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20250113181752_bigint_qc/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "QueryCount" ALTER COLUMN "total_queries" SET DATA TYPE BIGINT; -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20251114063002_add_completed_steps/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "User" ADD COLUMN "completedSteps" JSONB; 3 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "postgresql" -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "apps/web/src/content/newsletters-premium"] 2 | path = apps/web/src/content/newsletters-premium 3 | url = https://github.com/apsinghdev/opensox-newsletters-premium.git 4 | -------------------------------------------------------------------------------- /apps/web/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 | -------------------------------------------------------------------------------- /apps/web/src/lib/trpc.ts: -------------------------------------------------------------------------------- 1 | import { createTRPCReact } from "@trpc/react-query"; 2 | import type { AppRouter } from "../../../api/src/routers/_app"; 3 | 4 | export const trpc = createTRPCReact(); 5 | -------------------------------------------------------------------------------- /apps/web/src/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 | -------------------------------------------------------------------------------- /apps/web/src/app/api/auth/[...nextauth]/route.ts: -------------------------------------------------------------------------------- 1 | import NextAuth from "next-auth"; 2 | import { authConfig } from "@/lib/auth/config"; 3 | 4 | const handler = NextAuth(authConfig); 5 | export { handler as GET, handler as POST }; 6 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/typescript-config/react-library.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src"], 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/typescript-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/typescript-config", 3 | "version": "0.0.0", 4 | "private": true, 5 | "license": "MIT", 6 | "publishConfig": { 7 | "access": "public" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/typescript-config/react-library.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "React Library", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "jsx": "react-jsx" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.lint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/typescript-config/react-library.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src", "turbo"], 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/ui/src/code.tsx: -------------------------------------------------------------------------------- 1 | export function Code({ 2 | children, 3 | className, 4 | }: { 5 | children: React.ReactNode; 6 | className?: string; 7 | }): JSX.Element { 8 | return {children}; 9 | } 10 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20241216100538_init/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "QueryCount" ( 3 | "id" INTEGER NOT NULL DEFAULT 1, 4 | "total_queries" INTEGER NOT NULL, 5 | 6 | CONSTRAINT "QueryCount_pkey" PRIMARY KEY ("id") 7 | ); -------------------------------------------------------------------------------- /apps/docs/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import("eslint").Linter.Config} */ 2 | module.exports = { 3 | root: true, 4 | extends: ["@repo/eslint-config/next.js"], 5 | parser: "@typescript-eslint/parser", 6 | parserOptions: { 7 | project: true, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /packages/ui/turbo/generators/templates/component.hbs: -------------------------------------------------------------------------------- 1 | export const {{ pascalCase name }} = ({ children }: { children: React.ReactNode }) => { 2 | return ( 3 |
4 |

{{ pascalCase name }} Component

5 | {children} 6 |
7 | ); 8 | }; 9 | -------------------------------------------------------------------------------- /apps/web/src/app/(main)/login/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function LoginLayout({ 2 | children, 3 | }: Readonly<{ 4 | children: React.ReactNode; 5 | }>) { 6 | return ( 7 |
{children}
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /apps/web/src/app/(main)/(landing)/layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Layout = ({ children }: { children: React.ReactNode }) => { 4 | return ( 5 |
6 | {children} 7 |
8 | ) 9 | } 10 | 11 | export default Layout -------------------------------------------------------------------------------- /apps/web/src/components/ui/ErrMsg.tsx: -------------------------------------------------------------------------------- 1 | export const ErrMsg = ({ text }: { text: string }) => { 2 | return ( 3 |
4 |

{text}

5 |
6 | ); 7 | }; -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-29.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-29" 3 | name: "Live fix/implement the issue - 4" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | ### Live fix/implement the issue - 4 9 | 10 | Fourth live session on fixing and implementing a medium-hard difficulty issue. -------------------------------------------------------------------------------- /apps/web/src/components/ui/divider.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | import React from 'react' 3 | 4 | const Divider = ({ className }: { className?: string }) => { 5 | return ( 6 |
7 | ) 8 | } 9 | 10 | export default Divider -------------------------------------------------------------------------------- /apps/web/src/app/(main)/dashboard/page.tsx: -------------------------------------------------------------------------------- 1 | import DashboardContainer from "@/components/dashboard/DashboardContainer"; 2 | 3 | export default function Dashboard() { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-30.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-30" 3 | name: "Raise the PR and get it merged" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | ### Raise the PR and get it merged 9 | 10 | Learn the complete process of raising a pull request for a medium-hard issue and getting it successfully merged. -------------------------------------------------------------------------------- /apps/web/src/data/sheet/types.ts: -------------------------------------------------------------------------------- 1 | export interface SheetModule { 2 | id: string; // e.g., "module-0" 3 | name: string; // Module name 4 | docContent: string; // HTML content for documentation (rendered from markdown) 5 | videoUrl: string; // YouTube URL 6 | comingSoon?: boolean; // If true, module is not yet available 7 | } 8 | 9 | -------------------------------------------------------------------------------- /packages/ui/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import("eslint").Linter.Config} */ 2 | module.exports = { 3 | root: true, 4 | extends: ["@repo/eslint-config/react-internal.js"], 5 | parser: "@typescript-eslint/parser", 6 | parserOptions: { 7 | project: "./tsconfig.lint.json", 8 | tsconfigRootDir: __dirname, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-8.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-8" 3 | name: "Adhoc: How to learn anything fast?" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | # Adhoc: How to learn anything fast while contributing? 9 | 10 | Strategies and techniques for learning quickly while actively contributing to OPEN SOURCE projects. 11 | -------------------------------------------------------------------------------- /apps/web/src/store/useLoadingStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from "zustand"; 2 | 3 | interface LoadingProps { 4 | loading: boolean; 5 | setLoading: (value: boolean) => void; 6 | } 7 | 8 | export const useLoading = create((set) => ({ 9 | loading: false, 10 | setLoading: (value) => set({ loading: value }), 11 | })); 12 | -------------------------------------------------------------------------------- /apps/web/src/app/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { ThemeProvider as NextThemesProvider } from "next-themes" 4 | import { type ThemeProviderProps } from "next-themes" 5 | 6 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) { 7 | return {children} 8 | } 9 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-31.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-31" 3 | name: "How to get jobs/internships through OPEN SOURCE?" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | ### How to get jobs/internships through OPEN SOURCE? 9 | 10 | Learn how to leverage your OPEN SOURCE contributions to land jobs and internships in the tech industry. -------------------------------------------------------------------------------- /apps/web/src/types/projects.ts: -------------------------------------------------------------------------------- 1 | export type DashboardProjectsProps = { 2 | id: string; 3 | name: string; 4 | description: string; 5 | url: string; 6 | avatarUrl: string; 7 | totalIssueCount: number; 8 | primaryLanguage: string; 9 | popularity: string; 10 | stage: string; 11 | competition: string; 12 | activity: string; 13 | }; 14 | -------------------------------------------------------------------------------- /packages/shared/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@opensox/shared", 3 | "version": "1.0.0", 4 | "main": "dist/index.js", 5 | "types": "dist/index.d.ts", 6 | "scripts": { 7 | "build": "tsc", 8 | "clean": "rm -rf dist", 9 | "prepublishOnly": "pnpm run build" 10 | }, 11 | "devDependencies": { 12 | "typescript": "^4.9.5" 13 | } 14 | } -------------------------------------------------------------------------------- /apps/web/src/components/legal/LegalContent.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | interface LegalContentProps { 4 | children: React.ReactNode; 5 | } 6 | 7 | export function LegalContent({ children }: LegalContentProps) { 8 | return ( 9 |
10 | {children} 11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /apps/web/src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /apps/web/src/components/legal/LegalFooter.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export function LegalFooter() { 4 | return ( 5 |
6 |

7 | © {new Date().getFullYear()} Opensox AI. All rights reserved. 8 |

9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /apps/api/src/routers/queries.ts: -------------------------------------------------------------------------------- 1 | import { router, publicProcedure } from "../trpc.js"; 2 | import { queryService } from "../services/query.service.js"; 3 | 4 | export const queryRouter = router({ 5 | // get the total count of fetched queries 6 | count: publicProcedure.query(async ({ ctx }) => { 7 | return await queryService.getQueryCount(ctx.db.prisma); 8 | }), 9 | }); 10 | -------------------------------------------------------------------------------- /apps/web/types/sanitize-html.d.ts: -------------------------------------------------------------------------------- 1 | declare module "sanitize-html" { 2 | export interface IOptions { 3 | allowedTags?: string[]; 4 | allowedAttributes?: Record; 5 | allowedSchemes?: string[]; 6 | [key: string]: any; 7 | } 8 | 9 | function sanitizeHtml(dirty: string, options?: IOptions): string; 10 | export default sanitizeHtml; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /apps/web/src/components/legal/index.ts: -------------------------------------------------------------------------------- 1 | export { LegalPageLayout } from "./LegalPageLayout"; 2 | export { LegalPageHeader } from "./LegalPageHeader"; 3 | export { LegalSection } from "./LegalSection"; 4 | export { LegalCard } from "./LegalCard"; 5 | export { ContactInfo } from "./ContactInfo"; 6 | export { LegalFooter } from "./LegalFooter"; 7 | export { LegalContent } from "./LegalContent"; 8 | 9 | -------------------------------------------------------------------------------- /packages/typescript-config/nextjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Next.js", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "plugins": [{ "name": "next" }], 7 | "module": "ESNext", 8 | "moduleResolution": "Bundler", 9 | "allowJs": true, 10 | "jsx": "preserve", 11 | "noEmit": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/web/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | // "root": true, 3 | "extends": [ 4 | "next/core-web-vitals", 5 | "next/typescript" 6 | ], 7 | // "parser": "@typescript-eslint/parser", 8 | // "parserOptions": { 9 | // "project": "./tsconfig.lint.json", 10 | // "tsconfigRootDir": "__dirname" 11 | // }, 12 | "rules": { 13 | "@typescript-eslint/no-explicit-any": "off" 14 | } 15 | } -------------------------------------------------------------------------------- /apps/docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/typescript-config/nextjs.json", 3 | "compilerOptions": { 4 | "plugins": [ 5 | { 6 | "name": "next" 7 | } 8 | ] 9 | }, 10 | "include": [ 11 | "next-env.d.ts", 12 | "next.config.mjs", 13 | "**/*.ts", 14 | "**/*.tsx", 15 | ".next/types/**/*.ts" 16 | ], 17 | "exclude": ["node_modules"] 18 | } 19 | -------------------------------------------------------------------------------- /apps/web/src/store/useProjectTitleStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from "zustand"; 2 | 3 | interface ProjectTitleProps { 4 | projectTitle: string; 5 | setProjectTitle: (value: string) => void; 6 | } 7 | 8 | export const useProjectTitleStore = create((set) => ({ 9 | projectTitle: "Projects for you", 10 | setProjectTitle: (value) => set({ projectTitle: value }), 11 | })); 12 | -------------------------------------------------------------------------------- /apps/web/src/app/(main)/dashboard/oss-programs/page.tsx: -------------------------------------------------------------------------------- 1 | import { getAllPrograms, getAllTags } from "@/data/oss-programs"; 2 | import ProgramsList from "./ProgramsList"; 3 | 4 | export const revalidate = 3600; 5 | 6 | export default function Page() { 7 | const programs = getAllPrograms(); 8 | const tags = getAllTags(); 9 | 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /apps/web/src/components/oss-programs/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SearchInput } from './SearchInput'; 2 | export { default as TagFilter } from './TagFilter'; 3 | export { default as ProgramCard } from './ProgramCard'; 4 | export { default as ProgramHeader } from './ProgramHeader'; 5 | export { default as ProgramMetadata } from './ProgramMetadata'; 6 | export { default as ProgramSection } from './ProgramSection'; 7 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-17.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-17" 3 | name: "Live fix/implement the issue - 1" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 1 9 | 10 | Live fix/implement the issue - 1 11 | 12 | First live session on fixing and implementing a medium difficulty issue. 13 | 14 | First live session on fixing and implementing a medium difficulty issue. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-19.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-19" 3 | name: "Live fix/implement the issue - 3" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 3 9 | 10 | Live fix/implement the issue - 3 11 | 12 | Third live session on fixing and implementing a medium difficulty issue. 13 | 14 | Third live session on fixing and implementing a medium difficulty issue. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-21.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-21" 3 | name: "Live fix/implement the issue - 5" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 5 9 | 10 | Live fix/implement the issue - 5 11 | 12 | Fifth live session on fixing and implementing a medium difficulty issue. 13 | 14 | Fifth live session on fixing and implementing a medium difficulty issue. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/store/useProjectsFoundStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from "zustand"; 2 | 3 | interface ProjectNotFoundProps { 4 | projectsNotFound: boolean; 5 | setProjectsNotFound: (value: boolean) => void; 6 | } 7 | 8 | export const useProjectsNotFoundStore = create((set) => ({ 9 | projectsNotFound: false, 10 | setProjectsNotFound: (value) => set({ projectsNotFound: value }), 11 | })); 12 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-18.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-18" 3 | name: "Live fix/implement the issue - 2" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 2 9 | 10 | Live fix/implement the issue - 2 11 | 12 | Second live session on fixing and implementing a medium difficulty issue. 13 | 14 | Second live session on fixing and implementing a medium difficulty issue. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-20.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-20" 3 | name: "Live fix/implement the issue - 4" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 4 9 | 10 | Live fix/implement the issue - 4 11 | 12 | Fourth live session on fixing and implementing a medium difficulty issue. 13 | 14 | Fourth live session on fixing and implementing a medium difficulty issue. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/components/providers/SessionProvider.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { SessionProvider as Provider } from "next-auth/react"; 4 | import type { Session } from "next-auth"; 5 | 6 | type Props = { 7 | children: React.ReactNode; 8 | session: Session; 9 | }; 10 | 11 | export default function SessionProvider({ children, session }: Props) { 12 | return {children}; 13 | } 14 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-26.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-26" 3 | name: "Live fix/implement the issue - 1" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 1 9 | 10 | Live fix/implement the issue - 1 11 | 12 | First live session on fixing and implementing a medium-hard difficulty issue. 13 | 14 | First live session on fixing and implementing a medium-hard difficulty issue. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-28.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-28" 3 | name: "Live fix/implement the issue - 3" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 3 9 | 10 | Live fix/implement the issue - 3 11 | 12 | Third live session on fixing and implementing a medium-hard difficulty issue. 13 | 14 | Third live session on fixing and implementing a medium-hard difficulty issue. 15 | 16 | -------------------------------------------------------------------------------- /apps/docs/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-27.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-27" 3 | name: "Live fix/implement the issue - 2" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 2 9 | 10 | Live fix/implement the issue - 2 11 | 12 | Second live session on fixing and implementing a medium-hard difficulty issue. 13 | 14 | Second live session on fixing and implementing a medium-hard difficulty issue. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-10.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-10" 3 | name: "Live fix/implement the issue - 2" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 2 9 | 10 | Live fix/implement the issue - 2 11 | 12 | Second live session on fixing and implementing an issue in an OPEN SOURCE project. 13 | 14 | Second live session on fixing and implementing an issue in an OPEN SOURCE project. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-11.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-11" 3 | name: "Live fix/implement the issue - 3" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 3 9 | 10 | Live fix/implement the issue - 3 11 | 12 | Third live session on fixing and implementing an issue in an OPEN SOURCE project. 13 | 14 | Third live session on fixing and implementing an issue in an OPEN SOURCE project. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-12.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-12" 3 | name: "Live fix/implement the issue - 4" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Live fix/implement the issue - 4 9 | 10 | Live fix/implement the issue - 4 11 | 12 | Fourth live session on fixing and implementing an issue in an OPEN SOURCE project. 13 | 14 | Fourth live session on fixing and implementing an issue in an OPEN SOURCE project. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/types/zeptomail.d.ts: -------------------------------------------------------------------------------- 1 | declare module "zeptomail" { 2 | export class SendMailClient { 3 | constructor(config: { url: string; token: string }); 4 | sendMail(options: { 5 | from: { address: string; name: string }; 6 | to: Array<{ email_address: { address: string; name: string } }>; 7 | subject: string; 8 | htmlbody: string; 9 | textbody?: string; 10 | }): Promise; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/api/src/types/zeptomail.d.ts: -------------------------------------------------------------------------------- 1 | declare module "zeptomail" { 2 | export class SendMailClient { 3 | constructor(config: { url: string; token: string }); 4 | sendMail(options: { 5 | from: { address: string; name: string }; 6 | to: Array<{ email_address: { address: string; name: string } }>; 7 | subject: string; 8 | htmlbody: string; 9 | textbody?: string; 10 | }): Promise; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/web/src/app/SessionWrapper.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { ReactNode } from "react"; 4 | import { SessionProvider } from "next-auth/react"; 5 | import type { Session } from "next-auth"; 6 | 7 | export function SessionWrapper({ 8 | children, 9 | session, 10 | }: { 11 | children: ReactNode; 12 | session: Session | null; 13 | }) { 14 | return {children}; 15 | } 16 | -------------------------------------------------------------------------------- /apps/web/src/components/legal/LegalPageLayout.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | interface LegalPageLayoutProps { 4 | children: React.ReactNode; 5 | } 6 | 7 | export function LegalPageLayout({ children }: LegalPageLayoutProps) { 8 | return ( 9 |
10 |
{children}
11 |
12 | ); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-13.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-13" 3 | name: "Raise PRs and fix the reviews" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Raise PRs and fix the reviews 9 | 10 | Raise PRs and fix the reviews 11 | 12 | Learn how to create pull requests and effectively address review comments from maintainers. 13 | 14 | Learn how to create pull requests and effectively address review comments from maintainers. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/types/next-auth.d.ts: -------------------------------------------------------------------------------- 1 | import "next-auth"; 2 | 3 | declare module "next-auth" { 4 | interface Session { 5 | accessToken?: string; 6 | user?: { 7 | name?: string | null; 8 | email?: string | null; 9 | image?: string | null; 10 | createdAt?: string; 11 | }; 12 | } 13 | } 14 | 15 | declare module "next-auth/jwt" { 16 | interface JWT { 17 | jwtToken?: string; 18 | createdAt?: string; 19 | } 20 | } -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildCommand": "pnpm turbo build --filter=web...", 3 | "installCommand": "pnpm install --frozen-lockfile=false", 4 | "framework": "nextjs", 5 | "redirects": [ 6 | { 7 | "source": "/:path*", 8 | "has": [ 9 | { 10 | "type": "host", 11 | "value": "opensox.in" 12 | } 13 | ], 14 | "destination": "https://opensox.ai/:path*", 15 | "permanent": true 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-15.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-15" 3 | name: "Get/pick your second issue assigned (medium)" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Get/pick your second issue assigned (medium) 9 | 10 | Get/pick your second issue assigned (medium) 11 | 12 | Learn how to get your second issue assigned, focusing on medium difficulty issues. 13 | 14 | Learn how to get your second issue assigned, focusing on medium difficulty issues. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-22.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-22" 3 | name: "Raise the PR and get it merged" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Raise the PR and get it merged 9 | 10 | Raise the PR and get it merged 11 | 12 | Learn the complete process of raising a pull request and getting it successfully merged into the project. 13 | 14 | Learn the complete process of raising a pull request and getting it successfully merged into the project. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/store/useFilterStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from "zustand"; 2 | 3 | interface FilterState { 4 | showFilters: boolean; 5 | setShowFilters: (value: boolean) => void; 6 | toggleShowFilters: () => void; 7 | } 8 | 9 | export const useFilterStore = create((set) => ({ 10 | showFilters: false, 11 | setShowFilters: (value) => set({ showFilters: value }), 12 | toggleShowFilters: () => 13 | set((state) => ({ showFilters: !state.showFilters })), 14 | })); 15 | -------------------------------------------------------------------------------- /packages/shared/types/filter.ts: -------------------------------------------------------------------------------- 1 | export type DateRange = { 2 | start: string; 3 | end?: string; 4 | } 5 | 6 | export type StarRange = { 7 | min?: string; 8 | max?: string; 9 | custom?: string; 10 | } 11 | 12 | export type ForkRange = { 13 | min?: string; 14 | max?: string; 15 | } 16 | 17 | export type FilterProps = { 18 | language?: string; 19 | stars?: StarRange; 20 | forks?: ForkRange; 21 | pushed?: string; 22 | created?: string; 23 | } -------------------------------------------------------------------------------- /packages/ui/src/button.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { ReactNode } from "react"; 4 | 5 | interface ButtonProps { 6 | children: ReactNode; 7 | className?: string; 8 | appName: string; 9 | } 10 | 11 | export const Button = ({ children, className, appName }: ButtonProps) => { 12 | return ( 13 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-16.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-16" 3 | name: "How to plan/discuss with maintainers?" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | How to plan/discuss with maintainers? 9 | 10 | How to plan/discuss with maintainers? 11 | 12 | Best practices for communicating and planning with project maintainers before starting work on issues. 13 | 14 | Best practices for communicating and planning with project maintainers before starting work on issues. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/store/useProjectsDataStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from "zustand"; 2 | import { DashboardProjectsProps } from "@/types"; 3 | 4 | interface ProjectsDataProps { 5 | data: DashboardProjectsProps[]; 6 | setData: (value: DashboardProjectsProps[]) => void; 7 | eraseData: () => void; 8 | } 9 | 10 | export const useProjectsData = create((set) => ({ 11 | data: [], 12 | setData: (value) => set({ data: value }), 13 | eraseData: () => set({ data: [] }), 14 | })); 15 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-23.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-23" 3 | name: "How to make impressive contributions part-1?" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | How to make impressive contributions part-1? 9 | 10 | How to make impressive contributions part-1? 11 | 12 | First part of a guide on making standout contributions that get noticed in OPEN SOURCE projects. 13 | 14 | First part of a guide on making standout contributions that get noticed in OPEN SOURCE projects. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-24.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-24" 3 | name: "How to make impressive contributions part-2?" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | How to make impressive contributions part-2? 9 | 10 | How to make impressive contributions part-2? 11 | 12 | Second part of a guide on making standout contributions that get noticed in OPEN SOURCE projects. 13 | 14 | Second part of a guide on making standout contributions that get noticed in OPEN SOURCE projects. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-25.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-25" 3 | name: "Get/pick your third issue assigned (medium-hard)" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | Get/pick your third issue assigned (medium-hard) 9 | 10 | Get/pick your third issue assigned (medium-hard) 11 | 12 | Learn how to get your third issue assigned, focusing on medium to hard difficulty issues. 13 | 14 | Learn how to get your third issue assigned, focusing on medium to hard difficulty issues. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/lib/ox-constants.ts: -------------------------------------------------------------------------------- 1 | export const THEME_CONFIG = { 2 | light: "light", 3 | dark: "dark", 4 | } as const; 5 | 6 | export const SUPPORT_CONFIG = { 7 | UPI_ID: "ajeetunc@ptaxis", 8 | PAYEE_NAME: "Ajeet Pratap Singh", 9 | UPI_MSG: "Build something useful!", 10 | RAZORPAY_URL: "https://razorpay.me/@opensox", 11 | BUY_ME_COFFEE_URL: "", 12 | } as const; 13 | 14 | export const APP_CONFIG = { 15 | GITHUB_URL: "", 16 | TWITTER_URL: "", 17 | CONTRIBUTING_URL: "", 18 | } as const; -------------------------------------------------------------------------------- /apps/web/src/app/(main)/login/page.tsx: -------------------------------------------------------------------------------- 1 | import { Suspense } from "react"; 2 | import SignInPage from "@/components/login/SignInPage"; 3 | 4 | export default function Home() { 5 | return ( 6 |
7 |
8 | Loading...
}> 9 | 10 | 11 |
12 |
13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /apps/web/src/components/ui/overlay.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Overlay = () => { 4 | return ( 5 | <> 6 |
7 |
8 | 9 | ) 10 | } 11 | 12 | export default Overlay -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-7.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-7" 3 | name: "Get/pick your first issue assigned (easy-med)" 4 | videoUrl: "https://youtu.be/H-zCtw5c3uQ?si=wkPNFubBaVCwMS3f" 5 | comingSoon: false 6 | --- 7 | 8 | this module is just the implementation of an issue we picked in the previous module. 9 | 10 | ### todos: 11 | 12 | - [ ] just watch the [video](https://youtu.be/H-zCtw5c3uQ?si=wkPNFubBaVCwMS3f) 13 | - [ ] and follow along with your own issue. 14 | 15 | this is ajeetunc. see you in the next module 16 | -------------------------------------------------------------------------------- /apps/web/src/store/useFilterInputStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from "zustand"; 2 | 3 | interface FilterInputState { 4 | filters: object; 5 | updateFilters: (newFilter: Record) => void; 6 | resetFilters: () => void; 7 | } 8 | 9 | export const useFilterInputStore = create((set) => ({ 10 | filters: {}, 11 | updateFilters: (newFilter) => 12 | set((state) => ({ 13 | filters: { ...state.filters, ...newFilter }, 14 | })), 15 | resetFilters: () => set({ filters: {} }), 16 | })); 17 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-4" 3 | name: "Adhoc: How to setup projects locally" 4 | videoUrl: "https://youtu.be/qAlz8279M5A?si=PJ3ZKCZBx8RqvgOk" 5 | comingSoon: false 6 | --- 7 | 8 | you don't need to read my yap in this module. just follow along with [this video](https://youtu.be/qAlz8279M5A?si=PJ3ZKCZBx8RqvgOk) and set up any open source project locally. 9 | 10 | ### todos: 11 | 12 | - [ ] just set up the projects locally that you selected in module 3 (if you didn't, wake up and do it now) 13 | -------------------------------------------------------------------------------- /apps/web/src/data/sheet/content/module-14.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "module-14" 3 | name: "How to tackle competition in saturated orgs?" 4 | videoUrl: "" 5 | comingSoon: true 6 | --- 7 | 8 | How to tackle competition in saturated orgs? 9 | 10 | How to tackle competition in saturated orgs? 11 | 12 | Strategies for standing out and getting your contributions noticed in highly competitive OPEN SOURCE organizations. 13 | 14 | Strategies for standing out and getting your contributions noticed in highly competitive OPEN SOURCE organizations. 15 | 16 | -------------------------------------------------------------------------------- /apps/web/src/store/useRenderProjectsStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from "zustand"; 2 | 3 | interface RenderProjectProps { 4 | renderProjects: boolean; 5 | setRenderProjects: (value: boolean) => void; 6 | toggleRenderProjects: () => void; 7 | } 8 | 9 | export const useRenderProjects = create((set) => ({ 10 | renderProjects: false, 11 | setRenderProjects: (value) => set({ renderProjects: value }), 12 | toggleRenderProjects: () => 13 | set((state) => ({ renderProjects: !state.renderProjects })), 14 | })); 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "opensox", 3 | "private": true, 4 | "scripts": { 5 | "build": "turbo build", 6 | "dev": "turbo dev", 7 | "lint": "turbo lint", 8 | "format": "prettier --write \"**/*.{ts,tsx,md}\"" 9 | }, 10 | "devDependencies": { 11 | "prettier": "^3.2.5", 12 | "turbo": "^2.1.2", 13 | "typescript": "^5.4.5" 14 | }, 15 | "engines": { 16 | "node": ">=18" 17 | }, 18 | "packageManager": "pnpm@10.11.0", 19 | "workspaces": [ 20 | "apps/web/*", 21 | "packages/*" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /apps/web/src/store/useShowSidebar.ts: -------------------------------------------------------------------------------- 1 | import { create } from "zustand"; 2 | 3 | interface showSidebarProps { 4 | showSidebar: boolean; 5 | setShowSidebar: (value: boolean) => void; 6 | isCollapsed: boolean; 7 | toggleCollapsed: () => void; 8 | } 9 | 10 | export const useShowSidebar = create((set) => ({ 11 | showSidebar: false, 12 | setShowSidebar: (value) => set({ showSidebar: value }), 13 | isCollapsed: false, 14 | toggleCollapsed: () => 15 | set((state) => ({ isCollapsed: !state.isCollapsed })), 16 | })); 17 | -------------------------------------------------------------------------------- /apps/web/src/components/legal/LegalSection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | interface LegalSectionProps { 4 | title?: string; 5 | children: React.ReactNode; 6 | className?: string; 7 | } 8 | 9 | export function LegalSection({ 10 | title, 11 | children, 12 | className = "", 13 | }: LegalSectionProps) { 14 | return ( 15 |
16 | {title && ( 17 |

{title}

18 | )} 19 | {children} 20 |
21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /packages/eslint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/eslint-config", 3 | "version": "0.0.0", 4 | "private": true, 5 | "files": [ 6 | "library.js", 7 | "next.js", 8 | "react-internal.js" 9 | ], 10 | "devDependencies": { 11 | "@vercel/style-guide": "^5.2.0", 12 | "eslint-config-turbo": "^2.0.0", 13 | "eslint-config-prettier": "^9.1.0", 14 | "eslint-plugin-only-warn": "^1.1.0", 15 | "@typescript-eslint/parser": "^7.1.0", 16 | "@typescript-eslint/eslint-plugin": "^7.1.0", 17 | "typescript": "^5.3.3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.cursor/rules/general_rules.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | alwaysApply: true 3 | --- 4 | 5 | # Opensox AI - Cursor Rules 6 | 7 | ## Code Style 8 | 9 | ### Comments 10 | - always use lowercase when writing comments 11 | - avoid unnecessary comments; code should be self-documenting when possible 12 | - use comments to explain "why", not "what" 13 | 14 | 15 | ## Monorepo Structure 16 | - this is a turborepo monorepo 17 | - shared packages live in `packages/` 18 | - apps live in `apps/` (web, api, backend, docs) 19 | - respect package boundaries 20 | - use workspace dependencies properly 21 | 22 | -------------------------------------------------------------------------------- /.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.js 7 | 8 | # Local env files 9 | .env 10 | .env.local 11 | .env.development.local 12 | .env.test.local 13 | .env.production.local 14 | 15 | # Testing 16 | coverage 17 | 18 | # Turbo 19 | .turbo 20 | 21 | # Vercel 22 | .vercel 23 | 24 | # Build Outputs 25 | .next/ 26 | out/ 27 | build 28 | dist 29 | 30 | 31 | # Debug 32 | npm-debug.log* 33 | yarn-debug.log* 34 | yarn-error.log* 35 | 36 | # Misc 37 | .DS_Store 38 | *.pem 39 | -------------------------------------------------------------------------------- /apps/web/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": "src/app/globals.css", 9 | "baseColor": "slate", 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 | "types": "@/types" 20 | }, 21 | "iconLibrary": "lucide" 22 | } -------------------------------------------------------------------------------- /apps/docs/.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.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # env files (can opt-in for commiting if needed) 29 | .env* 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /packages/ui/src/card.tsx: -------------------------------------------------------------------------------- 1 | export function Card({ 2 | className, 3 | title, 4 | children, 5 | href, 6 | }: { 7 | className?: string; 8 | title: string; 9 | children: React.ReactNode; 10 | href: string; 11 | }): JSX.Element { 12 | return ( 13 | 19 |

20 | {title} -> 21 |

22 |

{children}

23 |
24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /apps/web/src/components/ui/client-side-tweet.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { TweetProps, useTweet } from "react-tweet"; 4 | import { MagicTweet } from "./Client-tweet"; 5 | 6 | 7 | 8 | export const ClientTweetCard = ({ 9 | id, 10 | apiUrl, 11 | components, 12 | fetchOptions, 13 | ...props 14 | }: TweetProps & { className?: string }) => { 15 | const { data, error, } = useTweet(id, apiUrl, fetchOptions); 16 | 17 | if (error || !data) { 18 | 19 | return <> 20 | } 21 | 22 | return ; 23 | }; 24 | -------------------------------------------------------------------------------- /apps/web/src/lib/auth/protected-routes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Configuration for dashboard routes that require authentication. 3 | * 4 | * To add a new protected route, simply add the path to this array. 5 | * To remove protection from a route, remove it from this array. 6 | * 7 | * Routes are matched using prefix matching, so nested routes under 8 | * a protected path will also be protected (e.g., /dashboard/projects/123 9 | * is protected if /dashboard/projects is in this array). 10 | */ 11 | export const PROTECTED_DASHBOARD_ROUTES = [ 12 | "/dashboard/projects", 13 | "/dashboard/sheet", 14 | ] as const; 15 | -------------------------------------------------------------------------------- /apps/web/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | images: { 4 | remotePatterns: [ 5 | { 6 | protocol: "https", 7 | hostname: "avatars.githubusercontent.com", 8 | }, 9 | { 10 | protocol: "https", 11 | hostname: "lh3.googleusercontent.com", 12 | }, 13 | { 14 | protocol: "https", 15 | hostname: "img.youtube.com", 16 | }, 17 | ], 18 | }, 19 | experimental: { 20 | optimizePackageImports: ['lucide-react', '@heroicons/react'], 21 | }, 22 | }; 23 | 24 | module.exports = nextConfig; -------------------------------------------------------------------------------- /apps/web/src/components/ui/ActiveTag.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | 3 | interface ActiveTagProps { 4 | className?: string; 5 | text?: string; 6 | } 7 | 8 | export function ActiveTag({ className, text = "active" }: ActiveTagProps) { 9 | return ( 10 | 20 | {text} 21 | 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /packages/shared/types/projects.ts: -------------------------------------------------------------------------------- 1 | export type OptionsTypesProps = { 2 | sort?: "stars"; 3 | order?: "desc"; 4 | per_page?: number; 5 | page?: number; 6 | }; 7 | 8 | export type RepositoryProps = { 9 | id: string; 10 | name: string; 11 | description: string; 12 | url: string; 13 | owner: { 14 | avatarUrl: string; 15 | }; 16 | issues: { 17 | totalCount: number; 18 | }; 19 | primaryLanguage: { 20 | name: string; 21 | }; 22 | }; 23 | 24 | export type GraphQLResponseProps = { 25 | search: { 26 | nodes: RepositoryProps[]; 27 | repositoryCount: number; 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /apps/web/src/components/landing-page/QueryCount.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { fetchTotalQueries } from "@/utils/queries"; 4 | import { NumberTickerDisplay } from "../ui/NumberTickerDisplay"; 5 | import { useEffect, useState } from "react"; 6 | 7 | export const QueryCount = () => { 8 | const [count, setCount] = useState(713); 9 | 10 | useEffect(() => { 11 | const fetchData = async () => { 12 | const totalCount = await fetchTotalQueries(); 13 | setCount(Number(totalCount)); 14 | }; 15 | fetchData(); 16 | }, []); 17 | return ; 18 | }; 19 | -------------------------------------------------------------------------------- /apps/web/src/app/checkout/page.tsx: -------------------------------------------------------------------------------- 1 | import CheckoutWrapper from "@/components/checkout/CheckoutWrapper"; 2 | import Image from "next/image"; 3 | 4 | export default function Checkout() { 5 | return ( 6 |
7 | background 14 |
15 | 16 |
17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /packages/typescript-config/base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Default", 4 | "compilerOptions": { 5 | "declaration": true, 6 | "declarationMap": true, 7 | "esModuleInterop": true, 8 | "incremental": false, 9 | "isolatedModules": true, 10 | "lib": ["es2022", "DOM", "DOM.Iterable"], 11 | "module": "NodeNext", 12 | "moduleDetection": "force", 13 | "moduleResolution": "NodeNext", 14 | "noUncheckedIndexedAccess": true, 15 | "resolveJsonModule": true, 16 | "skipLibCheck": true, 17 | "strict": true, 18 | "target": "ES2022" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/docs/public/file-text.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/shared/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "outDir": "./dist", 11 | "declaration": true, 12 | "declarationMap": true, 13 | "sourceMap": true, 14 | "resolveJsonModule": true 15 | }, 16 | "include": [ 17 | "src/**/*", 18 | "types/**/*" 19 | ], 20 | "exclude": [ 21 | "node_modules", 22 | "dist" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /apps/docs/app/globals.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --background: #ffffff; 3 | --foreground: #171717; 4 | } 5 | 6 | @media (prefers-color-scheme: dark) { 7 | :root { 8 | --background: #0a0a0a; 9 | --foreground: #ededed; 10 | } 11 | } 12 | 13 | html, 14 | body { 15 | max-width: 100vw; 16 | overflow-x: hidden; 17 | } 18 | 19 | body { 20 | color: var(--foreground); 21 | background: var(--background); 22 | } 23 | 24 | * { 25 | box-sizing: border-box; 26 | padding: 0; 27 | margin: 0; 28 | } 29 | 30 | a { 31 | color: inherit; 32 | text-decoration: none; 33 | } 34 | 35 | @media (prefers-color-scheme: dark) { 36 | html { 37 | color-scheme: dark; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /apps/web/src/components/ui/IconWrapper.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { cn } from "@/lib/utils" 4 | import React from "react"; 5 | 6 | interface IconWrapperProps extends React.HTMLAttributes { 7 | children: React.ReactNode; 8 | } 9 | 10 | export const IconWrapper = ({ children, className, ...props }: IconWrapperProps) => { 11 | return ( 12 |
19 | {children} 20 |
21 | ) 22 | } -------------------------------------------------------------------------------- /apps/web/.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 | 32 | # env files (can opt-in for commiting if needed) 33 | .env* 34 | 35 | # vercel 36 | .vercel 37 | 38 | # typescript 39 | *.tsbuildinfo 40 | next-env.d.ts 41 | 42 | src/content/newsletters-premium/ -------------------------------------------------------------------------------- /apps/api/src/clients/razorpay.ts: -------------------------------------------------------------------------------- 1 | import Razorpay from "razorpay"; 2 | 3 | const RAZORPAY_KEY_ID = process.env.RAZORPAY_KEY_ID; 4 | const RAZORPAY_KEY_SECRET = process.env.RAZORPAY_KEY_SECRET; 5 | 6 | if (!RAZORPAY_KEY_ID) { 7 | throw new Error( 8 | "RAZORPAY_KEY_ID is required but not set in environment variables. Please configure it in your .env file." 9 | ); 10 | } 11 | 12 | if (!RAZORPAY_KEY_SECRET) { 13 | throw new Error( 14 | "RAZORPAY_KEY_SECRET is required but not set in environment variables. Please configure it in your .env file." 15 | ); 16 | } 17 | 18 | export const rz_instance = new Razorpay({ 19 | key_id: RAZORPAY_KEY_ID, 20 | key_secret: RAZORPAY_KEY_SECRET, 21 | }); 22 | -------------------------------------------------------------------------------- /apps/web/src/components/ui/SpinnerElm.tsx: -------------------------------------------------------------------------------- 1 | interface SpinnerProps { 2 | text: string; 3 | } 4 | 5 | export default function SpinnerElm({ text }: SpinnerProps) { 6 | return ( 7 |
8 |
12 |
13 | {text} 14 |
15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /apps/web/src/components/legal/LegalPageHeader.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | interface LegalPageHeaderProps { 4 | title: string; 5 | effectiveDate?: string; 6 | subtitle?: string; 7 | } 8 | 9 | export function LegalPageHeader({ 10 | title, 11 | effectiveDate, 12 | subtitle, 13 | }: LegalPageHeaderProps) { 14 | return ( 15 | <> 16 |

{title}

17 | {(effectiveDate || subtitle) && ( 18 |

19 | {effectiveDate 20 | ? `Effective date: ${effectiveDate}` 21 | : subtitle} 22 |

23 | )} 24 | 25 | ); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /apps/web/src/components/legal/LegalCard.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { cn } from "@/lib/utils"; 3 | 4 | interface LegalCardProps { 5 | children: React.ReactNode; 6 | className?: string; 7 | variant?: "default" | "highlighted"; 8 | } 9 | 10 | export function LegalCard({ 11 | children, 12 | className = "", 13 | variant = "default", 14 | }: LegalCardProps) { 15 | return ( 16 |
25 | {children} 26 |
27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /apps/web/src/components/sheet/SheetContentRenderer.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useEffect, useState } from "react"; 4 | import DOMPurify from "dompurify"; 5 | 6 | interface SheetContentRendererProps { 7 | content: string; 8 | className?: string; 9 | } 10 | 11 | export function SheetContentRenderer({ 12 | content, 13 | className, 14 | }: SheetContentRendererProps) { 15 | const [sanitizedContent, setSanitizedContent] = useState(""); 16 | 17 | useEffect(() => { 18 | setSanitizedContent(DOMPurify.sanitize(content)); 19 | }, [content]); 20 | 21 | return ( 22 |
26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "ui": "tui", 4 | "tasks": { 5 | "build": { 6 | "dependsOn": ["^build"], 7 | "inputs": ["$TURBO_DEFAULT$", ".env*"], 8 | "outputs": [".next/**", "!.next/cache/**", "dist/**"], 9 | "env": [ 10 | "GITHUB_TOKEN", 11 | "GIT_SSH_KEY", 12 | "NEXTAUTH_SECRET", 13 | "GOOGLE_CLIENT_ID", 14 | "GOOGLE_CLIENT_SECRET", 15 | "NEXTAUTH_URL", 16 | "GITHUB_CLIENT_ID", 17 | "GITHUB_CLIENT_SECRET" 18 | ] 19 | }, 20 | "lint": { 21 | "dependsOn": ["^lint"] 22 | }, 23 | "dev": { 24 | "cache": false, 25 | "persistent": true 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /apps/api/src/context.ts: -------------------------------------------------------------------------------- 1 | import type { CreateExpressContextOptions } from "@trpc/server/adapters/express"; 2 | import prisma from "./prisma.js"; 3 | import type { User } from "@prisma/client"; 4 | 5 | export async function createContext({ 6 | req, 7 | res, 8 | }: CreateExpressContextOptions): Promise<{ 9 | req: CreateExpressContextOptions["req"]; 10 | res: CreateExpressContextOptions["res"]; 11 | db: typeof prisma; 12 | ip?: string; 13 | user?: User | null; 14 | }> { 15 | const ip = req.ip || req.socket.remoteAddress || "unknown"; 16 | 17 | return { 18 | req, 19 | res, 20 | db: prisma, 21 | ip, 22 | user: null, 23 | }; 24 | } 25 | 26 | export type Context = Awaited>; 27 | -------------------------------------------------------------------------------- /apps/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev --turbo --port 3001", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@repo/ui": "workspace:*", 13 | "next": "14.2.35", 14 | "react": "18.3.1", 15 | "react-dom": "18.3.1" 16 | }, 17 | "devDependencies": { 18 | "@repo/eslint-config": "workspace:*", 19 | "@repo/typescript-config": "workspace:*", 20 | "@types/node": "^20", 21 | "@types/react": "^18", 22 | "@types/react-dom": "^18", 23 | "eslint": "^8", 24 | "eslint-config-next": "14.2.35", 25 | "typescript": "^5" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /apps/docs/public/window.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/web/src/hooks/useGetProjects.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { FilterProps, RepositoryProps } from "@opensox/shared/types"; 3 | import { trpc } from "@/lib/trpc"; 4 | 5 | export const useGetProjects = () => { 6 | const utils = trpc.useUtils(); 7 | 8 | const func = useCallback( 9 | async (filters: FilterProps): Promise => { 10 | const data = await (utils.client.project.getGithubProjects as any).query({ 11 | filters: filters as any, 12 | options: { 13 | sort: "stars" as const, 14 | order: "desc" as const, 15 | per_page: 30, 16 | page: 1, 17 | }, 18 | }); 19 | return data; 20 | }, 21 | [utils] 22 | ); 23 | return func; 24 | }; 25 | -------------------------------------------------------------------------------- /apps/web/src/components/blogs/BlogHeader.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import Link from "next/link"; 4 | 5 | export default function BlogHeader() { 6 | return ( 7 |
8 |
9 | 13 | Opensox AI (Ajeet) 14 | 15 | 19 | Home 20 | 21 |
22 |
23 | ); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /apps/web/src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Textarea = React.forwardRef< 6 | HTMLTextAreaElement, 7 | React.ComponentProps<"textarea"> 8 | >(({ className, ...props }, ref) => { 9 | return ( 10 |