Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
a6e93c2
feat: Made some changes to application and added background to home
Dana-I Nov 17, 2025
9a4f7c3
refactor(updated hero section): Worked on updating the Hero UI
Dhivyeshp Dec 22, 2025
64cbe36
refactor(worked on updating the about section.): Updating the About Text
Dhivyeshp Dec 22, 2025
25b70a4
feat(countdown): Added countdown feature
Dhivyeshp Dec 24, 2025
36531eb
feat: Worked on updating countdown and fixing stats feature
Dhivyeshp Dec 24, 2025
b007669
feat: Updated the challenges UI
Dhivyeshp Dec 25, 2025
01cc33a
Merge pull request #1 from Dana-I/frontend
Dhivyeshp Dec 25, 2025
bc24647
feat: Registration, sign in, and profile functionality work
Dana-I Dec 26, 2025
ebb45f2
Merge branch 'develop' into registration
Dana-I Dec 26, 2025
0c47c49
feat(updated footer and schedule ui): Footer and Schedule UI
Dhivyeshp Dec 27, 2025
00bfdcd
style: Changed UI for register, apply, profile
Dana-I Dec 28, 2025
e4e4e86
feat: Application status shows up in database and profile now
Dana-I Dec 28, 2025
48edb2e
Merge pull request #2 from Dana-I/registration
Dana-I Dec 28, 2025
b2b78c5
feat: Worked on updating the background and sponsor section
Dhivyeshp Jan 1, 2026
c9aba02
feat: Worked on updating the sponsors section
Dhivyeshp Jan 2, 2026
6aeda94
feat: Updated footer UI/design
Dhivyeshp Jan 2, 2026
782c768
feat: Worked on parallax scroll effect, floating header text
Dhivyeshp Jan 2, 2026
261859a
Merge pull request #3 from Dana-I/frontend
Dhivyeshp Jan 2, 2026
0421d70
refactor: Migrated codebases for scanning issues
Dhivyeshp Jan 2, 2026
8d227cd
Merge pull request #4 from Dana-I/frontend
Dhivyeshp Jan 2, 2026
73a46ba
refactor: Migrated Scans
Dhivyeshp Jan 6, 2026
06e6566
Rename project to NTHS HackPortal
Dhivyeshp Jan 6, 2026
e2883e0
feat: Added sponsor logo cards
Dana-I Jan 9, 2026
7a5a7e0
fix: Updated Hero responsivenes
Dhivyeshp Jan 9, 2026
bcb06d1
Merge pull request #5 from Dana-I/frontend
Dhivyeshp Jan 9, 2026
4f50706
refactor: Refractored the responsiveness code
Dhivyeshp Jan 12, 2026
dde7372
fix(fixed responsive issues for about section): Worked on about section
Dhivyeshp Jan 14, 2026
6e77419
fix(stats section): Fixed responsivness buges for stats section
Dhivyeshp Jan 14, 2026
cbd3490
Merge pull request #6 from Dana-I/frontend
Dhivyeshp Jan 19, 2026
381aff6
feat: Changed responsiveness for laptops added responsiveness for mobile
Dana-I Jan 27, 2026
a48e321
Merge pull request #7 from Dana-I/responsiveness
Dana-I Jan 27, 2026
26dcfa7
feat: Fixed color for faqs
Dana-I Jan 27, 2026
f71c204
feat: Changed app icon and text
Dana-I Jan 29, 2026
b659596
feat: Linked sign in and profile to mobile nav bar
Dana-I Jan 29, 2026
1589a4d
Merge pull request #8 from Dana-I/UI
Dana-I Jan 29, 2026
cd55ed1
feat: Updated Schedule Logic
Kaushikdrko Jan 29, 2026
cd7b31b
Merge pull request #9 from Dana-I/changes
Dana-I Jan 30, 2026
95ae3d9
fix: Created sign components to aligns texts for web screens
Kaushikdrko Jan 30, 2026
55b085f
Merge pull request #10 from Dana-I/changes
Dana-I Jan 30, 2026
eec5ca1
feat: Added responsiveness for mobile and waivers
Dana-I Feb 16, 2026
5f5d730
Merge pull request #11 from Dana-I/mobile
Dana-I Feb 16, 2026
557f4e7
fix: Deployment fix
Dana-I Feb 17, 2026
9649c7b
Merge branch 'develop' of https://github.com/Dana-I/NTHSHackPortal in…
Dana-I Feb 17, 2026
437b936
chore: Fixed sponsor layout
Dana-I Feb 19, 2026
7a4ae87
feat: Added minor participant form
Kaushikdrko Feb 25, 2026
87065c9
chore: Changed minor participant form page field
Kaushikdrko Feb 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions .env.template

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# HackPortal
# NTHS HackPortal
### _A platform for user-friendly hackathon event management._

