Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion web/app/(splash)/GetStarted/GetStarted.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const GetStarted = () => {
</div>
<div className="mb-16 flex justify-center gap-4">
<Button asChild size="lg">
<Link href="/product">Get Started</Link>
<Link href="/hacker">Get Started</Link>
</Button>
<Button asChild size="lg" variant="outline">
<Link href="https://docs.convex.dev/home">Convex docs</Link>
Expand Down
214 changes: 214 additions & 0 deletions web/app/hacker/HackerForm/HackathonProfileForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
"use client"
import { useState, useEffect, useRef } from "react"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { Label } from "@/components/ui/label"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import { Progress } from "@/components/ui/progress"

const questions = [
{
"id": 1,
"text": "I prefer to lead team projects.",
"category": "Motivation and Goals"
},
{
"id": 2,
"text": "I am excited about attending multiple workshops and events at the hackathon.",
"category": "Commitment Level"
},
{
"id": 3,
"text": "I enjoy brainstorming and collaborating on ideas with others.",
"category": "Team Dynamics"
},
{
"id": 4,
"text": "I like when my teammates have skills that complement mine.",
"category": "Team Dynamics"
},
{
"id": 5,
"text": "Winning the hackathon is my top priority.",
"category": "Commitment Level"
},
{
"id": 6,
"text": "I am open to learning new technologies during the event.",
"category": "Skills and Experience"
},
{
"id": 7,
"text": "I work best under tight deadlines.",
"category": "Work Style"
},
{
"id": 8,
"text": "I prefer working with teammates who share similar strengths.",
"category": "Team Dynamics"
},
{
"id": 9,
"text": "I appreciate constructive feedback on my work.",
"category": "Skills and Experience"
},
{
"id": 10,
"text": "I am confident in my coding abilities.",
"category": "Skills and Experience"
},
{
"id": 11,
"text": "I enjoy taking on challenging problems.",
"category": "Skills and Experience"
},
{
"id": 12,
"text": "I prefer a well-structured plan before starting a project.",
"category": "Work Style"
},
{
"id": 13,
"text": "I am comfortable adapting to changes during the project.",
"category": "Work Style"
},
{
"id": 14,
"text": "I like to focus on one task at a time.",
"category": "Work Style"
},
{
"id": 15,
"text": "I am eager to help teammates who are struggling.",
"category": "Team Dynamics"
},
{
"id": 16,
"text": "I value creativity over functionality in projects.",
"category": "Motivation and Goals"
},
{
"id": 17,
"text": "I believe communication is key to a successful team.",
"category": "Team Dynamics"
},
{
"id": 18,
"text": "I am motivated by learning rather than winning.",
"category": "Motivation and Goals"
},
{
"id": 19,
"text": "I have experience with version control systems like GitHub.",
"category": "Skills and Experience"
},
{
"id": 20,
"text": "I enjoy working late hours to meet project goals.",
"category": "Commitment Level"
}
]

const questionsPerPage = 5
const totalPages = Math.ceil(questions.length / questionsPerPage)

export default function Component() {
const [answers, setAnswers] = useState<Record<number, string>>({})
const [currentPage, setCurrentPage] = useState(1)
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0)
const formRef = useRef<HTMLFormElement>(null)

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
if (currentPage < totalPages) {
setCurrentPage(currentPage + 1)
setCurrentQuestionIndex(0)
} else {
console.log("Submitted answers:", answers)
}
}

const handlePrevious = () => {
setCurrentPage(currentPage - 1)
setCurrentQuestionIndex(questionsPerPage - 1)
}

const handleAnswer = (questionId: number, value: string) => {
setAnswers(prev => ({ ...prev, [questionId]: value }))
if (currentQuestionIndex < questionsPerPage - 1) {
setCurrentQuestionIndex(currentQuestionIndex + 1)
}
}

useEffect(() => {
const currentQuestionElement = formRef.current?.querySelector(`#question-${currentQuestionIndex}`)
if (currentQuestionElement) {
currentQuestionElement.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
}
}, [currentQuestionIndex])

const startIndex = (currentPage - 1) * questionsPerPage
const endIndex = startIndex + questionsPerPage
const currentQuestions = questions.slice(startIndex, endIndex)

