Compare commits
No commits in common. "22f59ca6196a66ffaebb1eea8dd147cb9fbdb5ff" and "4895d3b8898dca24ccf70972a3c70c19ba7f9a8c" have entirely different histories.
22f59ca619
...
4895d3b889
6 changed files with 127 additions and 204 deletions
|
@ -1,47 +0,0 @@
|
|||
'use client';
|
||||
import { useState } from "react";
|
||||
|
||||
const Form = <T,>({ initialData, onSubmit }) => {
|
||||
const [formData, setFormData] = useState( initialData );
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
//q = formData;
|
||||
|
||||
//addQuestion( q );
|
||||
|
||||
//console.log( `Adding question ${JSON.stringify(q)}` );
|
||||
|
||||
onSubmit( formData );
|
||||
}
|
||||
|
||||
const handleChange = (event) => {
|
||||
const { name, value } = event.target;
|
||||
setFormData( (prevData) => ({
|
||||
...prevData,
|
||||
[name]: value
|
||||
}));
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="flex">
|
||||
<div>
|
||||
{Object.entries( initialData ).map( (key, val) => {
|
||||
return(
|
||||
<input
|
||||
type = { typeof( val ) == typeof( 0 ) ? "number" : "text" /* pretty hacky, we should change this */ }
|
||||
id = {key[0]}
|
||||
name = {key[0]}
|
||||
value = {formData[key[0]]}
|
||||
onChange = {handleChange}
|
||||
required
|
||||
/>)})}
|
||||
</div>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default Form;
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
|
||||
const TopicCard = ({ title, children, link }) => {
|
||||
return(
|
||||
<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">
|
||||
<svg
|
||||
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"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<circle cx={512} cy={512} r={512} fill="url(#759c1415-0410-454c-8f7c-9a820de03641)" fillOpacity="0.7" />
|
||||
<defs>
|
||||
<radialGradient id="759c1415-0410-454c-8f7c-9a820de03641">
|
||||
<stop stopColor="#7775D6" />
|
||||
<stop offset={1} stopColor="#E935C1" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<div className="p-8 sm:p-10 lg:flex-auto ">
|
||||
<h3 className="text-2xl font-bold tracking-tight text-gray-200">{title}</h3>
|
||||
<p className="mt-6 text-base leading-7 text-gray-200">
|
||||
{children}
|
||||
</p>
|
||||
</div>
|
||||
<div className="-mt-2 p-2 lg:mt-0 lg:w-full lg:max-w-md lg:flex-shrink-0">
|
||||
<div className="rounded-2xl bg-gray-50 py-10 text-center ring-1 ring-inset ring-gray-900/5 lg:flex lg:flex-col lg:justify-center lg:py-16">
|
||||
<div className="mx-auto max-w-xs px-8">
|
||||
<p className="mt-6 flex items-baseline justify-center gap-x-2">
|
||||
<span className="text-5xl font-bold tracking-tight text-gray-900">Start</span>
|
||||
<span className="text-sm font-semibold leading-6 tracking-wide text-gray-900">now!</span>
|
||||
</p>
|
||||
<a
|
||||
href={link}
|
||||
className="mt-10 block w-full rounded-md bg-indigo-600 px-3 py-2 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"
|
||||
>
|
||||
Begin
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TopicCard;
|
|
@ -1,33 +0,0 @@
|
|||
// the base URL of the api; all requests start with it
|
||||
const base_url: string = "http://localhost:4000/";
|
||||
|
||||
/*
|
||||
export const makeGetRequest = async<T> (path: string): Promise<T> => {
|
||||
return await (await fetch( base_url + path )).json();
|
||||
}
|
||||
*/
|
||||
|
||||
// generic function that makes a web request
|
||||
const makeRequest = async (path: string, method: string, body?: string): Promise<Response> => {
|
||||
console.log( `making ${method} request: ${base_url + path}, ${body}` );
|
||||
return fetch( base_url + path, { method: method, body: body ? body : null } );
|
||||
}
|
||||
|
||||
// the following functions are wrappers around `makeRequest`,
|
||||
// for every type of request that's needed.
|
||||
|
||||
export const makeGetRequest = async<T> (path: string): Promise<T> => {
|
||||
return (await makeRequest( path, "GET" )).json();
|
||||
}
|
||||
|
||||
export const makePostRequest = async<T> (path: string, body: T): Promise<T> => {
|
||||
return (await makeRequest( path, "POST", JSON.stringify( body ) )).json();
|
||||
}
|
||||
|
||||
export const makePutRequest = async<T> (path: string, body: T): Promise<T> => {
|
||||
return (await makeRequest( path, "PUT", JSON.stringify( body ) )).json();
|
||||
}
|
||||
|
||||
export const makeDeleteRequest = async<T> (path: string): Promise<T> => {
|
||||
return (await makeRequest( path, "DELETE" )).json();
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
import { makeDeleteRequest, makeGetRequest, makePostRequest } from "./api";
|
||||
|
||||
export const enum QuizQuestion {
|
||||
UL,
|
||||
UR,
|
||||
DL,
|
||||
DR
|
||||
};
|
||||
|
||||
export type Question = {
|
||||
id: number;
|
||||
category: string | null;
|
||||
type: string | null; // TODO: make a TS type for every question type
|
||||
text: string;
|
||||
answer: string | boolean | QuizQuestion;
|
||||
}
|
||||
|
||||
export const getQuestion = async (id: number): Promise<Question> => {
|
||||
return makeGetRequest( `questions/${id}/` );
|
||||
}
|
||||
|
||||
export const addQuestion = async (question: Question): Promise<Question> => {
|
||||
console.log( `adding question ${JSON.stringify( question)}` );
|
||||
return makePostRequest( `questions`, question );
|
||||
}
|
||||
|
||||
export const editQuestion = async (question: Question): Promise<Question> => {
|
||||
return makePostRequest( `questions/${question.id}`, question );
|
||||
}
|
||||
|
||||
export const deleteQuestion = async (id: number): Promise<Question> => {
|
||||
return makeDeleteRequest( `questions/${id}` );
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
import { makeGetRequest, makePostRequest } from "./api";
|
||||
|
||||
export type Session = {
|
||||
id: number;
|
||||
right: number;
|
||||
wrong: number;
|
||||
total: number;
|
||||
// user: string;
|
||||
}
|
||||
|
||||
export const getSession = async (id: number): Promise<Session> => {
|
||||
return makeGetRequest( `sessions/${id}/` );
|
||||
}
|
||||
|
||||
export const postSession = async (session: Session): Promise<Session> => {
|
||||
return makePostRequest( `sessions`, session );
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { CheckIcon } from '@heroicons/react/20/solid'
|
||||
import TopicCard from '../components/topic_card'
|
||||
|
||||
const includedFeatures = [
|
||||
'Private forum access',
|
||||
|
@ -9,38 +8,136 @@ const includedFeatures = [
|
|||
]
|
||||
|
||||
export default function Example() {
|
||||
|
||||
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", "It's cool ig", "/learn/geography"],
|
||||
["Learn C++", "Don't.", "/learn/cpp"],
|
||||
["Learn C", "Do.", "/learn/c"]
|
||||
];
|
||||
return (
|
||||
|
||||
<div className="bg-black py-24 sm:py-32">
|
||||
<div style={{ display:"flex", alignItems: 'center', justifyContent: 'center', paddingTop:'40px'}}><img className="flex" src="/logo-no-background.png" height="auto" width="40%" style={{ alignSelf: 'center'}}></img></div>
|
||||
<div className="mx-auto max-w-7xl px-6 lg:px-8">
|
||||
{ cards.map((elem) => {
|
||||
return (<TopicCard title={elem[0]} link={elem[2]}>{elem[1]}</TopicCard>)
|
||||
})}
|
||||
{/*
|
||||
<TopicCard title = "Learn cybersecurity">
|
||||
Learning cybersecurity is like becoming a guardian of the digital realm.
|
||||
<div className="mx-auto mt-16 max-w-2xl rounded-3xl ring-1 ring-gray-200 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">
|
||||
<svg
|
||||
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"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<circle cx={512} cy={512} r={512} fill="url(#759c1415-0410-454c-8f7c-9a820de03641)" fillOpacity="0.7" />
|
||||
<defs>
|
||||
<radialGradient id="759c1415-0410-454c-8f7c-9a820de03641">
|
||||
<stop stopColor="#7775D6" />
|
||||
<stop offset={1} stopColor="#E935C1" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<div className="p-8 sm:p-10 lg:flex-auto ">
|
||||
<h3 className="text-2xl font-bold tracking-tight text-gray-200">Learn cybersecurity</h3>
|
||||
<p className="mt-6 text-base leading-7 text-gray-200">
|
||||
Learning cybersecurity is like becoming the 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.
|
||||
</p>
|
||||
</div>
|
||||
<div className="-mt-2 p-2 lg:mt-0 lg:w-full lg:max-w-md lg:flex-shrink-0">
|
||||
<div className="rounded-2xl bg-gray-50 py-10 text-center ring-1 ring-inset ring-gray-900/5 lg:flex lg:flex-col lg:justify-center lg:py-16">
|
||||
<div className="mx-auto max-w-xs px-8">
|
||||
<p className="mt-6 flex items-baseline justify-center gap-x-2">
|
||||
<span className="text-5xl font-bold tracking-tight text-gray-900">Start</span>
|
||||
<span className="text-sm font-semibold leading-6 tracking-wide text-gray-900">now!</span>
|
||||
</p>
|
||||
<a
|
||||
href="#"
|
||||
className="mt-10 block w-full rounded-md bg-indigo-600 px-3 py-2 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"
|
||||
>
|
||||
Begin
|
||||
</a>
|
||||
<p className="mt-6 text-xs leading-5 text-gray-600">
|
||||
Take a short quiz to begin learning faster than ever
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx-auto mt-16 max-w-2xl rounded-3xl ring-1 ring-gray-200 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">
|
||||
<svg
|
||||
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"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<circle cx={512} cy={512} r={512} fill="url(#759c1415-0410-454c-8f7c-9a820de03641)" fillOpacity="0.7" />
|
||||
<defs>
|
||||
<radialGradient id="759c1415-0410-454c-8f7c-9a820de03641">
|
||||
<stop stopColor="#7775D6" />
|
||||
<stop offset={1} stopColor="#E935C1" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<div className="p-8 sm:p-10 lg:flex-auto ">
|
||||
<h3 className="text-2xl font-bold tracking-tight text-gray-200">Learn cybersecurity</h3>
|
||||
<p className="mt-6 text-base leading-7 text-gray-200">
|
||||
Learning cybersecurity is like becoming the 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.
|
||||
</p>
|
||||
</div>
|
||||
<div className="-mt-2 p-2 lg:mt-0 lg:w-full lg:max-w-md lg:flex-shrink-0">
|
||||
<div className="rounded-2xl bg-gray-50 py-10 text-center ring-1 ring-inset ring-gray-900/5 lg:flex lg:flex-col lg:justify-center lg:py-16">
|
||||
<div className="mx-auto max-w-xs px-8">
|
||||
<p className="mt-6 flex items-baseline justify-center gap-x-2">
|
||||
<span className="text-5xl font-bold tracking-tight text-gray-900">Start</span>
|
||||
<span className="text-sm font-semibold leading-6 tracking-wide text-gray-900">now!</span>
|
||||
</p>
|
||||
<a
|
||||
href="#"
|
||||
className="mt-10 block w-full rounded-md bg-indigo-600 px-3 py-2 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"
|
||||
>
|
||||
Begin
|
||||
</a>
|
||||
<p className="mt-6 text-xs leading-5 text-gray-600">
|
||||
Take a short quiz to begin learning faster than ever
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx-auto mt-16 max-w-2xl rounded-3xl ring-1 ring-gray-200 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">
|
||||
<svg
|
||||
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"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<circle cx={512} cy={512} r={512} fill="url(#759c1415-0410-454c-8f7c-9a820de03641)" fillOpacity="0.7" />
|
||||
<defs>
|
||||
<radialGradient id="759c1415-0410-454c-8f7c-9a820de03641">
|
||||
<stop stopColor="#7775D6" />
|
||||
<stop offset={1} stopColor="#E935C1" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<div className="p-8 sm:p-10 lg:flex-auto ">
|
||||
<h3 className="text-2xl font-bold tracking-tight text-gray-200">Learn cybersecurity</h3>
|
||||
<p className="mt-6 text-base leading-7 text-gray-200">
|
||||
Learning cybersecurity is like becoming the 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>
|
||||
*/}
|
||||
</p>
|
||||
</div>
|
||||
<div className="-mt-2 p-2 lg:mt-0 lg:w-full lg:max-w-md lg:flex-shrink-0">
|
||||
<div className="rounded-2xl bg-gray-50 py-10 text-center ring-1 ring-inset ring-gray-900/5 lg:flex lg:flex-col lg:justify-center lg:py-16">
|
||||
<div className="mx-auto max-w-xs px-8">
|
||||
<p className="mt-6 flex items-baseline justify-center gap-x-2">
|
||||
<span className="text-5xl font-bold tracking-tight text-gray-900">Start</span>
|
||||
<span className="text-sm font-semibold leading-6 tracking-wide text-gray-900">now!</span>
|
||||
</p>
|
||||
<a
|
||||
href="#"
|
||||
className="mt-10 block w-full rounded-md bg-indigo-600 px-3 py-2 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"
|
||||
>
|
||||
Begin
|
||||
</a>
|
||||
<p className="mt-6 text-xs leading-5 text-gray-600">
|
||||
Take a short quiz to begin learning faster than ever
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue