├── jsconfig.json ├── public ├── favicon.ico └── anokha_logo.png ├── postcss.config.mjs ├── next.config.mjs ├── app ├── _fonts │ ├── Gilroy-Black.ttf │ ├── Gilroy-Bold.ttf │ ├── Gilroy-Heavy.ttf │ ├── Gilroy-Light.ttf │ ├── Gilroy-Thin.ttf │ ├── Gilroy-Medium.ttf │ ├── Gilroy-Regular.ttf │ ├── Gilroy-SemiBold.ttf │ ├── Gilroy-BoldItalic.ttf │ ├── Gilroy-ExtraBold.ttf │ ├── Gilroy-ThinItalic.ttf │ ├── Gilroy-UltraLight.ttf │ ├── Gilroy-BlackItalic.ttf │ ├── Gilroy-HeavyItalic.ttf │ ├── Gilroy-LightItalic.ttf │ ├── Gilroy-MediumItalic.ttf │ ├── Gilroy-RegularItalic.ttf │ ├── Gilroy-ExtraBoldItalic.ttf │ ├── Gilroy-SemiBoldItalic.ttf │ └── Gilroy-UltraLightItalic.ttf ├── user │ ├── proposals │ │ ├── add │ │ │ └── page.jsx │ │ ├── [id] │ │ │ ├── edit │ │ │ │ └── page.jsx │ │ │ └── page.jsx │ │ └── page.jsx │ ├── page.jsx │ └── layout.jsx ├── reviewer │ ├── proposals │ │ ├── [id] │ │ │ └── page.jsx │ │ └── page.jsx │ ├── page.jsx │ └── layout.jsx ├── api │ ├── user │ │ ├── getAll │ │ │ └── route.js │ │ ├── [id] │ │ │ ├── pending │ │ │ │ └── route.js │ │ │ ├── reviewed │ │ │ │ └── route.js │ │ │ ├── proposal │ │ │ │ └── route.js │ │ │ ├── proposals │ │ │ │ └── route.js │ │ │ └── route.js │ │ ├── search │ │ │ └── route.js │ │ └── role │ │ │ └── route.js │ ├── proposal │ │ ├── [id] │ │ │ ├── reply │ │ │ │ └── route.js │ │ │ ├── forward │ │ │ │ └── route.js │ │ │ ├── status │ │ │ │ └── route.js │ │ │ ├── history │ │ │ │ └── route.js │ │ │ └── route.js │ │ ├── add │ │ │ └── route.js │ │ └── dept │ │ │ └── route.js │ ├── reviewer │ │ ├── getAll │ │ │ └── route.js │ │ ├── [id] │ │ │ ├── route.js │ │ │ ├── history │ │ │ │ └── route.js │ │ │ └── proposals │ │ │ │ └── route.js │ │ └── route.js │ ├── deleteUser │ │ └── route.js │ ├── createUser │ │ └── route.js │ ├── userService.js │ ├── reviewerService.js │ ├── proposalHistoryService.js │ └── proposalService.js ├── _components │ ├── config.js │ ├── ReviewerPages │ │ ├── ReviewerLayout.jsx │ │ └── ApprovedProposalCard.jsx │ └── ProposalPages │ │ ├── Dashboard.jsx │ │ └── ViewProposal.jsx ├── firebase │ └── firebase.js ├── layout.js ├── reset │ └── page.jsx ├── globals.css ├── signup │ └── page.jsx └── login │ └── page.jsx ├── lib └── utils.js ├── components └── ui │ ├── skeleton.jsx │ ├── label.jsx │ ├── separator.jsx │ ├── textarea.jsx │ ├── input.jsx │ ├── password-input.jsx │ ├── checkbox.jsx │ ├── popover.jsx │ ├── alert.jsx │ ├── tooltip.jsx │ ├── tabs.jsx │ ├── card.jsx │ ├── button.jsx │ ├── combo-box-level.jsx │ ├── combo-box-reviewer.jsx │ ├── combo-box.jsx │ ├── form.jsx │ ├── dialog.jsx │ ├── sheet.jsx │ ├── command.jsx │ └── select.jsx ├── components.json ├── hooks └── use-mobile.js ├── .gitignore ├── .github └── workflows │ └── prettier.yml ├── biome.json ├── utils └── apiRequest.js ├── package.json ├── schemas ├── proposal.schema.js └── user.schema.js └── README.md /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: ["@tailwindcss/postcss"], 3 | }; 4 | 5 | export default config; 6 | -------------------------------------------------------------------------------- /public/anokha_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/public/anokha_logo.png -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /app/_fonts/Gilroy-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-Black.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-Bold.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-Heavy.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-Heavy.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-Light.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-Thin.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-Medium.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-Regular.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-SemiBold.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-BoldItalic.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-ExtraBold.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-ThinItalic.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-UltraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-UltraLight.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-BlackItalic.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-HeavyItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-HeavyItalic.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-LightItalic.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-MediumItalic.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-RegularItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-RegularItalic.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /app/_fonts/Gilroy-UltraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SudharsanSaravanan/event-proposal-app/HEAD/app/_fonts/Gilroy-UltraLightItalic.ttf -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | import { clsx } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | export function cn(...inputs) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /components/ui/skeleton.jsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | 3 | function Skeleton({ className, ...props }) { 4 | return ( 5 |
10 | ); 11 | } 12 | 13 | export { Skeleton }; 14 | -------------------------------------------------------------------------------- /app/user/proposals/add/page.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import AddProposalContent from "@/app/_components/ProposalPages/AddProposal"; 4 | 5 | export default function AddProposalPage() { 6 | return ( 7 |
8 | 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": false, 6 | "tailwind": { 7 | "config": "", 8 | "css": "app/globals.css", 9 | "baseColor": "gray", 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 | } 22 | -------------------------------------------------------------------------------- /app/user/proposals/[id]/edit/page.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import EditProposalContent from "@/app/_components/ProposalPages/EditProposal"; 4 | import { useRouter, useParams } from "next/navigation"; 5 | 6 | export default function EditProposalPage() { 7 | const router = useRouter(); 8 | const { id } = useParams(); 9 | 10 | return ( 11 |
12 | router.push("/user/proposals")} 15 | /> 16 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /app/user/page.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import DashboardContent from "@/app/_components/ProposalPages/Dashboard"; 4 | import { useRouter } from "next/navigation"; 5 | 6 | export default function UserPage() { 7 | const router = useRouter(); 8 | 9 | const handleNavigate = (view) => { 10 | if (view === "view-proposals") { 11 | router.push("/user/proposals"); 12 | } else if (view === "add-proposal") { 13 | router.push("/user/proposals/add"); 14 | } 15 | }; 16 | 17 | return ; 18 | } 19 | -------------------------------------------------------------------------------- /app/user/proposals/[id]/page.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import ProposalTrackingContent from "@/app/_components/ProposalPages/ProposalTracking"; 4 | import { useRouter, useParams } from "next/navigation"; 5 | 6 | export default function ViewProposalDetailsPage() { 7 | const router = useRouter(); 8 | const { id } = useParams(); 9 | 10 | return ( 11 |
12 | router.push("/user/proposals")} 15 | /> 16 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /app/reviewer/proposals/[id]/page.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import ReviewerViewProposal from "@/app/_components/ReviewerPages/ReviewerViewProposal"; 4 | import { useRouter, useParams } from "next/navigation"; 5 | 6 | export default function ViewProposalDetailsPage() { 7 | const router = useRouter(); 8 | const { id } = useParams(); 9 | 10 | return ( 11 |
12 | router.push("/reviewer/proposals")} 15 | /> 16 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /app/api/user/getAll/route.js: -------------------------------------------------------------------------------- 1 | import { db } from "@/app/firebase/firebase"; 2 | import { collection, getDocs } from "firebase/firestore"; 3 | import { NextResponse } from "next/server"; 4 | 5 | export async function GET() { 6 | try { 7 | const snapshot = await getDocs(collection(db, "Auth")); 8 | const users = snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() })); 9 | return NextResponse.json(users); 10 | } catch (error) { 11 | console.error("Error fetching users:", error); 12 | return NextResponse.json( 13 | { error: "Failed to fetch users" }, 14 | { status: 500 }, 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/reviewer/page.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useRouter } from "next/navigation"; 4 | import ReviewerDashboard from "../_components/ReviewerPages/ReviewerDashboard"; 5 | 6 | export default function ReviewerPage() { 7 | const router = useRouter(); 8 | 9 | const handleNavigate = (view, proposalId = null) => { 10 | if (view === "view-proposals") { 11 | router.push("/reviewer/proposals"); 12 | } 13 | if (view === "view-proposal-details" && proposalId) { 14 | router.push(`/reviewer/proposals/${proposalId}`); 15 | } 16 | }; 17 | 18 | return ; 19 | } 20 | -------------------------------------------------------------------------------- /hooks/use-mobile.js: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /components/ui/label.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import * as LabelPrimitive from "@radix-ui/react-label"; 5 | 6 | import { cn } from "@/lib/utils"; 7 | 8 | function Label({ className, ...props }) { 9 | return ( 10 | 18 | ); 19 | } 20 | 21 | export { Label }; 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.* 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 | .cursor -------------------------------------------------------------------------------- /app/_components/config.js: -------------------------------------------------------------------------------- 1 | export const departments = [ 2 | { value: "CSE", label: "CSE" }, 3 | { value: "ECE", label: "ECE" }, 4 | { value: "EEE", label: "EEE" }, 5 | { value: "MECH", label: "MECH" }, 6 | { value: "CIVIL", label: "CIVIL" }, 7 | ]; 8 | 9 | export const workshopDurations = [ 10 | { value: "1 day", label: "1 day" }, 11 | { value: "2 days", label: "2 days" }, 12 | { value: "3 days", label: "3 days" }, 13 | ]; 14 | 15 | export const eventDurations = [ 16 | { value: "0.5 days", label: "0.5 days" }, 17 | { value: "1 day", label: "1 day" }, 18 | { value: "1.5 days", label: "1.5 days" }, 19 | { value: "2 days", label: "2 days" }, 20 | { value: "2.5 days", label: "2.5 days" }, 21 | { value: "3 days", label: "3 days" }, 22 | ]; 23 | -------------------------------------------------------------------------------- /.github/workflows/prettier.yml: -------------------------------------------------------------------------------- 1 | name: Code Formatting Check. 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - dev 8 | pull_request: 9 | branches: 10 | - main 11 | - dev 12 | workflow_dispatch: # For manual trigger 13 | 14 | jobs: 15 | quality: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | - name: Setup Biome 21 | uses: biomejs/setup-biome@v2 22 | with: 23 | version: latest 24 | - name: Run Biome 25 | run: biome check . --linter-enabled=false --formatter-enabled=true --assist-enabled=false 26 | -------------------------------------------------------------------------------- /components/ui/separator.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import * as SeparatorPrimitive from "@radix-ui/react-separator"; 5 | 6 | import { cn } from "@/lib/utils"; 7 | 8 | function Separator({ 9 | className, 10 | orientation = "horizontal", 11 | decorative = true, 12 | ...props 13 | }) { 14 | return ( 15 | 25 | ); 26 | } 27 | 28 | export { Separator }; 29 | -------------------------------------------------------------------------------- /components/ui/textarea.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "@/lib/utils"; 4 | 5 | function Textarea({ className, ...props }) { 6 | return ( 7 |