├── public ├── i.jpeg ├── git.jpeg ├── favicon.png └── github.png ├── app ├── favicon.ico ├── layout.tsx ├── globals.css ├── howtouse │ └── page.tsx └── page.tsx ├── .github └── FUNDING.yml ├── next.config.js ├── postcss.config.js ├── lib └── utils.ts ├── components.json ├── .gitignore ├── tailwind.config.ts ├── README.md ├── tsconfig.json ├── components ├── ui │ ├── label.tsx │ ├── input.tsx │ ├── button.tsx │ └── card.tsx ├── footer.tsx ├── header.tsx └── gpa.tsx └── package.json /public/i.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3hu1/gpa-calculator/HEAD/public/i.jpeg -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3hu1/gpa-calculator/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /public/git.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3hu1/gpa-calculator/HEAD/public/git.jpeg -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: m3hu1 4 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3hu1/gpa-calculator/HEAD/public/favicon.png -------------------------------------------------------------------------------- /public/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3hu1/gpa-calculator/HEAD/public/github.png -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {} 3 | 4 | module.exports = nextConfig 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /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": "gray", 10 | "cssVariables": false 11 | }, 12 | "aliases": { 13 | "utils": "@/lib/utils", 14 | "components": "@/components" 15 | } 16 | } -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Analytics } from '@vercel/analytics/react'; 2 | 3 | import type { Metadata } from "next"; 4 | import "./globals.css"; 5 | 6 | export const metadata: Metadata = { 7 | title: "BU GPA Calculator", 8 | description: "GPA Calculator for Bennett University Students", 9 | }; 10 | 11 | export default function RootLayout({ 12 | children, 13 | }: { 14 | children: React.ReactNode; 15 | }) { 16 | return ( 17 | 18 | {children} 19 | 20 | ); 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 | .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 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'tailwindcss' 2 | 3 | const config: Config = { 4 | darkMode: 'class', 5 | content: [ 6 | './pages/**/*.{js,ts,jsx,tsx,mdx}', 7 | './components/**/*.{js,ts,jsx,tsx,mdx}', 8 | './app/**/*.{js,ts,jsx,tsx,mdx}', 9 | ], 10 | theme: { 11 | extend: { 12 | backgroundImage: { 13 | 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 14 | 'gradient-conic': 15 | 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', 16 | }, 17 | }, 18 | }, 19 | plugins: [require("tailwindcss-animate")], 20 | } 21 | export default config 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GPA Calculator for BU Students (BTech CSE) 2 | 3 | A web application built using Next.js that allows students to calculate their GPA based on the courses they have taken. Course details such as course name, credits, and grade are taken as input and the application provides the calculated GPA. 4 | 5 | ## Technologies Used 6 | 7 | - Next.js 8 | - Tailwind CSS 9 | - React 10 | - TypeScript 11 | 12 | `Developed by Mehul` 13 | 14 | ## Contributors 15 | 16 | 17 | 18 | 19 |