return (
<Card className="w-3/4 mx-auto bg-white shadow-xl rounded-lg transition-all">
<CardHeader className="text-center">
<CardTitle className="text-3xl mb-2 font-bold text-gray-700">Hackathon Participant Survey</CardTitle>
<CardDescription className="text-lg text-gray-600">Please answer the following questions on a scale from strongly disagree to strongly agree.</CardDescription>
</CardHeader>
<form onSubmit={handleSubmit} ref={formRef}>
<CardContent className="space-y-10">
<Progress value={(currentPage / totalPages) * 100} className="w-full h-2 bg-gray-300 rounded-full" />
{currentQuestions.map((question, index) => (
<div key={question.id} id={`question-${index}`} className={`space-y-6 transition-opacity duration-500 ${index === currentQuestionIndex ? 'opacity-100' : 'opacity-50'}`}>
<Label htmlFor={`question-${question.id}`} className="text-center block text-xl font-medium text-gray-800">{question.text}</Label>
<div className="flex items-center justify-between px-6">
<span className="text-lg font-medium text-purple-400">Disagree</span>
<RadioGroup
id={`question-${question.id}`}
onValueChange={(value) => handleAnswer(question.id, value)}
className="flex justify-center items-center space-x-6"
>
{[1, 2, 3, 4, 5].map((value) => (
<div
key={value}
className={`flex flex-col items-center space-y-1 transition-transform ${
value === 1 || value === 5 ? 'scale-125' :
value === 2 || value === 4 ? 'scale-110' : ''
}`}
>
<RadioGroupItem
key={value}
value={value.toString()}
id={`q${question.id}-${value}`}
className={`h-8 w-8 border-4 rounded-full transition-colors duration-300 ${
value <= 2 ? 'hover:bg-[#e4b4f9] border-[#d393f7]' :
value >= 4 ? 'hover:bg-[#baf2df] border-[#8ee9c2]' :
'hover:bg-gray-200 border-gray-400'
}`}
/>
</div>
))}
</RadioGroup>

<span className="text-lg font-medium text-green-400">Agree</span>
</div>
<p className="text-base text-gray-500 text-center">{question.category}</p>
</div>
))}
</CardContent>
<CardFooter className="flex justify-center space-x-4">
{currentPage > 1 && (
<Button type="button" variant="outline" onClick={handlePrevious} className="text-lg px-6 py-3 transition-colors duration-200 bg-white hover:bg-gray-100 rounded-lg">
Previous
</Button>
)}
<Button type="submit" className="text-lg px-6 py-3 transition-colors duration-200 bg-blue-600 hover:bg-blue-700 text-white rounded-lg">
{currentPage < totalPages ? "Next" : "Submit"}
</Button>
</CardFooter>
</form>
</Card>
)
}
64 changes: 64 additions & 0 deletions web/app/hacker/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Button } from "@/components/ui/button";
import Image from "next/image";
import Link from "next/link";
import { ReactNode } from "react";

export default function SplashPageLayout({
children,
}: {
children: ReactNode;
}) {
return (
<div className="flex min-h-screen w-full flex-col">
<header className="sticky top-0 z-10 flex h-20 border-b bg-background/80 px-4 backdrop-blur md:px-6">
<nav className="container hidden w-full justify-between gap-6 text-lg font-medium md:flex md:flex-row md:items-center md:gap-5 md:text-sm lg:gap-6">
<Link href="/">

<Image
src="/Hackd.png"
alt="Logo"
width={128}
height={128}
className="rounded-full"/>
</Link>
<div className="flex items-center gap-4">
<SplashPageNav />
</div>
</nav>
</header>
<main className="flex grow flex-col">{children}</main>
<footer className="border-t">
<div className="container py-4 text-sm leading-loose">
Built with ❤️ at{" "}
<FooterLink href="https://hackthenorth2024.devpost.com/">HackTheNorth2024</FooterLink>.
Powered by Convex,{" "}
<FooterLink href="https://nextjs.org/">Next.js</FooterLink> and{" "}
<FooterLink href="https://ui.shadcn.com/">shadcn/ui</FooterLink>.
</div>
</footer>
</div>
);
}

function FooterLink({ href, children }: { href: string; children: ReactNode }) {
return (
<Link
href={href}
className="underline underline-offset-4 hover:no-underline"
target="_blank"
>
{children}
</Link>
);
}

function SplashPageNav() {
return (
<>

<Link href="/product">
<Button>Get Started</Button>
</Link>
</>
);
}
5 changes: 5 additions & 0 deletions web/app/hacker/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import SurveyForm from "./HackerForm/HackathonProfileForm";

export default function HomePage() {
return <SurveyForm/>;
}
4 changes: 2 additions & 2 deletions web/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { ConvexAuthNextjsServerProvider } from "@convex-dev/auth/nextjs/server";
const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
title: "Convex + Next.js + Convex Auth",
description: "Generated by npm create convex",
title: "Hackd",
description: "Find your next big team with Hackd.",
icons: {
icon: "/convex.svg",
},
Expand Down
26 changes: 13 additions & 13 deletions web/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"

import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"

const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
Expand Down Expand Up @@ -31,27 +31,27 @@ const buttonVariants = cva(
variant: "default",
size: "default",
},
},
);
}
)

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
asChild?: boolean
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
},
);
Button.displayName = "Button";
)
}
)
Button.displayName = "Button"

export { Button, buttonVariants };
export { Button, buttonVariants }
Loading