[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
Expand Down
6 changes: 2 additions & 4 deletions components/AppHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,8 @@ export default function AppHeader() {
className="flex gap-2 ml-[6px] font-display self-center items-center md:ml-0"
>
{/* !change src */}
<Image alt="HackPortal logo" src={'/assets/hp-logo.png'} width={45} height={35} />
<span className="text-lg font-black md:z-0 md:text-3xl text-primaryDark">
HackPortal
</span>
<Image alt="HackPortal logo" src={'/assets/LassoCow1ONLY.png'} width={45} height={35} />
<span className="text-lg font-black md:z-0 md:text-3xl text-primaryDark">NTHS26</span>
</Link>
</div>

Expand Down
45 changes: 45 additions & 0 deletions components/AppHeader2/FloatingDock/item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { motion, useSpring, useTransform, useMotionValue } from 'framer-motion';
import { PropsWithChildren, useEffect } from 'react';

type Props = {
className?: string;

originalHeight: number;
originalWidth: number;

widthScaleFactor: number;
distanceMagnify: number;
cursorFromCenter: number;
};

export default function BoxItem(props: PropsWithChildren<Props>) {
const minWidth = props.originalWidth;
const maxWidth = props.originalWidth + props.originalWidth * props.widthScaleFactor;

const cursorMotionValue = useMotionValue(props.cursorFromCenter);

useEffect(() => {
cursorMotionValue.set(props.cursorFromCenter);
}, [props.cursorFromCenter, cursorMotionValue]);

const widthSync = useTransform(
cursorMotionValue,
[-props.distanceMagnify, 0, props.distanceMagnify],
[minWidth, maxWidth, minWidth],
);

const width = useSpring(widthSync, {
mass: 0.1,
stiffness: 150,
damping: 12,
});

return (
<motion.div
style={{ width, height: props.originalHeight }}
className={props.className ?? 'shrink-0 flex justify-center items-center min-h-fit min-w-fit'}
>
{props.children}
</motion.div>
);
}
107 changes: 107 additions & 0 deletions components/AppHeader2/FloatingDock/wrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { useEffect, useRef, useState } from 'react';
import FloatingDockItem from './item';

type Props = {
items: JSX.Element[];

settings?: {
widthScaleFactor?: number;
distanceMagnify?: number;
};

classes?: {
wrapperDiv?: string;
itemDiv?: string;
};
};

export default function FloatingDockWrapper(props: Props) {
const originalWidths = props.items.map((item) => {
const el = item.props?.id ? document.getElementById(item.props.id) : null;
return el?.getBoundingClientRect().width ?? 0;
});

const originalHeights = props.items.map((item) => {
const el = item.props?.id ? document.getElementById(item.props.id) : null;
return el?.getBoundingClientRect().height ?? 0;
});

// in pixels
const widthScaleFactor = props.settings?.widthScaleFactor ?? 0.25;
const distanceMagnify = props.settings?.distanceMagnify ?? 140;

const boxRef = useRef<HTMLDivElement>(null);

// distance of cursor from center of each item
const [cursorFromCenters, setCursorFromCenters] = useState<number[]>(
Array(props.items.length).fill(distanceMagnify),
);

useEffect(() => {
const box = boxRef.current;

if (!box) {
return;
}

// Get children ---

const children: (Element | null)[] = [];
for (let i = 0; i < box.children.length; ++i) {
children.push(box.children.item(i));
}

// Handle mouse move ---

const handleMouseMove = (e: MouseEvent) => {
if (checkWithinRange(box, e.clientX, e.clientY)) {
const newDiffs = [...cursorFromCenters];
for (let i = 0; i < children.length; ++i) {
const child = children[i];
if (child && child instanceof HTMLElement) {
const el = child as HTMLElement;
const rect = el.getBoundingClientRect();
const center = rect.x + rect.width / 2;
const diff = e.clientX - center;
newDiffs[i] = diff;
}
}
setCursorFromCenters(newDiffs);
} else {
setCursorFromCenters(Array(props.items.length).fill(distanceMagnify));
}
};

window.addEventListener('mousemove', handleMouseMove);

return () => {
window.removeEventListener('mousemove', handleMouseMove);
};
}, [boxRef, cursorFromCenters, distanceMagnify, props.items]);

const checkWithinRange = (box: HTMLElement, mouseX: number, mouseY: number) => {
const { x, y, width, height } = box.getBoundingClientRect();
return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
};

return (
<div
ref={boxRef}
className={props.classes?.wrapperDiv ?? 'gap-4 flex justify-center items-center flex-wrap'}
>
{props.items.map((item, i) => (
<FloatingDockItem
key={i}
className={props.classes?.itemDiv}
originalHeight={originalHeights[i]}
originalWidth={originalWidths[i]}
widthScaleFactor={widthScaleFactor}
distanceMagnify={distanceMagnify}
cursorFromCenter={cursorFromCenters[i]}
>
{item}
</FloatingDockItem>
))}
</div>
);
}
24 changes: 15 additions & 9 deletions components/AppHeader2/QRScanDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useAuthContext } from '@/lib/user/AuthContext';
import { RequestHelper } from '@/lib/request-helper';
import QRCodeReaderV2 from './QRCodeReaderV2';
import QrScanner from 'qr-scanner';
import QRCodeReader from '../dashboardComponents/QRCodeReader';

interface QRScanDialogProps {
scan: {
Expand All @@ -24,6 +25,7 @@ const successStrings = {
unexpectedError: 'Unexpected error...',
notCheckedIn: "User hasn't checked in!",
invalidFormat: 'Invalid hacker tag format...',
lateCheckinIneligible: 'User is not eligible for late check-in...',
};

interface UserProfile extends Omit<Registration, 'user'> {
Expand All @@ -46,18 +48,21 @@ function getSuccessColor(success: string) {
export default function QRScanDialog({ scan, onModalClose }: QRScanDialogProps) {
const [scanData, setScanData] = useState(undefined);
const [success, setSuccess] = useState(undefined);
const [userScanned, setUserScanned] = useState(false);
const { user } = useAuthContext();
const [scannedUserInfo, setScannedUserInfo] = useState(undefined);

const handleScan = async (data: string) => {
if (userScanned) return;
if (!data.startsWith('hack:')) {
setScanData(data);
setSuccess(successStrings.invalidFormat);
return;
}
setUserScanned(true);
const query = new URL(`http://localhost:3000/api/scan`);
query.searchParams.append('id', data.replaceAll('hack:', ''));
fetch(query.toString().replaceAll('http://localhost:3000', ''), {
await fetch(query.toString().replaceAll('http://localhost:3000', ''), {
mode: 'cors',
headers: { Authorization: user.token },
method: 'POST',
Expand All @@ -81,6 +86,8 @@ export default function QRScanDialog({ scan, onModalClose }: QRScanDialogProps)
return setSuccess(successStrings.alreadyClaimed);
} else if (result.status === 403) {
return setSuccess(successStrings.notCheckedIn);
} else if (result.status === 400) {
return setSuccess(successStrings.lateCheckinIneligible);
} else if (result.status !== 200) {
return setSuccess(successStrings.unexpectedError);
}
Expand All @@ -99,7 +106,7 @@ export default function QRScanDialog({ scan, onModalClose }: QRScanDialogProps)

return (
<Transition appear show={scan !== null} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={onModalClose}>
<Dialog as="div" className="relative z-50" onClose={onModalClose}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
Expand Down Expand Up @@ -144,12 +151,7 @@ export default function QRScanDialog({ scan, onModalClose }: QRScanDialogProps)
</div>
) : (
<div className="p-3">
<QRCodeReaderV2
onScanFail={(err: string | Error) => console.error(err)}
onScanSuccess={async (scanResult: QrScanner.ScanResult) => {
await handleScan(scanResult.data);
}}
/>
<QRCodeReader width={200} height={200} callback={handleScan} />
</div>
)}
</div>
Expand All @@ -158,7 +160,10 @@ export default function QRScanDialog({ scan, onModalClose }: QRScanDialogProps)
<button
type="button"
className="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={() => setScanData(undefined)}
onClick={() => {
setScanData(undefined);
setUserScanned(false);
}}
>
Next Scan
</button>
Expand All @@ -167,6 +172,7 @@ export default function QRScanDialog({ scan, onModalClose }: QRScanDialogProps)
className="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={() => {
setScanData(undefined);
setUserScanned(false);
onModalClose();
}}
>
Expand Down
Loading