20 | Thanks for contributing! 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 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 | -------------------------------------------------------------------------------- /components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface InputProps 6 | extends React.InputHTMLAttributes {} 7 | 8 | const Input = React.forwardRef( 9 | ({ className, type, ...props }, ref) => { 10 | return ( 11 | 20 | ) 21 | } 22 | ) 23 | Input.displayName = "Input" 24 | 25 | export { Input } 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bugpa", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@radix-ui/react-icons": "^1.3.0", 13 | "@radix-ui/react-label": "^2.0.2", 14 | "@radix-ui/react-slot": "^1.0.2", 15 | "@vercel/analytics": "^1.1.1", 16 | "class-variance-authority": "^0.7.0", 17 | "clsx": "^2.0.0", 18 | "lucide-react": "^0.300.0", 19 | "next": "14.0.4", 20 | "next-themes": "^0.2.1", 21 | "react": "^18", 22 | "react-dom": "^18", 23 | "react-select": "^5.8.0", 24 | "react-typist-component": "^1.0.5", 25 | "tailwind-merge": "^2.2.0", 26 | "tailwindcss-animate": "^1.0.7" 27 | }, 28 | "devDependencies": { 29 | "@types/node": "^20", 30 | "@types/react": "^18", 31 | "@types/react-dom": "^18", 32 | "autoprefixer": "^10.0.1", 33 | "postcss": "^8", 34 | "tailwindcss": "^3.3.0", 35 | "typescript": "^5" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400&display=swap'); 6 | 7 | html, body { 8 | font-family: 'JetBrains Mono', monospace; 9 | } 10 | 11 | .custom-text-color { 12 | color: #2fed9d; 13 | } 14 | 15 | .custom-text-color-2 { 16 | color: #45474F; 17 | } 18 | 19 | .custom-text-color-3 { 20 | color: #E56B6F; 21 | } 22 | 23 | :root { 24 | --foreground-rgb: 0, 0, 0; 25 | --background-start-rgb: 214, 219, 220; 26 | --background-end-rgb: 255, 255, 255; 27 | } 28 | 29 | @media (prefers-color-scheme: dark) { 30 | :root { 31 | --foreground-rgb: 255, 255, 255; 32 | --background-start-rgb: 0, 0, 0; 33 | --background-end-rgb: 0, 0, 0; 34 | } 35 | } 36 | 37 | @keyframes grow { 38 | 0% { 39 | transform: scale(1); 40 | } 41 | 50% { 42 | transform: scale(1.1); 43 | } 44 | 100% { 45 | transform: scale(1); 46 | } 47 | } 48 | 49 | .howToUse { 50 | animation: grow 1s 3 forwards; 51 | } 52 | 53 | body { 54 | color: rgb(var(--foreground-rgb)); 55 | background: linear-gradient( 56 | to bottom, 57 | transparent, 58 | rgb(var(--background-end-rgb)) 59 | ) 60 | rgb(var(--background-start-rgb)); 61 | } 62 | -------------------------------------------------------------------------------- /components/footer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "next/link"; 3 | import Typist from "@/node_modules/react-typist-component"; 4 | 5 | const Footer = () => { 6 | return ( 7 |
8 | 9 |

10 | Developed by{" "} 11 | {/* */} 17 | Mehul 18 | {/* */} 19 |

20 |

21 | {" "} 22 | 28 | Instagram Logo 33 | GitHub 34 | 35 |

36 |

37 | {" "} 38 | 44 | Instagram Logo 49 | Instagram 50 | 51 |

52 |
53 |
54 | ); 55 | }; 56 | 57 | export default Footer; 58 | -------------------------------------------------------------------------------- /components/header.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React from "react"; 3 | import Link from "next/link"; 4 | import { Button } from "@/components/ui/button"; 5 | import Typist from "@/node_modules/react-typist-component"; 6 | 7 | const Header = () => { 8 | return ( 9 |
10 |
11 | Logo 12 | 13 | |}> 14 | 15 | GPA Calculator 16 | 17 | 18 | 19 | 20 | GPA Calculate Kar 21 | 22 | 23 | or 24 | 25 | 26 | 27 |
28 |
29 | 30 | How to Use 31 | 32 | 33 | 46 | 47 |
48 |
49 | ); 50 | }; 51 | 52 | export default Header; 53 | -------------------------------------------------------------------------------- /components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const buttonVariants = cva( 8 | "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", 9 | { 10 | variants: { 11 | variant: { 12 | default: "bg-primary text-primary-foreground hover:bg-primary/90", 13 | destructive: 14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90", 15 | outline: 16 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground", 17 | secondary: 18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80", 19 | ghost: "hover:bg-accent hover:text-accent-foreground", 20 | link: "text-primary underline-offset-4 hover:underline", 21 | }, 22 | size: { 23 | default: "h-10 px-4 py-2", 24 | sm: "h-9 rounded-md px-3", 25 | lg: "h-11 rounded-md px-8", 26 | icon: "h-10 w-10", 27 | }, 28 | }, 29 | defaultVariants: { 30 | variant: "default", 31 | size: "default", 32 | }, 33 | } 34 | ) 35 | 36 | export interface ButtonProps 37 | extends React.ButtonHTMLAttributes, 38 | VariantProps { 39 | asChild?: boolean 40 | } 41 | 42 | const Button = React.forwardRef( 43 | ({ className, variant, size, asChild = false, ...props }, ref) => { 44 | const Comp = asChild ? Slot : "button" 45 | return ( 46 | 51 | ) 52 | } 53 | ) 54 | Button.displayName = "Button" 55 | 56 | export { Button, buttonVariants } 57 | -------------------------------------------------------------------------------- /components/ui/card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Card = React.forwardRef< 6 | HTMLDivElement, 7 | React.HTMLAttributes 8 | >(({ className, ...props }, ref) => ( 9 |
17 | )) 18 | Card.displayName = "Card" 19 | 20 | const CardHeader = React.forwardRef< 21 | HTMLDivElement, 22 | React.HTMLAttributes 23 | >(({ className, ...props }, ref) => ( 24 |
29 | )) 30 | CardHeader.displayName = "CardHeader" 31 | 32 | const CardTitle = React.forwardRef< 33 | HTMLParagraphElement, 34 | React.HTMLAttributes 35 | >(({ className, ...props }, ref) => ( 36 |

44 | )) 45 | CardTitle.displayName = "CardTitle" 46 | 47 | const CardDescription = React.forwardRef< 48 | HTMLParagraphElement, 49 | React.HTMLAttributes 50 | >(({ className, ...props }, ref) => ( 51 |

56 | )) 57 | CardDescription.displayName = "CardDescription" 58 | 59 | const CardContent = React.forwardRef< 60 | HTMLDivElement, 61 | React.HTMLAttributes 62 | >(({ className, ...props }, ref) => ( 63 |

64 | )) 65 | CardContent.displayName = "CardContent" 66 | 67 | const CardFooter = React.forwardRef< 68 | HTMLDivElement, 69 | React.HTMLAttributes 70 | >(({ className, ...props }, ref) => ( 71 |
76 | )) 77 | CardFooter.displayName = "CardFooter" 78 | 79 | export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } 80 | -------------------------------------------------------------------------------- /components/gpa.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from "@/components/ui/button" 2 | import { CardTitle, CardDescription, CardHeader, CardContent, CardFooter, Card } from "@/components/ui/card" 3 | import { Label } from "@/components/ui/label" 4 | import { Input } from "@/components/ui/input" 5 | 6 | export function gpa() { 7 | return ( 8 |
9 |
10 |
11 | GPA Calculator 12 |
13 | 27 |
28 |
29 | 30 | 31 | Add Course 32 | Enter your course details below 33 | 34 | 35 |
36 | 37 | 38 |
39 |
40 | 41 | 42 |
43 |
44 | 45 | 46 |
47 |
48 | 49 | 50 | 51 |
52 | 53 | 54 | Your Courses 55 | All your added courses will appear here 56 | 57 | 58 |
59 |

No courses added yet.

60 |
61 |
62 |
63 | 64 | 65 | Your GPA 66 | Your calculated GPA will appear here 67 | 68 | 69 |

-

70 |
71 |
72 |
73 |
74 | ) 75 | } 76 | 77 | export default gpa; 78 | -------------------------------------------------------------------------------- /app/howtouse/page.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Header from "@/components/header"; 3 | import { CardTitle, CardHeader, Card } from "@/components/ui/card"; 4 | 5 | const HowToUse = () => { 6 | return ( 7 |
8 |
9 |
10 | 11 | 12 | 13 | How to Use 14 | 15 |
16 |
17 |

18 | To help you estimate your GPA, I have provided grade ranges 19 | based on the total marks scored last year. These ranges are 20 | indicative and can serve as a guide for predicting your expected 21 | grades. 22 |

23 |
24 |

Here are the average marks associated with each grade:

25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
GradeTotal Marks
A+80+
A71-80
B+61-70
B52-60
C+43-51
C35-42
D32-35
FBelow 32
68 |
69 |

70 | To calculate your GPA, you can select your expected grades based 71 | on your total marks. Use these ranges as a reference while 72 | selecting your grades. 73 |

74 |
75 |

76 | Remember, this tool is designed to provide an estimate, and the 77 | actual grading criteria may vary. Some subjects have higher 78 | average marks, and some have lower, so the criteria for 79 | different subjects can differ. Feel free to add your courses, 80 | enter your grades, and let the GPA Calculator do the math for 81 | you! 82 |

83 |
84 |
85 |
86 |
87 |
88 | ); 89 | }; 90 | 91 | export default HowToUse; 92 | -------------------------------------------------------------------------------- /app/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useState } from "react"; 4 | import { Button } from "@/components/ui/button"; 5 | import { 6 | CardTitle, 7 | CardDescription, 8 | CardHeader, 9 | CardContent, 10 | CardFooter, 11 | Card, 12 | } from "@/components/ui/card"; 13 | import { Label } from "@/components/ui/label"; 14 | import { Input } from "@/components/ui/input"; 15 | import Select from "react-select"; 16 | import Header from "@/components/header"; 17 | import Footer from "@/components/footer"; 18 | import Script from "next/script"; 19 | 20 | interface CustomStyles { 21 | control: (provided: any, state: any) => any; 22 | option: (provided: any, state: any) => any; 23 | menu: (provided: any) => any; 24 | singleValue: (provided: any) => any; 25 | placeholder: (provided: any) => any; 26 | } 27 | 28 | const customStyles: CustomStyles = { 29 | control: (provided) => ({ 30 | ...provided, 31 | border: "1px solid #ccc", 32 | borderRadius: "5px", 33 | backgroundColor: "#1E1E1E", 34 | }), 35 | option: (provided, state) => ({ 36 | ...provided, 37 | backgroundColor: state.isSelected ? "#1E1E1E" : "#1E1E1E", 38 | }), 39 | menu: (provided) => ({ 40 | ...provided, 41 | backgroundColor: "#1E1E1E", 42 | }), 43 | singleValue: (provided) => ({ 44 | ...provided, 45 | color: "white", 46 | }), 47 | placeholder: (provided) => ({ 48 | ...provided, 49 | color: "#9CA3AF", 50 | fontSize: "14px", 51 | }), 52 | }; 53 | 54 | interface Course { 55 | name: string; 56 | credits: number; 57 | grade: string; 58 | } 59 | 60 | const Page = () => { 61 | const [isClearable, setIsClearable] = useState(true); 62 | const [isCustomCourse, setIsCustomCourse] = useState(false); 63 | const [customCourseCode, setCustomCourseCode] = useState(""); 64 | const [courses, setCourses] = useState([]); 65 | const [selectedCourse, setSelectedCourse] = useState<{ 66 | value: string; 67 | label: string; 68 | credits: number; 69 | } | null>(null); 70 | const [selectedCredits, setSelectedCredits] = useState(""); 71 | const [selectedGrade, setSelectedGrade] = useState(null); 72 | const [selectedYear, setSelectedYear] = useState<{ 73 | value: string; 74 | label: string; 75 | } | null>(null); 76 | const gradeOptions: { value: string; label: string }[] = [ 77 | { value: "A+", label: "A+" }, 78 | { value: "A", label: "A" }, 79 | { value: "B+", label: "B+" }, 80 | { value: "B", label: "B" }, 81 | { value: "C+", label: "C+" }, 82 | { value: "C", label: "C" }, 83 | { value: "D", label: "D" }, 84 | { value: "F", label: "F" }, 85 | ]; 86 | const courseOptions: { 87 | label: string; 88 | options: { value: string; label: string; credits: number }[]; 89 | }[] = [ 90 | { 91 | label: "1st Year", 92 | options: [ 93 | { 94 | value: "CSET101", 95 | label: "Computational Thinking and Programming", 96 | credits: 5, 97 | }, 98 | { value: "EMAT101", label: "Engineering Calculus ", credits: 4 }, 99 | { 100 | value: "EPHY111L", 101 | label: "Electromagnetics + Mechanics", 102 | credits: 5, 103 | }, 104 | { 105 | value: "CSET108", 106 | label: "Environment and Sustainability", 107 | credits: 3, 108 | }, 109 | { 110 | value: "CSET107", 111 | label: "Foundations of Innovation and Entrepreneurship", 112 | credits: 2, 113 | }, 114 | { value: "CSET103 ", label: "New Age Life Skills", credits: 2 }, 115 | { 116 | value: "CSET102", 117 | label: "Introduction to Electrical and Electronics Engineering", 118 | credits: 4, 119 | }, 120 | { 121 | value: "EMAT102", 122 | label: "Linear Algebra and Ordinary Differential Equations", 123 | credits: 4, 124 | }, 125 | { 126 | value: "CSET106", 127 | label: "Discrete Mathematical Structures", 128 | credits: 4, 129 | }, 130 | { value: "CSET105", label: "Digital Design", credits: 4 }, 131 | { 132 | value: "CSET109", 133 | label: "Object Oriented Programming using Java", 134 | credits: 6, 135 | }, 136 | { 137 | value: "CUSTOM", 138 | label: "Custom Course", 139 | credits: 0, 140 | }, 141 | ], 142 | }, 143 | { 144 | label: "2nd Year", 145 | options: [ 146 | { 147 | value: "CSET201", 148 | label: "Information Management Systems", 149 | credits: 4, 150 | }, 151 | { value: "CSET202", label: "Data Structures using C++", credits: 7 }, 152 | { 153 | value: "CSET203", 154 | label: "Microprocessors and Computer Architecture", 155 | credits: 4, 156 | }, 157 | { value: "CSET240", label: "Probability and Statistics", credits: 5 }, 158 | { value: "CSET205", label: "Software Engineering", credits: 4 }, 159 | { value: "CSET211", label: "AI", credits: 3 }, 160 | { value: "CSET212", label: "Blockchain", credits: 3 }, 161 | { value: "CSET213", label: "Cyber Security", credits: 3 }, 162 | { value: "CSET214", label: "Data Science", credits: 3 }, 163 | { value: "CSET216", label: "Core", credits: 3 }, 164 | { 165 | value: "CSET217", 166 | label: "DevOps", 167 | credits: 3, 168 | }, 169 | { value: "CSET218", label: "Full Stack", credits: 3 }, 170 | { value: "CSET224", label: "Cloud", credits: 3 }, 171 | { 172 | value: "CSET206", 173 | label: "Design and Analysis of Algorithms", 174 | credits: 6, 175 | }, 176 | { 177 | value: "CSET207", 178 | label: "Computer Networks", 179 | credits: 4, 180 | }, 181 | { 182 | value: "CSET208", 183 | label: "Ethics for Engineers, Patents, Copyrights and IPR", 184 | credits: 1, 185 | }, 186 | { 187 | value: "CSET209", 188 | label: "Operating Systems", 189 | credits: 4, 190 | }, 191 | { 192 | value: "CSET210", 193 | label: "Design Thinking & Innovation", 194 | credits: 2, 195 | }, 196 | { value: "CSETxxx", label: "Biological Machines", credits: 3 }, 197 | { value: "CSETxxx", label: "Growth Hacking", credits: 3 }, 198 | { 199 | value: "CSETxxx", 200 | label: "Linux Apache MySQL PHP (LAMP)", 201 | credits: 3, 202 | }, 203 | { value: "CSETxxx", label: "Fostering Mental Health", credits: 3 }, 204 | { 205 | value: "CSETxxx", 206 | label: "Quality and Reliability Engineering", 207 | credits: 3, 208 | }, 209 | { value: "CSETxxx", label: "Sociology Of Gender", credits: 3 }, 210 | { value: "CUSTOM", label: "Custom Course", credits: 0 }, 211 | ], 212 | }, 213 | { 214 | label: "3rd Year", 215 | options: [ 216 | { 217 | value: "CSET301", 218 | label: "Artificial Intelligence and Machine Learning ", 219 | credits: 5, 220 | }, 221 | { 222 | value: "CSET302", 223 | label: "Automata Theory and Computability", 224 | credits: 4, 225 | }, 226 | { 227 | value: "CSET305", 228 | label: "High Performance Computing ", 229 | credits: 4, 230 | }, 231 | { 232 | value: "CSET303", 233 | label: "Seminar on Special Topics in Emerging Areas", 234 | credits: 1, 235 | }, 236 | { 237 | value: "CSET304", 238 | label: "Competitive Programming", 239 | credits: 2, 240 | }, 241 | { 242 | value: "CSETxxx", 243 | label: "Specialization Elective", 244 | credits: 3, 245 | }, 246 | { 247 | value: "CSETxxx", 248 | label: "Open Elective", 249 | credits: 3, 250 | }, 251 | { value: "CUSTOM", label: "Custom Course", credits: 0 }, 252 | ], 253 | }, 254 | ]; 255 | 256 | const deleteCourse = (index: number) => { 257 | const updatedCourses = [...courses]; 258 | updatedCourses.splice(index, 1); 259 | setCourses(updatedCourses); 260 | }; 261 | 262 | const addCourse = () => { 263 | if ( 264 | (selectedCourse && selectedCourse.value !== "Select...") || 265 | (isCustomCourse && customCourseCode) 266 | ) { 267 | const newCourse = { 268 | name: isCustomCourse ? customCourseCode : selectedCourse?.value || "", 269 | credits: parseInt(selectedCredits), 270 | grade: selectedGrade || "", 271 | }; 272 | 273 | setCourses([...courses, newCourse]); 274 | setSelectedCourse(null); 275 | setIsCustomCourse(false); 276 | setCustomCourseCode(""); 277 | setSelectedCredits(""); 278 | setSelectedGrade(null); 279 | } 280 | }; 281 | 282 | const handleKeyPress = (e: React.KeyboardEvent) => { 283 | if (e.key === "Enter") { 284 | addCourse(); 285 | } 286 | }; 287 | 288 | const calculateGPA = () => { 289 | const totalCredits = courses.reduce( 290 | (acc, course) => acc + course.credits, 291 | 0 292 | ); 293 | const totalScore = courses.reduce((acc, course) => { 294 | const gradeScore = getGradeScore(course.grade); 295 | return acc + gradeScore * course.credits; 296 | }, 0); 297 | 298 | const rawGPA = totalCredits === 0 ? 0 : totalScore / totalCredits; 299 | const roundedGPA = parseFloat(rawGPA.toFixed(2)); 300 | return roundedGPA; 301 | }; 302 | 303 | const getGradeScore = (grade: string) => { 304 | const gradeScores: Record = { 305 | "A+": 10, 306 | A: 9, 307 | "B+": 8, 308 | B: 7, 309 | "C+": 6, 310 | C: 5, 311 | D: 4, 312 | F: 0, 313 | }; 314 | return gradeScores[grade] || 0; 315 | }; 316 | 317 | const filteredCourseOptions = 318 | courseOptions.find((year) => year.label === selectedYear?.value)?.options || 319 | []; 320 | 321 | return ( 322 |
323 |
324 | 334 |
335 | 336 | 337 | Add Course 338 | Enter your course details below 339 | 340 | 341 |
342 | 343 | { 366 | if (selectedOption && selectedOption.value === "CUSTOM") { 367 | setIsCustomCourse(true); 368 | } else { 369 | setSelectedCourse(selectedOption); 370 | setIsCustomCourse(false); 371 | } 372 | setSelectedCredits(String(selectedOption?.credits || 0)); 373 | }} 374 | styles={customStyles} 375 | placeholder={isCustomCourse ? "Custom Course" : "Select Course"} 376 | isClearable={isClearable} 377 | /> 378 | {isCustomCourse && ( 379 | setCustomCourseCode(e.target.value)} 384 | style={{ 385 | color: "white", 386 | backgroundColor: "#1E1E1E", 387 | }} 388 | /> 389 | )} 390 |
391 |
392 | 393 | setSelectedCredits(e.target.value)} 400 | onKeyPress={handleKeyPress} 401 | style={{ color: "white", backgroundColor: "#1E1E1E" }} 402 | /> 403 |
404 |
405 | 406 |