feat: added dark theme, codesnippet and image support in question, and quiz topic screen
main
-
96README.md
-
34src/App.tsx
-
24src/assets/icons/app-logo.svg
-
14src/assets/icons/bulb.svg
-
69src/assets/icons/colored-logo.svg
-
64src/assets/icons/logo.svg
-
3src/assets/icons/moon.svg
-
11src/assets/icons/sun.svg
-
BINsrc/assets/images/Xeven-Quiz-ReactJS-Quiz-App-Template.jpg
-
BINsrc/assets/images/add-images-to-questions.png
-
BINsrc/assets/images/brand-logo.jpg
-
BINsrc/assets/images/car.jpg
-
BINsrc/assets/images/code-snippet-1.png
-
BINsrc/assets/images/dish.jpg
-
BINsrc/assets/images/mosque.jpg
-
BINsrc/assets/images/place.jpg
-
BINsrc/assets/images/reptile.jpg
-
4src/components/Main/index.tsx
-
6src/components/QuestionScreen/Answer/index.tsx
-
10src/components/QuestionScreen/Question/index.tsx
-
19src/components/QuestionScreen/index.tsx
-
23src/components/QuizDetailsScreen/index.tsx
-
117src/components/QuizTopicsScreen/index.tsx
-
3src/components/ResultScreen/RightAnswer/index.tsx
-
38src/components/ResultScreen/index.tsx
-
12src/components/ui/Button/index.tsx
-
27src/components/ui/Button/styled.tsx
-
29src/components/ui/CodeSnippet/index.tsx
-
4src/components/ui/ModalWrapper/index.tsx
-
20src/components/ui/QuizImage/index.tsx
-
117src/components/ui/ToggleTheme/index.tsx
-
6src/config/icons.ts
-
29src/context/QuizContext.ts
-
31src/context/QuizProvider.tsx
-
76src/data/QuizQuestions/generalKnowledge.ts
-
8src/data/QuizQuestions/index.ts
-
129src/data/QuizQuestions/javascript.ts
-
178src/data/QuizQuestions/python.ts
-
105src/data/QuizQuestions/react.ts
-
5src/data/quizTopics.tsx
-
3src/hooks/index.ts
-
17src/hooks/useShuffleQuestions.ts
-
1src/logo.svg
-
29src/styles/Global.ts
-
78src/styles/Theme.ts
-
70src/styles/styled.d.ts
-
2src/types/index.ts
@ -1,17 +1,41 @@ |
|||
import { useState } from 'react' |
|||
import { ThemeProvider } from 'styled-components' |
|||
|
|||
import Main from './components/Main' |
|||
import QuizProvider from './context/QuizContext' |
|||
import ToggleTheme from './components/ui/ToggleTheme' |
|||
import QuizProvider from './context/QuizProvider' |
|||
import { GlobalStyles } from './styles/Global' |
|||
import { theme as AppTheme } from './styles/Theme' |
|||
import { themes } from './styles/Theme' |
|||
|
|||
const App = () => ( |
|||
<ThemeProvider theme={AppTheme}> |
|||
function App() { |
|||
const [currentTheme, setCurrentTheme] = useState(() => { |
|||
const savedTheme = localStorage.getItem('theme') |
|||
return savedTheme || 'light' |
|||
}) |
|||
|
|||
const toggleTheme = (e: React.ChangeEvent<HTMLInputElement>) => { |
|||
const { checked } = e.target |
|||
setCurrentTheme(checked ? 'dark' : 'light') |
|||
localStorage.setItem('theme', checked ? 'dark' : 'light') |
|||
} |
|||
|
|||
const theme = currentTheme === 'light' ? themes.light : themes.dark |
|||
|
|||
return ( |
|||
<ThemeProvider theme={theme}> |
|||
<GlobalStyles /> |
|||
<QuizProvider> |
|||
<ToggleTheme |
|||
onChange={toggleTheme} |
|||
currentTheme={currentTheme} |
|||
checked={currentTheme === 'dark'} |
|||
id="toggleTheme" |
|||
value="theme" |
|||
/> |
|||
<Main /> |
|||
</QuizProvider> |
|||
</ThemeProvider> |
|||
) |
|||
) |
|||
} |
|||
|
|||
export default App |
24
src/assets/icons/app-logo.svg
File diff suppressed because it is too large
View File
14
src/assets/icons/bulb.svg
File diff suppressed because it is too large
View File
69
src/assets/icons/colored-logo.svg
File diff suppressed because it is too large
View File
64
src/assets/icons/logo.svg
File diff suppressed because it is too large
View File
@ -0,0 +1,3 @@ |
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> |
|||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.65784 3.17857C5.14829 3.35425 3.16699 5.44573 3.16699 7.99996C3.16699 10.6693 5.33095 12.8333 8.00033 12.8333C10.1389 12.8333 11.9535 11.4441 12.5902 9.51907C12.1001 9.72153 11.5631 9.83329 11.0003 9.83329C8.69914 9.83329 6.83366 7.96781 6.83366 5.66663C6.83366 4.73386 7.1404 3.87269 7.65784 3.17857ZM2.16699 7.99996C2.16699 4.7783 4.77866 2.16663 8.00033 2.16663C8.30007 2.16663 8.59484 2.18928 8.88296 2.23304C9.08227 2.26331 9.2439 2.41032 9.29289 2.60587C9.34188 2.80142 9.26863 3.00726 9.10714 3.12792C8.33315 3.70619 7.83366 4.62801 7.83366 5.66663C7.83366 7.41553 9.25142 8.83329 11.0003 8.83329C11.7565 8.83329 12.4495 8.56889 12.994 8.12705C13.1505 8.00009 13.3679 7.97945 13.5454 8.07469C13.723 8.16994 13.826 8.36245 13.8068 8.56303C13.5232 11.5208 11.0321 13.8333 8.00033 13.8333C4.77866 13.8333 2.16699 11.2216 2.16699 7.99996Z" fill="#282526"/> |
|||
</svg> |
@ -0,0 +1,11 @@ |
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> |
|||
<path d="M7.99967 0.833618C8.27582 0.833618 8.49967 1.05748 8.49967 1.33362V2.00028C8.49967 2.27643 8.27582 2.50028 7.99967 2.50028C7.72353 2.50028 7.49967 2.27643 7.49967 2.00028V1.33362C7.49967 1.05748 7.72353 0.833618 7.99967 0.833618Z" fill="#E9EAF0"/> |
|||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.16634 8.00029C4.16634 5.88319 5.88258 4.16695 7.99967 4.16695C10.1168 4.16695 11.833 5.88319 11.833 8.00029C11.833 10.1174 10.1168 11.8336 7.99967 11.8336C5.88258 11.8336 4.16634 10.1174 4.16634 8.00029ZM7.99967 5.16695C6.43487 5.16695 5.16634 6.43548 5.16634 8.00029C5.16634 9.56509 6.43487 10.8336 7.99967 10.8336C9.56448 10.8336 10.833 9.56509 10.833 8.00029C10.833 6.43548 9.56448 5.16695 7.99967 5.16695Z" fill="#E9EAF0"/> |
|||
<path d="M3.63919 2.9327C3.44393 2.73744 3.12735 2.73744 2.93209 2.9327C2.73682 3.12796 2.73682 3.44455 2.93209 3.63981L3.40349 4.11121C3.59875 4.30648 3.91533 4.30648 4.1106 4.11121C4.30586 3.91595 4.30586 3.59937 4.1106 3.40411L3.63919 2.9327Z" fill="#E9EAF0"/> |
|||
<path d="M15.1663 8.00029C15.1663 8.27643 14.9425 8.50029 14.6663 8.50029H13.9997C13.7235 8.50029 13.4997 8.27643 13.4997 8.00029C13.4997 7.72414 13.7235 7.50029 13.9997 7.50029H14.6663C14.9425 7.50029 15.1663 7.72414 15.1663 8.00029Z" fill="#E9EAF0"/> |
|||
<path d="M13.0673 3.6398C13.2625 3.44454 13.2625 3.12796 13.0673 2.9327C12.872 2.73743 12.5554 2.73743 12.3602 2.9327L11.8887 3.4041C11.6935 3.59936 11.6935 3.91594 11.8887 4.11121C12.084 4.30647 12.4006 4.30647 12.5959 4.11121L13.0673 3.6398Z" fill="#E9EAF0"/> |
|||
<path d="M7.99967 13.5003C8.27582 13.5003 8.49967 13.7241 8.49967 14.0003V14.667C8.49967 14.9431 8.27582 15.167 7.99967 15.167C7.72353 15.167 7.49967 14.9431 7.49967 14.667V14.0003C7.49967 13.7241 7.72353 13.5003 7.99967 13.5003Z" fill="#E9EAF0"/> |
|||
<path d="M12.5959 11.8894C12.4006 11.6941 12.0841 11.6941 11.8888 11.8894C11.6935 12.0846 11.6935 12.4012 11.8888 12.5965L12.3602 13.0679C12.5555 13.2631 12.872 13.2631 13.0673 13.0679C13.2626 12.8726 13.2626 12.556 13.0673 12.3608L12.5959 11.8894Z" fill="#E9EAF0"/> |
|||
<path d="M2.49967 8.00029C2.49967 8.27643 2.27582 8.50029 1.99967 8.50029H1.33301C1.05687 8.50029 0.833008 8.27643 0.833008 8.00029C0.833008 7.72414 1.05687 7.50029 1.33301 7.50029H1.99967C2.27582 7.50029 2.49967 7.72414 2.49967 8.00029Z" fill="#E9EAF0"/> |
|||
<path d="M4.11055 12.5965C4.30581 12.4012 4.30581 12.0846 4.11055 11.8894C3.91529 11.6941 3.59871 11.6941 3.40345 11.8894L2.93204 12.3608C2.73678 12.556 2.73678 12.8726 2.93204 13.0679C3.1273 13.2631 3.44389 13.2631 3.63915 13.0679L4.11055 12.5965Z" fill="#E9EAF0"/> |
|||
</svg> |
Before Width: 590 | Height: 300 | Size: 25 KiB |
After Width: 871 | Height: 930 | Size: 128 KiB |
After Width: 640 | Height: 427 | Size: 26 KiB |
After Width: 640 | Height: 800 | Size: 96 KiB |
After Width: 792 | Height: 620 | Size: 50 KiB |
After Width: 640 | Height: 960 | Size: 116 KiB |
After Width: 640 | Height: 489 | Size: 55 KiB |
After Width: 640 | Height: 640 | Size: 86 KiB |
After Width: 640 | Height: 400 | Size: 36 KiB |
@ -0,0 +1,117 @@ |
|||
import styled from 'styled-components' |
|||
|
|||
import { AppLogo } from '../../config/icons' |
|||
import { useQuiz } from '../../context/QuizContext' |
|||
import { quizTopics } from '../../data/quizTopics' |
|||
import { device } from '../../styles/BreakPoints' |
|||
import { |
|||
CenterCardContainer, |
|||
HighlightedText, |
|||
LogoContainer, |
|||
PageCenter, |
|||
} from '../../styles/Global' |
|||
import { ScreenTypes } from '../../types' |
|||
|
|||
import Button from '../ui/Button' |
|||
|
|||
const Heading = styled.h2`
|
|||
font-size: 32px; |
|||
font-weight: 700; |
|||
margin-bottom: 20px; |
|||
text-align: center; |
|||
`
|
|||
|
|||
const DetailText = styled.p`
|
|||
font-weight: 500; |
|||
font-size: 20px; |
|||
line-height: 29px; |
|||
text-align: center; |
|||
`
|
|||
|
|||
const SelectButtonContainer = styled.div`
|
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
justify-content: center; |
|||
max-width: 60%; |
|||
gap: 30px; |
|||
margin-top: 40px; |
|||
margin-bottom: 45px; |
|||
@media ${device.md} { |
|||
row-gap: 20px; |
|||
column-gap: 20px; |
|||
max-width: 100%; |
|||
} |
|||
`
|
|||
|
|||
interface SelectButtonProps { |
|||
active: boolean |
|||
disabled?: boolean |
|||
} |
|||
|
|||
const SelectButton = styled.div<SelectButtonProps>`
|
|||
background-color: ${({ disabled, theme }) => |
|||
disabled ? `${theme.colors.disabledCard}` : `${theme.colors.selectTopicBg}`}; |
|||
border: ${({ active, theme }) => |
|||
active |
|||
? `2px solid ${theme.colors.themeColor}` |
|||
: `1px solid ${theme.colors.disabledButton}`}; |
|||
transition: background-color 0.4s ease-out; |
|||
border-radius: 10px; |
|||
padding: 14px 10px; |
|||
display: flex; |
|||
align-items: center; |
|||
cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')}; |
|||
@media ${device.md} { |
|||
padding: 10px; |
|||
tap-highlight-color: transparent; |
|||
-webkit-tap-highlight-color: transparent; |
|||
} |
|||
`
|
|||
|
|||
const SelectButtonText = styled.span`
|
|||
font-size: 18px; |
|||
font-weight: 600; |
|||
margin-left: 10px; |
|||
@media ${device.md} { |
|||
font-size: 16px; |
|||
font-weight: 500; |
|||
} |
|||
`
|
|||
|
|||
const QuizTopicsScreen: React.FC = () => { |
|||
const { quizTopic, selectQuizTopic, setCurrentScreen } = useQuiz() |
|||
|
|||
const goToQuizDetailsScreen = () => { |
|||
setCurrentScreen(ScreenTypes.QuizDetailsScreen) |
|||
} |
|||
|
|||
return ( |
|||
<PageCenter light justifyCenter> |
|||
<CenterCardContainer> |
|||
<LogoContainer> |
|||
<AppLogo /> |
|||
</LogoContainer> |
|||
<Heading> |
|||
WELCOME TO <HighlightedText> XEVEN QUIZ</HighlightedText> |
|||
</Heading> |
|||
<DetailText>Select topic below to start your Quiz.</DetailText> |
|||
<SelectButtonContainer> |
|||
{quizTopics.map(({ title, icon, disabled }) => ( |
|||
<SelectButton |
|||
key={title} |
|||
active={quizTopic === title} |
|||
onClick={() => !disabled && selectQuizTopic(title)} |
|||
disabled={disabled} |
|||
> |
|||
{icon} |
|||
<SelectButtonText>{title}</SelectButtonText> |
|||
</SelectButton> |
|||
))} |
|||
</SelectButtonContainer> |
|||
<Button text="Continue" onClick={goToQuizDetailsScreen} bold /> |
|||
</CenterCardContainer> |
|||
</PageCenter> |
|||
) |
|||
} |
|||
|
|||
export default QuizTopicsScreen |
@ -0,0 +1,29 @@ |
|||
import Prism from 'prismjs' |
|||
import 'prismjs/themes/prism-solarizedlight.css' |
|||
|
|||
import React, { useEffect, useRef } from 'react' |
|||
|
|||
interface CodeSnippetProps { |
|||
code: string |
|||
language: string |
|||
} |
|||
|
|||
const CodeSnippet: React.FC<CodeSnippetProps> = ({ code, language }) => { |
|||
const codeRef = useRef<HTMLElement | null>(null) |
|||
|
|||
useEffect(() => { |
|||
if (codeRef.current) { |
|||
Prism.highlightElement(codeRef.current) |
|||
} |
|||
}, [code]) |
|||
|
|||
return ( |
|||
<pre className={`language-${language}`}> |
|||
<code className={`language-${language}`} ref={codeRef}> |
|||
{code} |
|||
</code> |
|||
</pre> |
|||
) |
|||
} |
|||
|
|||
export default CodeSnippet |
@ -0,0 +1,20 @@ |
|||
import { FC } from 'react' |
|||
import styled from 'styled-components' |
|||
|
|||
interface QuizImageProps { |
|||
image: string |
|||
} |
|||
|
|||
const ImageStyle = styled.img`
|
|||
border-radius: 10px; |
|||
height: 400px; |
|||
max-width: 100%; |
|||
box-shadow: 6px 6px 2px ${({ theme }) => theme.colors.themeColor}; |
|||
margin-bottom: 20px; |
|||
`
|
|||
|
|||
const QuizImage: FC<QuizImageProps> = ({ image }) => ( |
|||
<ImageStyle src={image} alt="picture quiz" /> |
|||
) |
|||
|
|||
export default QuizImage |
@ -0,0 +1,117 @@ |
|||
import React, { FC } from 'react' |
|||
import styled, { keyframes } from 'styled-components' |
|||
import { Moon, Sun } from '../../../config/icons' |
|||
|
|||
const ToggleLabel = styled.label`
|
|||
font-size: 16px; |
|||
font-weight: 700; |
|||
color: ${({ theme }) => theme.colors.themeText}; |
|||
display: flex; |
|||
align-items: center; |
|||
position: absolute; |
|||
top: 12px; |
|||
right: 25px; |
|||
`
|
|||
|
|||
const SlideOn = keyframes`
|
|||
0% { |
|||
transform: translateX(0) scale(1); |
|||
} |
|||
50% { |
|||
transform: translateX(15px) scale(1.1); |
|||
} |
|||
100% { |
|||
transform: translateX(23px) scale(1); |
|||
} |
|||
`
|
|||
|
|||
const SlideOff = keyframes`
|
|||
0% { |
|||
transform: translateX(23px) scale(1); |
|||
} |
|||
50% { |
|||
transform: translateX(15px) scale(1.1); |
|||
} |
|||
100% { |
|||
transform: translateX(0px) scale(1); |
|||
} |
|||
`
|
|||
|
|||
const ToggleInput = styled.input`
|
|||
visibility: hidden; |
|||
border: 1px solid red; |
|||
margin: 0; |
|||
&:checked + span { |
|||
background-color: ${({ theme }) => theme.colors.dark}; |
|||
svg { |
|||
animation: ${SlideOn} 0.2s linear forwards; |
|||
} |
|||
} |
|||
&:checked + span::after { |
|||
background-color: ${({ theme }) => theme.colors.white}; |
|||
animation: ${SlideOn} 0.2s linear forwards; |
|||
} |
|||
`
|
|||
|
|||
const Ball = styled.span`
|
|||
width: 52px; |
|||
height: 26px; |
|||
background-color: ${({ theme }) => theme.colors.white}; |
|||
display: inline-block; |
|||
cursor: pointer; |
|||
border-radius: 50px; |
|||
position: relative; |
|||
svg { |
|||
position: absolute; |
|||
top: 5px; |
|||
left: 7px; |
|||
z-index: 1; |
|||
animation: ${SlideOff} 0.2s linear forwards; |
|||
} |
|||
&::after { |
|||
content: ''; |
|||
width: 21px; |
|||
height: 21px; |
|||
background-color: ${({ theme }) => theme.colors.dark}; |
|||
border-radius: 50%; |
|||
display: inline-block; |
|||
position: absolute; |
|||
top: 3px; |
|||
left: 5px; |
|||
align-items: center; |
|||
justify-content: center; |
|||
animation: ${SlideOff} 0.2s linear forwards; |
|||
} |
|||
`
|
|||
|
|||
interface ToggleThemeProps { |
|||
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void |
|||
id: string |
|||
value: string |
|||
checked: boolean |
|||
currentTheme: string |
|||
} |
|||
|
|||
const ToggleTheme: FC<ToggleThemeProps> = ({ |
|||
onChange, |
|||
id, |
|||
value, |
|||
checked, |
|||
currentTheme, |
|||
}) => { |
|||
return ( |
|||
<ToggleLabel htmlFor={id}> |
|||
Mode: |
|||
<ToggleInput |
|||
type="checkbox" |
|||
id={id} |
|||
onChange={onChange} |
|||
value={value} |
|||
checked={checked} |
|||
/> |
|||
<Ball>{currentTheme === 'light' ? <Sun /> : <Moon />}</Ball> |
|||
</ToggleLabel> |
|||
) |
|||
} |
|||
|
|||
export default ToggleTheme |
@ -1,10 +1,10 @@ |
|||
import { ReactComponent as AppLogo } from '../assets/icons/app-logo.svg' |
|||
import { ReactComponent as CheckIcon } from '../assets/icons/check.svg' |
|||
import { ReactComponent as AppColoredLogo } from '../assets/icons/colored-logo.svg' |
|||
import { ReactComponent as Next } from '../assets/icons/next.svg' |
|||
import { ReactComponent as Refresh } from '../assets/icons/refresh.svg' |
|||
import { ReactComponent as TimerIcon } from '../assets/icons/timer.svg' |
|||
import { ReactComponent as Logo } from '../assets/icons/logo.svg' |
|||
import { ReactComponent as StartIcon } from '../assets/icons/start.svg' |
|||
import { ReactComponent as Sun } from '../assets/icons/sun.svg' |
|||
import { ReactComponent as Moon } from '../assets/icons/moon.svg' |
|||
|
|||
export { AppColoredLogo, AppLogo, CheckIcon, Next, Refresh, TimerIcon, Logo, StartIcon } |
|||
export { AppLogo, CheckIcon, Next, Refresh, TimerIcon, StartIcon, Sun, Moon } |
@ -0,0 +1,29 @@ |
|||
import { createContext, useContext } from 'react' |
|||
import { QuizContextTypes, ScreenTypes } from '../types' |
|||
|
|||
export const initialState: QuizContextTypes = { |
|||
currentScreen: ScreenTypes.SplashScreen, |
|||
setCurrentScreen: () => {}, |
|||
quizTopic: 'React', |
|||
selectQuizTopic: () => {}, |
|||
questions: [], |
|||
setQuestions: () => {}, |
|||
result: [], |
|||
setResult: () => {}, |
|||
timer: 15, |
|||
setTimer: () => {}, |
|||
endTime: 0, |
|||
setEndTime: () => {}, |
|||
quizDetails: { |
|||
totalQuestions: 0, |
|||
totalScore: 0, |
|||
totalTime: 0, |
|||
selectedQuizTopic: 'React', |
|||
}, |
|||
} |
|||
|
|||
export const QuizContext = createContext<QuizContextTypes>(initialState) |
|||
|
|||
export function useQuiz() { |
|||
return useContext(QuizContext) |
|||
} |
@ -1,34 +1,7 @@ |
|||
import { ReactNode, createContext, useContext, useEffect, useState } from 'react' |
|||
|
|||
import { ReactNode, useEffect, useState } from 'react' |
|||
import { quiz } from '../data/QuizQuestions' |
|||
import { QuizContextTypes, Result, ScreenTypes } from '../types' |
|||
|
|||
const initialState: QuizContextTypes = { |
|||
currentScreen: ScreenTypes.SplashScreen, |
|||
setCurrentScreen: () => {}, |
|||
quizTopic: 'React', |
|||
selectQuizTopic: () => {}, |
|||
questions: [], |
|||
setQuestions: () => {}, |
|||
result: [], |
|||
setResult: () => {}, |
|||
timer: 15, |
|||
setTimer: () => {}, |
|||
endTime: 0, |
|||
setEndTime: () => {}, |
|||
quizDetails: { |
|||
totalQuestions: 0, |
|||
totalScore: 0, |
|||
totalTime: 0, |
|||
selectedQuizTopic: 'React', |
|||
}, |
|||
} |
|||
|
|||
export const QuizContext = createContext<QuizContextTypes>(initialState) |
|||
|
|||
export function useQuiz() { |
|||
return useContext(QuizContext) |
|||
} |
|||
import { QuizContext, initialState } from './QuizContext' |
|||
|
|||
type QuizProviderProps = { |
|||
children: ReactNode |
@ -0,0 +1,76 @@ |
|||
// Question Types
|
|||
// 1. MCQs | Multiple Choice | single
|
|||
// 2. boolean | true/false | single
|
|||
// 3. MAQs | Multiple Answers | multiple
|
|||
|
|||
import { Topic } from '.' |
|||
import BrandLogo from '../../assets/images/brand-logo.jpg' |
|||
import Car from '../../assets/images/car.jpg' |
|||
import Dish from '../../assets/images/dish.jpg' |
|||
import Mosque from '../../assets/images/mosque.jpg' |
|||
import Place from '../../assets/images/place.jpg' |
|||
import Reptile from '../../assets/images/reptile.jpg' |
|||
|
|||
export const generalKnowledge: Topic = { |
|||
topic: 'GeneralKnowledge', |
|||
level: 'Beginner', |
|||
totalQuestions: 6, |
|||
totalScore: 60, |
|||
totalTime: 60, |
|||
questions: [ |
|||
{ |
|||
question: 'What is the name of this reptile?', |
|||
image: Reptile, |
|||
choices: ['Snake', 'Turtle', 'Crocodile', 'Lizard'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['Turtle'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'In which country is this historical place located?', |
|||
image: Place, |
|||
choices: ['China', 'Greece', 'India', 'Egypt'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['China'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'This is a famous Pakistani dish. What is the name of this dish?', |
|||
image: Dish, |
|||
choices: ['Kebab', 'Haleem', 'Paya', 'Biryani'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['Biryani'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'Which famous car is this?', |
|||
image: Car, |
|||
choices: ['Ford', 'Toyota', 'Mercedes', 'Honda'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['Mercedes'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'To which renowned automobile brand does this logo belong?', |
|||
image: BrandLogo, |
|||
choices: ['Audi', 'Tesla', 'BMW', 'Hyundai'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['Tesla'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'Do you recognize this iconic mosque? If so, where is it situated?', |
|||
image: Mosque, |
|||
choices: [ |
|||
'Faisal Mosque, Islamabad', |
|||
'Sheikh Zayed Grand Mosque, UAE', |
|||
'Taj Mahal, India', |
|||
'Blue Mosque, Turkey', |
|||
], |
|||
|
|||
type: 'MCQs', |
|||
correctAnswers: ['Faisal Mosque, Islamabad'], |
|||
score: 10, |
|||
}, |
|||
], |
|||
} |
@ -0,0 +1,129 @@ |
|||
// Question Types
|
|||
// 1. MCQs | Multiple Choice | single
|
|||
// 2. boolean | true/false | single
|
|||
// 3. MAQs | Multiple Answers | multiple
|
|||
|
|||
import { Topic } from '.' |
|||
|
|||
export const javascript: Topic = { |
|||
topic: 'Javascript', |
|||
level: 'Beginner', |
|||
totalQuestions: 14, |
|||
totalScore: 125, |
|||
totalTime: 240, |
|||
questions: [ |
|||
{ |
|||
question: |
|||
'Which of the following are JavaScript data types? (Select all that apply)', |
|||
choices: ['String', 'Number', 'Function', 'Array'], |
|||
type: 'MAQs', |
|||
correctAnswers: ['String', 'Number', 'Array'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'The "this" keyword in JavaScript refers to the current function.', |
|||
choices: ['True', 'False'], |
|||
type: 'boolean', |
|||
correctAnswers: ['False'], |
|||
score: 5, |
|||
}, |
|||
{ |
|||
question: 'Which operator is used for strict equality comparison in JavaScript?', |
|||
choices: ['==', '===', '=', '!='], |
|||
type: 'MCQs', |
|||
correctAnswers: ['==='], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: |
|||
'Which of the following methods is used to add an element to the end of an array in JavaScript?', |
|||
choices: ['push()', 'pop()', 'shift()', 'unshift()'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['push()'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'What is the value of x after executing the following code snippet?', |
|||
code: `let x = 5;
|
|||
x += 2; |
|||
x *= 3;`,
|
|||
choices: ['21', '25', '33', '35'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['25'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'What is the output of the following code snippet?', |
|||
code: `console.log(typeof null);`, |
|||
choices: ['Object', 'Null', 'Undefined', 'NullObject'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['Object'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'Which of the following is NOT a valid JavaScript variable name?', |
|||
choices: ['myVariable', '_variable', '123variable', '$variable'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['123variable'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: |
|||
'Which of the following methods is used to remove the last element from an array in JavaScript?', |
|||
choices: ['push()', 'pop()', 'shift()', 'unshift()'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['pop()'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'JavaScript is a case-sensitive language.', |
|||
choices: ['True', 'False'], |
|||
type: 'boolean', |
|||
correctAnswers: ['True'], |
|||
score: 5, |
|||
}, |
|||
{ |
|||
question: 'What is the output of the following code snippet?', |
|||
code: `console.log(2 + '2');`, |
|||
choices: ['4', '22', '24', "'22'"], |
|||
type: 'MCQs', |
|||
correctAnswers: ['22'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'Which of the following is NOT a JavaScript data type?', |
|||
choices: ['String', 'Boolean', 'Integer', 'Object'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['Integer'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: |
|||
'Which of the following are valid JavaScript loop statements? (Select all that apply)', |
|||
choices: ['for', 'while', 'loop', 'do...while'], |
|||
type: 'MAQs', |
|||
correctAnswers: ['for', 'while', 'do...while'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'JavaScript is a statically typed language.', |
|||
choices: ['True', 'False'], |
|||
type: 'boolean', |
|||
correctAnswers: ['False'], |
|||
score: 5, |
|||
}, |
|||
{ |
|||
question: |
|||
'Which of the following is a valid way to comment a single line in JavaScript?', |
|||
choices: [ |
|||
'// This is a comment', |
|||
'/* This is a comment */', |
|||
'<!-- This is a comment -->', |
|||
'# This is a comment', |
|||
], |
|||
type: 'MCQs', |
|||
correctAnswers: ['// This is a comment'], |
|||
score: 10, |
|||
}, |
|||
], |
|||
} |
@ -0,0 +1,178 @@ |
|||
// Question Types
|
|||
// 1. MCQs | Multiple Choice | single
|
|||
// 2. boolean | true/false | single
|
|||
// 3. MAQs | Multiple Answers | multiple
|
|||
|
|||
import { Topic } from '.' |
|||
|
|||
export const python: Topic = { |
|||
topic: 'Python', |
|||
level: 'Advanced', |
|||
totalQuestions: 14, |
|||
totalScore: 125, |
|||
totalTime: 360, |
|||
questions: [ |
|||
{ |
|||
question: |
|||
'Which of the following are valid ways to handle exceptions in Python? (Select all that apply)', |
|||
choices: [ |
|||
'Using try-except blocks', |
|||
'Using the finally block', |
|||
'Using the raise statement', |
|||
'Using assert statements', |
|||
], |
|||
type: 'MAQs', |
|||
correctAnswers: [ |
|||
'Using try-except blocks', |
|||
'Using the finally block', |
|||
'Using the raise statement', |
|||
], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'In Python, strings are mutable objects.', |
|||
choices: ['True', 'False'], |
|||
type: 'boolean', |
|||
correctAnswers: ['False'], |
|||
score: 5, |
|||
}, |
|||
{ |
|||
question: |
|||
'What is the difference between a shallow copy and a deep copy in Python?', |
|||
choices: [ |
|||
'A shallow copy creates a new object and copies the references to the original elements, while a deep copy creates a new object and recursively copies the elements', |
|||
'A shallow copy creates a new object and copies the elements, while a deep copy creates a new object and references the original elements', |
|||
'A shallow copy modifies the original object, while a deep copy creates a new object without modifying the original', |
|||
'There is no difference between a shallow copy and a deep copy in Python', |
|||
], |
|||
type: 'MCQs', |
|||
correctAnswers: [ |
|||
'A shallow copy creates a new object and copies the references to the original elements, while a deep copy creates a new object and recursively copies the elements', |
|||
], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: |
|||
'Python supports multiple inheritance, allowing a class to inherit from multiple parent classes.', |
|||
choices: ['True', 'False'], |
|||
type: 'boolean', |
|||
correctAnswers: ['True'], |
|||
score: 5, |
|||
}, |
|||
{ |
|||
question: 'What is the output of the following Python code?', |
|||
code: 'print(list(filter(lambda x: x % 2 == 0, range(10))))', |
|||
choices: [ |
|||
'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', |
|||
'[0, 2, 4, 6, 8]', |
|||
'[1, 3, 5, 7, 9]', |
|||
'[0, 1, 2, 3, 4, 9]', |
|||
], |
|||
type: 'MCQs', |
|||
correctAnswers: ['[0, 2, 4, 6, 8]'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'What is the purpose of the "__init__" method in a Python class?', |
|||
choices: [ |
|||
'To initialize the class attributes', |
|||
'To define the constructor of the class', |
|||
'To create a new instance of the class', |
|||
'To define the destructor of the class', |
|||
], |
|||
type: 'MCQs', |
|||
correctAnswers: ['To define the constructor of the class'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'Which of the following is NOT a built-in decorator in Python?', |
|||
choices: ['@staticmethod', '@classmethod', '@property', '@inheritance'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['@inheritance'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: |
|||
'The "pass" statement in Python is used as a placeholder and does nothing when executed.', |
|||
choices: ['True', 'False'], |
|||
type: 'boolean', |
|||
correctAnswers: ['True'], |
|||
score: 5, |
|||
}, |
|||
{ |
|||
question: |
|||
'Which of the following are true about Python generators? (Select all that apply)', |
|||
choices: [ |
|||
'Generators are functions that can be paused and resumed', |
|||
'Generators can only be used to generate numerical sequences', |
|||
'Generators save memory by generating values on-the-fly', |
|||
'Generators use the "yield" keyword to return values', |
|||
], |
|||
type: 'MAQs', |
|||
correctAnswers: [ |
|||
'Generators are functions that can be paused and resumed', |
|||
'Generators save memory by generating values on-the-fly', |
|||
'Generators use the "yield" keyword to return values', |
|||
], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'What is the output of the following Python code?', |
|||
code: 'print(len({True: 1, False: 0, "True": 2}))', |
|||
choices: ['0', '1', '2', '3'], |
|||
type: 'MCQs', |
|||
correctAnswers: ['2'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'What is the purpose of the "with" statement in Python?', |
|||
choices: [ |
|||
'To define a context manager', |
|||
'To handle exceptions', |
|||
'To control the flow of a loop', |
|||
'To create a new file', |
|||
], |
|||
type: 'MCQs', |
|||
correctAnswers: ['To define a context manager'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: |
|||
'Which of the following is NOT a valid method for string formatting in Python?', |
|||
choices: [ |
|||
'String interpolation using f-strings', |
|||
'String interpolation using % operator', |
|||
'String interpolation using format() method', |
|||
'String interpolation using printf() function', |
|||
], |
|||
type: 'MCQs', |
|||
correctAnswers: ['String interpolation using printf() function'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: 'What is the purpose of the "is" operator in Python?', |
|||
choices: [ |
|||
'To check if two objects have the same value', |
|||
'To check if two objects have the same identity', |
|||
'To check if two objects have the same type', |
|||
'To check if two objects have the same length', |
|||
], |
|||
type: 'MCQs', |
|||
correctAnswers: ['To check if two objects have the same identity'], |
|||
score: 10, |
|||
}, |
|||
{ |
|||
question: |
|||
'Which of the following are valid ways to create a virtual environment in Python? (Select all that apply)', |
|||
choices: [ |
|||
'Using the "venv" module', |
|||
'Using the "conda" package manager', |
|||
'Using the "pipenv" package', |
|||
'Using the "virtualenv" package', |
|||
], |
|||
type: 'MAQs', |
|||
correctAnswers: ['Using the "venv" module', 'Using the "virtualenv" package'], |
|||
score: 10, |
|||
}, |
|||
], |
|||
} |
@ -1,4 +1,3 @@ |
|||
import useShuffleQuestions from './useShuffleQuestions' |
|||
import useTimer from './useTimer' |
|||
|
|||
export { useShuffleQuestions, useTimer } |
|||
export { useTimer } |
@ -1,17 +0,0 @@ |
|||
import { useEffect } from 'react' |
|||
|
|||
import { useQuiz } from '../context/QuizContext' |
|||
import { ScreenTypes } from '../types' |
|||
import { shuffleArray } from '../utils/helpers' |
|||
|
|||
export const useShuffleQuestions = () => { |
|||
const { setQuestions, currentScreen, questions } = useQuiz() |
|||
|
|||
useEffect(() => { |
|||
if (currentScreen === ScreenTypes.QuizDetailsScreen) { |
|||
setQuestions(shuffleArray(questions)) |
|||
} |
|||
}, [currentScreen]) |
|||
} |
|||
|
|||
export default useShuffleQuestions |
@ -0,0 +1 @@ |
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg> |
@ -1,46 +1,52 @@ |
|||
// import original module declarations
|
|||
import 'styled-components' |
|||
|
|||
// and extend them!
|
|||
declare module 'styled-components' { |
|||
export interface DefaultTheme { |
|||
export interface Theme { |
|||
colors: { |
|||
primaryText: '#11052C' // question text color
|
|||
secondaryText: '#2D264B' // answer text color
|
|||
themeColor: '#800080' |
|||
themeGradient: 'linear-gradient(to right,#800080, #FFC0CB)' |
|||
text: '#000000' |
|||
background: '#E5E5E5' |
|||
success: '#12B40E' |
|||
successLight: '#DDFFDC' |
|||
danger: '#FF143E' |
|||
dangerLight: '#FFD7DE' |
|||
lightPink: '#FFD6FF' |
|||
infoText: '#FF783F' // skip button text
|
|||
infoBackground: '#ffb23f26' // skip button background
|
|||
codeBackground: '#F9F9F9' |
|||
disabledCard: '#fbf4ecbc' |
|||
disabledButton: '#e7e8e9' |
|||
white: '#FFFFFF' |
|||
black: '#000000' |
|||
grayText: '#9993A3' |
|||
darkGrayText: '#9fa3a9' |
|||
darkerGray: '#817a8e' |
|||
lightGray: '#eaeaea' |
|||
darkText: '' |
|||
primaryText: string |
|||
secondaryText: string |
|||
themeText: string |
|||
themeColor: string |
|||
themeGradient: string |
|||
background: string |
|||
cardBackground: string |
|||
selectTopicBg: string |
|||
appLogo: string |
|||
buttonText: string |
|||
outlineButtonText: string |
|||
buttonBackground: string |
|||
selectedAnswer: string |
|||
infoText: string |
|||
infoBackground: string |
|||
border: string |
|||
answerBg: string |
|||
disabledCard: string |
|||
disabledButton: string |
|||
success: string |
|||
successLight: string |
|||
danger: string |
|||
dangerLight: string |
|||
white: string |
|||
black: string |
|||
dark: string |
|||
darkGray: string |
|||
darkerGray: string |
|||
} |
|||
fonts: { |
|||
anekMalayalam: 'Anek Malayalam' |
|||
anekMalayalam: string |
|||
} |
|||
shadows: { |
|||
activeButton: '3px 2px 22px 1px rgba(0, 0, 0, 0.24)' |
|||
activeButton: string |
|||
} |
|||
paddings: { |
|||
container: '15px' |
|||
pageTop: '30px' |
|||
container: string |
|||
pageTop: string |
|||
} |
|||
margins: { |
|||
pageTop: '30px' |
|||
} |
|||
pageTop: string |
|||
} |
|||
} |
|||
|
|||
declare module 'styled-components' { |
|||
export interface DefaultTheme extends Theme {} |
|||
} |