Compare commits

..

17 commits

Author SHA1 Message Date
28b3f8a0b0 Fixed answer buttons
Signed-off-by: Ioan Cristian CHELARU <iccjoc@proton.me>
2024-06-02 12:58:56 +03:00
6367c690a4 Fixed answer buttons
Signed-off-by: Ioan Cristian CHELARU <iccjoc@proton.me>
2024-06-02 12:07:02 +03:00
2f6981f4f6 redid some changes
Signed-off-by: Alex Stan <alex.stan.2010@proton.me>
2024-06-02 12:04:45 +03:00
089d1c8f14 Updated the 'about us' page
Signed-off-by: Alex Stan <alex.stan.2010@proton.me>
2024-06-02 12:01:41 +03:00
kali
1e767da34c Updated spacing and some text 2024-06-02 12:01:24 +03:00
kali
6839343269 Updated spacing and some text 2024-06-02 11:58:56 +03:00
d0fe776b68 redid some changes
Signed-off-by: Alex Stan <alex.stan.2010@proton.me>

untangled some nasty merge conflicts
2024-06-02 11:48:44 +03:00
6761a2b0d0 Updated animations (#11)
Co-authored-by: Alex Stan <alex.stan.2010@proton.me>
Co-committed-by: Alex Stan <alex.stan.2010@proton.me>
2024-06-02 11:47:22 +03:00
5500da1f6d merged
Signed-off-by: Alex Stan <alex.stan.2010@proton.me>
2024-06-02 11:42:25 +03:00
kali
10da00708a Commented landing page 2024-06-02 11:33:41 +03:00
92f0d25cd0 Added comments to |sessionconfig|
Signed-off-by: Ioan Cristian CHELARU <iccjoc@proton.me>
2024-06-02 11:32:00 +03:00
kali
bcb098218b Commented about-us page 2024-06-02 11:26:28 +03:00
kali
62b44acbdf Made the background static and updated spacing 2024-06-02 10:42:05 +03:00
5adfd1ffc1 fixed results screen sending you to /learn/sessionconfig
Signed-off-by: Ioan Cristian CHELARU <iccjoc@proton.me>
2024-06-02 10:36:07 +03:00
kali
10b3e4e71c Redid undone changes durring merge errors 2024-06-02 10:28:47 +03:00
6741f0de18 fixed answer button
Signed-off-by: Ioan Cristian CHELARU <iccjoc@proton.me>
2024-06-02 10:27:18 +03:00
kali
e8b8e5b800 Added licence button in about us page 2024-06-02 10:17:10 +03:00
14 changed files with 302 additions and 95 deletions

View file

@ -1,25 +1,29 @@
import { DocumentTextIcon } from '@heroicons/react/24/outline'; import { ClipboardDocumentListIcon, DocumentTextIcon } from '@heroicons/react/24/outline';
import Logo from '../components/logo'; import Logo from '../components/logo';
import TopicCard from '../components/topic_card'; import TopicCard from '../components/topic_card';
import LinkButton from '../components/link-button';
{/*Index of people and their respective image and title*/}
const people = [ const people = [
{ {
name: 'Andrei Banu', name: 'Andrei Banu',
role: 'UI/UX designer', role: 'UI/UX designer',
imageUrl: imageUrl:
'arch.png', 'arch.png',
email: 'mailto:child1.andy@gmail.com'
}, },
{ {
name: 'Ioan Cristian Chelaru', name: 'Ioan Cristian Chelaru',
role: 'UI/UX designer', role: 'UI/UX designer',
imageUrl: imageUrl:
'blahaj.avif', 'blahaj.avif',
email: 'mailto:iccjoc@proton.me'
}, },
{ {
name: 'Alexandru Gabriel Stan', name: 'Alexandru Gabriel Stan',
role: 'Back end developer', role: 'Backend & UI developer',
imageUrl: imageUrl:
'alex.png', 'alex.png',
email: 'mailto:alex.stan.2010@proton.me'
}, },
// More people... // More people...
] ]
@ -27,6 +31,7 @@ const people = [
export default function Example() { export default function Example() {
return ( return (
<div className="sm:py-32"> <div className="sm:py-32">
{/*Background visuals*/}
<div <div
className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80" className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
aria-hidden="true" aria-hidden="true"
@ -38,47 +43,6 @@ const people = [
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)', 'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}} }}
/> />
</div>
<Logo/>
<div style={{paddingBottom: '100px'}}></div>
<div className="mx-auto grid max-w-7xl gap-x-8 gap-y-20 px-6 lg:px-8 xl:grid-cols-3">
<div className="max-w-2xl">
<h2 className="text-3xl font-bold tracking-tight text-gray-200 sm:text-4xl">Meet our developers</h2>
<p className="mt-6 text-lg leading-8 text-gray-200">
We are a group of passionate middle schoolers that got togather to hopefully make a difference in the world
</p>
</div>
<ul role="list" className="grid gap-x-8 gap-y-12 sm:grid-cols-2 sm:gap-y-16 xl:col-span-2">
{people.map((person) => (
<li key={person.name}>
<div className="flex items-center gap-x-6">
<img className="h-16 w-16 rounded-full" src={person.imageUrl} alt="" />
<div>
<h3 className="text-base font-semibold leading-7 tracking-tight text-gray-200">{person.name}</h3>
<p className="text-sm font-semibold leading-6 text-indigo-200">{person.role}</p>
</div>
</div>
</li>
))}
</ul>
</div>
<br></br>
<div
style={{display:"flex", alignItems: 'center', justifyContent: 'center', marginLeft: "40px", marginRight: "40px"}}
>
<a
href="https://git.gra.phite.ro/BlahajTeam/next-app"
className="rounded-md text-sm font-semibold text-gray-200 shadow-sm hover:text-gray-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
style={{maxWidth: '250px', paddingLeft: '50px', paddingRight: '50px', paddingTop: '20px', paddingBottom: '20px', alignSelf: 'center'}}
>
<DocumentTextIcon></DocumentTextIcon>
Source Code
</a>
</div>
<div
className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
aria-hidden="true"
>
<div <div
className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]" className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]"
style={{ style={{
@ -87,6 +51,59 @@ const people = [
}} }}
/> />
</div> </div>
<Logo/>
<div style={{paddingBottom: '100px'}}></div>
<div className="mx-auto grid max-w-7xl gap-x-8 gap-y-20 px-6 lg:px-8 xl:grid-cols-3"> {/*Team presentation text*/}
<div className="max-w-2xl">
<h2 className="text-3xl font-bold tracking-tight text-gray-200 sm:text-4xl">Meet our developers</h2>
<p className="mt-6 text-lg leading-8 text-gray-200">
We are a group of passionate middle schoolers that got together to hopefully make a difference in the world
</p>
</div>
{/*Display people*/}
<ul role="list" className="grid gap-x-8 gap-y-12 sm:grid-cols-2 sm:gap-y-16 xl:col-span-2">
{people.map((person) => (
<li key={person.name}>
<div className="flex items-center gap-x-6">
<img className="h-16 w-16 rounded-full" src={person.imageUrl} alt="" />
<div>
<h3 className="text-base font-semibold leading-7 tracking-tight text-gray-200">{person.name}</h3>
<p className="text-sm font-semibold leading-6 text-indigo-200">{person.role}</p>
<LinkButton text="Send mail" href={person.email}/>
</div>
</div>
</li>
))}
</ul>
</div>
<br></br>
{/*Licence and source code buttons*/}
<div
style={{display:"flex", alignItems: 'center', alignSelf:'center', justifyContent: 'center', marginLeft: "40px", marginRight: "40px"}}
>
<a
href="https://git.gra.phite.ro/BlahajTeam/next-app"
className="rounded-md text-sm font-semibold text-gray-200 shadow-sm hover:text-gray-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
style={{minWidth: '190px', maxWidth: '190px', paddingLeft: '50px', paddingRight: '50px', paddingTop: '20px', paddingBottom: '20px', alignSelf: 'center'}}
>
<DocumentTextIcon></DocumentTextIcon>
Source Code
</a>
<a
href="https://git.gra.phite.ro/BlahajTeam/next-app/src/branch/main/LICENSE"
className="rounded-md text-sm font-semibold text-gray-200 shadow-sm hover:text-gray-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
style={{minWidth: '190px', maxWidth: '190px', paddingLeft: '50px', paddingRight: '50px', paddingTop: '20px', paddingBottom: '20px', alignSelf: 'center'}}
>
<ClipboardDocumentListIcon></ClipboardDocumentListIcon>
Our Licence
</a>
</div>
<div
className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
aria-hidden="true"
>
</div>
</div> </div>
) )
} }

