From dcbb27b8d601227bdc8921e8c292167f554bfd69 Mon Sep 17 00:00:00 2001 From: Kewonit <108450560+kewonit@users.noreply.github.com.> Date: Fri, 4 Jul 2025 18:08:04 +0530 Subject: [PATCH 1/6] refactor: update layout and functionality of account form; improve redirect handling in login and signup actions; enhance MHT-CET login page links --- app/account/account-form.tsx | 29 +++++------------ app/login/actions.tsx | 50 +++++++++++++++++++---------- app/mht-cet-login-required/page.tsx | 9 ++++-- app/mht-cet/state-cutoffs/page.tsx | 21 +----------- 4 files changed, 48 insertions(+), 61 deletions(-) diff --git a/app/account/account-form.tsx b/app/account/account-form.tsx index edac0d3..0c5b787 100644 --- a/app/account/account-form.tsx +++ b/app/account/account-form.tsx @@ -80,27 +80,14 @@ export default function AccountForm({ user, message }: { user: User | null; mess -
-
- - Update Profile - -
-
-
- -
-
+
+ + Update Profile +
diff --git a/app/login/actions.tsx b/app/login/actions.tsx index e689f47..c463bcf 100644 --- a/app/login/actions.tsx +++ b/app/login/actions.tsx @@ -14,19 +14,19 @@ export async function login(formData: FormData) { // Validate input if (!email || !password) { const params = new URLSearchParams({ message: 'Please fill in all fields' }) - if (redirectTo !== '/account') params.set('redirect', redirectTo) + if (redirectTo && redirectTo !== '/account') params.set('redirect', redirectTo) return redirect(`/login?${params.toString()}`) } if (!email.includes('@')) { const params = new URLSearchParams({ message: 'Please enter a valid email address' }) - if (redirectTo !== '/account') params.set('redirect', redirectTo) + if (redirectTo && redirectTo !== '/account') params.set('redirect', redirectTo) return redirect(`/login?${params.toString()}`) } if (password.length < 8) { const params = new URLSearchParams({ message: 'Password must be at least 8 characters long' }) - if (redirectTo !== '/account') params.set('redirect', redirectTo) + if (redirectTo && redirectTo !== '/account') params.set('redirect', redirectTo) return redirect(`/login?${params.toString()}`) } @@ -59,7 +59,7 @@ export async function login(formData: FormData) { } catch (error) { console.error('Login error:', error) const params = new URLSearchParams() - if (redirectTo !== '/account') params.set('redirect', redirectTo) + if (redirectTo && redirectTo !== '/account') params.set('redirect', redirectTo) if (error instanceof ClientResponseError) { if (error.status === 400) { @@ -85,31 +85,31 @@ export async function signup(formData: FormData) { // Validate input if (!email || !password || !passwordConfirm || !name) { const params = new URLSearchParams({ message: 'Please fill in all fields' }) - if (redirectTo !== '/account') params.set('redirect', redirectTo) + if (redirectTo && redirectTo !== '/account') params.set('redirect', redirectTo) return redirect(`/signup?${params.toString()}`) } if (!email.includes('@')) { const params = new URLSearchParams({ message: 'Please enter a valid email address' }) - if (redirectTo !== '/account') params.set('redirect', redirectTo) + if (redirectTo && redirectTo !== '/account') params.set('redirect', redirectTo) return redirect(`/signup?${params.toString()}`) } if (password.length < 8) { const params = new URLSearchParams({ message: 'Password must be at least 8 characters long' }) - if (redirectTo !== '/account') params.set('redirect', redirectTo) + if (redirectTo && redirectTo !== '/account') params.set('redirect', redirectTo) return redirect(`/signup?${params.toString()}`) } if (password !== passwordConfirm) { const params = new URLSearchParams({ message: 'Passwords do not match' }) - if (redirectTo !== '/account') params.set('redirect', redirectTo) + if (redirectTo && redirectTo !== '/account') params.set('redirect', redirectTo) return redirect(`/signup?${params.toString()}`) } if (name.trim().length < 2) { const params = new URLSearchParams({ message: 'Name must be at least 2 characters long' }) - if (redirectTo !== '/account') params.set('redirect', redirectTo) + if (redirectTo && redirectTo !== '/account') params.set('redirect', redirectTo) return redirect(`/signup?${params.toString()}`) } @@ -122,14 +122,13 @@ export async function signup(formData: FormData) { passwordConfirm: passwordConfirm, name: name.trim(), } - try { const record = await pb.collection('users').create(data) await pb.collection('users').requestVerification(email) } catch (error) { console.error('Signup error:', error) const params = new URLSearchParams() - if (redirectTo !== '/account') params.set('redirect', redirectTo) + if (redirectTo && redirectTo !== '/account') params.set('redirect', redirectTo) if (error instanceof ClientResponseError) { const errorData = error.response?.data @@ -149,9 +148,11 @@ export async function signup(formData: FormData) { params.set('message', 'Failed to create account. Please try again.') return redirect(`/signup?${params.toString()}`) } - // Automatically log the user in after successful signup try { + // Small delay to ensure user record is fully created + await new Promise(resolve => setTimeout(resolve, 100)) + const authData = await pb.collection('users').authWithPassword(email, password) const cookieStore = await cookies() @@ -171,13 +172,28 @@ export async function signup(formData: FormData) { }) revalidatePath('/', 'layout') - redirect(redirectTo) + + // Try to add success message to destination URL if possible + try { + const url = new URL(redirectTo, 'https://example.com') // Use dummy base for relative URLs + url.searchParams.set('message', 'Account created successfully! Welcome to the platform.') + redirect(url.pathname + url.search) + } catch { + // If URL manipulation fails, just redirect to the destination + redirect(redirectTo) + } } catch (error) { - // If auto-login fails, redirect to login page with success message + // If auto-login fails, still redirect to original destination but with a success message revalidatePath('/', 'layout') - const params = new URLSearchParams({ message: 'Account created successfully! Please log in to access the platform.' }) - if (redirectTo !== '/account') params.set('redirect', redirectTo) - redirect(`/login?${params.toString()}`) + // Try to add success message to destination URL if possible + try { + const url = new URL(redirectTo, 'https://example.com') // Use dummy base for relative URLs + url.searchParams.set('message', 'Account created successfully! You have been logged in.') + redirect(url.pathname + url.search) + } catch { + // If URL manipulation fails, just redirect to the destination + redirect(redirectTo) + } } } diff --git a/app/mht-cet-login-required/page.tsx b/app/mht-cet-login-required/page.tsx index ce53f2d..4b5aebe 100644 --- a/app/mht-cet-login-required/page.tsx +++ b/app/mht-cet-login-required/page.tsx @@ -2,9 +2,12 @@ import Link from "next/link"; import Image from "next/image"; import { Button } from "@/components/ui/button"; -export default function MHTCETLoginRequired({ searchParams }: { +export default async function MHTCETLoginRequired({ searchParams }: { searchParams: Promise<{ redirect?: string }> }) { + const params = await searchParams + const redirectTo = params?.redirect || '/mht-cet' + return (
@@ -34,7 +37,7 @@ export default function MHTCETLoginRequired({ searchParams }: {
-
- {/* Stats */} - {totalItems > 0 && ( -
-

Total Records

-

{totalItems.toLocaleString()}

-
- )} - {/* Export Button */} - -
{/* Filters */} @@ -1169,7 +1150,7 @@ export default function StateCutoffsPage() {
{ const value = e.target.value; From 21e2164bc1b435acba347c02c518bfad5ea5a8cd Mon Sep 17 00:00:00 2001 From: Kewonit <108450560+kewonit@users.noreply.github.com.> Date: Fri, 4 Jul 2025 23:02:35 +0530 Subject: [PATCH 2/6] feat: enhance CategoryFlowChart with new seat types and improved layout; add connections for Ladies, PWD, and Defence categories --- components/CategoryFlowChart.tsx | 716 +++++++++++++++++++++++++++++-- 1 file changed, 681 insertions(+), 35 deletions(-) diff --git a/components/CategoryFlowChart.tsx b/components/CategoryFlowChart.tsx index 77364ab..24e9b91 100644 --- a/components/CategoryFlowChart.tsx +++ b/components/CategoryFlowChart.tsx @@ -81,7 +81,7 @@ const CategoryFlowChart = () => { { id: '2', type: 'custom', - position: { x: 400, y: 0 }, + position: { x: 400, y: -200 }, data: { label: 'General', type: 'category', @@ -89,11 +89,89 @@ const CategoryFlowChart = () => { }, }, + // Main Seat Type - Ladies (centered with its children) + { + id: '35', + type: 'custom', + position: { x: 400, y: 2675 }, // Centered around Ladies children (2100-3600) + data: { + label: 'Ladies', + type: 'category', + description: 'Ladies seat type', + }, + }, + + // Main Seat Type - PWD (centered with its children) + { + id: '56', + type: 'custom', + position: { x: 400, y: 4375 }, // Centered around PWD children (3900-4900) + data: { + label: 'PWD', + type: 'category', + description: 'Persons with Disabilities seat type', + }, + }, + + // Main Seat Type - Defence (centered with its children) + { + id: '57', + type: 'custom', + position: { x: 400, y: 5600 }, // Centered around Defence children (5200-6000) + data: { + label: 'Defence', + type: 'category', + description: 'Defence seat type', + }, + }, + + // Special Categories (spaced out better) + { + id: '58', + type: 'custom', + position: { x: 400, y: 400 }, + data: { + label: 'EWS', + type: 'final', + description: 'Economically Weaker Section', + }, + }, + { + id: '59', + type: 'custom', + position: { x: 400, y: 550 }, + data: { + label: 'ORPHAN', + type: 'final', + description: 'Orphan Category', + }, + }, + { + id: '60', + type: 'custom', + position: { x: 400, y: 700 }, + data: { + label: 'TFWS', + type: 'final', + description: 'Tuition Fee Waiver Scheme', + }, + }, + { + id: '61', + type: 'custom', + position: { x: 400, y: 850 }, + data: { + label: 'MI', + type: 'final', + description: 'Minority Institutions', + }, + }, + // Category Level under General (properly aligned with final codes) { id: '3', type: 'custom', - position: { x: 800, y: -600 }, // Aligned with OPEN codes + position: { x: 800, y: -800 }, // Aligned with OPEN codes data: { label: 'OPEN', type: 'subcategory', @@ -103,7 +181,7 @@ const CategoryFlowChart = () => { { id: '4', type: 'custom', - position: { x: 800, y: -250 }, // Aligned with OBC codes + position: { x: 800, y: -450 }, // Aligned with OBC codes data: { label: 'OBC', type: 'subcategory', @@ -113,7 +191,7 @@ const CategoryFlowChart = () => { { id: '5', type: 'custom', - position: { x: 800, y: 100 }, // Aligned with SC codes + position: { x: 800, y: -100 }, // Aligned with SC codes data: { label: 'SC', type: 'subcategory', @@ -123,7 +201,7 @@ const CategoryFlowChart = () => { { id: '6', type: 'custom', - position: { x: 800, y: 450 }, // Aligned with ST codes + position: { x: 800, y: 250 }, // Aligned with ST codes data: { label: 'ST', type: 'subcategory', @@ -133,7 +211,7 @@ const CategoryFlowChart = () => { { id: '7', type: 'custom', - position: { x: 800, y: 800 }, // Aligned with VJ codes + position: { x: 800, y: 600 }, // Aligned with VJ codes data: { label: 'VJ', type: 'subcategory', @@ -143,7 +221,7 @@ const CategoryFlowChart = () => { { id: '8', type: 'custom', - position: { x: 800, y: 1150 }, // Aligned with NT1 codes + position: { x: 800, y: 950 }, // Aligned with NT1 codes data: { label: 'NT1', type: 'subcategory', @@ -153,7 +231,7 @@ const CategoryFlowChart = () => { { id: '9', type: 'custom', - position: { x: 800, y: 1500 }, // Aligned with NT2 codes + position: { x: 800, y: 1300 }, // Aligned with NT2 codes data: { label: 'NT2', type: 'subcategory', @@ -163,7 +241,7 @@ const CategoryFlowChart = () => { { id: '10', type: 'custom', - position: { x: 800, y: 1850 }, // Aligned with NT3 codes + position: { x: 800, y: 1650 }, // Aligned with NT3 codes data: { label: 'NT3', type: 'subcategory', @@ -171,11 +249,167 @@ const CategoryFlowChart = () => { }, }, + // Category Level under Ladies (properly aligned with final codes) + { + id: '36', + type: 'custom', + position: { x: 800, y: 2100 }, // Aligned with Ladies OPEN codes + data: { + label: 'OPEN', + type: 'subcategory', + description: 'Open category (Ladies)', + }, + }, + { + id: '37', + type: 'custom', + position: { x: 800, y: 2450 }, // Aligned with Ladies OBC codes + data: { + label: 'OBC', + type: 'subcategory', + description: 'Other Backward Classes (Ladies)', + }, + }, + { + id: '38', + type: 'custom', + position: { x: 800, y: 2800 }, // Aligned with Ladies SC codes + data: { + label: 'SC', + type: 'subcategory', + description: 'Scheduled Caste (Ladies)', + }, + }, + { + id: '39', + type: 'custom', + position: { x: 800, y: 3150 }, // Aligned with Ladies ST codes + data: { + label: 'ST', + type: 'subcategory', + description: 'Scheduled Tribe (Ladies)', + }, + }, + { + id: '40', + type: 'custom', + position: { x: 800, y: 3500 }, // Aligned with Ladies VJ codes + data: { + label: 'VJ', + type: 'subcategory', + description: 'Vimukta Jati (Ladies)', + }, + }, + + // Category Level under PWD (properly aligned with final codes) + { + id: '62', + type: 'custom', + position: { x: 800, y: 3900 }, // Aligned with PWD OPEN codes + data: { + label: 'OPEN', + type: 'subcategory', + description: 'Open category (PWD)', + }, + }, + { + id: '63', + type: 'custom', + position: { x: 800, y: 4150 }, // Aligned with PWD OBC codes + data: { + label: 'OBC', + type: 'subcategory', + description: 'Other Backward Classes (PWD)', + }, + }, + { + id: '64', + type: 'custom', + position: { x: 800, y: 4400 }, // Aligned with PWD SC codes + data: { + label: 'SC', + type: 'subcategory', + description: 'Scheduled Caste (PWD)', + }, + }, + { + id: '65', + type: 'custom', + position: { x: 800, y: 4650 }, // Aligned with PWD ST codes + data: { + label: 'ST', + type: 'subcategory', + description: 'Scheduled Tribe (PWD)', + }, + }, + { + id: '66', + type: 'custom', + position: { x: 800, y: 4900 }, // Aligned with PWD VJ codes + data: { + label: 'VJ', + type: 'subcategory', + description: 'Vimukta Jati (PWD)', + }, + }, + + // Category Level under Defence (properly aligned with final codes) + { + id: '67', + type: 'custom', + position: { x: 800, y: 5200 }, // Aligned with Defence OPEN codes + data: { + label: 'OPEN', + type: 'subcategory', + description: 'Open category (Defence)', + }, + }, + { + id: '68', + type: 'custom', + position: { x: 800, y: 5400 }, // Aligned with Defence OBC codes + data: { + label: 'OBC', + type: 'subcategory', + description: 'Other Backward Classes (Defence)', + }, + }, + { + id: '69', + type: 'custom', + position: { x: 800, y: 5600 }, // Aligned with Defence SC codes + data: { + label: 'SC', + type: 'subcategory', + description: 'Scheduled Caste (Defence)', + }, + }, + { + id: '70', + type: 'custom', + position: { x: 800, y: 5800 }, // Aligned with Defence ST codes + data: { + label: 'ST', + type: 'subcategory', + description: 'Scheduled Tribe (Defence)', + }, + }, + { + id: '71', + type: 'custom', + position: { x: 800, y: 6000 }, // Aligned with Defence VJ codes + data: { + label: 'VJ', + type: 'subcategory', + description: 'Vimukta Jati (Defence)', + }, + }, + // Final Category Codes - OPEN (no overlap, proper spacing) { id: '11', type: 'custom', - position: { x: 1200, y: -700 }, + position: { x: 1200, y: -900 }, data: { label: 'GOPENS', type: 'final', @@ -185,7 +419,7 @@ const CategoryFlowChart = () => { { id: '12', type: 'custom', - position: { x: 1200, y: -600 }, + position: { x: 1200, y: -800 }, data: { label: 'GOPENH', type: 'final', @@ -195,7 +429,7 @@ const CategoryFlowChart = () => { { id: '13', type: 'custom', - position: { x: 1200, y: -500 }, + position: { x: 1200, y: -700 }, data: { label: 'GOPENO', type: 'final', @@ -207,7 +441,7 @@ const CategoryFlowChart = () => { { id: '14', type: 'custom', - position: { x: 1200, y: -350 }, + position: { x: 1200, y: -550 }, data: { label: 'GOBCS', type: 'final', @@ -217,7 +451,7 @@ const CategoryFlowChart = () => { { id: '15', type: 'custom', - position: { x: 1200, y: -250 }, + position: { x: 1200, y: -450 }, data: { label: 'GOBCH', type: 'final', @@ -227,7 +461,7 @@ const CategoryFlowChart = () => { { id: '16', type: 'custom', - position: { x: 1200, y: -150 }, + position: { x: 1200, y: -350 }, data: { label: 'GOBCO', type: 'final', @@ -239,7 +473,7 @@ const CategoryFlowChart = () => { { id: '17', type: 'custom', - position: { x: 1200, y: 0 }, + position: { x: 1200, y: -200 }, data: { label: 'GSCS', type: 'final', @@ -249,7 +483,7 @@ const CategoryFlowChart = () => { { id: '18', type: 'custom', - position: { x: 1200, y: 100 }, + position: { x: 1200, y: -100 }, data: { label: 'GSCH', type: 'final', @@ -259,7 +493,7 @@ const CategoryFlowChart = () => { { id: '19', type: 'custom', - position: { x: 1200, y: 200 }, + position: { x: 1200, y: 0 }, data: { label: 'GSCO', type: 'final', @@ -271,7 +505,7 @@ const CategoryFlowChart = () => { { id: '20', type: 'custom', - position: { x: 1200, y: 350 }, + position: { x: 1200, y: 150 }, data: { label: 'GSTS', type: 'final', @@ -281,7 +515,7 @@ const CategoryFlowChart = () => { { id: '21', type: 'custom', - position: { x: 1200, y: 450 }, + position: { x: 1200, y: 250 }, data: { label: 'GSTH', type: 'final', @@ -291,7 +525,7 @@ const CategoryFlowChart = () => { { id: '22', type: 'custom', - position: { x: 1200, y: 550 }, + position: { x: 1200, y: 350 }, data: { label: 'GSTO', type: 'final', @@ -303,7 +537,7 @@ const CategoryFlowChart = () => { { id: '23', type: 'custom', - position: { x: 1200, y: 700 }, + position: { x: 1200, y: 500 }, data: { label: 'GVJS', type: 'final', @@ -313,7 +547,7 @@ const CategoryFlowChart = () => { { id: '24', type: 'custom', - position: { x: 1200, y: 800 }, + position: { x: 1200, y: 600 }, data: { label: 'GVJH', type: 'final', @@ -323,7 +557,7 @@ const CategoryFlowChart = () => { { id: '25', type: 'custom', - position: { x: 1200, y: 900 }, + position: { x: 1200, y: 700 }, data: { label: 'GVJO', type: 'final', @@ -335,7 +569,7 @@ const CategoryFlowChart = () => { { id: '26', type: 'custom', - position: { x: 1200, y: 1050 }, + position: { x: 1200, y: 850 }, data: { label: 'GNT1S', type: 'final', @@ -345,7 +579,7 @@ const CategoryFlowChart = () => { { id: '27', type: 'custom', - position: { x: 1200, y: 1150 }, + position: { x: 1200, y: 950 }, data: { label: 'GNT1H', type: 'final', @@ -355,7 +589,7 @@ const CategoryFlowChart = () => { { id: '28', type: 'custom', - position: { x: 1200, y: 1250 }, + position: { x: 1200, y: 1050 }, data: { label: 'GNT1O', type: 'final', @@ -367,7 +601,7 @@ const CategoryFlowChart = () => { { id: '29', type: 'custom', - position: { x: 1200, y: 1400 }, + position: { x: 1200, y: 1200 }, data: { label: 'GNT2S', type: 'final', @@ -377,7 +611,7 @@ const CategoryFlowChart = () => { { id: '30', type: 'custom', - position: { x: 1200, y: 1500 }, + position: { x: 1200, y: 1300 }, data: { label: 'GNT2H', type: 'final', @@ -387,7 +621,7 @@ const CategoryFlowChart = () => { { id: '31', type: 'custom', - position: { x: 1200, y: 1600 }, + position: { x: 1200, y: 1400 }, data: { label: 'GNT2O', type: 'final', @@ -399,7 +633,7 @@ const CategoryFlowChart = () => { { id: '32', type: 'custom', - position: { x: 1200, y: 1750 }, + position: { x: 1200, y: 1550 }, data: { label: 'GNT3S', type: 'final', @@ -409,7 +643,7 @@ const CategoryFlowChart = () => { { id: '33', type: 'custom', - position: { x: 1200, y: 1850 }, + position: { x: 1200, y: 1650 }, data: { label: 'GNT3H', type: 'final', @@ -419,18 +653,345 @@ const CategoryFlowChart = () => { { id: '34', type: 'custom', - position: { x: 1200, y: 1950 }, + position: { x: 1200, y: 1750 }, data: { label: 'GNT3O', type: 'final', description: 'General NT3 Other University', }, }, + + // Final Category Codes - Ladies OPEN (no overlap, proper spacing) + { + id: '41', + type: 'custom', + position: { x: 1200, y: 2000 }, + data: { + label: 'LOPENS', + type: 'final', + description: 'Ladies Open State', + }, + }, + { + id: '42', + type: 'custom', + position: { x: 1200, y: 2100 }, + data: { + label: 'LOPENH', + type: 'final', + description: 'Ladies Open Home University', + }, + }, + { + id: '43', + type: 'custom', + position: { x: 1200, y: 2200 }, + data: { + label: 'LOPENO', + type: 'final', + description: 'Ladies Open Other University', + }, + }, + + // Final Category Codes - Ladies OBC (no overlap, proper spacing) + { + id: '44', + type: 'custom', + position: { x: 1200, y: 2350 }, + data: { + label: 'LOBCS', + type: 'final', + description: 'Ladies OBC State', + }, + }, + { + id: '45', + type: 'custom', + position: { x: 1200, y: 2450 }, + data: { + label: 'LOBCH', + type: 'final', + description: 'Ladies OBC Home University', + }, + }, + { + id: '46', + type: 'custom', + position: { x: 1200, y: 2550 }, + data: { + label: 'LOBCO', + type: 'final', + description: 'Ladies OBC Other University', + }, + }, + + // Final Category Codes - Ladies SC (no overlap, proper spacing) + { + id: '47', + type: 'custom', + position: { x: 1200, y: 2700 }, + data: { + label: 'LSCS', + type: 'final', + description: 'Ladies SC State', + }, + }, + { + id: '48', + type: 'custom', + position: { x: 1200, y: 2800 }, + data: { + label: 'LSCH', + type: 'final', + description: 'Ladies SC Home University', + }, + }, + { + id: '49', + type: 'custom', + position: { x: 1200, y: 2900 }, + data: { + label: 'LSCO', + type: 'final', + description: 'Ladies SC Other University', + }, + }, + + // Final Category Codes - Ladies ST (no overlap, proper spacing) + { + id: '50', + type: 'custom', + position: { x: 1200, y: 3050 }, + data: { + label: 'LSTS', + type: 'final', + description: 'Ladies ST State', + }, + }, + { + id: '51', + type: 'custom', + position: { x: 1200, y: 3150 }, + data: { + label: 'LSTH', + type: 'final', + description: 'Ladies ST Home University', + }, + }, + { + id: '52', + type: 'custom', + position: { x: 1200, y: 3250 }, + data: { + label: 'LSTO', + type: 'final', + description: 'Ladies ST Other University', + }, + }, + + // Final Category Codes - Ladies VJ (no overlap, proper spacing) + { + id: '53', + type: 'custom', + position: { x: 1200, y: 3400 }, + data: { + label: 'LVJS', + type: 'final', + description: 'Ladies VJ State', + }, + }, + { + id: '54', + type: 'custom', + position: { x: 1200, y: 3500 }, + data: { + label: 'LVJH', + type: 'final', + description: 'Ladies VJ Home University', + }, + }, + { + id: '55', + type: 'custom', + position: { x: 1200, y: 3600 }, + data: { + label: 'LVJO', + type: 'final', + description: 'Ladies VJ Other University', + }, + }, + + // Final Category Codes - PWD OPEN + { + id: '72', + type: 'custom', + position: { x: 1200, y: 3850 }, + data: { + label: 'PWDOPENS', + type: 'final', + description: 'PWD Open State', + }, + }, + { + id: '73', + type: 'custom', + position: { x: 1200, y: 3950 }, + data: { + label: 'PWDOPENH', + type: 'final', + description: 'PWD Open Home University', + }, + }, + + // Final Category Codes - PWD OBC + { + id: '74', + type: 'custom', + position: { x: 1200, y: 4100 }, + data: { + label: 'PWDOBCS', + type: 'final', + description: 'PWD OBC State', + }, + }, + { + id: '75', + type: 'custom', + position: { x: 1200, y: 4200 }, + data: { + label: 'PWDOBCH', + type: 'final', + description: 'PWD OBC Home University', + }, + }, + + // Final Category Codes - PWD SC + { + id: '76', + type: 'custom', + position: { x: 1200, y: 4350 }, + data: { + label: 'PWDSCS', + type: 'final', + description: 'PWD SC State', + }, + }, + { + id: '77', + type: 'custom', + position: { x: 1200, y: 4450 }, + data: { + label: 'PWDSCH', + type: 'final', + description: 'PWD SC Home University', + }, + }, + + // Final Category Codes - PWD ST + { + id: '78', + type: 'custom', + position: { x: 1200, y: 4600 }, + data: { + label: 'PWDRSTS', + type: 'final', + description: 'PWD ST State', + }, + }, + { + id: '79', + type: 'custom', + position: { x: 1200, y: 4700 }, + data: { + label: 'PWDRSTH', + type: 'final', + description: 'PWD ST Home University', + }, + }, + + // Final Category Codes - PWD VJ + { + id: '80', + type: 'custom', + position: { x: 1200, y: 4850 }, + data: { + label: 'PWDRVJS', + type: 'final', + description: 'PWD VJ State', + }, + }, + + // Final Category Codes - Defence OPEN + { + id: '81', + type: 'custom', + position: { x: 1200, y: 5150 }, + data: { + label: 'DEFOPENS', + type: 'final', + description: 'Defence Open State', + }, + }, + + // Final Category Codes - Defence OBC + { + id: '82', + type: 'custom', + position: { x: 1200, y: 5350 }, + data: { + label: 'DEFOBCS', + type: 'final', + description: 'Defence OBC State', + }, + }, + + // Final Category Codes - Defence SC + { + id: '83', + type: 'custom', + position: { x: 1200, y: 5550 }, + data: { + label: 'DEFSCS', + type: 'final', + description: 'Defence SC State', + }, + }, + + // Final Category Codes - Defence ST + { + id: '84', + type: 'custom', + position: { x: 1200, y: 5750 }, + data: { + label: 'DEFSTS', + type: 'final', + description: 'Defence ST State', + }, + }, + + // Final Category Codes - Defence VJ + { + id: '85', + type: 'custom', + position: { x: 1200, y: 5950 }, + data: { + label: 'DEFRVJS', + type: 'final', + description: 'Defence VJ State', + }, + }, ], []); const initialEdges: Edge[] = useMemo(() => [ - // Root to General + // Root to all main categories { id: 'e1-2', source: '1', target: '2', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e1-35', source: '1', target: '35', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e1-56', source: '1', target: '56', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e1-57', source: '1', target: '57', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e1-58', source: '1', target: '58', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e1-59', source: '1', target: '59', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e1-60', source: '1', target: '60', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e1-61', source: '1', target: '61', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, // General to all categories { id: 'e2-3', source: '2', target: '3', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, @@ -442,6 +1003,88 @@ const CategoryFlowChart = () => { { id: 'e2-9', source: '2', target: '9', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, { id: 'e2-10', source: '2', target: '10', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + // Ladies to all categories + { id: 'e35-36', source: '35', target: '36', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e35-37', source: '35', target: '37', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e35-38', source: '35', target: '38', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e35-39', source: '35', target: '39', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e35-40', source: '35', target: '40', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + + // PWD to all categories + { id: 'e56-62', source: '56', target: '62', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e56-63', source: '56', target: '63', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e56-64', source: '56', target: '64', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e56-65', source: '56', target: '65', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e56-66', source: '56', target: '66', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + + // Defence to all categories + { id: 'e57-67', source: '57', target: '67', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e57-68', source: '57', target: '68', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e57-69', source: '57', target: '69', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e57-70', source: '57', target: '70', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + { id: 'e57-71', source: '57', target: '71', markerEnd: { type: MarkerType.Arrow }, style: { strokeWidth: 2 } }, + + // ...existing code... + + // Ladies OPEN to final codes + { id: 'e36-41', source: '36', target: '41', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e36-42', source: '36', target: '42', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e36-43', source: '36', target: '43', markerEnd: { type: MarkerType.Arrow } }, + + // Ladies OBC to final codes + { id: 'e37-44', source: '37', target: '44', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e37-45', source: '37', target: '45', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e37-46', source: '37', target: '46', markerEnd: { type: MarkerType.Arrow } }, + + // Ladies SC to final codes + { id: 'e38-47', source: '38', target: '47', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e38-48', source: '38', target: '48', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e38-49', source: '38', target: '49', markerEnd: { type: MarkerType.Arrow } }, + + // Ladies ST to final codes + { id: 'e39-50', source: '39', target: '50', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e39-51', source: '39', target: '51', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e39-52', source: '39', target: '52', markerEnd: { type: MarkerType.Arrow } }, + + // Ladies VJ to final codes + { id: 'e40-53', source: '40', target: '53', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e40-54', source: '40', target: '54', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e40-55', source: '40', target: '55', markerEnd: { type: MarkerType.Arrow } }, + + // PWD OPEN to final codes + { id: 'e62-72', source: '62', target: '72', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e62-73', source: '62', target: '73', markerEnd: { type: MarkerType.Arrow } }, + + // PWD OBC to final codes + { id: 'e63-74', source: '63', target: '74', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e63-75', source: '63', target: '75', markerEnd: { type: MarkerType.Arrow } }, + + // PWD SC to final codes + { id: 'e64-76', source: '64', target: '76', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e64-77', source: '64', target: '77', markerEnd: { type: MarkerType.Arrow } }, + + // PWD ST to final codes + { id: 'e65-78', source: '65', target: '78', markerEnd: { type: MarkerType.Arrow } }, + { id: 'e65-79', source: '65', target: '79', markerEnd: { type: MarkerType.Arrow } }, + + // PWD VJ to final codes + { id: 'e66-80', source: '66', target: '80', markerEnd: { type: MarkerType.Arrow } }, + + // Defence OPEN to final codes + { id: 'e67-81', source: '67', target: '81', markerEnd: { type: MarkerType.Arrow } }, + + // Defence OBC to final codes + { id: 'e68-82', source: '68', target: '82', markerEnd: { type: MarkerType.Arrow } }, + + // Defence SC to final codes + { id: 'e69-83', source: '69', target: '83', markerEnd: { type: MarkerType.Arrow } }, + + // Defence ST to final codes + { id: 'e70-84', source: '70', target: '84', markerEnd: { type: MarkerType.Arrow } }, + + // Defence VJ to final codes + { id: 'e71-85', source: '71', target: '85', markerEnd: { type: MarkerType.Arrow } }, + // OPEN to final codes { id: 'e3-11', source: '3', target: '11', markerEnd: { type: MarkerType.Arrow } }, { id: 'e3-12', source: '3', target: '12', markerEnd: { type: MarkerType.Arrow } }, @@ -504,7 +1147,7 @@ const CategoryFlowChart = () => { MHT-CET Category Code Structure
- Interactive flow chart showing the hierarchy: Seat Types → General → Categories → Final Codes + Interactive flow chart showing the hierarchy: Seat Types → Categories (General/Ladies/PWD/Defence) → Sub-Categories → Final Codes
@@ -524,6 +1167,9 @@ const CategoryFlowChart = () => { minZoom={0.5} maxZoom={2} attributionPosition="bottom-left" + nodesDraggable={false} + nodesConnectable={false} + elementsSelectable={true} > From 1205a886bc5056f822d8862222b63b8b32385e30 Mon Sep 17 00:00:00 2001 From: Kewonit <108450560+kewonit@users.noreply.github.com.> Date: Sat, 5 Jul 2025 00:23:27 +0530 Subject: [PATCH 3/6] feat: add DonationCard component to encourage contributions for project support --- app/mht-cet/state-cutoffs/page.tsx | 355 +++++++++++++++++++---------- components/DonationCard.tsx | 37 +++ 2 files changed, 274 insertions(+), 118 deletions(-) create mode 100644 components/DonationCard.tsx diff --git a/app/mht-cet/state-cutoffs/page.tsx b/app/mht-cet/state-cutoffs/page.tsx index 87ecb31..280bbe8 100644 --- a/app/mht-cet/state-cutoffs/page.tsx +++ b/app/mht-cet/state-cutoffs/page.tsx @@ -57,6 +57,7 @@ import { } from "@/components/ui/accordion"; import { BookUser, Building, GraduationCap, Info, Lightbulb, MapPin, ShieldCheck, Users, Video } from 'lucide-react'; import CategoryFlowChart from '@/components/CategoryFlowChart'; +import { DonationCard } from '@/components/DonationCard'; // Types interface CutoffRecord { @@ -1127,7 +1128,7 @@ export default function StateCutoffsPage() { MHT-CET State Cutoffs 2024

- Round 1 cutoffs for engineering colleges + Use these to predict your chances of admission based on your percentile. (Data : 2024 Round 1)

@@ -1168,7 +1169,6 @@ export default function StateCutoffsPage() {
- {/* How to Use This Tool */} + {/* How to Use This Tool - always on top, full width */} +
- -
- + +
+
How to Use This Tool
- -
    -
  1. - 1 - - Enter Your Percentile - Type your MHT-CET percentile to see colleges in a -10% range. - -
  2. -
  3. - 2 - - Filter Your Preferences - Select categories, courses, and seat types to narrow down results. - -
  4. -
  5. - 3 - - Analyze & Strategize - Results are sorted by highest cutoff. Use this to plan your CAP round choices. - -
  6. -
-
- - + +
+ {/* Step 1 */} +
+
+ 1 +
+

Enter Your MHT-CET Percentile

+

+ Type your percentile score (e.g., 95.5) in the box above.
+ The tool will show all colleges where the cutoff is less than or equal to your percentile.
(Range: 0% up to your target percentile)
+

+
+ {/* Step 2 */} +
+
+ 2 +
+

Filter Your Preferences

+

+ Use the filters to select categories, courses, seat types, and university regions.
+ This helps you narrow down the results to match your eligibility and interests. +

+
+ {/* Step 3 */} +
+
+ 3 +
+

Analyze & Plan

+

+ Results are sorted by highest cutoff first.
+ Use this to plan your CAP round choices and maximize your admission chances. +

+
+
+
+ + - - Pro Tip: Enter your percentile to see all colleges where you have a chance of admission (from 0% to your target percentile). Results show the distance from your target. + + Tip: Enter your percentile to see all colleges where you have a chance of admission (from 0% up to your target percentile).
+ This tool uses official DTE Maharashtra cutoff data for accuracy.
+ Always double-check with the latest official DTE Maharashtra sources and college websites for the most current and authoritative information. We do not guarantee admission or take responsibility for any decisions made using this tool.
+
- {/* Seat Allocation Types */} - -
- - -
- + {/* Seat Allocation Types and Category & Code Legends side by side */} +
+ {/* Seat Allocation Types - left */} + +
+ + +
+
- Seat Allocation Types + Seat Allocation Types (Explained)
- -
- -
- State Level - Open to all Maharashtra candidates. + +
+ {/* State Level */} +
+ +
+
State Level (S)
+
+ Who can apply?
+ All students from Maharashtra, regardless of their home university region. +
+
+ Example: If you are from any part of Maharashtra, you can compete for these seats. +
+
-
-
- -
- Home University - For students within the same university region. + + {/* Home University */} +
+ +
+
Home University (H)
+
+ Who can apply?
+ Only students whose Home University matches the college's university region. +
+
+ What is Home University?
+ The university region where you completed your 12th standard (HSC) or equivalent. Each district in Maharashtra is mapped to a university region. +
+
+ Example: If you studied in Pune district, your Home University is "Savitribai Phule Pune University". You can apply for Home University seats in colleges under this university. +
+
-
-
- -
- Other University - For students from different university regions. + + {/* Other University */} +
+ +
+
Other University (O)
+
+ Who can apply?
+ Students from other university regions (not the college's Home University region). +
+
+ Example: If your Home University is "Mumbai University" and you are applying to a college under "Pune University", you are eligible for Other University seats there. +
+
+
+ + {/* Visual Table for Quick Reference */} +
+
+ + Quick Reference Table +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
TypeCodeWho Can Apply?
State LevelSAll Maharashtra students
Home UniversityHStudents from the same university region
Other UniversityOStudents from other university regions
+
+
+ Tip: If you are unsure about your Home University, check your 12th (HSC) board details or ask your school/college. +
-
-
- Tip: Hover on seat types in the table for more info.
- {/* Category and Code Legends */} - -
- - -
- + {/* Category and Code Legends - right */} + +
+ + +
+
- Category & Code Legends + Category & Code Legends
- - - -
- - Category Code Format -
-
- -
-

G = General, L = Ladies

-

H = Home Uni, O = Other Uni, S = State

-

Example: GOPENH is General Open Home University.

-
-
-
- - -
- - Special Category Codes -
-
- -
-

TFWS: Tuition Fee Waiver Scheme

-

EWS: Economically Weaker Section

-

DEF: Defence Reserved

-

PWD: Persons with Disability

-

MI: Minority Institutions

-
-
-
- - -
- - Video Explanation +
+ {/* Category Code Format */} +
+
+ + Category Code Format +
+
    +
  • +
    +
    G = General (open to all)
    +
    L = Ladies (female candidates only)
    +
    SC = Scheduled Caste, ST = Scheduled Tribe, OBC = Other Backward Class, EWS = Economically Weaker Section
    +
    +
  • +
  • +
    +
    OPEN = Open to all within that category
    +
    SC/ST/OBC/EWS = Reserved for specific categories
    +
    +
  • +
  • +
    +
    H = Home University (your university region)
    +
    O = Other University (other regions)
    +
    S = State Level (all Maharashtra students)
    +
    +
  • +
  • +
    +
    Example 1: GOPENH = General, Open seat, Home University
    +
    Example 2: LOPENO = Ladies, Open seat, Other University
    +
    +
  • +
+
+ How to read a code: Most codes are a combination of: +
    +
  • First part: G = General, L = Ladies, SC = Scheduled Caste, ST = Scheduled Tribe, OBC = Other Backward Class, EWS = Economically Weaker Section, etc.
  • +
  • OPEN: Open to all within that category (not a reserved sub-quota). Other codes like OBC, SC, etc. indicate reservation for that group.
  • +
  • H/O/S: H = Home University, O = Other University, S = State Level. This is always at the end of the code.
  • +
+
+ Full Example: + GOPENO = General, Open seat, Other University.
+ LOPENS = Ladies, Open seat, State Level.
- - -
-