├── README.md
├── .eslintrc
├── src
├── components
│ ├── ExamCard.tsx
│ └── NavBar.tsx
├── pages
│ ├── 404.tsx
│ ├── exams
│ │ ├── revise
│ │ │ └── [slug].tsx
│ │ ├── study
│ │ │ └── [slug].tsx
│ │ ├── mock-test
│ │ │ └── [slug].tsx
│ │ └── index.tsx
│ ├── _app.tsx
│ ├── _document.tsx
│ ├── api
│ │ └── exams
│ │ │ ├── index.ts
│ │ │ └── aws
│ │ │ └── [...slug].ts
│ └── index.tsx
├── app
│ ├── theme.tsx
│ └── layout.tsx
├── types
│ ├── Question.ts
│ ├── ExamListitem.ts
│ ├── Api.ts
│ ├── Exam.ts
│ └── _ExamMeta.ts
├── services
│ └── apiClient.ts
└── utils
│ └── api.ts
├── public
├── favicon.ico
├── vercel.svg
├── logo-dark.svg
└── logo-light.svg
├── next.config.js
├── .prettierrc
├── next-env.d.ts
├── .gitignore
├── tsconfig.json
├── package.json
└── data
└── examlist.json
/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next", "next/core-web-vitals"]
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/ExamCard.tsx:
--------------------------------------------------------------------------------
1 | export default function ExamCard() {
2 | return
ExamCard
;
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | export default function NotFound() {
2 | return 404 - Page Not Found
;
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/exams/revise/[slug].tsx:
--------------------------------------------------------------------------------
1 | export default function Revise() {
2 | return Study
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/exams/study/[slug].tsx:
--------------------------------------------------------------------------------
1 | export default function Study() {
2 | return Study
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/exams/mock-test/[slug].tsx:
--------------------------------------------------------------------------------
1 | export default function MockTest() {
2 | return Study
3 | }
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thesohailjafri/Aws-Exam-Preparation-Material/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | images: {
3 | domains: ['res.cloudinary.com', 'imgur.com'],
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/src/app/theme.tsx:
--------------------------------------------------------------------------------
1 | import { extendTheme } from '@chakra-ui/react';
2 | const config = {
3 | initialColorMode: 'dark',
4 | useSystemColorMode: false,
5 | };
6 | const theme = extendTheme({ config });
7 | export default theme;
8 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": true,
3 | "tabWidth": 2,
4 | "singleQuote": true,
5 | "trailingComma": "all",
6 | "semi": false,
7 | "jsxSingleQuote": true,
8 | "jsxBracketSameLine": false,
9 | "arrowParens": "always",
10 | "printWidth": 100
11 | }
12 |
--------------------------------------------------------------------------------
/src/pages/exams/index.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Text } from '@chakra-ui/react';
2 |
3 | export default function ExamsPages() {
4 | return (
5 |
6 |
7 | Available Exams
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 |
5 | // NOTE: This file should not be edited
6 | // see https://nextjs.org/docs/basic-features/typescript for more information.
7 |
--------------------------------------------------------------------------------
/src/types/Question.ts:
--------------------------------------------------------------------------------
1 | // Types definition for Question
2 |
3 | import { ExamType, Option } from "./_ExamMeta"
4 |
5 |
6 | export default interface Question {
7 | id: string | number;
8 | question: string;
9 | questionType: ExamType;
10 | options: Option[];
11 | answer: string[];
12 | answerDescription: string;
13 | answerLink: string;
14 | }
15 |
--------------------------------------------------------------------------------
/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import { Container } from '@chakra-ui/react';
2 | import NavBar from '../components/NavBar';
3 |
4 | export default function RootLayout({ children }: { children: React.ReactNode }) {
5 | return (
6 | <>
7 |
8 |
9 | {children}
10 |
11 | >
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import { AppProps } from 'next/app';
2 | import { ChakraProvider } from '@chakra-ui/react';
3 | import theme from '../app/theme';
4 | import RootLayout from '../app/layout';
5 |
6 | function MyApp({ Component, pageProps }: AppProps) {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 | );
14 | }
15 | export default MyApp;
16 |
--------------------------------------------------------------------------------
/src/types/ExamListitem.ts:
--------------------------------------------------------------------------------
1 | export interface ExamListitem {
2 | exam: string
3 | examCode: string
4 | examLink: string
5 | examPriceInDollar: number | string
6 | examDurationInMinutes: number | string
7 | examPassingScore: number | string
8 | examMaxScore: number | string
9 | examLanguage: string
10 | examFormat: string
11 | examType: string
12 | examAudience: string
13 | examObjectiveLink: string
14 | examImage: string
15 | examDomains: string[]
16 | }
17 |
--------------------------------------------------------------------------------
/src/types/Api.ts:
--------------------------------------------------------------------------------
1 | export type Method =
2 | | 'GET'
3 | | 'DELETE'
4 | | 'HEAD'
5 | | 'OPTIONS'
6 | | 'POST'
7 | | 'PUT'
8 | | 'PATCH'
9 | | 'PURGE'
10 | | 'LINK'
11 | | 'UNLINK';
12 |
13 | // Shape of the response when an error is thrown
14 | export interface ErrorResponse {
15 | error: {
16 | message: string;
17 | err?: any; // Sent for unhandled errors reulting in 500
18 | };
19 | status?: number; // Sent for unhandled errors reulting in 500
20 | }
21 |
--------------------------------------------------------------------------------
/src/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import { ColorModeScript } from '@chakra-ui/react';
2 | import { Html, Head, Main, NextScript } from 'next/document';
3 | import theme from '../app/theme';
4 | export default function Document() {
5 | return (
6 |
7 |
9 | {/* 👇 Here's the script */}
10 |
11 |
12 |
13 |
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
36 |
--------------------------------------------------------------------------------
/src/types/Exam.ts:
--------------------------------------------------------------------------------
1 | import { ExamType } from "./_ExamMeta"
2 | import Question from "./Question"
3 |
4 | // ExamMeta Type Definition
5 | export default interface Exam {
6 | exam: string;
7 | examCode: string;
8 | examLink: string;
9 | examPriceInDollar: number;
10 | examDurationInMinutes: number;
11 | examPassingScore: number;
12 | examMaxScore: number;
13 | examLanguage: string;
14 | examFormat: string;
15 | examType: string;
16 | examAudience: string;
17 | examObjectiveLink: string;
18 | questionTypes: ExamType[];
19 | questions: Question[],
20 | }
--------------------------------------------------------------------------------
/src/types/_ExamMeta.ts:
--------------------------------------------------------------------------------
1 | // Type definition for ExamMeta
2 |
3 | export interface Option {
4 | a: string | undefined;
5 | b: string | undefined;
6 | c: string | undefined;
7 | d: string | undefined;
8 | e: string | undefined;
9 | }
10 |
11 | export type ExamType = 'single' | 'multiple';
12 |
13 | export type ExamDomain =
14 | | 'Cloud Computing'
15 | | 'Data Science'
16 | | 'Machine Learning'
17 | | 'Web Development'
18 | | 'Mobile Development'
19 | | 'DevOps'
20 | | 'Cyber Security'
21 | | 'Backend Development'
22 | | 'Frontend Development'
23 | | 'Other';
24 |
--------------------------------------------------------------------------------
/src/services/apiClient.ts:
--------------------------------------------------------------------------------
1 | import axios, { AxiosRequestConfig } from 'axios'
2 |
3 | const axiosInstance = axios.create({
4 | baseURL: '/api',
5 | })
6 |
7 | class APIClient {
8 | endpoint: string
9 | constructor(endpoint: string) {
10 | this.endpoint = endpoint
11 | }
12 |
13 | getAll = async (config: AxiosRequestConfig) => {
14 | return axiosInstance.get(this.endpoint, config).then((response) => response.data)
15 | }
16 |
17 | getOne = async (slug: string) => {
18 | return axiosInstance.get(`${this.endpoint}/${slug}`).then((response) => response.data)
19 | }
20 | }
21 |
22 | export default APIClient
23 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "baseUrl": ".",
16 | "paths": {
17 | "@/*": ["src/*"]
18 | },
19 | "jsx": "preserve",
20 | "incremental": true,
21 | "plugins": [
22 | {
23 | "name": "next"
24 | }
25 | ]
26 | },
27 | "exclude": ["node_modules", ".next", "out"],
28 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js", ".next/types/**/*.ts"]
29 | }
30 |
--------------------------------------------------------------------------------
/src/pages/api/exams/index.ts:
--------------------------------------------------------------------------------
1 | import { ExamListitem } from '@/types/ExamListitem';
2 | import { apiHandler } from '@/utils/api';
3 | import { promises as fs } from 'fs';
4 | import type { NextApiRequest, NextApiResponse } from 'next';
5 | import path from 'path';
6 | type Data = {
7 | exams: ExamListitem[];
8 | count: number;
9 | };
10 |
11 | async function getExamList(req: NextApiRequest, res: NextApiResponse) {
12 | const { domain } = req.query;
13 | const dataDirectory = path.join(process.cwd(), 'data');
14 | const fileContents = await fs.readFile(dataDirectory + '/examlist.json', 'utf8');
15 | let data = JSON.parse(fileContents);
16 | if (domain) {
17 | data = data.filter((exam: any) => exam.domains.includes(domain));
18 | }
19 | res.status(200).json({ exams: data, count: data.length });
20 | }
21 |
22 | export default apiHandler({
23 | GET: getExamList,
24 | });
25 |
--------------------------------------------------------------------------------
/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 | import type { InferGetStaticPropsType, GetStaticProps } from 'next'
3 | import { ExamListitem } from '../types/ExamListitem'
4 | interface Exams {
5 | exams: ExamListitem[]
6 | count: number
7 | }
8 |
9 | export const getStaticProps = (async (context) => {
10 | const res = await fetch('http://localhost:3000/api/exams')
11 | const examsData = await res.json()
12 | return { props: { examsData } }
13 | }) satisfies GetStaticProps<{
14 | examsData: Exams
15 | }>
16 |
17 | export default function Home({ examsData }: InferGetStaticPropsType) {
18 | console.log(examsData)
19 |
20 | return (
21 |
22 |
23 |
AWS Exam Prep App
24 |
25 |
26 | AWS Exam Prep App
27 |
28 |
29 | )
30 | }
31 |
32 | // read data/examlist.json and create pages for each exam
33 |
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aws-exam-preparation",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "devDependencies": {
12 | "@types/axios": "^0.14.0",
13 | "@types/http-errors": "^2.0.2",
14 | "@types/lodash": "^4.14.199",
15 | "@types/node": "^20.7.1",
16 | "@types/react": "^18.2.23",
17 | "autoprefixer": "^10.4.16",
18 | "babel-plugin-import": "^1.13.8",
19 | "babel-plugin-macros": "^3.1.0",
20 | "babel-plugin-module-resolver": "^5.0.0",
21 | "eslint": "^8.50.0",
22 | "eslint-config-next": "^13.5.3",
23 | "typescript": "^5.2.2"
24 | },
25 | "dependencies": {
26 | "@chakra-ui/icons": "^2.1.1",
27 | "@chakra-ui/next-js": "^2.1.5",
28 | "@chakra-ui/react": "^2.8.1",
29 | "@emotion/react": "^11.11.1",
30 | "@emotion/styled": "^11.11.0",
31 | "axios": "^1.5.1",
32 | "date-fns": "^2.30.0",
33 | "framer-motion": "^10.16.4",
34 | "http-errors": "^2.0.0",
35 | "lodash": "^4.17.21",
36 | "next": "^13.5.3",
37 | "react": "^18.2.0",
38 | "react-dom": "^18.2.0",
39 | "react-query": "^3.39.3"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/pages/api/exams/aws/[...slug].ts:
--------------------------------------------------------------------------------
1 | import { ExamListitem } from '@/types/ExamListitem'
2 | import { apiHandler } from '@/utils/api'
3 | import { promises as fs } from 'fs'
4 | import type { NextApiRequest, NextApiResponse } from 'next'
5 | import path from 'path'
6 | import exam from '..'
7 | interface Exam extends ExamListitem {
8 | questions: []
9 | }
10 |
11 | type Query = {
12 | page?: number
13 | limit?: number
14 | view_all?: boolean
15 | }
16 |
17 | async function getExamList(req: NextApiRequest, res: NextApiResponse) {
18 | const {
19 | page = 1, // Current page number
20 | limit = 20, // Number of items per page
21 | view_all = false, // View all items
22 | }: Query = req.query
23 |
24 | let examFileLocation = req.url?.replace('/api/exam', '')
25 | examFileLocation = examFileLocation?.split('?')[0]
26 | const dataDirectory = path.join(process.cwd(), 'data')
27 | const fileContents = await fs.readFile(dataDirectory + `${examFileLocation}.json`, 'utf8')
28 | let data = JSON.parse(fileContents)
29 | if (!view_all) {
30 | data.questions = data.questions.slice((page - 1) * limit, page * limit)
31 | }
32 |
33 | res.status(200).json(data)
34 | }
35 |
36 | export default apiHandler({
37 | GET: getExamList,
38 | })
39 |
--------------------------------------------------------------------------------
/src/utils/api.ts:
--------------------------------------------------------------------------------
1 | import createHttpError from 'http-errors';
2 |
3 | import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
4 | import { ErrorResponse, Method } from '@/types/Api';
5 |
6 | type ApiMethodHandlers = {
7 | [key in Uppercase]?: NextApiHandler;
8 | };
9 |
10 | function errorHandler(
11 | err: {
12 | statusCode: number;
13 | message: string;
14 | expose: boolean;
15 | },
16 | res: NextApiResponse,
17 | ) {
18 | // Errors with statusCode >= 500 are should not be exposed
19 | if (createHttpError.isHttpError(err) && err.expose) {
20 | // Handle all errors thrown by http-errors module
21 | return res.status(err.statusCode).json({ error: { message: err.message } });
22 | } else {
23 | // default to 500 server error
24 | console.error(err);
25 | return res.status(500).json({
26 | error: { message: 'Internal Server Error', err: err },
27 | status: createHttpError.isHttpError(err) ? err.statusCode : 500,
28 | });
29 | }
30 | }
31 |
32 | export function apiHandler(handler: ApiMethodHandlers) {
33 | return async (req: NextApiRequest, res: NextApiResponse) => {
34 | try {
35 | const method = req.method ? (req.method.toUpperCase() as keyof ApiMethodHandlers) : undefined;
36 |
37 | // check if handler supports current HTTP method
38 | if (!method)
39 | throw new createHttpError.MethodNotAllowed(`No method specified on path ${req.url}!`);
40 |
41 | const methodHandler = handler[method];
42 | if (!methodHandler)
43 | throw new createHttpError.MethodNotAllowed(
44 | `Method ${req.method} Not Allowed on path ${req.url}!`,
45 | );
46 |
47 | // call method handler
48 | await methodHandler(req, res);
49 | } catch (err: any) {
50 | // global error handler
51 | errorHandler(err, res);
52 | }
53 | };
54 | }
55 |
--------------------------------------------------------------------------------
/data/examlist.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "exam": "AWS Certified Cloud Practitioner",
4 | "examCode": "AWS-CCP",
5 | "examLink": "https://aws.amazon.com/certification/certified-cloud-practitioner/",
6 | "examPriceInDollar": "100",
7 | "examDurationInMinutes": "90",
8 | "examPassingScore": "700",
9 | "examMaxScore": "1000",
10 | "examLanguage": "English, Japanese, Korean, Simplified Chinese",
11 | "examFormat": "Multiple choice, multiple answer",
12 | "examType": "Associate",
13 | "examAudience": "Individuals who have basic knowledge of AWS Cloud",
14 | "examObjectiveLink": "https://d1.awsstatic.com/training-and-certification/docs-cloud-practitioner/AWS-Certified-Cloud-Practitioner_Exam-Guide.pdf",
15 | "examImage": "/images/aws-certified-cloud-practitioner.png",
16 | "examDomains": [
17 | "Cloud Computing",
18 | "Data Science",
19 | "Machine Learning",
20 | "Web Development",
21 | "Mobile Development",
22 | "DevOps",
23 | "Cyber Security"
24 | ],
25 | "questionTypes": ["single", "multiple"]
26 | },
27 | {
28 | "exam": "AWS Solutions Architect Associate",
29 | "examCode": "AWS-SAA",
30 | "examLink": "https://aws.amazon.com/certification/certified-solutions-architect-associate/",
31 | "examPriceInDollar": "150",
32 | "examDurationInMinutes": "130",
33 | "examPassingScore": "720",
34 | "examMaxScore": "1000",
35 | "examLanguage": "English, Japanese, Korean, Simplified Chinese",
36 | "examFormat": "Multiple choice, multiple answer",
37 | "examType": "Associate",
38 | "examAudience": "Individuals who have basic knowledge of AWS Cloud",
39 | "examObjectiveLink": "https://d1.awsstatic.com/training-and-certification/docs-sa-assoc/AWS-Certified-Solutions-Architect-Associate_Exam-Guide.pdf",
40 | "examImage": "/images/aws-certified-solutions-architect-associate.png",
41 | "examDomains": [
42 | "Cloud Computing",
43 | "Data Science",
44 | "Machine Learning",
45 | "Web Development",
46 | "Mobile Development",
47 | "DevOps",
48 | "Cyber Security"
49 | ]
50 | }
51 | ]
52 |
--------------------------------------------------------------------------------
/src/components/NavBar.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import {
4 | ChevronDownIcon,
5 | ChevronRightIcon,
6 | CloseIcon,
7 | HamburgerIcon,
8 | MoonIcon,
9 | SunIcon,
10 | } from '@chakra-ui/icons'
11 | import {
12 | Box,
13 | Button,
14 | Collapse,
15 | Flex,
16 | Icon,
17 | IconButton,
18 | Image,
19 | Popover,
20 | PopoverContent,
21 | PopoverTrigger,
22 | Stack,
23 | Text,
24 | useColorMode,
25 | useColorModeValue,
26 | useDisclosure,
27 | } from '@chakra-ui/react'
28 | import Link from 'next/link'
29 |
30 | export default function WithSubnavigation() {
31 | const { isOpen, onToggle } = useDisclosure()
32 |
33 | return (
34 |
40 |
49 |
50 | : }
53 | variant={'ghost'}
54 | aria-label={'Toggle Navigation'}
55 | _hover={{
56 | bg: useColorModeValue('orange.200', 'orange.800'),
57 | }}
58 | />
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | )
78 | }
79 |
80 | const Logo = () => {
81 | const { colorMode } = useColorMode()
82 | return (
83 |
84 |
91 |
92 | )
93 | }
94 |
95 | const DesktopNav = () => {
96 | const linkColor = useColorModeValue('black', 'white')
97 | const linkHoverColor = useColorModeValue('orange.800', 'orange.200')
98 | const popoverContentBgColor = useColorModeValue('orange.100', 'orange.900')
99 |
100 | return (
101 |
102 | {NAV_ITEMS.map((navItem) => (
103 |
104 |
105 |
106 |
118 | {navItem.label}
119 |
120 |
121 |
122 | {navItem.children && (
123 |
131 |
132 | {navItem.children.map((child) => (
133 |
134 | ))}
135 |
136 |
137 | )}
138 |
139 |
140 | ))}
141 |
142 | )
143 | }
144 |
145 | const DesktopSubNav = ({ label, href, subLabel }: NavItem) => {
146 | return (
147 |
148 |
149 |
150 |
151 | {label}
152 |
153 | {subLabel}
154 |
155 |
164 |
165 |
166 |
167 |
168 | )
169 | }
170 |
171 | const MobileNav = () => {
172 | return (
173 |
174 | {NAV_ITEMS.map((navItem) => (
175 |
176 | ))}
177 |
178 | )
179 | }
180 |
181 | const MobileNavItem = ({ label, children, href }: NavItem) => {
182 | const { isOpen, onToggle } = useDisclosure()
183 | const linkColor = useColorModeValue('black', 'white')
184 | const linkHoverColor = useColorModeValue('orange.800', 'orange.200')
185 | return (
186 |
187 |
197 |
205 | {label}
206 |
207 | {children && (
208 |
215 | )}
216 |
217 |
218 |
219 |
220 | {children &&
221 | children.map((child) => (
222 |
223 | {child.label}
224 |
225 | ))}
226 |
227 |
228 |
229 | )
230 | }
231 |
232 | interface NavItem {
233 | label: string
234 | subLabel?: string
235 | children?: Array
236 | href?: string
237 | }
238 |
239 | const NAV_ITEMS: Array = [
240 | {
241 | label: 'View All Exams',
242 | href: '/exams',
243 | },
244 | {
245 | label: 'Popular Exams',
246 | href: '/exams/popular',
247 | },
248 | {
249 | label: 'My Accessments',
250 | href: '/exams/accessments',
251 | },
252 | {
253 | label: 'Want to Contribute?',
254 | href: 'https://github.com/thesohailjafri/Aws-Exam-Preparation-Material/issues',
255 | },
256 | ]
257 |
258 | const ColorModeSwitch = () => {
259 | const { toggleColorMode, colorMode } = useColorMode()
260 |
261 | return (
262 | : }
265 | variant={'ghost'}
266 | aria-label={'Toggle Navigation'}
267 | _hover={{
268 | bg: useColorModeValue('orange.200', 'orange.800'),
269 | }}
270 | />
271 | )
272 | }
273 |
--------------------------------------------------------------------------------
/public/logo-dark.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/logo-light.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------