View file

@ -0,0 +1,26 @@
'use client';
import { motion } from "framer-motion"
import { useState } from "react";
const LinkButton = ({text, href, onPress}: {text: string, href: string, onPress?: () => any}) => {
const [buttonHovered, setButtonHovered] = useState( false );
const [buttonPressed, setButtonPressed] = useState( false );
return (
<div className="mt-10 flex items-center justify-center gap-x-6 lg:justify-start">
<motion.a
href={href}
className="rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
style={{ marginBottom: '40px' }}
animate={{opacity: buttonHovered ? 0.8 : 1}}
onMouseEnter={()=>setButtonHovered(true)}
onMouseLeave={()=>setButtonHovered(false)}
onClick={()=>{setButtonPressed(true); onPress && onPress();}}
>
{text}
</motion.a>
</div>
);
}
export default LinkButton;

View file

@ -1,6 +1,8 @@
'use client'; 'use client';
import { Transition } from "@headlessui/react"; import { Transition } from "@headlessui/react";
import { motion } from "framer-motion";
import { useState } from "react"; import { useState } from "react";
import LinkButton from "./link-button";
const Logo = () => { const Logo = () => {
@ -18,20 +20,24 @@ const Logo = () => {
leave="transition-opacity duration-75" leave="transition-opacity duration-75"
leaveFrom={logoHovered ? "opacity-70" : "opacity-100"} leaveFrom={logoHovered ? "opacity-70" : "opacity-100"}
leaveTo={logoHovered ? "opacity-100" : "opacity-70"}> */} leaveTo={logoHovered ? "opacity-100" : "opacity-70"}> */}
<a href="/" style={{ marginBottom: '40px', marginLeft: '40px', transition: 'opacity', opacity: logoHovered ? 0.7 : 1 , animationDuration: '0.3s'}} <motion.a href="/" style={{ marginBottom: '40px', marginLeft: '40px'}} animate={{opacity: logoHovered ? 0.7 : 1}}
onMouseEnter={()=>setLogoHovered(true)} onMouseEnter={()=>setLogoHovered(true)}
onMouseLeave={()=>setLogoHovered(false)}> onMouseLeave={()=>setLogoHovered(false)}>
<img src="/logo-no-background.png" height="auto" width="400px"/> <img src="/logo-no-background.png" height="auto" width="400px"/>
</a> </motion.a>
{/* </Transition> */} {/* </Transition> */}
<div style={{ marginBottom: '40px', marginRight: '40px' }}></div> <div style={{ marginBottom: '40px', marginRight: '50px' }}></div>
<a {/* <motion.a
href="/about-us" href="/about-us"
className="rounded-md bg-white text-sm font-semibold text-gray-900 shadow-sm hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white" className="rounded-md bg-white text-sm font-semibold text-gray-900 shadow-sm hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
style={{ marginBottom: '40px', marginRight: '40px', padding: '10px' }} style={{ marginBottom: '40px', marginRight: '40px', padding: '10px' }}
animate={{opacity: aboutButtonHovered ? 0.8 : 1}}
onMouseEnter={()=>setAboutButtonHovered(true)}
onMouseLeave={()=>setAboutButtonHovered(false)}
> >
About us About us
</a> </motion.a> */}
<LinkButton text="About us" href="/about-us"/>
</div> </div>
) )
} }

