├── app ├── favicon.ico ├── [not-found] │ └── page.tsx ├── api │ ├── leetcode │ │ ├── controllers │ │ │ ├── index.ts │ │ │ ├── fetchUserDetails.ts │ │ │ └── fetchDataRawFormat.ts │ │ └── userDetails │ │ │ └── route.ts │ ├── etc │ │ └── supabase-activity-scheduler │ │ │ └── route.ts │ └── auth │ │ ├── user │ │ └── route.ts │ │ └── register │ │ └── route.ts ├── styles │ └── style.css ├── auth │ ├── signin │ │ └── page.tsx │ ├── register │ │ └── page.tsx │ ├── forgot-password │ │ └── page.tsx │ ├── verify │ │ └── page.tsx │ └── reset-password │ │ └── page.tsx ├── layout.tsx ├── dashboard │ └── layout.tsx ├── not-found.tsx ├── actions │ └── action.ts ├── title.css ├── page.tsx └── globals.css ├── public ├── logo.png ├── dark-auth.jpg ├── hero-banner.png ├── light-auth.jpg ├── System-design.png ├── vercel.svg ├── window.svg ├── file.svg ├── grid.svg ├── PricingTick.svg ├── globe.svg └── next.svg ├── prisma ├── migrations │ ├── 20250108161333_usernamefix │ │ └── migration.sql │ ├── migration_lock.toml │ └── 20250108154722_init │ │ └── migration.sql └── schema.prisma ├── .env.example ├── postcss.config.mjs ├── utils ├── supabase │ ├── client.ts │ ├── server.ts │ └── middleware.ts ├── hashing.ts ├── problem.ts ├── detailedProblem.ts ├── leetcode │ ├── queryLeetCodeAPI.ts │ └── leetcodeContollers.ts └── userData.ts ├── lib ├── supabaseClient.ts ├── database │ └── prismaClient.ts ├── leetcode-calendar-theme.ts ├── utils.ts └── tags.ts ├── components ├── theme-provider.tsx ├── ui │ ├── skeleton.tsx │ ├── textarea.tsx │ ├── label.tsx │ ├── input.tsx │ ├── separator.tsx │ ├── sonner.tsx │ ├── resource-card.tsx │ ├── checkbox.tsx │ ├── tooltip.tsx │ ├── badge.tsx │ ├── support-section.tsx │ ├── avatar.tsx │ ├── alert.tsx │ ├── rainbow-button.tsx │ ├── scroll-area.tsx │ ├── tabs.tsx │ ├── button.tsx │ ├── card.tsx │ ├── accordion.tsx │ ├── shiny-button.tsx │ ├── ripple.tsx │ ├── percept-ui │ │ └── loader.tsx │ ├── hero-hihglight.tsx │ ├── background-gradient.tsx │ ├── table.tsx │ ├── navbar-menu.tsx │ ├── sparkles-text.tsx │ ├── sheet.tsx │ └── form.tsx ├── AuthComponent │ ├── AuthBottom.tsx │ ├── SearchParamsWrapper.tsx │ ├── LoadingButton.tsx │ └── Logout.tsx ├── DashboardV2 │ ├── Icons │ │ ├── XIcon.tsx │ │ ├── LinkedinIcon.tsx │ │ ├── GithubIcon.tsx │ │ └── DiscordIcon.tsx │ ├── ToggleTheme.tsx │ ├── CommunitySection.tsx │ ├── ServicesSection.tsx │ ├── HeroSection.tsx │ ├── BenefitsSection.tsx │ ├── FeaturesSection.tsx │ ├── FAQSection.tsx │ ├── FooterSection.tsx │ ├── PricingSection.tsx │ └── TeamSection.tsx ├── theme-toggle.tsx ├── HintCard.tsx └── dashboardComponents │ ├── MobileSidebar.tsx │ ├── DashboardNavbar.tsx │ └── AppSidebar.tsx ├── data └── SidebarData.ts ├── .github ├── workflows │ ├── ping.yml │ └── newContibuter.yaml ├── Pull_request_Template.md ├── ISSUE_TEMPLATE │ ├── Bug-report.yaml │ ├── General_issue.yaml │ └── Feature-Request.yaml └── FUNDING.yml ├── next.config.ts ├── eslint.config.mjs ├── Dockerfile ├── components.json ├── hooks ├── use-mobile.tsx └── useAuth.ts ├── middleware.ts ├── .gitignore ├── tsconfig.json ├── .dockerignore ├── validations └── validation.ts ├── GQL_Queries ├── recentSubmit.ts ├── recentAcSubmit.ts ├── languageStats.ts ├── contest.ts └── userProfile.ts ├── store ├── LeetcodeStore │ └── useLeetcodeStore.ts └── AuthStore │ └── useAuthStore.ts ├── package.json ├── CONTRIBUTING.md ├── README.md ├── types └── typeInterfaces.ts └── tailwind.config.ts /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashksaini-coder/Leetcode-Journal/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashksaini-coder/Leetcode-Journal/HEAD/public/logo.png -------------------------------------------------------------------------------- /public/dark-auth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashksaini-coder/Leetcode-Journal/HEAD/public/dark-auth.jpg -------------------------------------------------------------------------------- /public/hero-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashksaini-coder/Leetcode-Journal/HEAD/public/hero-banner.png -------------------------------------------------------------------------------- /public/light-auth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashksaini-coder/Leetcode-Journal/HEAD/public/light-auth.jpg -------------------------------------------------------------------------------- /public/System-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashksaini-coder/Leetcode-Journal/HEAD/public/System-design.png -------------------------------------------------------------------------------- /prisma/migrations/20250108161333_usernamefix/migration.sql: -------------------------------------------------------------------------------- 1 | -- DropIndex 2 | DROP INDEX "User_leetcodeUsername_key"; 3 | -------------------------------------------------------------------------------- /app/[not-found]/page.tsx: -------------------------------------------------------------------------------- 1 | import {notFound} from "next/navigation" 2 | 3 | export default function NotFoundCatchAll() { 4 | notFound() 5 | } -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_SUPABASE_URL = supabase_url 2 | NEXT_PUBLIC_SUPABASE_ANON_KEY = supabase_anon_key 3 | DATABASE_URL = database_url -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (e.g., Git) 3 | provider = "postgresql" -------------------------------------------------------------------------------- /app/api/leetcode/controllers/index.ts: -------------------------------------------------------------------------------- 1 | export { default as fetchUserDetails } from './fetchUserDetails'; 2 | export { default as fetchDataRawFormat } from './fetchDataRawFormat'; -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/styles/style.css: -------------------------------------------------------------------------------- 1 | .react-calendar-heatmap .color-scale-1 { fill: #d6e685; } 2 | .react-calendar-heatmap .color-scale-2 { fill: #8cc665; } 3 | .react-calendar-heatmap .color-scale-3 { fill: #44a340; } 4 | .react-calendar-heatmap .color-scale-4 { fill: #1e6823; } -------------------------------------------------------------------------------- /utils/supabase/client.ts: -------------------------------------------------------------------------------- 1 | import { createBrowserClient } from '@supabase/ssr' 2 | 3 | export function createClient() { 4 | return createBrowserClient( 5 | process.env.NEXT_PUBLIC_SUPABASE_URL!, 6 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! 7 | ) 8 | } -------------------------------------------------------------------------------- /app/auth/signin/page.tsx: -------------------------------------------------------------------------------- 1 | import SigninForm from "@/components/AuthComponent/SigninForm"; 2 | 3 | export default function SignupPage() { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /lib/supabaseClient.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from '@supabase/supabase-js'; 2 | 3 | const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; 4 | const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!; 5 | 6 | export const supabase = createClient(supabaseUrl, supabaseAnonKey); 7 | -------------------------------------------------------------------------------- /app/api/etc/supabase-activity-scheduler/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from 'next/server'; 2 | 3 | export async function GET() { 4 | return NextResponse.json({ 5 | message: 'Backend API service is healthy', 6 | status: 'healthy', 7 | timestamp: new Date().toISOString() 8 | }, { status: 200 }); 9 | } 10 | -------------------------------------------------------------------------------- /components/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /data/SidebarData.ts: -------------------------------------------------------------------------------- 1 | import { FileQuestion, Settings } from "lucide-react"; 2 | 3 | export const SidebarData = [ 4 | { 5 | title: "Dashboard", 6 | icon: Settings, 7 | href: "/dashboard", 8 | }, 9 | { 10 | title: "Problems", 11 | icon: FileQuestion, 12 | href: "/dashboard/problems", 13 | }, 14 | ]; 15 | -------------------------------------------------------------------------------- /utils/hashing.ts: -------------------------------------------------------------------------------- 1 | import bcrypt from 'bcryptjs'; 2 | 3 | export const hashPassword = async (password: string) => { 4 | const salt = await bcrypt.genSalt(10); 5 | return await bcrypt.hash(password, salt); 6 | } 7 | 8 | export const comparePassword = async (password: string, hashedPassword: string) => { 9 | return await bcrypt.compare(password, hashedPassword); 10 | } -------------------------------------------------------------------------------- /public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/database/prismaClient.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client'; 2 | 3 | let prisma: PrismaClient; 4 | 5 | if (process.env.NODE_ENV === 'production') { 6 | prisma = new PrismaClient(); 7 | } else { 8 | const globalAny: any = global; 9 | if (!globalAny.prisma) { 10 | globalAny.prisma = new PrismaClient(); 11 | } 12 | prisma = globalAny.prisma; 13 | } 14 | 15 | export default prisma; -------------------------------------------------------------------------------- /public/grid.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.github/workflows/ping.yml: -------------------------------------------------------------------------------- 1 | # .github/workflows/supabase-activity-scheduler.yml 2 | 3 | name: Supabase Activity Scheduler 4 | 5 | on: 6 | schedule: 7 | - cron: "0 0 * * *" # Runs at 00:00 every day 8 | workflow_dispatch: 9 | 10 | jobs: 11 | send-http-request: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Send HTTP Request 16 | run: curl -X GET https://leetcode-journal.vercel.app/api/etc/supabase-activity-scheduler -------------------------------------------------------------------------------- /next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | /* config options here */ 5 | eslint: { 6 | ignoreDuringBuilds: true, // Ignores all ESLint warnings and errors during builds 7 | }, 8 | images: { 9 | remotePatterns: [ 10 | { 11 | protocol: 'https', 12 | hostname: '**', // Match any hostname 13 | }, 14 | ], 15 | }, 16 | }; 17 | 18 | export default nextConfig; 19 | -------------------------------------------------------------------------------- /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 | 16 | export default eslintConfig; 17 | -------------------------------------------------------------------------------- /.github/Pull_request_Template.md: -------------------------------------------------------------------------------- 1 | # Pull Request Template 2 | 3 | ## Summary 4 | Just write what issue worked on and how it is working now. 5 | 6 | Fixes # (issue) 7 | 8 | ## Type of Change 9 | Please mark [X] for applicable items: 10 | 11 | - [ ] Bug fix (non-breaking change which fixes an issue) 12 | - [ ] New feature (non-breaking change which adds functionality) 13 | 14 | ## Screenshots/Videos (optional) 15 | Please attach relevant screenshots or videos demonstrating the changes. -------------------------------------------------------------------------------- /components/AuthComponent/AuthBottom.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import React from "react"; 3 | 4 | interface AuthBottomProps { 5 | href: string; 6 | title: string; 7 | toTitle: string; 8 | } 9 | 10 | export default function AuthBottom({ href, title, toTitle }: AuthBottomProps) { 11 | return ( 12 | 13 | {title} {toTitle} 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /lib/leetcode-calendar-theme.ts: -------------------------------------------------------------------------------- 1 | export const exampleTheme = { 2 | light: [ 3 | 'rgb(235, 235, 235)', 4 | 'rgba(192, 132, 245, 0.44)', 5 | 'rgba(192, 132, 245, 0.6)', 6 | 'rgba(192, 132, 245, 0.76)', 7 | 'rgba(192, 132, 245, 0.92)', 8 | ], 9 | dark: [ 10 | 'rgb(235, 235, 235)', 11 | 'rgba(192, 132, 245, 0.44)', 12 | 'rgba(192, 132, 245, 0.6)', 13 | 'rgba(192, 132, 245, 0.76)', 14 | 'rgba(192, 132, 245, 0.92)', 15 | ], 16 | }; -------------------------------------------------------------------------------- /utils/problem.ts: -------------------------------------------------------------------------------- 1 | export type TopicTag = { 2 | name: string; 3 | id: string; 4 | slug: string; 5 | }; 6 | 7 | export type Problem = { 8 | acRate: number; 9 | difficulty: 'Easy' | 'Medium' | 'Hard'; 10 | freqBar: number | null; 11 | questionFrontendId: string; 12 | isFavor: boolean; 13 | isPaidOnly: boolean; 14 | status: string | null; 15 | title: string; 16 | titleSlug: string; 17 | topicTags: TopicTag[]; 18 | hasSolution: boolean; 19 | hasVideoSolution: boolean; 20 | }; -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official Node.js image as the base image 2 | FROM node:22 3 | 4 | # Set the working directory inside the container 5 | WORKDIR /app 6 | 7 | # Copy package.json and package-lock.json to the working directory 8 | COPY prisma ./prisma package*.json ./ 9 | 10 | # Install dependencies 11 | RUN npm install 12 | 13 | # Copy the rest of the application code to the working directory 14 | COPY . . 15 | 16 | # Expose the port the app runs on 17 | EXPOSE 3000 18 | 19 | # Command to run the application 20 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "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 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /app/auth/register/page.tsx: -------------------------------------------------------------------------------- 1 | import { Suspense } from "react"; 2 | import SignupForm from "@/components/AuthComponent/SignupForm"; 3 | import SearchParamsWrapper from "@/components/AuthComponent/SearchParamsWrapper"; 4 | 5 | 6 | export default function SignupPage() { 7 | return ( 8 |
9 | Loading...
}> 10 | 11 | 12 | 13 | 14 |
15 | ); 16 | } -------------------------------------------------------------------------------- /utils/detailedProblem.ts: -------------------------------------------------------------------------------- 1 | type Difficulty = 'All' | 'Easy' | 'Medium' | 'Hard'; 2 | 3 | export interface DetailedProblem { 4 | content: string; 5 | companyTagStats: string[]; 6 | difficulty: Difficulty; 7 | dislikes: number; 8 | exampleTestcases: object[]; 9 | hints: []; 10 | isPaidOnly: boolean; 11 | likes: number; 12 | questionId: number; 13 | questionFrontendId: number; 14 | solution: string; 15 | similarQuestions: object[]; 16 | title: string; 17 | titleSlug: string; 18 | topicTags: string[]; 19 | } 20 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { clsx, type ClassValue } from "clsx" 3 | import { twMerge } from "tailwind-merge" 4 | 5 | export function cn(...inputs: ClassValue[]) { 6 | return twMerge(clsx(inputs)) 7 | } 8 | 9 | export const fetchLeetCodeStats = async (username: string,id: string) => { 10 | try { 11 | const response = await axios.post(`/api/leetcode?username=${username}&id=${id}`); 12 | return response.data; 13 | } catch (error) { 14 | console.error('Error fetching LeetCode stats:', error); 15 | return null; 16 | } 17 | }; -------------------------------------------------------------------------------- /components/DashboardV2/Icons/XIcon.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | function XIcon(props: React.SVGProps | undefined) { 4 | return ( 5 | 13 | 14 | 15 | ); 16 | } 17 | 18 | export default XIcon; -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug-report.yaml: -------------------------------------------------------------------------------- 1 | name: ​🐞 Bug 2 | description: Report an issue to help us improve the project. 3 | title: "[BUG] write a title here" 4 | labels: ["bug"] 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: Description 9 | description: A brief description of the issue or bug you are facing, also include what you tried and what didn't work. 10 | validations: 11 | required: true 12 | 13 | - type: textarea 14 | attributes: 15 | label: Screenshots 16 | description: Please add screenshots if applicable 17 | validations: 18 | required: false -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /middleware.ts: -------------------------------------------------------------------------------- 1 | import { type NextRequest } from 'next/server' 2 | import { updateSession } from '@/utils/supabase/middleware' 3 | 4 | export async function middleware(request: NextRequest) { 5 | return await updateSession(request) 6 | } 7 | 8 | export const config = { 9 | matcher: [ 10 | /* 11 | * Match all request paths except for the ones starting with: 12 | * - _next/static (static files) 13 | * - _next/image (image optimization files) 14 | * - favicon.ico (favicon file) 15 | * Feel free to modify this pattern to include more paths. 16 | */ 17 | '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)', 18 | ], 19 | } -------------------------------------------------------------------------------- /.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 | 43 | /app/test -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Environment files 2 | .env 3 | .env.* 4 | *.env 5 | 6 | # Version control 7 | .git 8 | .gitignore 9 | .svn 10 | .hg 11 | 12 | # Development files 13 | node_modules 14 | venv 15 | __pycache__ 16 | *.pyc 17 | *.pyo 18 | *.pyd 19 | .Python 20 | .pytest_cache 21 | .coverage 22 | coverage 23 | .tox 24 | 25 | # IDE specific files 26 | .idea 27 | .vscode 28 | *.swp 29 | *.swo 30 | .DS_Store 31 | 32 | # Build and dist directories 33 | dist 34 | build 35 | *.egg-info 36 | 37 | # Log files 38 | *.log 39 | logs 40 | npm-debug.log* 41 | 42 | # Docker specific 43 | Dockerfile 44 | docker-compose*.yml 45 | .docker 46 | 47 | # Documentation 48 | docs 49 | README.md 50 | CHANGELOG.md 51 | LICENSE 52 | 53 | # Test files 54 | test 55 | tests -------------------------------------------------------------------------------- /validations/validation.ts: -------------------------------------------------------------------------------- 1 | import * as z from "zod"; 2 | 3 | export const signupSchema = z.object({ 4 | fullName: z.string().min(2, "Full name must be at least 2 characters"), 5 | email: z.string().email("Invalid email address"), 6 | password: z 7 | .string() 8 | .min(6, "Password must be at least 6 characters") 9 | .max(100, "Password must be less than 100 characters"), 10 | leetcodeUsername: z.string().min(1, "LeetCode username is required"), 11 | gender: z.enum(["male", "female", "other"], { 12 | required_error: "Please select a gender", 13 | }), 14 | }); 15 | 16 | export const signinSchema = z.object({ 17 | email: z.string().email("Invalid email address"), 18 | password: z.string().min(1, "Password is required"), 19 | }); 20 | -------------------------------------------------------------------------------- /components/AuthComponent/SearchParamsWrapper.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useSearchParams } from "next/navigation"; 4 | import React from "react"; 5 | 6 | interface ChildProps { 7 | searchParams?: ReturnType; 8 | } 9 | 10 | export default function SearchParamsWrapper({ 11 | children 12 | }: { 13 | children: React.ReactNode 14 | }) { 15 | const searchParams = useSearchParams(); 16 | 17 | return ( 18 | <> 19 | {React.Children.map(children, child => { 20 | if (React.isValidElement(child)) { 21 | return React.cloneElement(child, { searchParams }); 22 | } 23 | return child; 24 | })} 25 | 26 | ); 27 | } -------------------------------------------------------------------------------- /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 |