Skip to content

Commit

Permalink
Merge pull request #42 from zacharyLYH/zac-refine-implementation
Browse files Browse the repository at this point in the history
Zac refine implementation
  • Loading branch information
ES-Legacy authored Dec 9, 2023
2 parents a31e9a3 + db2789a commit 058b884
Show file tree
Hide file tree
Showing 38 changed files with 502 additions and 569 deletions.
5 changes: 4 additions & 1 deletion app/api/code/submit/submit-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ const DOMPurify = createDOMPurify(window);

// Sanitizer function
export const validateHTML = (html: string): boolean => {
html = html.replace(/\n/g, " ").replace(/\s+/g, " ").trim();
if (!isHtml(html)) {
return false;
}

const cleanHTML = DOMPurify.sanitize(html, {
ALLOWED_ATTR: ["href", "src", "alt", "title", "style"],
ALLOWED_ATTR: ["style", "class"],
FORBID_TAGS: [
"script",
"iframe",
Expand All @@ -21,6 +22,8 @@ export const validateHTML = (html: string): boolean => {
"link",
"style",
"form",
"img",
"a",
],
FORBID_ATTR: [
"onerror",
Expand Down
13 changes: 7 additions & 6 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import AboutTailspin from "@/components/landing/about-tailspin";
import FAQ from "@/components/landing/faq";
import Timeline from "@/components/landing/timeline";
import ThanksPage from "@/components/landing/thanks";
import StepperCard from "@/components/ui/useCode/StepperCard";
import RatingBody from "@/components/core/rating-area/rating-component";
import GrowOnScroll from "@/components/ui/grow-on-scroll";
import Footer from "@/components/landing/footer";
import ComponentCarousel from "@/components/ui/component-carousel";
import { Separator } from "@/components/ui/separator";
import ChallengeMain from "@/components/landing/challenge/challenge-main";

export default function Home() {
return (
Expand Down Expand Up @@ -41,12 +41,13 @@ export default function Home() {
</h2>
<p className='text-sm font-semibold text-gray-400'>
We hate to be non-inclusive towards phones and
tablets, however we want to provide you with the
best experience possible!
tablets, however coding on small screens is
currently unsupported! Try us on your
laptop/desktop!
</p>
</div>
</div>
<StepperCard />
<ChallengeMain />
</section>
<GrowOnScroll className='flex flex-col md:flex-row'>
<SiteCounter />
Expand All @@ -56,11 +57,11 @@ export default function Home() {
<section>
<ComponentCarousel
nodes={[<FAQ key='faq' />, <ThanksPage key='thanksPage' />]}
title='Some useless information'
title='Incase you were wondering...'
/>
</section>
<Separator />
<section>
<section id='rating'>
<RatingBody />
</section>
<section>
Expand Down
2 changes: 1 addition & 1 deletion components/core/code-area-actions/submit-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ const SubmitButton = () => {
};

const handleContinueButtonClick = () => {
setContinueClicked(true);
handleReset();
setContinueClicked(true);
router.push("/");
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { usePutRating } from "@/client-side-queries/rq-queries/rating-submit";
import { Button } from "@/components/ui/button";
import { useRatingStore } from "@/data-store/rating-store";
import { saveToLocalStorage } from "@/lib/localStorage";
import { Check, Loader2 } from "lucide-react";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
Expand All @@ -28,6 +29,7 @@ const RatingSubmitButton = () => {
if (mutation.isSuccess) {
toast.success("We really appreciated your help!");
setSubmittingRating(false);
saveToLocalStorage("rating", "true");
}
}, [mutation.isSuccess]);

Expand Down
57 changes: 57 additions & 0 deletions components/core/rating-area/rating-component-server.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import OverallRating from "./components/overall-rating";
import Grid from "./util/arrange-rating-sections";
import RatingSubmitButton from "./components/submit-rating-component";
import UxRating from "./components/ux-rating";
import FunRating from "./components/fun-rating";
import { FeedbackModal } from "@/components/landing/feedback/feedback-modal";

/*
Ratings are stored as per the following schema:
<Name of rating> : <Total Score-Number of rates>
For example:
- Overall_Rating : 500-100
- This states that we currently have a total score of 500 over 100 ratings. Which means, on average, we get 5 stars from every rating.
- Ux_Rating : 100-30
- Implies we have about 3.3333333... stars per rate
- Fun_Rating : 0-2345
- We got 0 stars on average
*/
const RatingBodyServer = () => {
return (
<div className='m-2 flex min-h-[60vh] items-center justify-center lg:m-6'>
<Card className='border-white lg:w-1/2'>
<CardHeader>
<CardTitle>Rate Tailspin</CardTitle>
<CardDescription>
30 seconds of your time could translates to a lot of
feedback for the team!
</CardDescription>
</CardHeader>
<CardContent>
<Grid>
<OverallRating />
<UxRating />
<FunRating />
</Grid>
</CardContent>
<CardFooter className='flex flex-col justify-between lg:flex-row'>
<div className='mb-4 w-[300] rounded-xl border border-white p-2 font-semibold text-muted-foreground md:mb-0'>
<FeedbackModal buttonName='(Optionally) Give us more feedback!' />
</div>
<RatingSubmitButton />
</CardFooter>
</Card>
</div>
);
};

export default RatingBodyServer;
65 changes: 14 additions & 51 deletions components/core/rating-area/rating-component.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,20 @@
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import OverallRating from "./components/overall-rating";
import Grid from "./util/arrange-rating-sections";
import RatingSubmitButton from "./components/submit-rating-component";
import UxRating from "./components/ux-rating";
import FunRating from "./components/fun-rating";
import { FeedbackModal } from "@/components/landing/feedback/feedback-modal";
"use client";

/*
Ratings are stored as per the following schema:
<Name of rating> : <Total Score-Number of rates>
import { loadFromLocalStorage } from "@/lib/localStorage";
import RatingBodyServer from "./rating-component-server";

For example:
- Overall_Rating : 500-100
- This states that we currently have a total score of 500 over 100 ratings. Which means, on average, we get 5 stars from every rating.
- Ux_Rating : 100-30
- Implies we have about 3.3333333... stars per rate
- Fun_Rating : 0-2345
- We got 0 stars on average
*/
const RatingBody = () => {
return (
<div className='m-2 flex min-h-[60vh] items-center justify-center lg:m-6'>
<Card className='border-white lg:w-1/2'>
<CardHeader>
<CardTitle>Rate Tailspin</CardTitle>
<CardDescription>
30 seconds of your time could translates to a lot of
feedback for the team!
</CardDescription>
</CardHeader>
<CardContent>
<Grid>
<OverallRating />
<UxRating />
<FunRating />
</Grid>
</CardContent>
<CardFooter className='flex flex-col justify-between lg:flex-row'>
<div className='mb-4 w-[300] rounded-xl border border-white p-2 font-semibold text-muted-foreground md:mb-0'>
<FeedbackModal buttonName='(Optionally) Give us more feedback!' />
</div>
<RatingSubmitButton />
</CardFooter>
</Card>
</div>
);
const rated = loadFromLocalStorage("rating");

if (!rated) {
return <RatingBodyServer />;
} else {
return (
<p className='my-4 text-center text-sm font-bold text-muted-foreground'>
You&apos;ve already rated Tailspin. Thanks!
</p>
);
}
};

export default RatingBody;
4 changes: 3 additions & 1 deletion components/landing/about-tailspin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Link from "next/link";
import { Button } from "@/components/ui/button";
import { BarChartBig } from "lucide-react";
import FlipOnScroll from "../ui/flip-on-scroll";
import { TailspinLogo } from "../ui/spinning-logo";

type AboutTailSpinBoxesProps = {
title: string;
Expand Down Expand Up @@ -37,7 +38,8 @@ const AboutTailspin = () => {
className='relative flex h-full flex-col items-center justify-center rounded-lg bg-black p-6'
id='about-section'
>
<p className='mb-5 bg-gradient-to-r from-orange-400 to-pink-500 bg-clip-text text-center text-4xl font-bold text-transparent'>
<TailspinLogo />
<p className='mb-5 flex bg-gradient-to-r from-orange-400 to-pink-500 bg-clip-text text-center text-4xl font-bold text-transparent'>
Tailspin
</p>
<div className='grid rounded-lg md:grid-cols-2'>
Expand Down
75 changes: 75 additions & 0 deletions components/landing/challenge/challenge-intro.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Badge } from "@/components/ui/badge";
import Link from "next/link";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
CardFooter,
} from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";

interface ChallengeIntroProps {
button: () => React.ReactNode;
}

const ChallengeIntro: React.FC<ChallengeIntroProps> = ({ button }) => {
return (
<Card className='mx-auto my-8 h-[420px] w-2/3 overflow-hidden rounded-2xl bg-gray-800'>
<CardHeader className='p-4'>
<CardTitle className='mb-4 text-3xl font-semibold text-white'>
🥳 We&apos;re glad you&apos;re here!
</CardTitle>
<CardDescription>
<Badge className='mx-1 rounded-full bg-blue-400 px-2 py-1 text-white'>
Alpha
</Badge>
<Badge className='mx-1 rounded-full bg-blue-400 px-2 py-1 text-white'>
MVP
</Badge>
</CardDescription>
</CardHeader>
<Separator className='bg-gray-700' />
<CardContent className='p-4'>
<p className='text-gray-300'>
It&apos;s simple. We&apos;ll provide you a coding
environment and a target image 🖼️. Your job is to recreate
that image using{" "}
<span className='font-semibold text-green-500'>HTML</span>{" "}
and{" "}
<span className='font-semibold text-green-500'>
TailwindCSS
</span>
. After you submit, we&apos;ll send your scores via Email
📧. <br />
<br /> Currently, we only provide a playground which
represents the core services of Tailspin. When you submit
code from our platform, we score your code and email the
result of similarity to you.{" "}
<span className='text-red-500'>
In this MVP, we don&apos;t have a way for you to track
all your previous submissions or rank yourself against
other developers trying out Tailspin.
</span>
</p>
</CardContent>
<CardFooter className='p-4'>
<p className='text-sm text-muted-foreground'>
At this stage, we&apos;re presenting a bare bones look at
what&apos;s to come for Tailspin and looking for{" "}
<Link href='#rating' className='text-blue-500 underline'>
feedback
</Link>
!
</p>
</CardFooter>
<Separator className='bg-gray-700' />
<div className='flex items-center justify-center p-4'>
{button()}
</div>
</Card>
);
};

export default ChallengeIntro;
28 changes: 28 additions & 0 deletions components/landing/challenge/challenge-main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"use client";

import { useState } from "react";
import ChallengeIntro from "./challenge-intro";
import StepperCard from "./stepper-pages/StepperCard";
import { Button } from "@/components/ui/button";
import { Code } from "lucide-react";

const ChallengeMain = () => {
const [goToStepper, setGoToStepper] = useState(false);

const readyToCodeButton = () => {
return (
<Button onClick={() => setGoToStepper(true)}>
<code>Ready to code</code>
<Code className='ml-2' />
</Button>
);
};
return (
<>
{!goToStepper && <ChallengeIntro button={readyToCodeButton} />}
{goToStepper && <StepperCard />}
</>
);
};

export default ChallengeMain;
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import { useStepperStore } from "@/data-store/stepper-store";

import { StepOne } from "./StepOne";
import { StepTwo } from "./StepTwo";
import { useEffect } from "react";
import { StepOne } from "../stepper-pages/StepOne";
import { StepTwo } from "../stepper-pages/StepTwo";

export function StepperForm() {
const { step, setChallenge, setCheck, setEmail, setProgress, setStep } =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {
useStepperStore,
progressIncrements,
} from "@/data-store/stepper-store";
import { EmailFormField } from "./Email-FormField";
import { TOSFormField } from "./TOS-FormField";
import { Loader2 } from "lucide-react";
import { TOSFormField } from "../forms/TOS-FormField";
import { EmailFormField } from "../forms/Email-FormField";

export function StepOne() {
const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import {
import useSessionStore from "@/data-store/session-store";
import LandingPageCode from "@/components/landing/test-challenges/placeholder-code";
import { useRouter } from "next/navigation";
import { ChallengeFormField } from "./Challenge-FormField";
import { Loader2 } from "lucide-react";
import { challengeEnum } from "@/data-store/challenge-store";
import { saveToLocalStorage } from "@/lib/localStorage";
import { ChallengeFormField } from "../forms/Challenge-FormField";

const formStepTwoSchema = z.object({
challenge: z.nativeEnum(challengeEnum, {
Expand Down
Loading

0 comments on commit 058b884

Please sign in to comment.