View file

@ -1,8 +1,10 @@
import { ReactComponentElement, ReactNode } from "react"; import { ReactComponentElement, ReactNode, useEffect } from "react";
import { AnswerType, Question } from "../lib/question"; import { AnswerType, Question } from "../lib/question";
import { SessionState } from "../lib/session"; import { SessionState } from "../lib/session";
import { CheckCircleIcon, XCircleIcon } from "@heroicons/react/24/outline"; import { CheckCircleIcon, XCircleIcon } from "@heroicons/react/24/outline";
import { Button, Transition } from "@headlessui/react"; import { Button, Transition } from "@headlessui/react";
import wait from "../lib/delay";
import { motion } from "framer-motion";
const QuestionView = ({ question, setState, state }: { question: Question, setState: any, state: SessionState }) => { const QuestionView = ({ question, setState, state }: { question: Question, setState: any, state: SessionState }) => {
@ -16,6 +18,10 @@ const QuestionView = ({ question, setState, state }: { question: Question, setSt
})) }))
} }
useEffect( () => {
wait( 1000 );
}, [] );
const handleAnswerClick = (right: boolean) => { const handleAnswerClick = (right: boolean) => {
setState( (prevState: SessionState) => ({ setState( (prevState: SessionState) => ({
...prevState, ...prevState,
@ -47,14 +53,16 @@ const QuestionView = ({ question, setState, state }: { question: Question, setSt
{question.text} {question.text}
</h1> </h1>
</Transition> </Transition>
<Transition {/* <Transition
show={(question && state.opened[ question.id ]) ? true : false} show={(question && state.opened[ question.id ]) ? true : false}
enter="transition-opacity duration-300" enter="transition-opacity duration-300"
enterFrom="opacity-0" enterFrom="opacity-0"
enterTo="opacity-90" enterTo="opacity-90"
leave="transition-opacity duration-150" leave="transition-opacity duration-150"
leaveFrom="opacity-90" leaveFrom="opacity-90"
leaveTo="opacity-0"> leaveTo="opacity-0"> */}
{/* <motion.div animate={{visibility: ((question && state.opened[ question.id ]) ? "visible" : "collapse") }}> */}
<motion.div animate={(question && state.opened[ question.id ]) ? {visibility: "visible", opacity: 1} : {visibility: "collapse", opacity: 0}}>
<div><p className="mt-6 text-lg leading-8 text-gray-200"> <div><p className="mt-6 text-lg leading-8 text-gray-200">
{question.answer} {question.answer}
</p> </p>
@ -76,22 +84,22 @@ const QuestionView = ({ question, setState, state }: { question: Question, setSt
<button <button
onClick={() => { handleAnswerClick( true )}} onClick={() => { handleAnswerClick( true )}}
className="rounded-md bg-green-600 px-3.5 py-2.5 text-s font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" className="rounded-md bg-green-600 px-3.5 py-2.5 text-s font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
style={{width:'30%', height:'30%'}} style={{minWidth:'40%', minHeight:'40%', maxWidth:'40%', maxHeight:'40%'}}
> >
<CheckCircleIcon></CheckCircleIcon> <CheckCircleIcon></CheckCircleIcon>
I knew that! I knew that!
</button> </button>
<button <button
onClick={() => {handleAnswerClick( false )}} onClick={() => {handleAnswerClick( false )}}
className="rounded-md bg-red-600 px-3.5 py-2.5 text-xs font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" className="rounded-md bg-red-600 px-3.5 py-2.5 text-s font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
style={{width:'30%', height:'30%'}} style={{minWidth:'40%', minHeight:'40%', maxWidth:'40%', maxHeight:'40%'}}
> >
<XCircleIcon></XCircleIcon> <XCircleIcon></XCircleIcon>
I didn't know that! I didn't know!
</button> </button>
</div> </div>
</div> </div>
</Transition> </motion.div>
<Transition <Transition
show={(question && (state.opened[ question.id ])) ? false : true} show={(question && (state.opened[ question.id ])) ? false : true}
enter="transition-opacity duration-300" enter="transition-opacity duration-300"
@ -100,7 +108,7 @@ const QuestionView = ({ question, setState, state }: { question: Question, setSt
leave="transition-opacity duration-150" leave="transition-opacity duration-150"
leaveFrom="opacity-90" leaveFrom="opacity-90"
leaveTo="opacity-0"> leaveTo="opacity-0">
<Button className="text-sm font-semibold leading-6 text-gray-200" onClick={handleOpenClick}> <Button className="leading-6 text-black back rounded-md bg-white text-sm font-semibold text-gray-900" onClick={handleOpenClick} style = {{padding: '5px'}}>
Show answer Show answer
</Button> </Button>
</Transition> </Transition>

View file

@ -1,6 +1,7 @@
import { CheckIcon, XMarkIcon, QuestionMarkCircleIcon, FingerPrintIcon, LockClosedIcon } from '@heroicons/react/24/outline' import { CheckIcon, XMarkIcon, QuestionMarkCircleIcon, FingerPrintIcon, LockClosedIcon } from '@heroicons/react/24/outline'
import Logo from './logo'; import Logo from './logo';
import { SessionState } from '../lib/session'; import { SessionState } from '../lib/session';
import LinkButton from './link-button';
/* /*
const features = [ const features = [
@ -81,16 +82,17 @@ const ResultScreen = ({state}: {state: SessionState}) => {
))} */} ))} */}
<Result name="Correct Answers" key="correct" text1="Congrats for your" number={state.right} text2="correctly answered questions! Great job!" Icon={CheckIcon}/> <Result name="Correct Answers" key="correct" text1="Congrats for your" number={state.right} text2="correctly answered questions! Great job!" Icon={CheckIcon}/>
<Result name="Wrong Answers" key="wrong" text1="You had" number={state.wrong} text2="wrong answers... It's never too late to learn!" Icon={XMarkIcon}/> <Result name="Wrong Answers" key="wrong" text1="You had" number={state.wrong} text2="wrong answers... It's never too late to learn!" Icon={XMarkIcon}/>
<Result name="Total answers" key="total" text1="The" number={state.answered} text2="questions you answered surely helped you learn more." Icon={QuestionMarkCircleIcon}/> <Result name="Total Answers" key="total" text1="The" number={state.answered} text2="questions you answered surely helped you learn more." Icon={QuestionMarkCircleIcon}/>
</dl> </dl>
<br></br> <br></br>
<a {/* <a
href="sessionconfig" href="/sessionconfig"
className="rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-gray-100 shadow-sm hover:bg-indigo-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white" className="rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-gray-100 shadow-sm hover:bg-indigo-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
style={{ marginTop: '100px' }} style={{ marginTop: '100px' }}
> >
Go Back Go Back
</a> </a> */}
<LinkButton text="Learn about another topic" href="/sessionconfig"/>
</div> </div>
</div> </div>
<div <div

View file

@ -1,7 +1,13 @@
import { PlayIcon } from '@heroicons/react/24/outline' 'use client';
import { motion } from 'framer-motion';
import { useState } from 'react';
import LinkButton from './link-button';
const TopicCard = ({ title, children, link }: { title: string, children: any, link: string }) => { const TopicCard = ({ title, children, link }: { title: string, children: any, link: string }) => {
return( const [clicked, setClicked] = useState( false );
<div className="mx-auto mt-16 max-w-2xl rounded-3xl sm:mt-20 lg:mx-0 lg:flex lg:max-w-none relative isolate overflow-hidden bg-gray-900 px-6 pt-16 shadow-2xl sm:rounded-3xl sm:px-16 md:pt-24 lg:flex lg:gap-x-20 lg:px-24 lg:pt-0" style={{marginTop: '20px', paddingTop: '0px', paddingBottom: '24px'}}> const [hovered, setHovered] = useState( false );
return (
<motion.div className="mx-auto mt-16 max-w-2xl rounded-3xl sm:mt-20 lg:mx-0 lg:flex lg:max-w-none relative isolate overflow-hidden bg-gray-900 px-6 pt-16 shadow-2xl sm:rounded-3xl sm:px-16 md:pt-24 lg:flex lg:gap-x-20 lg:px-24 lg:pt-0" style={{marginTop: '20px', paddingTop: '0px', paddingBottom: '24px'}}
animate={{x: hovered? 10 : 0, opacity: clicked ? 0.5 : 1 }} onMouseEnter={()=>setHovered(true)} onMouseLeave={()=>setHovered(false)}>
<svg <svg
viewBox="0 0 1024 1024" viewBox="0 0 1024 1024"
className="absolute left-1/2 top-1/2 -z-10 h-[64rem] w-[64rem] -translate-y-1/2 [mask-image:radial-gradient(closest-side,white,transparent)] sm:left-full sm:-ml-80 lg:left-1/2 lg:ml-0 lg:-translate-x-1/2 lg:translate-y-0" className="absolute left-1/2 top-1/2 -z-10 h-[64rem] w-[64rem] -translate-y-1/2 [mask-image:radial-gradient(closest-side,white,transparent)] sm:left-full sm:-ml-80 lg:left-1/2 lg:ml-0 lg:-translate-x-1/2 lg:translate-y-0"
@ -25,16 +31,17 @@ const TopicCard = ({ title, children, link }: { title: string, children: any, li
className="-mt-2 p-2 lg:mt-0 lg:max-w-md lg:flex-shrink-0 lg:flex lg:flex-col lg:justify-center" className="-mt-2 p-2 lg:mt-0 lg:max-w-md lg:flex-shrink-0 lg:flex lg:flex-col lg:justify-center"
style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}
> >
<a {/* <a
href={link} href={link}
className="mt-10 block w-full rounded-md bg-blue-500 text-center text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" className="rounded-md text-sm font-semibold border text-gray-200 shadow-sm hover:text-gray-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
style={{ paddingLeft: '50px', paddingRight: '50px', paddingTop: '20px', paddingBottom: '20px'}} style={{ paddingLeft: '50px', paddingRight: '50px', paddingTop: '20px', paddingBottom: '20px'}}
> >
Begin Begin
</a> </a> */}
<LinkButton text="Begin" href={link} onPress={()=>setClicked(true)}/>
</div> </div>
</div> </motion.div>
) )
} }

View file

@ -92,8 +92,15 @@ const Page = ({ params }: { params: { category: string }}) => {
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)', 'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}} }}
/> />
<div
className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]"
style={{
clipPath:
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}}
/>
</div> </div>
<div style={{paddingTop: '72px'}}></div>
{(()=>{ {(()=>{
if ( !questions[ 0 ] ) if ( !questions[ 0 ] )
@ -107,13 +114,7 @@ const Page = ({ params }: { params: { category: string }}) => {
className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]" className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
aria-hidden="true" aria-hidden="true"
> >
<div
className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]"
style={{
clipPath:
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}}
/>
</div> </div>
</div> </div>
</div> </div>

87
app/learn/page.tsx Normal file
View file

@ -0,0 +1,87 @@
import { CheckIcon } from '@heroicons/react/20/solid'
import TopicCard from '../components/topic_card'
import Logo from '../components/logo';
import { Transition } from '@headlessui/react';
const includedFeatures = [
'Private forum access',
'Member resources',
'Entry to annual conference',
'Official member t-shirt',
]
export default function Example() {
//List of topics
const cards = [
["Learn cybersecurity", "Learning cybersecurity is like becoming a guardian of the digital realm.\nIt's about mastering the art of protecting information, systems, and networks from cyber threats.\nFrom understanding encryption algorithms to detecting malware, every lesson equips you with tools to fortify against cyber-attacks.", "/learn/cybersec" ],
["Learn geography", "Geography is the study of our world's intricate tapestry — from the towering peaks of the Himalayas to the vast expanse of the Sahara Desert. It's about understanding the relationships between people, places, and the environment.", "/learn/geography"],
["Learn CPP", "As a powerful, versatile language, CPP teaches you the fundamentals of object-oriented programming while offering fine-grained control over system resources. You'll explore concepts like classes, inheritance, and polymorphism, alongside memory management and pointers.", "/learn/cpp"]
];
return (
<div className="py-24 sm:py-32" style = {{ alignItems: 'center', justifyContent: 'center' }}>
{/*Background*/}
<div
className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
aria-hidden="true"
>
<div
className="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]"
style={{
clipPath:
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}}
/>
<div
className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]"
style={{
clipPath:
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}}
/>
</div>
{/*The logo*/}
<Logo/>
<div style={{paddingTop: '128px'}}></div>
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<Transition
appear={true}
show={true}
enter="transition-opacity duration-300"
enterFrom="opacity-0"
enterTo="opacity-80">
<div>
{ cards.map((elem) => {
return (
<TopicCard title={elem[0]} link={elem[2]}>{elem[1]}</TopicCard>
)})}
</div>
</Transition>
{/*
<TopicCard title = "Learn cybersecurity">
Learning cybersecurity is like becoming a guardian of the digital realm.
It's about mastering the art of protecting information, systems, and networks from cyber threats.
From understanding encryption algorithms to detecting malware, every lesson equips you with tools to fortify against cyber-attacks.
</TopicCard>
<TopicCard title = "Learn geography">
Learning cybersecurity is like becoming a guardian of the digital realm.
It's about mastering the art of protecting information, systems, and networks from cyber threats.
From understanding encryption algorithms to detecting malware, every lesson equips you with tools to fortify against cyber-attacks.
</TopicCard>
<TopicCard title = "Learn C++">
Learning cybersecurity is like becoming a guardian of the digital realm.
It's about mastering the art of protecting information, systems, and networks from cyber threats.
From understanding encryption algorithms to detecting malware, every lesson equips you with tools to fortify against cyber-attacks.
</TopicCard>
*/}
</div>
{/*Background*/}
<div
className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
aria-hidden="true"
>
</div>
</div>
)
}

5
app/lib/delay.ts Normal file
View file

@ -0,0 +1,5 @@
const wait = (time: number): Promise<void> => {
return new Promise( res => setTimeout( res, time ) );
}
export default wait;

View file

@ -1,14 +1,18 @@
'use client';
import { Fragment } from 'react' import { Fragment, useState } from 'react'
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react' import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
import { ChevronDownIcon } from '@heroicons/react/20/solid' import { ChevronDownIcon } from '@heroicons/react/20/solid'
import Logo from './components/logo'; import Logo from './components/logo';
import { motion } from 'framer-motion';
import LinkButton from './components/link-button';
function classNames(...classes) { function classNames(...classes) {
return classes.filter(Boolean).join(' ') return classes.filter(Boolean).join(' ')
} }
export default function Example() { export default function Example() {
const [buttonPressed, setButtonPressed] = useState( false );
return ( return (
<div> <div>
{/*Background visual elements*/}
<div <div
className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80" className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
aria-hidden="true" aria-hidden="true"
@ -20,15 +24,25 @@ export default function Example() {
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)', 'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}} }}
/> />
<div
className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]"
style={{
clipPath:
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}}
/>
</div> </div>
<div style={{paddingTop: '128px'}}></div> <div style={{paddingTop: '128px'}}></div>
<Logo/> <Logo/>
<Transition <Transition
appear={true} appear={true}
show={true} show={!buttonPressed}
enter="transition-opacity duration-500" enter="transition-opacity duration-500"
enterFrom="opacity-0" enterFrom="opacity-0"
enterTo="opacity-80"> enterTo="opacity-80"
leave="transition-opacity duration-150"
leaveFrom="opacity-80"
leaveTo="opacity-0">
<div className="mx-auto max-w-7xl py-24 sm:px-6 sm:py-32 lg:px-8"> <div className="mx-auto max-w-7xl py-24 sm:px-6 sm:py-32 lg:px-8">
<div className="relative isolate overflow-hidden bg-gray-900 px-6 pt-16 shadow-2xl sm:rounded-3xl sm:px-16 md:pt-24 lg:flex lg:gap-x-20 lg:px-24 lg:pt-0"> <div className="relative isolate overflow-hidden bg-gray-900 px-6 pt-16 shadow-2xl sm:rounded-3xl sm:px-16 md:pt-24 lg:flex lg:gap-x-20 lg:px-24 lg:pt-0">
<svg <svg
@ -54,14 +68,18 @@ export default function Example() {
Get questions from a multitude of different subjects that include cybersecurity, geography and C++ Get questions from a multitude of different subjects that include cybersecurity, geography and C++
</p> </p>
<div className="mt-10 flex items-center justify-center gap-x-6 lg:justify-start"> <div className="mt-10 flex items-center justify-center gap-x-6 lg:justify-start">
<a {/* <motion.a
href="sessionconfig" href="sessionconfig"
className="rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white" className="rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
style={{ marginBottom: '40px' }} style={{ marginBottom: '40px' }}
animate={{opacity: buttonHovered ? 0.8 : 1}}
onMouseEnter={()=>setButtonHovered(true)}
onMouseLeave={()=>setButtonHovered(false)}
onClick={()=>setButtonPressed(true)}
> >
Get started Get started
</a> </motion.a> */}
<LinkButton text="Get started" href="/sessionconfig" onPress={()=>setButtonPressed(true)}/>
</div> </div>
</div> </div>
</div> </div>

View file

@ -12,14 +12,16 @@ const includedFeatures = [
export default function Example() { export default function Example() {
//List of topics
const cards = [ const cards = [
["Learn cybersecurity", "Learning cybersecurity is like becoming a guardian of the digital realm.\nIt's about mastering the art of protecting information, systems, and networks from cyber threats.\nFrom understanding encryption algorithms to detecting malware, every lesson equips you with tools to fortify against cyber-attacks.", "/learn/cybersec" ], ["Learn cybersecurity", "Learning cybersecurity is like becoming a guardian of the digital realm.\nIt's about mastering the art of protecting information, systems, and networks from cyber threats.\nFrom understanding encryption algorithms to detecting malware, every lesson equips you with tools to fortify against cyber-attacks.", "/learn/cybersec" ],
["Learn geography", "Geography is the study of our world's intricate tapestry — from the towering peaks of the Himalayas to the vast expanse of the Sahara Desert. It's about understanding the relationships between people, places, and the environment.", "/learn/geography"], ["Learn geography", "Geography is the study of our world's intricate tapestry — from the towering peaks of the Himalayas to the vast expanse of the Sahara Desert. It's about understanding the relationships between people, places and the environment.", "/learn/geography"],
["Learn CPP", "As a powerful, versatile language, CPP teaches you the fundamentals of object-oriented programming while offering fine-grained control over system resources. You'll explore concepts like classes, inheritance, and polymorphism, alongside memory management and pointers.", "/learn/cpp"] ["Learn CPP", "As a powerful, versatile language, C++ teaches you the fundamentals of object-oriented programming while offering fine-grained control over system resources. You'll explore concepts like classes, inheritance, and polymorphism, alongside memory management and pointers.", "/learn/cpp"]
]; ];
return ( return (
<div className="py-24 sm:py-32" style = {{ alignItems: 'center', justifyContent: 'center' }}> <div className="py-24 sm:py-32" style = {{ alignItems: 'center', justifyContent: 'center' }}>
{/*Background*/}
<div <div
className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80" className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
aria-hidden="true" aria-hidden="true"
@ -31,7 +33,15 @@ export default function Example() {
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)', 'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}} }}
/> />
<div
className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]"
style={{
clipPath:
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}}
/>
</div> </div>
{/*The logo*/}
<Logo/> <Logo/>
<div style={{paddingTop: '128px'}}></div> <div style={{paddingTop: '128px'}}></div>
<div className="mx-auto max-w-7xl px-6 lg:px-8"> <div className="mx-auto max-w-7xl px-6 lg:px-8">
@ -66,17 +76,11 @@ export default function Example() {
</TopicCard> </TopicCard>
*/} */}
</div> </div>
{/*Background*/}
<div <div
className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]" className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
aria-hidden="true" aria-hidden="true"
> >
<div
className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]"
style={{
clipPath:
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}}
/>
</div> </div>
</div> </div>
) )

25
package-lock.json generated
View file

@ -10,6 +10,7 @@
"dependencies": { "dependencies": {
"@headlessui/react": "^2.0.4", "@headlessui/react": "^2.0.4",
"@heroicons/react": "^2.1.3", "@heroicons/react": "^2.1.3",
"framer-motion": "^11.2.10",
"next": "14.2.3", "next": "14.2.3",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",
@ -2245,6 +2246,30 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/framer-motion": {
"version": "11.2.10",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.2.10.tgz",
"integrity": "sha512-/gr3PLZUVFCc86a9MqCUboVrALscrdluzTb3yew+2/qKBU8CX6nzs918/SRBRCqaPbx0TZP10CB6yFgK2C5cYQ==",
"dependencies": {
"tslib": "^2.4.0"
},
"peerDependencies": {
"@emotion/is-prop-valid": "*",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"peerDependenciesMeta": {
"@emotion/is-prop-valid": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/fs.realpath": { "node_modules/fs.realpath": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",

View file

@ -11,6 +11,7 @@
"dependencies": { "dependencies": {
"@headlessui/react": "^2.0.4", "@headlessui/react": "^2.0.4",
"@heroicons/react": "^2.1.3", "@heroicons/react": "^2.1.3",
"framer-motion": "^11.2.10",
"next": "14.2.3", "next": "14.2.3",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB