| Tekijä | SHA1 | Viesti | Päivämäärä |
|---|---|---|---|
|
|
a0d40d5793 | isCheckbox prop to RadioButton component and replaced it with Ion checkbox | 3 vuotta sitten |
|
|
7204950b9d | created custom radio button component | 3 vuotta sitten |
| @@ -39,7 +39,6 @@ import Celebration from './pages/celebration/Celebration'; | |||||
| import SignaturePhoto from './pages/joiningLetter/SignaturePhoto'; | import SignaturePhoto from './pages/joiningLetter/SignaturePhoto'; | ||||
| import TechinicalInterviewResults from './pages/technicalInterview/TechinicalInterviewResults'; | import TechinicalInterviewResults from './pages/technicalInterview/TechinicalInterviewResults'; | ||||
| setupIonicReact(); | setupIonicReact(); | ||||
| const App: React.FC = () => ( | const App: React.FC = () => ( | ||||
| @@ -0,0 +1,30 @@ | |||||
| .radioHolder { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| min-width: 33.5rem; | |||||
| margin: 0 auto; | |||||
| --background: white; | |||||
| border: 1px solid #DBDBDB; | |||||
| border-radius: 25px; | |||||
| height: 4rem; | |||||
| .icon { | |||||
| width: 2rem; | |||||
| height: 2rem; | |||||
| margin-left: 1.5rem; | |||||
| } | |||||
| .option { | |||||
| margin-left: 2rem; | |||||
| color: #626262; | |||||
| font-size: 1.2rem; | |||||
| font-weight: 200; | |||||
| } | |||||
| &.highlighted { | |||||
| box-shadow: 0px 0px 10px #00000029; | |||||
| .icon { | |||||
| color: var(--primary-button-color); | |||||
| transform: scale(1.1); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,39 @@ | |||||
| import styles from "./RadioButton.module.scss"; | |||||
| import { radioButtonOff, radioButtonOn, checkmarkCircle } from "ionicons/icons"; | |||||
| import { IonIcon } from "@ionic/react"; | |||||
| import { useEffect, useState } from "react"; | |||||
| interface OwnProps { | |||||
| option: string; | |||||
| isChecked: boolean; | |||||
| isHighlighted?: boolean; | |||||
| isCheckBox?: boolean; | |||||
| } | |||||
| const RadioButton: React.FC<OwnProps> = (props) => { | |||||
| const [icon, setIcon] = useState(radioButtonOff); | |||||
| useEffect(() => { | |||||
| if (props.isChecked) { | |||||
| setIcon(radioButtonOn); | |||||
| if (props.isCheckBox) { | |||||
| setIcon(checkmarkCircle); | |||||
| } | |||||
| } else { | |||||
| setIcon(radioButtonOff); | |||||
| } | |||||
| }, [props.isChecked]); | |||||
| return ( | |||||
| <div className={styles.radioContent}> | |||||
| <div className={styles.radioHolder + " " + (props.isChecked ? styles.highlighted : "")}> | |||||
| <IonIcon icon={icon} className={styles.icon} /> | |||||
| <div className={styles.option}>{props.option}</div> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| } | |||||
| export default RadioButton; | |||||
| @@ -12,7 +12,7 @@ const QUIZ_DETAILS: QuizDetails[] = [ | |||||
| ], | ], | ||||
| answer: ["System.out.println('Hello, how are you?');"], | answer: ["System.out.println('Hello, how are you?');"], | ||||
| result: false, | result: false, | ||||
| timeLimit: 5, | |||||
| timeLimit: 60, | |||||
| type: OptionType.SINGLE_SELECT | type: OptionType.SINGLE_SELECT | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -25,7 +25,7 @@ const QUIZ_DETAILS: QuizDetails[] = [ | |||||
| ], | ], | ||||
| answer: ["alert('Hello World');"], | answer: ["alert('Hello World');"], | ||||
| result: false, | result: false, | ||||
| timeLimit: 10, | |||||
| timeLimit: 30, | |||||
| type: OptionType.SINGLE_SELECT | type: OptionType.SINGLE_SELECT | ||||
| }, | }, | ||||
| @@ -39,7 +39,7 @@ const QUIZ_DETAILS: QuizDetails[] = [ | |||||
| ], | ], | ||||
| answer: ["B", "C"], | answer: ["B", "C"], | ||||
| result: false, | result: false, | ||||
| timeLimit: 60, | |||||
| timeLimit: 120, | |||||
| type: OptionType.MULTI_SELECT | type: OptionType.MULTI_SELECT | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -47,7 +47,7 @@ const QUIZ_DETAILS: QuizDetails[] = [ | |||||
| options: [], | options: [], | ||||
| answer: ["single threaded"], | answer: ["single threaded"], | ||||
| result: false, | result: false, | ||||
| timeLimit: 60, | |||||
| timeLimit: 120, | |||||
| type: OptionType.INPUT_TEXT | type: OptionType.INPUT_TEXT | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -60,9 +60,22 @@ const QUIZ_DETAILS: QuizDetails[] = [ | |||||
| ], | ], | ||||
| answer: ["B", "C"], | answer: ["B", "C"], | ||||
| result: false, | result: false, | ||||
| timeLimit: 35, | |||||
| timeLimit: 60, | |||||
| type: OptionType.MULTI_SELECT | type: OptionType.MULTI_SELECT | ||||
| }, | }, | ||||
| { | |||||
| question: "is javascript", | |||||
| options: [ | |||||
| "A", | |||||
| "B", | |||||
| "C", | |||||
| "D" | |||||
| ], | |||||
| answer: ["B", "C"], | |||||
| result: false, | |||||
| timeLimit: 60, | |||||
| type: OptionType.MULTI_SELECT | |||||
| } | |||||
| ]; | ]; | ||||
| export default QUIZ_DETAILS; | export default QUIZ_DETAILS; | ||||
| @@ -18,7 +18,7 @@ const PreliminaryRoundResults: React.FC = () => { | |||||
| <IonIcon src={goodJobIcon} /> | <IonIcon src={goodJobIcon} /> | ||||
| <div className={styles.score}> | <div className={styles.score}> | ||||
| <h5>You have scored</h5> | <h5>You have scored</h5> | ||||
| <h5 className={styles.result}>{(parseInt(localStorage.getItem("answer")!) / Quiz_Details.length) * 100}%</h5> | |||||
| <h5 className={styles.result}>{((parseInt(localStorage.getItem("answer")!) / Quiz_Details.length) * 100).toFixed(2)}%</h5> | |||||
| </div> | </div> | ||||
| <p className={styles.description}> | <p className={styles.description}> | ||||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. | ||||
| @@ -3,6 +3,7 @@ import { useEffect, useRef, useState } from 'react'; | |||||
| import { Link } from 'react-router-dom'; | import { Link } from 'react-router-dom'; | ||||
| import styles from './Options.module.scss'; | import styles from './Options.module.scss'; | ||||
| import { OptionType } from '../../models/QuizDetails' | import { OptionType } from '../../models/QuizDetails' | ||||
| import RadioButton from '../../components/RadioButton/RadioButton'; | |||||
| interface OwnProps { | interface OwnProps { | ||||
| options: string[] | undefined; | options: string[] | undefined; | ||||
| @@ -22,10 +23,11 @@ const Options: React.FC<OwnProps> = (props) => { | |||||
| const inputRef = useRef<HTMLTextAreaElement>(null); | const inputRef = useRef<HTMLTextAreaElement>(null); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| setSelected(undefined); | |||||
| setSelected(""); | |||||
| setSelectedOptions([]); | setSelectedOptions([]); | ||||
| setTextInput(""); | setTextInput(""); | ||||
| }, [props.options]); | |||||
| }, [props.questionNumber]); | |||||
| const selectChecked = (option: string) => { | const selectChecked = (option: string) => { | ||||
| let newOption: string[] = []; | let newOption: string[] = []; | ||||
| @@ -43,7 +45,8 @@ const Options: React.FC<OwnProps> = (props) => { | |||||
| setAnswers(answers + 1); | setAnswers(answers + 1); | ||||
| } | } | ||||
| } else if (props.type === "multiSelect") { | } else if (props.type === "multiSelect") { | ||||
| if (props.answer.length === selectedOptions.length && props.answer.sort().join(',') === selectedOptions.sort().join(',')) { | |||||
| if (props.answer.length === selectedOptions.length && | |||||
| props.answer.sort().join(',') === selectedOptions.sort().join(',')) { | |||||
| setAnswers(answers + 1); | setAnswers(answers + 1); | ||||
| } | } | ||||
| @@ -55,36 +58,29 @@ const Options: React.FC<OwnProps> = (props) => { | |||||
| } | } | ||||
| const handleInput = () => { | const handleInput = () => { | ||||
| setTextInput(inputRef.current?.value!) | |||||
| setTextInput(inputRef.current?.value!); | |||||
| } | } | ||||
| const setAnswer = () => { | const setAnswer = () => { | ||||
| localStorage.setItem("answer", answers.toString()); | localStorage.setItem("answer", answers.toString()); | ||||
| } | } | ||||
| const options = props.options!.map((option, key) => { | const options = props.options!.map((option, key) => { | ||||
| return ( | return ( | ||||
| <IonItem lines='none' key={key} className={(option === selected) ? styles.highlighted : ""}> | |||||
| <IonLabel>{option}</IonLabel> | |||||
| <IonRadio mode='md' slot="start" value={option} /> | |||||
| </IonItem> | |||||
| <div key={key} onClick={() => setSelected(option)}> | |||||
| <RadioButton option={option} isChecked={selected === option} /> | |||||
| </div> | |||||
| ); | ); | ||||
| }); | }); | ||||
| const MultiSelectOptions = props.options!.map((option, key) => { | const MultiSelectOptions = props.options!.map((option, key) => { | ||||
| return ( | return ( | ||||
| <IonItem lines='none' key={key} className={(selectedOptions.includes(option)) ? styles.highlighted : ""}> | |||||
| <div className={(selectedOptions.includes(option)) ? (styles.activeCheck + " " + styles.checkBoxHolder) : styles.checkBoxHolder}> | |||||
| <IonCheckbox | |||||
| slot="start" | |||||
| mode='ios' | |||||
| className={styles.checkBox} | |||||
| onIonChange={e => selectChecked(option)} /> | |||||
| </div> | |||||
| <IonLabel className={styles.multiSelectLabel}>{option}</IonLabel> | |||||
| </IonItem> | |||||
| <div key={key} onClick={() => selectChecked(option)}> | |||||
| <RadioButton | |||||
| isCheckBox={true} | |||||
| option={option} | |||||
| isChecked={selectedOptions.includes(option)} /> | |||||
| </div> | |||||
| ); | ); | ||||
| }); | }); | ||||
| @@ -92,9 +88,9 @@ const Options: React.FC<OwnProps> = (props) => { | |||||
| <div className={styles.optionHolder}> | <div className={styles.optionHolder}> | ||||
| <IonList> | <IonList> | ||||
| {props.type === "singleSelect" && | {props.type === "singleSelect" && | ||||
| <IonRadioGroup onIonChange={e => setSelected(e.detail.value)} allowEmptySelection={true} className={styles.options}> | |||||
| <div className={styles.options}> | |||||
| {options} | {options} | ||||
| </IonRadioGroup> | |||||
| </div> | |||||
| } | } | ||||
| {props.type === "multiSelect" && | {props.type === "multiSelect" && | ||||
| <div className={styles.options}> | <div className={styles.options}> | ||||