Skip to content

Commit 3c251f7

Browse files
feat: polish all animations & components
1 parent df22b93 commit 3c251f7

File tree

12 files changed

+378
-92
lines changed

12 files changed

+378
-92
lines changed

app/exam/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ const Exam: NextPage<{ searchParams: { url: string; name: string } }> = ({
221221
<div className="flex flex-col sm:flex-row justify-center">
222222
<Button
223223
type="button"
224-
intent="secondary"
224+
intent="primary"
225225
size="medium"
226226
onClick={() => startTimer()}
227227
>

app/modes/page.tsx

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,58 @@
1+
"use client";
2+
3+
import { useState } from "react";
14
import type { NextPage } from "next";
25
import ExamLink from "@azure-fundamentals/components/ExamLink";
36

47
const Modes: NextPage<{ searchParams: { url: string; name: string } }> = ({
58
searchParams,
69
}) => {
710
const { url, name } = searchParams;
11+
const [hoveredCard, setHoveredCard] = useState<string | null>(null);
812

913
return (
10-
<div className="mx-auto mb-6 w-full md:w-[90vw] lg:w-[70vw] 2xl:w-[45%] text-center">
11-
<h2 className="text-gray-900 dark:text-gray-100 text-4xl text-leading font-bold uppercase md:mt-14">
14+
<div className="mx-auto mb-6 w-full lg:w-[70vw] 2xl:w-[45%] text-center px-6 pr-8 sm:px-8 sm:pr-12 lg:px-12 lg:pr-16 modes-page">
15+
<h2 className="text-gray-900 dark:text-gray-100 text-4xl text-leading font-bold uppercase mt-16">
1216
{name}
1317
</h2>
14-
<p className="text-gray-900 dark:text-gray-100 text-lg mt-4 mb-14 px-5 leading-6">
18+
<p className="text-gray-900 dark:text-gray-100 text-lg mt-4 mb-6 leading-6">
1519
Test your knowledge under pressure with our timed exam mode or explore
1620
and master all the questions at your own pace with our practice mode.
1721
</p>
18-
<div className="flex max-sm:flex-col max-sm:align-center justify-center gap-10 mx-5 md:mx-16">
19-
<ExamLink
20-
href={{
21-
pathname: "/practice",
22-
query: { url, name },
23-
}}
24-
heading="Practice mode"
25-
paragraph="Learn and familiarize yourself with the questions and answers without any time constraint."
26-
subparagraph="You can copy URL to comeback to the same question later."
27-
/>
28-
<ExamLink
29-
href={{
30-
pathname: "/exam",
31-
query: { url, name },
32-
}}
33-
heading="Exam mode"
34-
paragraph="Put your knowledge to the test by answering a fixed number of randomly selected questions under a time
35-
limit."
36-
/>
22+
<div className="cards-container grid grid-cols-1 md:grid-cols-2 gap-5">
23+
<div
24+
onMouseEnter={() => setHoveredCard("practice")}
25+
onMouseLeave={() => setHoveredCard(null)}
26+
>
27+
<ExamLink
28+
href={{
29+
pathname: "/practice",
30+
query: { url, name },
31+
}}
32+
heading="Practice mode"
33+
paragraph="Learn and familiarize yourself with the questions and answers without any time constraint.<br /><br />You can copy URL to comeback to the same question later."
34+
wrapperClassNames={
35+
hoveredCard && hoveredCard !== "practice" ? "dimmed" : ""
36+
}
37+
/>
38+
</div>
39+
<div
40+
onMouseEnter={() => setHoveredCard("exam")}
41+
onMouseLeave={() => setHoveredCard(null)}
42+
>
43+
<ExamLink
44+
href={{
45+
pathname: "/exam",
46+
query: { url, name },
47+
}}
48+
heading="Exam mode"
49+
paragraph="Put your knowledge to the test by answering a fixed number of randomly selected questions under a time
50+
limit."
51+
wrapperClassNames={
52+
hoveredCard && hoveredCard !== "exam" ? "dimmed" : ""
53+
}
54+
/>
55+
</div>
3756
</div>
3857
</div>
3958
);

app/not-found.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ export default function NotFound() {
3434
{/* Action buttons */}
3535
<div className="link-container">
3636
<Link href="/" className="more-link">
37-
🚀 Return Home
38-
</Link>
39-
<Link href="/modes" className="more-link">
4037
📚 Browse Exams
4138
</Link>
4239
</div>

app/page.tsx

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import useDebounce from "@azure-fundamentals/hooks/useDebounce";
88

99
const Home: NextPage = () => {
1010
const [searchTerm, setSearchTerm] = useState("");
11+
const [hoveredCard, setHoveredCard] = useState<string | null>(null);
1112
const debouncedSearchTerm = useDebounce(searchTerm, 500);
1213

1314
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
@@ -19,40 +20,47 @@ const Home: NextPage = () => {
1920
);
2021

2122
return (
22-
<div className="mx-auto mb-6 w-full lg:w-[70vw] 2xl:w-[45%] text-center">
23-
<h2 className="text-gray-900 dark:text-gray-100 text-5xl font-bold uppercase">
23+
<div className="mx-auto mb-6 w-full lg:w-[70vw] 2xl:w-[45%] text-center px-6 pr-8 sm:px-8 sm:pr-12 lg:px-12 lg:pr-16">
24+
<h2 className="text-gray-900 dark:text-gray-100 text-5xl font-bold uppercase mt-16">
2425
Welcome!
2526
</h2>
26-
<p className="text-gray-900 dark:text-gray-100 text-lg mt-4 mb-6 px-5 leading-6">
27+
<p className="text-gray-900 dark:text-gray-100 text-lg mt-4 mb-6 leading-6">
2728
Select an exam from the list below.
2829
</p>
2930
<input
3031
type="text"
3132
value={searchTerm}
3233
onChange={handleSearchChange}
3334
placeholder="Search exams"
34-
className="mb-6 px-4 py-2 border border-gray-200 dark:border-gray-800 bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100 rounded-md w-3/4 lg:w-1/2"
35+
className="mb-6 px-4 py-2 border border-gray-200 dark:border-gray-800 bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100 rounded-md w-3/4 lg:w-1/2 focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20"
3536
/>
3637
<div
37-
className={`grid ${
38+
className={`cards-container grid ${
3839
filteredExams.length > 0
3940
? "grid-cols-1 sm:grid-cols-2 gap-x-10 gap-y-5"
4041
: "flex justify-center items-center"
4142
} mx-5 lg:mx-0`}
4243
>
4344
{filteredExams.length > 0 ? (
4445
filteredExams.map((exam) => (
45-
<NameLink
46+
<div
4647
key={exam.name}
47-
href={{
48-
pathname: "/modes",
49-
query: { url: exam.url, name: exam.name },
50-
}}
51-
heading={exam.name}
52-
paragraph={exam.subtitle}
53-
wrapperClassNames=""
54-
headingClassNames=""
55-
/>
48+
onMouseEnter={() => setHoveredCard(exam.name)}
49+
onMouseLeave={() => setHoveredCard(null)}
50+
>
51+
<NameLink
52+
href={{
53+
pathname: "/modes",
54+
query: { url: exam.url, name: exam.name },
55+
}}
56+
heading={exam.name}
57+
paragraph={exam.subtitle}
58+
wrapperClassNames={
59+
hoveredCard && hoveredCard !== exam.name ? "dimmed" : ""
60+
}
61+
headingClassNames=""
62+
/>
63+
</div>
5664
))
5765
) : (
5866
<p className="text-gray-900 dark:text-gray-100 text-lg mt-4">

components/Button.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ const button = cva("button", {
66
intent: {
77
primary: ["btn-primary", "focus:ring-primary-800"],
88
secondary: [
9-
"bg-primary-500/20",
9+
"bg-transparent",
1010
"border-primary-500",
11-
"hover:bg-primary-500/30",
11+
"hover:bg-primary-500/10",
1212
"hover:border-primary-600",
13+
"hover:scale-105",
14+
"hover:shadow-primary-500/20",
1315
"focus:ring-primary-800",
14-
"text-primary-700 dark:text-primary-300",
16+
"text-primary-500 dark:text-white",
1517
"sm:mr-2",
1618
],
1719
},
@@ -52,7 +54,7 @@ export const Button: React.FC<ButtonProps> = ({
5254
intent,
5355
size,
5456
variant,
55-
})} text-white rounded-lg focus:outline-none focus:ring-1 border mb-2 sm:mb-0 disabled:cursor-not-allowed disabled:opacity-50 ${
57+
})} rounded-lg focus:outline-none focus:ring-1 border mb-2 sm:mb-0 disabled:cursor-not-allowed disabled:opacity-50 ${
5658
className || ""
5759
}`}
5860
{...props}

components/ExamLink.tsx

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,35 @@ const ExamLink = ({
2525
{...linkProps}
2626
className={clsx(
2727
"group rounded-xl w-full h-[350px] cursor-pointer transition-all duration-200",
28-
"bg-gray-200 dark:bg-gray-700 border border-gray-200 dark:border-gray-700",
28+
"bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700",
2929
"hover:shadow-xl hover:shadow-primary-500/20 hover:scale-105 hover:border hover:border-primary-500 dark:hover:shadow-xl dark:hover:shadow-primary-500/20 dark:hover:border dark:hover:border-primary-500",
30+
"card-hover-effect flex flex-col justify-center items-center px-7",
3031
wrapperClassNames,
3132
)}
3233
>
33-
<div
34+
<h2
3435
className={clsx(
36+
"uppercase text-3xl font-bold transition-colors duration-200 text-center",
37+
"text-gray-900 dark:text-white",
38+
"group-hover:text-primary",
3539
headingClassNames,
36-
"flex flex-col justify-center items-center h-full rounded-xl px-7 transition-colors duration-200",
37-
"bg-white dark:bg-gray-800",
3840
)}
3941
>
40-
<h2
41-
className={clsx(
42-
"uppercase text-3xl font-bold transition-colors duration-200",
43-
"text-gray-900 dark:text-white",
44-
"group-hover:text-primary",
45-
)}
46-
>
47-
{heading}
48-
</h2>
49-
<p className="text-sm text-gray-600 dark:text-gray-400 mt-7">
50-
{paragraph}
42+
{heading}
43+
</h2>
44+
<p
45+
className="text-sm text-gray-600 dark:text-gray-400 mt-10 text-center"
46+
dangerouslySetInnerHTML={{ __html: paragraph }}
47+
/>
48+
{subparagraph !== "" && (
49+
<p className="text-sm text-gray-600 dark:text-gray-400 mt-2 text-center">
50+
{subparagraph}
5151
</p>
52-
{subparagraph !== "" && (
53-
<p className="text-sm text-gray-600 dark:text-gray-400 mt-2">
54-
{subparagraph}
55-
</p>
56-
)}
52+
)}
53+
54+
{/* Corner arrow */}
55+
<div className="go-corner">
56+
<div className="go-arrow"></div>
5757
</div>
5858
</Link>
5959
);

components/NameLink.tsx

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,21 @@ const NameLink = ({
2424
return (
2525
<Link
2626
{...linkProps}
27-
className={clsx(
28-
"group rounded-xl w-full h-[100px] cursor-pointer transition-all duration-200",
29-
"bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700",
30-
"hover:shadow-xl hover:shadow-primary-500/20 hover:scale-105 hover:border-primary-500 dark:hover:shadow-xl dark:hover:shadow-primary-500/20 dark:hover:border-primary-500",
31-
wrapperClassNames,
32-
)}
27+
className={clsx("card-hover-effect", wrapperClassNames)}
3328
>
34-
<div
29+
<h3
3530
className={clsx(
31+
"text-gray-900 dark:text-white text-lg font-bold mb-2",
3632
headingClassNames,
37-
"flex flex-col justify-center items-center h-full rounded-xl px-7",
3833
)}
3934
>
40-
<h2
41-
className={clsx(
42-
"uppercase text-xl font-bold transition-colors duration-200",
43-
"text-gray-900 dark:text-white",
44-
"group-hover:text-primary",
45-
)}
46-
>
47-
{heading}
48-
</h2>
49-
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
50-
{paragraph}
51-
</p>
35+
{heading}
36+
</h3>
37+
<p className="text-sm text-gray-600 dark:text-gray-400">{paragraph}</p>
38+
39+
{/* Corner arrow */}
40+
<div className="go-corner">
41+
<div className="go-arrow"></div>
5242
</div>
5343
</Link>
5444
);

components/QuizExamForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ const QuizExamForm: FC<Props> = ({
400400
</Button>
401401
<Button
402402
type="button"
403-
intent="secondary"
403+
intent="primary"
404404
size="medium"
405405
onClick={() => {
406406
if (hideExam) {

components/QuizExamFormUF.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ const QuizExamForm: FC<Props> = ({
357357
</Button>
358358
<Button
359359
type="button"
360-
intent="secondary"
360+
intent="primary"
361361
size="medium"
362362
onClick={() => {
363363
if (hideExam) {

0 commit comments

Comments
 (0)