├── Frontend ├── src │ ├── App.css │ ├── JSX │ │ ├── Context │ │ │ ├── AuthContext.js │ │ │ ├── ThemeContext.jsx │ │ │ └── AuthContextProvider.jsx │ │ ├── Components │ │ │ ├── Footer.jsx │ │ │ ├── Compose.jsx │ │ │ ├── Inbox.jsx │ │ │ ├── Sent.jsx │ │ │ ├── dummyEmails.js │ │ │ ├── Protection │ │ │ │ └── ProtectedRoute.jsx │ │ │ ├── MessageView.jsx │ │ │ ├── SentList.jsx │ │ │ ├── InboxList.jsx │ │ │ ├── ComposeMail.jsx │ │ │ ├── NotFoundPage.jsx │ │ │ ├── EmailLayout.jsx │ │ │ ├── Aurora.jsx │ │ │ ├── Sidebar.jsx │ │ │ ├── ResetPassword.jsx │ │ │ └── Login.jsx │ │ └── Pages │ │ │ ├── LoginPage.jsx │ │ │ ├── SignUpPage.jsx │ │ │ ├── QuizzesPage.jsx │ │ │ ├── LeaderboardPage.jsx │ │ │ ├── PrivacyPolicyPage.jsx │ │ │ └── TermsOfServicePage.jsx │ ├── Config │ │ └── index.js │ ├── index.css │ ├── BackToTop.css │ ├── BackToTop.jsx │ ├── App.jsx │ └── assets │ │ └── react.svg ├── .prettierignore ├── public │ ├── logo.png │ └── vite.svg ├── .prettierrc ├── vite.config.js ├── .gitignore ├── vercel.json ├── README.md ├── eslint.config.js ├── package.json └── index.html ├── App-React-Native ├── services │ └── api.js ├── utils │ └── helpers.js ├── constants │ ├── colors.js │ └── Colors.ts ├── navigation │ └── AppNavigator.js ├── hooks │ ├── useColorScheme.ts │ ├── useColorScheme.web.ts │ └── useThemeColor.ts ├── assets │ ├── images │ │ ├── icon.png │ │ ├── favicon.png │ │ ├── react-logo.png │ │ ├── splash-icon.png │ │ ├── adaptive-icon.png │ │ ├── react-logo@2x.png │ │ ├── react-logo@3x.png │ │ └── partial-react-logo.png │ └── fonts │ │ └── SpaceMono-Regular.ttf ├── .gitignore ├── app │ ├── (tabs) │ │ ├── index.tsx │ │ ├── profile.tsx │ │ └── _layout.tsx │ ├── email.tsx │ ├── events.tsx │ ├── aiassist.tsx │ ├── elibrary.tsx │ ├── quizzes.tsx │ ├── mentoring.tsx │ ├── resources.tsx │ ├── counselling.tsx │ ├── leaderboard.tsx │ ├── studentchat.tsx │ └── _layout.tsx ├── components │ ├── ui │ │ ├── TabBarBackground.tsx │ │ ├── TabBarBackground.ios.tsx │ │ ├── IconSymbol.ios.tsx │ │ └── IconSymbol.tsx │ ├── ThemedView.tsx │ ├── HapticTab.tsx │ ├── ExternalLink.tsx │ ├── HelloWave.tsx │ ├── Collapsible.tsx │ ├── ThemedText.tsx │ └── ParallaxScrollView.tsx ├── tsconfig.json ├── src │ └── @types │ │ └── react-native-progress.d.ts ├── app.json ├── package.json ├── scripts │ └── reset-project.js └── screens │ └── HomeScreen.js ├── CKsEdu.xlsx ├── Backend-Node ├── .prettierignore ├── src │ ├── Constants.js │ ├── Utils │ │ ├── ApiResponse.js │ │ ├── AsyncHandler.js │ │ ├── ApiError.js │ │ └── Cloudinary.js │ ├── Middlewares │ │ ├── multer.middleware.js │ │ └── auth.middleware.js │ ├── Routes │ │ ├── dailyStudyGoal.routes.js │ │ └── user.routes.js │ ├── index.js │ ├── db │ │ └── index.js │ ├── Models │ │ ├── dailyStudyGoal.model.js │ │ ├── index.js │ │ ├── user.model.js │ │ ├── student.model.js │ │ ├── professor.model.js │ │ ├── clgAdmin.model.js │ │ ├── college.model.js │ │ ├── department.model.js │ │ ├── semester.model.js │ │ └── subject.model.js │ ├── app.js │ └── Controllers │ │ └── dailyStudyGoal.controller.js ├── .prettierrc ├── vercel.json ├── package.json ├── .env.sample └── .gitignore ├── eslint.config.js ├── .gitignore ├── .github ├── ISSUE_TEMPLATE │ ├── enhancement.yml │ ├── feature-request.yml │ └── bug-report.yml └── PULL_REQUEST_TEMPLATE.md ├── CONTRIBUTING.md ├── README.md └── CODE_OF_CONDUCT.md /Frontend/src/App.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /App-React-Native/services/api.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /App-React-Native/utils/helpers.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /App-React-Native/constants/colors.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /App-React-Native/navigation/AppNavigator.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CKsEdu.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/CKsEdu.xlsx -------------------------------------------------------------------------------- /App-React-Native/hooks/useColorScheme.ts: -------------------------------------------------------------------------------- 1 | export { useColorScheme } from 'react-native'; 2 | -------------------------------------------------------------------------------- /Frontend/.prettierignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /node_modules 3 | ./dist 4 | 5 | *.env 6 | .env 7 | .env.* 8 | -------------------------------------------------------------------------------- /Backend-Node/.prettierignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /node_modules 3 | ./dist 4 | 5 | *.env 6 | .env 7 | .env.* 8 | -------------------------------------------------------------------------------- /Frontend/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/Frontend/public/logo.png -------------------------------------------------------------------------------- /Backend-Node/src/Constants.js: -------------------------------------------------------------------------------- 1 | export const DB_NAME = 'CKsEdu'; 2 | export const FRONTEND_URL = process.env.FRONTEND_URL -------------------------------------------------------------------------------- /App-React-Native/assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/App-React-Native/assets/images/icon.png -------------------------------------------------------------------------------- /App-React-Native/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/App-React-Native/assets/images/favicon.png -------------------------------------------------------------------------------- /App-React-Native/assets/images/react-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/App-React-Native/assets/images/react-logo.png -------------------------------------------------------------------------------- /App-React-Native/assets/images/splash-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/App-React-Native/assets/images/splash-icon.png -------------------------------------------------------------------------------- /App-React-Native/assets/images/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/App-React-Native/assets/images/adaptive-icon.png -------------------------------------------------------------------------------- /App-React-Native/assets/images/react-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/App-React-Native/assets/images/react-logo@2x.png -------------------------------------------------------------------------------- /App-React-Native/assets/images/react-logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/App-React-Native/assets/images/react-logo@3x.png -------------------------------------------------------------------------------- /App-React-Native/assets/fonts/SpaceMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/App-React-Native/assets/fonts/SpaceMono-Regular.ttf -------------------------------------------------------------------------------- /App-React-Native/assets/images/partial-react-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrishChothani/CKsEdu/HEAD/App-React-Native/assets/images/partial-react-logo.png -------------------------------------------------------------------------------- /Frontend/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "bracketSpacing": true, 4 | "tabWidth": 2, 5 | "trailingComma": "es5", 6 | "semi": true 7 | } 8 | -------------------------------------------------------------------------------- /Backend-Node/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "bracketSpacing": true, 4 | "tabWidth": 2, 5 | "trailingComma": "es5", 6 | "semi": true 7 | } 8 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Context/AuthContext.js: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | 3 | const AuthContext = createContext(); 4 | 5 | export default AuthContext; 6 | -------------------------------------------------------------------------------- /App-React-Native/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb 3 | # The following patterns were generated by expo-cli 4 | 5 | expo-env.d.ts 6 | # @end expo-cli -------------------------------------------------------------------------------- /Frontend/src/JSX/Components/Footer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | function Footer() { 4 | return ( 5 |
6 | 7 |
8 | ) 9 | } 10 | 11 | export default Footer 12 | -------------------------------------------------------------------------------- /App-React-Native/app/(tabs)/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import HomeScreen from "../../screens/HomeScreen"; 3 | 4 | const index = () => { 5 | return ; 6 | }; 7 | 8 | export default index; 9 | -------------------------------------------------------------------------------- /App-React-Native/app/(tabs)/profile.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ProfileScreen from "../../screens/ProfileScreen"; 3 | 4 | const profile = () => { 5 | return ; 6 | }; 7 | 8 | export default profile; 9 | -------------------------------------------------------------------------------- /App-React-Native/components/ui/TabBarBackground.tsx: -------------------------------------------------------------------------------- 1 | // This is a shim for web and Android where the tab bar is generally opaque. 2 | export default undefined; 3 | 4 | export function useBottomTabOverflow() { 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Pages/LoginPage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Login from '../Components/Login' 3 | 4 | function LoginPage() { 5 | return ( 6 | <> 7 | 8 | 9 | ) 10 | } 11 | 12 | export default LoginPage 13 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Pages/SignUpPage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import SignUp from '../Components/SignUp' 3 | 4 | function SignUpPage() { 5 | return ( 6 | <> 7 | 8 | 9 | ) 10 | } 11 | 12 | export default SignUpPage 13 | -------------------------------------------------------------------------------- /Frontend/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | import tailwindcss from "@tailwindcss/vite"; 4 | 5 | // https://vite.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react(), tailwindcss()], 8 | }); 9 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | // https://docs.expo.dev/guides/using-eslint/ 2 | const { defineConfig } = require('eslint/config'); 3 | const expoConfig = require('eslint-config-expo/flat'); 4 | 5 | module.exports = defineConfig([ 6 | expoConfig, 7 | { 8 | ignores: ['dist/*'], 9 | }, 10 | ]); 11 | -------------------------------------------------------------------------------- /Backend-Node/src/Utils/ApiResponse.js: -------------------------------------------------------------------------------- 1 | class ApiResponse { 2 | constructor(statusCode, data, message = "Success") { 3 | this.statusCode = statusCode; 4 | this.data = data; 5 | this.message = message; 6 | this.success = statusCode < 400; 7 | } 8 | } 9 | 10 | export { ApiResponse }; 11 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Components/Compose.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useOutletContext } from "react-router-dom"; 3 | import ComposeMail from "./ComposeMail"; 4 | 5 | export default function Compose() { 6 | const context = useOutletContext(); 7 | 8 | return context?.pane === "right" ? : null; 9 | } 10 | -------------------------------------------------------------------------------- /Backend-Node/src/Middlewares/multer.middleware.js: -------------------------------------------------------------------------------- 1 | import multer from "multer"; 2 | import path from "path"; 3 | import os from "os"; 4 | 5 | 6 | const storage = multer.diskStorage({ 7 | destination: os.tmpdir(), 8 | filename: (req, file, cb) => { 9 | cb(null, file.originalname); 10 | }, 11 | }); 12 | export const upload = multer({ storage }); 13 | -------------------------------------------------------------------------------- /Backend-Node/src/Utils/AsyncHandler.js: -------------------------------------------------------------------------------- 1 | const AsyncHandler = (requestHandler) => { 2 | return (req, res, next) => { 3 | Promise.resolve(requestHandler(req, res, next)).catch((err) => { 4 | return res.status(err.statusCode || 500).json({ 5 | message: err.message, 6 | ...err 7 | }) 8 | }) 9 | } 10 | }; 11 | export { AsyncHandler }; 12 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Components/Inbox.jsx: -------------------------------------------------------------------------------- 1 | 2 | import React from "react"; 3 | import { useOutletContext } from "react-router-dom"; 4 | import InboxList from "./InboxList"; 5 | 6 | export default function Inbox() { 7 | const { setSelectedEmail } = useOutletContext(); 8 | 9 | return ( 10 | setSelectedEmail(email)} /> 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Components/Sent.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useOutletContext } from "react-router-dom"; 3 | import SentList from "./SentList"; 4 | 5 | export default function Sent() { 6 | const { setSelectedEmail } = useOutletContext(); 7 | 8 | return ( 9 | setSelectedEmail(email)} /> 10 | ); 11 | } 12 | 13 | 14 | -------------------------------------------------------------------------------- /Frontend/src/Config/index.js: -------------------------------------------------------------------------------- 1 | const DEV_MODE = import.meta.env.VITE_APP_MODE; 2 | console.log(DEV_MODE) 3 | let BACKEND_URL; 4 | 5 | if (DEV_MODE === "DEV") { 6 | BACKEND_URL = "http://localhost:5000"; 7 | } else if (DEV_MODE === "PROD") { 8 | BACKEND_URL = "https://cksedu-backend.vercel.app"; 9 | } 10 | console.log("BACKEND_URL:", BACKEND_URL); 11 | export default BACKEND_URL; 12 | -------------------------------------------------------------------------------- /Frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | .env 27 | -------------------------------------------------------------------------------- /App-React-Native/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "expo/tsconfig.base", 3 | "compilerOptions": { 4 | "strict": true, 5 | "types": ["react", "react-native"], 6 | "jsx": "react-native", 7 | "paths": { 8 | "@/*": [ 9 | "./*" 10 | ] 11 | } 12 | }, 13 | "include": [ 14 | "**/*.ts", 15 | "**/*.tsx", 16 | ".expo/types/**/*.ts", 17 | "expo-env.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /Backend-Node/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "builds": [ 4 | { 5 | "src": "src/index.js", 6 | "use": "@vercel/node", 7 | "config": { 8 | "maxDuration": 30 9 | } 10 | } 11 | ], 12 | "routes": [ 13 | { 14 | "src": "/api/(.*)", 15 | "dest": "src/index.js" 16 | }, 17 | { 18 | "src": "/(.*)", 19 | "dest": "/public/$1" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Pages/QuizzesPage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Quizzes from '../Components/Quizzes'; 3 | 4 | /** 5 | * QuizzesPage Component 6 | * 7 | * Page wrapper for the Quizzes component. 8 | * This follows the same pattern as other pages in the application. 9 | */ 10 | function QuizzesPage() { 11 | return ( 12 | <> 13 | 14 | 15 | ); 16 | } 17 | 18 | export default QuizzesPage; 19 | -------------------------------------------------------------------------------- /Frontend/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "builds": [ 4 | { 5 | "src": "package.json", 6 | "use": "@vercel/static-build" 7 | } 8 | ], 9 | "headers": [ 10 | { 11 | "source": "src/assets/(.*)", 12 | "headers": [ 13 | { 14 | "key": "Content-Type", 15 | "value": "application/javascript" 16 | } 17 | ] 18 | } 19 | ], 20 | "rewrites": [{ "source": "/(.*)", "destination": "/" }] 21 | } 22 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Pages/LeaderboardPage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Leaderboard from '../Components/Leaderboard'; 3 | 4 | /** 5 | * LeaderboardPage Component 6 | * 7 | * Page wrapper for the Leaderboard component. 8 | * This follows the same pattern as other pages in the application. 9 | */ 10 | function LeaderboardPage() { 11 | return ( 12 | <> 13 | 14 | 15 | ); 16 | } 17 | 18 | export default LeaderboardPage; 19 | -------------------------------------------------------------------------------- /App-React-Native/app/email.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | 4 | export default function EmailScreen() { 5 | return ( 6 | 7 | Email 8 | 9 | ); 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | alignItems: "center", 16 | justifyContent: "center", 17 | }, 18 | title: { 19 | fontSize: 20, 20 | fontWeight: "bold", 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /App-React-Native/app/events.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | 4 | export default function EventsScreen() { 5 | return ( 6 | 7 | Events 8 | 9 | ); 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | alignItems: "center", 16 | justifyContent: "center", 17 | }, 18 | title: { 19 | fontSize: 20, 20 | fontWeight: "bold", 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /Frontend/src/index.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | /* Custom utilities for text truncation */ 4 | .line-clamp-1 { 5 | overflow: hidden; 6 | display: -webkit-box; 7 | -webkit-box-orient: vertical; 8 | -webkit-line-clamp: 1; 9 | } 10 | 11 | .line-clamp-2 { 12 | overflow: hidden; 13 | display: -webkit-box; 14 | -webkit-box-orient: vertical; 15 | -webkit-line-clamp: 2; 16 | } 17 | 18 | .line-clamp-3 { 19 | overflow: hidden; 20 | display: -webkit-box; 21 | -webkit-box-orient: vertical; 22 | -webkit-line-clamp: 3; 23 | } 24 | -------------------------------------------------------------------------------- /App-React-Native/app/aiassist.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | 4 | export default function AiAssistScreen() { 5 | return ( 6 | 7 | AI Assist 8 | 9 | ); 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | alignItems: "center", 16 | justifyContent: "center", 17 | }, 18 | title: { 19 | fontSize: 20, 20 | fontWeight: "bold", 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /App-React-Native/app/elibrary.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | 4 | export default function ELibraryScreen() { 5 | return ( 6 | 7 | E-Library 8 | 9 | ); 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | alignItems: "center", 16 | justifyContent: "center", 17 | }, 18 | title: { 19 | fontSize: 20, 20 | fontWeight: "bold", 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /App-React-Native/app/quizzes.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | 4 | export default function QuizzesScreen() { 5 | return ( 6 | 7 | Quizzes 8 | 9 | ); 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | alignItems: "center", 16 | justifyContent: "center", 17 | }, 18 | title: { 19 | fontSize: 20, 20 | fontWeight: "bold", 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /App-React-Native/app/mentoring.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | 4 | export default function MentoringScreen() { 5 | return ( 6 | 7 | Mentoring 8 | 9 | ); 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | alignItems: "center", 16 | justifyContent: "center", 17 | }, 18 | title: { 19 | fontSize: 20, 20 | fontWeight: "bold", 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /App-React-Native/app/resources.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | 4 | export default function ResourcesScreen() { 5 | return ( 6 | 7 | Resources 8 | 9 | ); 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | alignItems: "center", 16 | justifyContent: "center", 17 | }, 18 | title: { 19 | fontSize: 20, 20 | fontWeight: "bold", 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /App-React-Native/app/counselling.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | 4 | export default function CounsellingScreen() { 5 | return ( 6 | 7 | Counselling 8 | 9 | ); 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | alignItems: "center", 16 | justifyContent: "center", 17 | }, 18 | title: { 19 | fontSize: 20, 20 | fontWeight: "bold", 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /App-React-Native/app/leaderboard.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | 4 | export default function LeaderboardScreen() { 5 | return ( 6 | 7 | Leaderboard 8 | 9 | ); 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | alignItems: "center", 16 | justifyContent: "center", 17 | }, 18 | title: { 19 | fontSize: 20, 20 | fontWeight: "bold", 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /App-React-Native/app/studentchat.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | 4 | export default function StudentChatScreen() { 5 | return ( 6 | 7 | Student Chat 8 | 9 | ); 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | alignItems: "center", 16 | justifyContent: "center", 17 | }, 18 | title: { 19 | fontSize: 20, 20 | fontWeight: "bold", 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /App-React-Native/components/ThemedView.tsx: -------------------------------------------------------------------------------- 1 | import { View, type ViewProps } from 'react-native'; 2 | 3 | import { useThemeColor } from '@/hooks/useThemeColor'; 4 | 5 | export type ThemedViewProps = ViewProps & { 6 | lightColor?: string; 7 | darkColor?: string; 8 | }; 9 | 10 | export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) { 11 | const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background'); 12 | 13 | return ; 14 | } 15 | -------------------------------------------------------------------------------- /Backend-Node/src/Routes/dailyStudyGoal.routes.js: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | import { createDailyStudyGoal, updateDailyStudyGoal, getDailyStudyGoal } from "../Controllers/dailyStudyGoal.controller.js"; 3 | import { verifyJWT } from "../Middlewares/auth.middleware.js"; 4 | 5 | const router = Router(); 6 | 7 | router.route("/daily-goal").post(verifyJWT, createDailyStudyGoal); 8 | router.route("/daily-goal").patch(verifyJWT, updateDailyStudyGoal); 9 | router.route("/daily-goal").get(verifyJWT, getDailyStudyGoal); 10 | 11 | export default router; -------------------------------------------------------------------------------- /Backend-Node/src/index.js: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | import connectDB from "./db/index.js"; 3 | import { app } from "./app.js"; 4 | 5 | dotenv.config({ path: ".env" }); 6 | 7 | connectDB() 8 | .then(() => { 9 | const PORT = process.env.PORT || 5000; 10 | app.listen(PORT, () => { 11 | console.log(`Server started on port: ${PORT}`); 12 | }); 13 | }) 14 | .catch((error) => { 15 | console.error("MongoDB connection failed:", error); 16 | }); 17 | 18 | app.get("/", (req, res) => { 19 | res.send("Welcome to CKsEdu"); 20 | }); 21 | -------------------------------------------------------------------------------- /Backend-Node/src/Utils/ApiError.js: -------------------------------------------------------------------------------- 1 | class ApiError extends Error { 2 | constructor( 3 | statusCode, 4 | message = "Something went wrong", 5 | errors = [], 6 | stack = "" 7 | ) { 8 | super(message); 9 | this.statusCode = statusCode; 10 | this.data = null; 11 | this.message = message; 12 | this.success = false; 13 | this.errors = errors; 14 | 15 | if (stack) { 16 | this.stack = stack; 17 | } else { 18 | Error.captureStackTrace(this, this.constructor); 19 | } 20 | } 21 | } 22 | export { ApiError }; 23 | -------------------------------------------------------------------------------- /Backend-Node/src/db/index.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import { DB_NAME } from "../Constants.js"; 3 | 4 | const connectDB = async () => { 5 | try { 6 | const connectionInstance = await mongoose.connect( 7 | `${process.env.MONGODB_URI}/${DB_NAME}` 8 | ); 9 | console.log( 10 | `\n MongoDb Connected Successfully !! DB HOST: ${connectionInstance.connection.host}` 11 | ); 12 | } catch (error) { 13 | console.log("Mongodb Connection Error: ", error); 14 | process.exit(1); 15 | } 16 | }; 17 | 18 | export default connectDB; 19 | -------------------------------------------------------------------------------- /Backend-Node/src/Models/dailyStudyGoal.model.js: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema } from "mongoose"; 2 | 3 | const dailyStudyGoalSchema = new Schema({ 4 | userId: { 5 | type: Schema.Types.ObjectId, 6 | ref: "User", 7 | required: true, 8 | }, 9 | goal: { 10 | type: Number, 11 | required: true, 12 | }, 13 | progress: { 14 | type: Number, 15 | default: 0, 16 | }, 17 | date: { 18 | type: Date, 19 | default: Date.now, 20 | }, 21 | }, { timestamps: true }); 22 | 23 | export const DailyStudyGoal = mongoose.model("DailyStudyGoal", dailyStudyGoalSchema); -------------------------------------------------------------------------------- /App-React-Native/hooks/useColorScheme.web.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { useColorScheme as useRNColorScheme } from 'react-native'; 3 | 4 | /** 5 | * To support static rendering, this value needs to be re-calculated on the client side for web 6 | */ 7 | export function useColorScheme() { 8 | const [hasHydrated, setHasHydrated] = useState(false); 9 | 10 | useEffect(() => { 11 | setHasHydrated(true); 12 | }, []); 13 | 14 | const colorScheme = useRNColorScheme(); 15 | 16 | if (hasHydrated) { 17 | return colorScheme; 18 | } 19 | 20 | return 'light'; 21 | } 22 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Components/dummyEmails.js: -------------------------------------------------------------------------------- 1 | 2 | export const inboxEmails = [ 3 | { 4 | id: "1", 5 | subject: "Meeting Tomorrow", 6 | sender: "alice@example.com", 7 | body: "Don't forget the meeting at 10am." 8 | }, 9 | { 10 | id: "2", 11 | subject: "Weekly Dev Tips", 12 | sender: "newsletter@devweekly.com", 13 | body: "Here are some cool React tricks!" 14 | } 15 | ]; 16 | 17 | export const sentEmails = [ 18 | { 19 | id: "3", 20 | subject: "Project Update", 21 | sender: "me@example.com", 22 | body: "Hi team, the project is on track for delivery." 23 | } 24 | ]; 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files 2 | 3 | # dependencies 4 | node_modules/ 5 | **/node_modules/ 6 | 7 | # Expo 8 | .expo/ 9 | dist/ 10 | web-build/ 11 | expo-env.d.ts 12 | 13 | # Native 14 | .kotlin/ 15 | *.orig.* 16 | *.jks 17 | *.p8 18 | *.p12 19 | *.key 20 | *.mobileprovision 21 | 22 | # Metro 23 | .metro-health-check* 24 | 25 | # debug 26 | npm-debug.* 27 | yarn-debug.* 28 | yarn-error.* 29 | 30 | # macOS 31 | .DS_Store 32 | *.pem 33 | 34 | # local env files 35 | .env*.local 36 | 37 | # typescript 38 | *.tsbuildinfo 39 | 40 | app-example 41 | .vscode/ -------------------------------------------------------------------------------- /App-React-Native/hooks/useThemeColor.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Learn more about light and dark modes: 3 | * https://docs.expo.dev/guides/color-schemes/ 4 | */ 5 | 6 | import { Colors } from '@/constants/Colors'; 7 | import { useColorScheme } from '@/hooks/useColorScheme'; 8 | 9 | export function useThemeColor( 10 | props: { light?: string; dark?: string }, 11 | colorName: keyof typeof Colors.light & keyof typeof Colors.dark 12 | ) { 13 | const theme = useColorScheme() ?? 'light'; 14 | const colorFromProps = props[theme]; 15 | 16 | if (colorFromProps) { 17 | return colorFromProps; 18 | } else { 19 | return Colors[theme][colorName]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /App-React-Native/components/HapticTab.tsx: -------------------------------------------------------------------------------- 1 | import { BottomTabBarButtonProps } from '@react-navigation/bottom-tabs'; 2 | import { PlatformPressable } from '@react-navigation/elements'; 3 | import * as Haptics from 'expo-haptics'; 4 | 5 | export function HapticTab(props: BottomTabBarButtonProps) { 6 | return ( 7 | { 10 | if (process.env.EXPO_OS === 'ios') { 11 | // Add a soft haptic feedback when pressing down on the tabs. 12 | Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); 13 | } 14 | props.onPressIn?.(ev); 15 | }} 16 | /> 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /App-React-Native/components/ui/TabBarBackground.ios.tsx: -------------------------------------------------------------------------------- 1 | import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; 2 | import { BlurView } from 'expo-blur'; 3 | import { StyleSheet } from 'react-native'; 4 | 5 | export default function BlurTabBarBackground() { 6 | return ( 7 | 14 | ); 15 | } 16 | 17 | export function useBottomTabOverflow() { 18 | return useBottomTabBarHeight(); 19 | } 20 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Components/Protection/ProtectedRoute.jsx: -------------------------------------------------------------------------------- 1 | import AuthContext from "../../Context/AuthContext"; 2 | import React, { useContext } from "react"; 3 | import { Navigate } from "react-router-dom"; 4 | 5 | function ProtectedRoute({ children }) { 6 | const { user, loading } = useContext(AuthContext); 7 | 8 | // console.log("user from protect route", user); 9 | // console.log("loading from protect route", loading); 10 | 11 | // Wait until auth check finishes 12 | if (loading) { 13 | return
Loading...
; // or custom loader 14 | } 15 | 16 | if (!user) { 17 | return ; 18 | } 19 | 20 | return children; 21 | } 22 | 23 | export default ProtectedRoute; 24 | -------------------------------------------------------------------------------- /App-React-Native/src/@types/react-native-progress.d.ts: -------------------------------------------------------------------------------- 1 | declare module "react-native-progress/Circle" { 2 | import { Component } from "react"; 3 | import { ViewStyle, TextStyle, StyleProp } from "react-native"; 4 | 5 | export interface ProgressCircleProps { 6 | progress?: number; 7 | size?: number; 8 | thickness?: number; 9 | color?: string; 10 | unfilledColor?: string; 11 | borderWidth?: number; 12 | showsText?: boolean; 13 | formatText?: () => string; 14 | textStyle?: StyleProp; 15 | strokeCap?: "butt" | "round" | "square"; 16 | indeterminate?: boolean; 17 | style?: StyleProp; 18 | } 19 | 20 | export default class ProgressCircle extends Component {} 21 | } 22 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Components/MessageView.jsx: -------------------------------------------------------------------------------- 1 | 2 | export default function MessageView({ email }) { 3 | if (!email) return null; 4 | 5 | return ( 6 |
7 |
8 |

{email.subject}

9 |

From: {email.sender}

10 | {email.receiver && ( 11 |

To: {email.receiver}

12 | )} 13 |
14 |
15 |
16 | {email.body} 17 |
18 |
19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /App-React-Native/components/ui/IconSymbol.ios.tsx: -------------------------------------------------------------------------------- 1 | import { SymbolView, SymbolViewProps, SymbolWeight } from 'expo-symbols'; 2 | import { StyleProp, ViewStyle } from 'react-native'; 3 | 4 | export function IconSymbol({ 5 | name, 6 | size = 24, 7 | color, 8 | style, 9 | weight = 'regular', 10 | }: { 11 | name: SymbolViewProps['name']; 12 | size?: number; 13 | color: string; 14 | style?: StyleProp; 15 | weight?: SymbolWeight; 16 | }) { 17 | return ( 18 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /App-React-Native/components/ExternalLink.tsx: -------------------------------------------------------------------------------- 1 | import { Href, Link } from 'expo-router'; 2 | import { openBrowserAsync } from 'expo-web-browser'; 3 | import { type ComponentProps } from 'react'; 4 | import { Platform } from 'react-native'; 5 | 6 | type Props = Omit, 'href'> & { href: Href & string }; 7 | 8 | export function ExternalLink({ href, ...rest }: Props) { 9 | return ( 10 | { 15 | if (Platform.OS !== 'web') { 16 | // Prevent the default behavior of linking to the default browser on native. 17 | event.preventDefault(); 18 | // Open the link in an in-app browser. 19 | await openBrowserAsync(href); 20 | } 21 | }} 22 | /> 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /Backend-Node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend-node", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "type": "module", 6 | "scripts": { 7 | "start": "node -r dotenv/config --experimental-json-modules src/index.js", 8 | "dev": "nodemon -r dotenv/config --experimental-json-modules src/index.js" 9 | }, 10 | "author": "Krish Chothani", 11 | "license": "ISC", 12 | "description": "", 13 | "dependencies": { 14 | "bcrypt": "^6.0.0", 15 | "cookie-parser": "^1.4.7", 16 | "cors": "^2.8.5", 17 | "dotenv": "^17.0.1", 18 | "express": "^5.1.0", 19 | "jsonwebtoken": "^9.0.2", 20 | "mongoose": "^8.16.1", 21 | "nodemailer": "^7.0.4", 22 | "path": "^0.12.7", 23 | "streamifier": "^0.1.1", 24 | "url": "^0.11.4" 25 | }, 26 | "devDependencies": { 27 | "nodemon": "^3.1.10" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /App-React-Native/constants/Colors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Below are the colors that are used in the app. The colors are defined in the light and dark mode. 3 | * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc. 4 | */ 5 | 6 | const tintColorLight = '#0a7ea4'; 7 | const tintColorDark = '#fff'; 8 | 9 | export const Colors = { 10 | light: { 11 | text: '#11181C', 12 | background: '#fff', 13 | tint: tintColorLight, 14 | icon: '#687076', 15 | tabIconDefault: '#687076', 16 | tabIconSelected: tintColorLight, 17 | }, 18 | dark: { 19 | text: '#ECEDEE', 20 | background: '#151718', 21 | tint: tintColorDark, 22 | icon: '#9BA1A6', 23 | tabIconDefault: '#9BA1A6', 24 | tabIconSelected: tintColorDark, 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /Frontend/src/BackToTop.css: -------------------------------------------------------------------------------- 1 | /* BackToTop.css */ 2 | #backToTop { 3 | background-color: #333; 4 | color: #fff; 5 | border: none; 6 | border-radius: 5px; 7 | cursor: pointer; 8 | position: fixed; 9 | bottom: 20px; 10 | right: 20px; 11 | z-index: 9999; /* bring it above other elements */ 12 | display: block; /* or inline-block */ 13 | visibility: visible; 14 | opacity: 1; 15 | width: 50px; 16 | height: 50px; 17 | font-size: 2rem; 18 | box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18); 19 | /* opacity: 0; 20 | pointer-events: none; 21 | transition: opacity 0.4s, transform 0.2s; */ 22 | } 23 | 24 | body.dark-mode #backToTop { 25 | background: #e0e0e0; 26 | color: #0d0d0d; 27 | } 28 | 29 | #backToTop.show { 30 | opacity: 1; 31 | /* pointer-events: auto; 32 | transform: scale(1.08); */ 33 | } 34 | 35 | #backToTop:hover { 36 | transform: scale(1.15); 37 | } -------------------------------------------------------------------------------- /Frontend/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. 13 | -------------------------------------------------------------------------------- /Frontend/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import { defineConfig, globalIgnores } from 'eslint/config' 6 | 7 | export default defineConfig([ 8 | globalIgnores(['dist']), 9 | { 10 | files: ['**/*.{js,jsx}'], 11 | extends: [ 12 | js.configs.recommended, 13 | reactHooks.configs['recommended-latest'], 14 | reactRefresh.configs.vite, 15 | ], 16 | languageOptions: { 17 | ecmaVersion: 2020, 18 | globals: globals.browser, 19 | parserOptions: { 20 | ecmaVersion: 'latest', 21 | ecmaFeatures: { jsx: true }, 22 | sourceType: 'module', 23 | }, 24 | }, 25 | rules: { 26 | 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], 27 | }, 28 | }, 29 | ]) 30 | -------------------------------------------------------------------------------- /Frontend/src/BackToTop.jsx: -------------------------------------------------------------------------------- 1 | // src/components/BackToTop.jsx 2 | import React, { useState, useEffect } from "react"; 3 | import "./BackToTop.css"; // adjust path if you put css elsewhere 4 | 5 | const BackToTop = () => { 6 | const [show, setShow] = useState(false); 7 | 8 | useEffect(() => { 9 | const handleScroll = () => { 10 | console.log("ScrollY:", window.scrollY); // debug 11 | setShowButton(window.scrollY > 100); 12 | }; 13 | window.addEventListener("scroll", handleScroll); 14 | return () => window.removeEventListener("scroll", handleScroll); 15 | }, []); 16 | 17 | const goTop = () => window.scrollTo({ top: 0, behavior: "smooth" }); 18 | 19 | return ( 20 | 28 | ); 29 | }; 30 | 31 | export default BackToTop; -------------------------------------------------------------------------------- /Backend-Node/src/Models/index.js: -------------------------------------------------------------------------------- 1 | // Export all models for easier importing 2 | export { User } from './user.model.js'; 3 | export { Student } from './student.model.js'; 4 | export { Professor } from './professor.model.js'; 5 | export { ClgAdmin } from './clgAdmin.model.js'; 6 | 7 | // Academic Structure Models 8 | export { College } from './college.model.js'; 9 | export { Department } from './department.model.js'; 10 | export { Subject } from './subject.model.js'; 11 | export { Semester } from './semester.model.js'; 12 | export { Result } from './result.model.js'; 13 | 14 | // Professor Related Models 15 | export { Project } from './project.model.js'; 16 | export { ResearchWork } from './researchWork.model.js'; 17 | export { ExperienceOrganization } from './experienceOrganization.model.js'; 18 | 19 | // Community and Activity Models 20 | export { Club } from './club.model.js'; 21 | export { Event } from './event.model.js'; 22 | export { Resource } from './resource.model.js'; 23 | export { ELibrary } from './eLibrary.model.js'; 24 | -------------------------------------------------------------------------------- /Backend-Node/.env.sample: -------------------------------------------------------------------------------- 1 | # Server configuration 2 | PORT=your_port_here 3 | 4 | # MongoDB 5 | MONGODB_URI=your_mongodb_connection_string 6 | 7 | # CORS 8 | CORS_ORIGIN=your_cors_origin 9 | 10 | # Set your frontend URL here. 11 | # Use http://localhost:5173 during development, 12 | # and https://cksedu.vercel.app in production. 13 | FRONTEND_URL= 14 | 15 | 16 | # JWT / Auth 17 | JWT_SECRET=your_jwt_secret 18 | ACCESS_TOKEN_SECRET=your_access_token_secret 19 | ACCESS_TOKEN_EXPIRY=your_access_token_expiry # e.g., 1d 20 | REFRESH_TOKEN_SECRET=your_refresh_token_secret 21 | REFRESH_TOKEN_EXPIRY=your_refresh_token_expiry # e.g., 10d 22 | 23 | # Cloudinary (Media Storage) 24 | CLOUDINARY_CLOUD_NAME=your_cloudinary_cloud_name 25 | CLOUDINARY_API_KEY=your_cloudinary_api_key 26 | CLOUDINARY_API_SECRET=your_cloudinary_api_secret 27 | 28 | # Email verification credentials 29 | EMAIL_ID_FOR_VERIFICATION=your_email@example.com 30 | EMAIL_PASSWORD_FOR_VERIFICATION=your_email_app_password 31 | 32 | # External APIs 33 | GEMINI_API_KEY=your_gemini_api_key 34 | NEWS_API_KEY=your_news_api_key 35 | 36 | -------------------------------------------------------------------------------- /Backend-Node/src/Middlewares/auth.middleware.js: -------------------------------------------------------------------------------- 1 | import { User } from "../Models/user.model.js"; 2 | import { ApiError } from "../Utils/ApiError.js"; 3 | import jwt from "jsonwebtoken"; 4 | import { AsyncHandler } from "../Utils/AsyncHandler.js"; 5 | 6 | export const verifyJWT = AsyncHandler(async (req, _, next) => { 7 | try { 8 | const token = 9 | req.cookies?.accessToken || 10 | req.cookies?.refreshToken || 11 | req.header("Authorization")?.replace("Bearer ", ""); 12 | if (!token) { 13 | throw new ApiError(401, "Unauthorized request"); 14 | } 15 | 16 | const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); 17 | const user = await User.findById(decodedToken?._id).select( 18 | "-password -refreshToken" 19 | ); 20 | 21 | if (!user) { 22 | // NEXT_VIDEO: discuss about front-end 23 | throw new ApiError(401, "Invalid AccessToken"); 24 | } 25 | 26 | req.user = user; 27 | next(); 28 | } catch (error) { 29 | throw new ApiError(401, error?.message || "Invalid AccessToken"); 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Components/SentList.jsx: -------------------------------------------------------------------------------- 1 | 2 | import { sentEmails } from "./dummyEmails"; 3 | 4 | export default function SentList({ onSelect, selectedEmail }) { 5 | return ( 6 |
7 |

Sent

8 | {sentEmails.map((email) => ( 9 |
onSelect(email)} 12 | className={`p-4 mb-3 rounded-lg border border-gray-200 shadow-sm cursor-pointer transition-all duration-200 hover:shadow-md hover:bg-gray-50 ${ 13 | selectedEmail?.id === email.id 14 | ? "bg-blue-50 border-blue-400 shadow-md" 15 | : "bg-white" 16 | }`} 17 | > 18 |

{email.subject}

19 |

To: {email.receiver}

20 |

21 | {email.body.slice(0, 90)}... 22 |

23 |
24 | ))} 25 |
26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Components/InboxList.jsx: -------------------------------------------------------------------------------- 1 | 2 | import { inboxEmails } from "./dummyEmails"; 3 | 4 | export default function InboxList({ onSelect, selectedEmail }) { 5 | return ( 6 |
7 |

Inbox

8 | {inboxEmails.map((email) => ( 9 |
onSelect(email)} 12 | className={`p-4 mb-3 rounded-lg border border-gray-200 shadow-sm cursor-pointer transition-all duration-200 hover:shadow-md hover:bg-gray-50 ${ 13 | selectedEmail?.id === email.id 14 | ? "bg-blue-50 border-blue-400 shadow-md" 15 | : "bg-white" 16 | }`} 17 | > 18 |

{email.subject}

19 |

From: {email.sender}

20 |

21 | {email.body.slice(0, 90)}... 22 |

23 |
24 | ))} 25 |
26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /App-React-Native/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "CKsEdu", 4 | "slug": "CKsEdu", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/images/icon.png", 8 | "scheme": "cksedu", 9 | "userInterfaceStyle": "automatic", 10 | "newArchEnabled": true, 11 | "ios": { 12 | "supportsTablet": true 13 | }, 14 | "android": { 15 | "adaptiveIcon": { 16 | "foregroundImage": "./assets/images/adaptive-icon.png", 17 | "backgroundColor": "#ffffff" 18 | }, 19 | "edgeToEdgeEnabled": true 20 | }, 21 | "web": { 22 | "bundler": "metro", 23 | "output": "static", 24 | "favicon": "./assets/images/favicon.png" 25 | }, 26 | "plugins": [ 27 | "expo-router", 28 | [ 29 | "expo-splash-screen", 30 | { 31 | "image": "./assets/images/splash-icon.png", 32 | "imageWidth": 200, 33 | "resizeMode": "contain", 34 | "backgroundColor": "#ffffff" 35 | } 36 | ] 37 | ], 38 | "experiments": { 39 | "typedRoutes": true 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /App-React-Native/components/HelloWave.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { StyleSheet } from 'react-native'; 3 | import Animated, { 4 | useAnimatedStyle, 5 | useSharedValue, 6 | withRepeat, 7 | withSequence, 8 | withTiming, 9 | } from 'react-native-reanimated'; 10 | 11 | import { ThemedText } from '@/components/ThemedText'; 12 | 13 | export function HelloWave() { 14 | const rotationAnimation = useSharedValue(0); 15 | 16 | useEffect(() => { 17 | rotationAnimation.value = withRepeat( 18 | withSequence(withTiming(25, { duration: 150 }), withTiming(0, { duration: 150 })), 19 | 4 // Run the animation 4 times 20 | ); 21 | }, [rotationAnimation]); 22 | 23 | const animatedStyle = useAnimatedStyle(() => ({ 24 | transform: [{ rotate: `${rotationAnimation.value}deg` }], 25 | })); 26 | 27 | return ( 28 | 29 | 👋 30 | 31 | ); 32 | } 33 | 34 | const styles = StyleSheet.create({ 35 | text: { 36 | fontSize: 28, 37 | lineHeight: 32, 38 | marginTop: -6, 39 | }, 40 | }); 41 | -------------------------------------------------------------------------------- /Backend-Node/src/app.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import cors from "cors"; 3 | import cookieParser from "cookie-parser"; 4 | import path from "path"; 5 | import { fileURLToPath } from "url"; 6 | const app = express(); 7 | 8 | const allowedOrigins = [ 9 | "http://localhost:5173", 10 | "https://cksedu.vercel.app" 11 | ]; 12 | 13 | app.use( 14 | cors({ 15 | origin: function (origin, callback) { 16 | if (!origin || allowedOrigins.includes(origin)) { 17 | callback(null, true); 18 | } else { 19 | callback(new Error("CORS not allowed for this origin")); 20 | } 21 | }, 22 | credentials: true, 23 | }) 24 | ); 25 | app.use(express.json({ limit: "100mb" })); 26 | app.use(express.urlencoded({ extended: true, limit: "100mb" })); 27 | 28 | const __filename = fileURLToPath(import.meta.url); 29 | const __dirname = path.dirname(__filename); 30 | app.use(express.static(path.join(__dirname, "..", "Public"))); 31 | 32 | app.use(cookieParser()); 33 | 34 | import userRouter from "./Routes/user.routes.js"; 35 | app.use("/api/v1/users", userRouter); 36 | 37 | export { app }; 38 | 39 | import dailyStudyGoalRouter from "./Routes/dailyStudyGoal.routes.js"; 40 | app.use("/api/v1/goals", dailyStudyGoalRouter); 41 | -------------------------------------------------------------------------------- /Backend-Node/src/Routes/user.routes.js: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | import { 3 | getCurrentUser, 4 | healthCheck, 5 | loginUser, 6 | logoutUser, 7 | refreshAccessToken, 8 | registerUser, 9 | resendEmailVerification, 10 | resetPassword, 11 | sendResetPasswordEmail, 12 | updateaccountDetails, 13 | verifyEmail, 14 | } from "../Controllers/user.controller.js"; 15 | import { verifyJWT } from "../Middlewares/auth.middleware.js"; 16 | 17 | const router = Router(); 18 | 19 | router.route("/register").post(registerUser); 20 | 21 | router.route("/login").post(loginUser); 22 | 23 | //secured routes 24 | 25 | router.route("/logout").post(verifyJWT, logoutUser); 26 | router.route("/refresh-token").post(refreshAccessToken); 27 | // router.route("/change-password").post(verifyJWT, changeCurrentPassword); 28 | router.route("/current-user").get(verifyJWT, getCurrentUser); 29 | router.route("/update-account").patch(verifyJWT, updateaccountDetails); 30 | router.route("/verify-email").get(verifyEmail); 31 | router.route("/checkAuth").get(verifyJWT,healthCheck); 32 | router.route("/resend-email-verification").post(resendEmailVerification); 33 | router.route("/send-reset-password-link").post(sendResetPasswordEmail); 34 | router.route("/reset-password").post(resetPassword) 35 | export default router; 36 | -------------------------------------------------------------------------------- /Frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@expo/vector-icons": "^14.1.0", 14 | "@tailwindcss/vite": "^4.1.11", 15 | "axios": "^1.10.0", 16 | "expo": "^53.0.22", 17 | "expo-linear-gradient": "~14.1.5", 18 | "framer-motion": "^12.23.6", 19 | "jwt-decode": "^4.0.0", 20 | "lucide-react": "^0.525.0", 21 | "ogl": "^1.0.11", 22 | "prettier": "^3.6.2", 23 | "react": "^19.1.1", 24 | "react-dom": "^19.1.1", 25 | "react-hot-toast": "^2.5.2", 26 | "react-native": "^0.81.1", 27 | "react-router-dom": "^7.6.3", 28 | "tailwindcss": "^4.1.11" 29 | }, 30 | "devDependencies": { 31 | "@eslint/js": "^9.30.1", 32 | "@tsconfig/react-native": "^3.0.6", 33 | "@types/expo": "^32.0.13", 34 | "@types/react": "^19.1.12", 35 | "@types/react-dom": "^19.1.6", 36 | "@types/react-native": "^0.72.8", 37 | "@vitejs/plugin-react": "^4.6.0", 38 | "eslint": "^9.30.1", 39 | "eslint-plugin-react-hooks": "^5.2.0", 40 | "eslint-plugin-react-refresh": "^0.4.20", 41 | "globals": "^16.3.0", 42 | "typescript": "^5.8.3", 43 | "vite": "^7.0.4" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Frontend/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Frontend/src/JSX/Components/ComposeMail.jsx: -------------------------------------------------------------------------------- 1 | import { useNavigate } from "react-router-dom"; 2 | import { useState } from "react"; 3 | 4 | export default function ComposeEmail() { 5 | const navigate = useNavigate(); 6 | const [to, setTo] = useState(""); 7 | const [subject, setSubject] = useState(""); 8 | const [body, setBody] = useState(""); 9 | 10 | const handleSend = () => { 11 | alert(`Email sent to ${to}!\nSubject: ${subject}\nBody: ${body}`); 12 | navigate("/app/email/sent"); 13 | }; 14 | 15 | return ( 16 |
17 |

Compose Email

18 | setTo(e.target.value)} 23 | className="block w-full mb-2 p-2 border rounded" 24 | /> 25 | setSubject(e.target.value)} 30 | className="block w-full mb-2 p-2 border rounded" 31 | /> 32 |