mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-01-09 06:04:17 -05:00
feat(client): render all mcq's and add first lecture placeholder (#56582)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@@ -1697,7 +1697,10 @@
|
||||
"intro": ["placeholder"],
|
||||
"blocks": {
|
||||
"efpl": { "title": "0", "intro": [] },
|
||||
"xpmy": { "title": "1", "intro": [] },
|
||||
"lecture-what-is-html": {
|
||||
"title": "What is HTML?",
|
||||
"intro": ["Learn what HTML is in these lecture videos."]
|
||||
},
|
||||
"workshop-cat-photo-app": {
|
||||
"title": "Build a Cat Photo App",
|
||||
"intro": [
|
||||
|
||||
@@ -390,6 +390,7 @@
|
||||
"assignment-not-complete": "Please complete the assignments",
|
||||
"assignments": "Assignments",
|
||||
"question": "Question",
|
||||
"questions": "Questions",
|
||||
"explanation": "Explanation",
|
||||
"solution-link": "Solution Link",
|
||||
"source-code-link": "Source Code Link",
|
||||
@@ -491,8 +492,8 @@
|
||||
"fill-in-the-blank": "Fill in the blank",
|
||||
"blank": "blank",
|
||||
"quiz": {
|
||||
"correct-answer": "Correct",
|
||||
"incorrect-answer": "Incorrect",
|
||||
"correct-answer": "Correct!",
|
||||
"incorrect-answer": "Incorrect.",
|
||||
"unanswered-questions": "The following questions are unanswered: {{ unansweredQuestions }}. You must answer all questions.",
|
||||
"have-n-correct-questions": "You have {{ correctAnswerCount }} out of {{ total }} questions correct."
|
||||
},
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Introduction to What is HTML?
|
||||
block: lecture-what-is-html
|
||||
superBlock: front-end-development
|
||||
---
|
||||
|
||||
## Introduction to What is HTML?
|
||||
|
||||
Learn what HTML is in these lecture videos.
|
||||
@@ -7,74 +7,109 @@ import ChallengeHeading from './challenge-heading';
|
||||
import PrismFormatted from './prism-formatted';
|
||||
|
||||
type MultipleChoiceQuestionsProps = {
|
||||
questions: Question;
|
||||
selectedOption: number | null;
|
||||
isWrongAnswer: boolean;
|
||||
handleOptionChange: (
|
||||
changeEvent: React.ChangeEvent<HTMLInputElement>
|
||||
) => void;
|
||||
questions: Question[];
|
||||
selectedOptions: (number | null)[];
|
||||
handleOptionChange: (questionIndex: number, answerIndex: number) => void;
|
||||
submittedMcqAnswers: (number | null)[];
|
||||
showFeedback: boolean;
|
||||
};
|
||||
|
||||
function removeParagraphTags(text: string): string {
|
||||
return text.replace(/^<p>|<\/p>$/g, '');
|
||||
}
|
||||
|
||||
function MultipleChoiceQuestions({
|
||||
questions: { text, answers },
|
||||
selectedOption,
|
||||
isWrongAnswer,
|
||||
handleOptionChange
|
||||
questions,
|
||||
selectedOptions,
|
||||
handleOptionChange,
|
||||
submittedMcqAnswers,
|
||||
showFeedback
|
||||
}: MultipleChoiceQuestionsProps): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const feedback =
|
||||
selectedOption !== null ? answers[selectedOption].feedback : undefined;
|
||||
|
||||
return (
|
||||
<>
|
||||
<ChallengeHeading heading={t('learn.question')} />
|
||||
<PrismFormatted className={'line-numbers'} text={text} />
|
||||
<div className='video-quiz-options'>
|
||||
{answers.map(({ answer }, index) => (
|
||||
<label
|
||||
className='video-quiz-option-label'
|
||||
key={index}
|
||||
htmlFor={`mc-question-${index}`}
|
||||
>
|
||||
<input
|
||||
name='quiz'
|
||||
checked={selectedOption === index}
|
||||
className='sr-only'
|
||||
onChange={handleOptionChange}
|
||||
type='radio'
|
||||
value={index}
|
||||
id={`mc-question-${index}`}
|
||||
/>{' '}
|
||||
<span className='video-quiz-input-visible'>
|
||||
{selectedOption === index ? (
|
||||
<span className='video-quiz-selected-input' />
|
||||
) : null}
|
||||
</span>
|
||||
<PrismFormatted
|
||||
className={'video-quiz-option'}
|
||||
text={answer.replace(/^<p>|<\/p>$/g, '')}
|
||||
useSpan
|
||||
noAria
|
||||
/>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
{isWrongAnswer && (
|
||||
<>
|
||||
<Spacer size='medium' />
|
||||
<div className='text-center'>
|
||||
{feedback ? (
|
||||
<PrismFormatted
|
||||
className={'multiple-choice-feedback'}
|
||||
text={feedback}
|
||||
/>
|
||||
) : (
|
||||
t('learn.wrong-answer')
|
||||
)}
|
||||
<ChallengeHeading
|
||||
heading={
|
||||
questions.length > 1 ? t('learn.questions') : t('learn.question')
|
||||
}
|
||||
/>
|
||||
{questions.map((question, questionIndex) => (
|
||||
<div key={questionIndex}>
|
||||
<PrismFormatted className={'line-numbers'} text={question.text} />
|
||||
<div className='video-quiz-options'>
|
||||
{question.answers.map(({ answer }, answerIndex) => {
|
||||
const isSubmittedAnswer =
|
||||
submittedMcqAnswers[questionIndex] === answerIndex;
|
||||
const feedback =
|
||||
questions[questionIndex].answers[answerIndex].feedback;
|
||||
const isCorrect =
|
||||
submittedMcqAnswers[questionIndex] ===
|
||||
// -1 because the solution is 1-indexed
|
||||
questions[questionIndex].solution - 1;
|
||||
|
||||
return (
|
||||
<React.Fragment key={answerIndex}>
|
||||
<label
|
||||
className={`video-quiz-option-label
|
||||
${showFeedback && isSubmittedAnswer ? 'mcq-hide-border' : ''}
|
||||
${showFeedback && isSubmittedAnswer ? (isCorrect ? 'mcq-correct-border' : 'mcq-incorrect-border') : ''}`}
|
||||
htmlFor={`mc-question-${questionIndex}-answer-${answerIndex}`}
|
||||
>
|
||||
<input
|
||||
name='quiz'
|
||||
checked={selectedOptions[questionIndex] === answerIndex}
|
||||
className='sr-only'
|
||||
onChange={() =>
|
||||
handleOptionChange(questionIndex, answerIndex)
|
||||
}
|
||||
type='radio'
|
||||
value={answerIndex}
|
||||
id={`mc-question-${questionIndex}-answer-${answerIndex}`}
|
||||
/>{' '}
|
||||
<span className='video-quiz-input-visible'>
|
||||
{selectedOptions[questionIndex] === answerIndex ? (
|
||||
<span className='video-quiz-selected-input' />
|
||||
) : null}
|
||||
</span>
|
||||
<PrismFormatted
|
||||
className={'video-quiz-option'}
|
||||
text={removeParagraphTags(answer)}
|
||||
useSpan
|
||||
noAria
|
||||
/>
|
||||
</label>
|
||||
{showFeedback && isSubmittedAnswer && (
|
||||
<div
|
||||
className={`video-quiz-option-label mcq-feedback ${isCorrect ? 'mcq-correct' : 'mcq-incorrect'}`}
|
||||
>
|
||||
{isCorrect
|
||||
? t('learn.quiz.correct-answer')
|
||||
: t('learn.quiz.incorrect-answer')}
|
||||
{feedback && (
|
||||
<>
|
||||
<span> </span>
|
||||
<PrismFormatted
|
||||
className={
|
||||
isCorrect
|
||||
? 'mcq-prism-correct'
|
||||
: 'mcq-prism-incorrect'
|
||||
}
|
||||
text={removeParagraphTags(feedback)}
|
||||
useSpan
|
||||
noAria
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<Spacer size='medium' />
|
||||
</div>
|
||||
))}
|
||||
<Spacer size='medium' />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -9,6 +9,7 @@ import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import type { Dispatch } from 'redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { Container, Col, Row, Button } from '@freecodecamp/ui';
|
||||
import ShortcutsModal from '../components/shortcuts-modal';
|
||||
|
||||
@@ -78,9 +79,9 @@ interface ShowOdinProps {
|
||||
interface ShowOdinState {
|
||||
subtitles: string;
|
||||
downloadURL: string | null;
|
||||
selectedOption: number | null;
|
||||
answer: number;
|
||||
isWrongAnswer: boolean;
|
||||
selectedMcqOptions: (number | null)[];
|
||||
submittedMcqAnswers: (number | null)[];
|
||||
showFeedback: boolean;
|
||||
assignmentsCompleted: number;
|
||||
allAssignmentsCompleted: boolean;
|
||||
videoIsLoaded: boolean;
|
||||
@@ -94,14 +95,23 @@ class ShowOdin extends Component<ShowOdinProps, ShowOdinState> {
|
||||
|
||||
constructor(props: ShowOdinProps) {
|
||||
super(props);
|
||||
|
||||
const {
|
||||
data: {
|
||||
challengeNode: {
|
||||
challenge: { assignments, questions }
|
||||
}
|
||||
}
|
||||
} = this.props;
|
||||
|
||||
this.state = {
|
||||
subtitles: '',
|
||||
downloadURL: null,
|
||||
selectedOption: null,
|
||||
answer: 1,
|
||||
isWrongAnswer: false,
|
||||
selectedMcqOptions: questions.map(() => null),
|
||||
submittedMcqAnswers: questions.map(() => null),
|
||||
showFeedback: false,
|
||||
assignmentsCompleted: 0,
|
||||
allAssignmentsCompleted: false,
|
||||
allAssignmentsCompleted: assignments.length == 0,
|
||||
videoIsLoaded: false,
|
||||
isScenePlaying: false
|
||||
};
|
||||
@@ -166,34 +176,43 @@ class ShowOdin extends Component<ShowOdinProps, ShowOdinState> {
|
||||
}
|
||||
}
|
||||
|
||||
handleSubmit(
|
||||
solution: number,
|
||||
openCompletionModal: () => void,
|
||||
assignments: string[]
|
||||
) {
|
||||
const hasAssignments = assignments.length > 0;
|
||||
const completed = this.state.allAssignmentsCompleted;
|
||||
const isCorrect = solution - 1 === this.state.selectedOption;
|
||||
handleSubmit = () => {
|
||||
const {
|
||||
data: {
|
||||
challengeNode: {
|
||||
challenge: { questions }
|
||||
}
|
||||
},
|
||||
openCompletionModal
|
||||
} = this.props;
|
||||
|
||||
if (isCorrect) {
|
||||
this.setState({
|
||||
isWrongAnswer: false
|
||||
});
|
||||
if (!hasAssignments || completed) openCompletionModal();
|
||||
} else {
|
||||
this.setState({
|
||||
isWrongAnswer: true
|
||||
});
|
||||
}
|
||||
}
|
||||
// subract 1 because the solutions are 1-indexed
|
||||
const mcqSolutions = questions.map(question => question.solution - 1);
|
||||
|
||||
handleOptionChange = (
|
||||
changeEvent: React.ChangeEvent<HTMLInputElement>
|
||||
): void => {
|
||||
this.setState({
|
||||
isWrongAnswer: false,
|
||||
selectedOption: parseInt(changeEvent.target.value, 10)
|
||||
submittedMcqAnswers: this.state.selectedMcqOptions,
|
||||
showFeedback: true
|
||||
});
|
||||
|
||||
const allMcqAnswersCorrect = isEqual(
|
||||
mcqSolutions,
|
||||
this.state.selectedMcqOptions
|
||||
);
|
||||
|
||||
if (this.state.allAssignmentsCompleted && allMcqAnswersCorrect) {
|
||||
openCompletionModal();
|
||||
}
|
||||
};
|
||||
|
||||
handleMcqOptionChange = (
|
||||
questionIndex: number,
|
||||
answerIndex: number
|
||||
): void => {
|
||||
this.setState(state => ({
|
||||
selectedMcqOptions: state.selectedMcqOptions.map((option, index) =>
|
||||
index === questionIndex ? answerIndex : option
|
||||
)
|
||||
}));
|
||||
};
|
||||
|
||||
handleAssignmentChange = (
|
||||
@@ -245,7 +264,6 @@ class ShowOdin extends Component<ShowOdinProps, ShowOdinState> {
|
||||
}
|
||||
}
|
||||
},
|
||||
openCompletionModal,
|
||||
openHelpModal,
|
||||
pageContext: {
|
||||
challengeMeta: { nextChallengePath, prevChallengePath }
|
||||
@@ -254,18 +272,13 @@ class ShowOdin extends Component<ShowOdinProps, ShowOdinState> {
|
||||
isChallengeCompleted
|
||||
} = this.props;
|
||||
|
||||
const question = questions[0];
|
||||
const { solution } = question;
|
||||
|
||||
const blockNameTitle = `${t(
|
||||
`intro:${superBlock}.blocks.${block}.title`
|
||||
)} - ${title}`;
|
||||
|
||||
return (
|
||||
<Hotkeys
|
||||
executeChallenge={() => {
|
||||
this.handleSubmit(solution, openCompletionModal, assignments);
|
||||
}}
|
||||
executeChallenge={this.handleSubmit}
|
||||
containerRef={this.container}
|
||||
nextChallengePath={nextChallengePath}
|
||||
prevChallengePath={prevChallengePath}
|
||||
@@ -331,10 +344,11 @@ class ShowOdin extends Component<ShowOdinProps, ShowOdinState> {
|
||||
)}
|
||||
|
||||
<MultipleChoiceQuestions
|
||||
questions={question}
|
||||
selectedOption={this.state.selectedOption}
|
||||
isWrongAnswer={this.state.isWrongAnswer}
|
||||
handleOptionChange={this.handleOptionChange}
|
||||
questions={questions}
|
||||
selectedOptions={this.state.selectedMcqOptions}
|
||||
handleOptionChange={this.handleMcqOptionChange}
|
||||
submittedMcqAnswers={this.state.submittedMcqAnswers}
|
||||
showFeedback={this.state.showFeedback}
|
||||
/>
|
||||
</ObserveKeys>
|
||||
|
||||
@@ -348,13 +362,7 @@ class ShowOdin extends Component<ShowOdinProps, ShowOdinState> {
|
||||
block={true}
|
||||
size='medium'
|
||||
variant='primary'
|
||||
onClick={() =>
|
||||
this.handleSubmit(
|
||||
solution,
|
||||
openCompletionModal,
|
||||
assignments
|
||||
)
|
||||
}
|
||||
onClick={this.handleSubmit}
|
||||
>
|
||||
{t('buttons.check-answer')}
|
||||
</Button>
|
||||
|
||||
@@ -115,6 +115,36 @@ input:focus-visible + .video-quiz-input-visible {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.multiple-choice-feedback p {
|
||||
margin-bottom: 0;
|
||||
.mcq-correct-border {
|
||||
border-left-color: var(--success-background);
|
||||
}
|
||||
|
||||
.mcq-incorrect-border {
|
||||
border-left-color: var(--danger-background);
|
||||
}
|
||||
|
||||
.mcq-correct {
|
||||
color: var(--success-color);
|
||||
border-left-color: var(--success-background);
|
||||
}
|
||||
|
||||
.mcq-incorrect {
|
||||
color: var(--danger-color);
|
||||
border-left-color: var(--danger-background);
|
||||
}
|
||||
|
||||
.mcq-hide-border {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.mcq-feedback {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.mcq-prism-correct code {
|
||||
color: var(--success-color);
|
||||
}
|
||||
|
||||
.mcq-prism-incorrect code {
|
||||
color: var(--danger-color);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import type { Dispatch } from 'redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { Container, Col, Row, Button } from '@freecodecamp/ui';
|
||||
|
||||
// Local Utilities
|
||||
@@ -75,9 +76,9 @@ interface ShowVideoProps {
|
||||
interface ShowVideoState {
|
||||
subtitles: string;
|
||||
downloadURL: string | null;
|
||||
selectedOption: number | null;
|
||||
answer: number;
|
||||
showWrong: boolean;
|
||||
selectedMcqOptions: (number | null)[];
|
||||
submittedMcqAnswers: (number | null)[];
|
||||
showFeedback: boolean;
|
||||
videoIsLoaded: boolean;
|
||||
}
|
||||
|
||||
@@ -88,16 +89,23 @@ class ShowVideo extends Component<ShowVideoProps, ShowVideoState> {
|
||||
|
||||
constructor(props: ShowVideoProps) {
|
||||
super(props);
|
||||
|
||||
const {
|
||||
data: {
|
||||
challengeNode: {
|
||||
challenge: { questions }
|
||||
}
|
||||
}
|
||||
} = this.props;
|
||||
|
||||
this.state = {
|
||||
subtitles: '',
|
||||
downloadURL: null,
|
||||
selectedOption: null,
|
||||
answer: 1,
|
||||
showWrong: false,
|
||||
selectedMcqOptions: questions.map(() => null),
|
||||
submittedMcqAnswers: questions.map(() => null),
|
||||
showFeedback: false,
|
||||
videoIsLoaded: false
|
||||
};
|
||||
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
@@ -157,26 +165,43 @@ class ShowVideo extends Component<ShowVideoProps, ShowVideoState> {
|
||||
}
|
||||
}
|
||||
|
||||
handleSubmit(solution: number, openCompletionModal: () => void) {
|
||||
if (solution - 1 === this.state.selectedOption) {
|
||||
this.setState({
|
||||
showWrong: false
|
||||
});
|
||||
openCompletionModal();
|
||||
} else {
|
||||
this.setState({
|
||||
showWrong: true
|
||||
});
|
||||
}
|
||||
}
|
||||
handleSubmit = () => {
|
||||
const {
|
||||
data: {
|
||||
challengeNode: {
|
||||
challenge: { questions }
|
||||
}
|
||||
},
|
||||
openCompletionModal
|
||||
} = this.props;
|
||||
|
||||
// subract 1 because the solutions are 1-indexed
|
||||
const mcqSolutions = questions.map(question => question.solution - 1);
|
||||
|
||||
handleOptionChange = (
|
||||
changeEvent: React.ChangeEvent<HTMLInputElement>
|
||||
): void => {
|
||||
this.setState({
|
||||
showWrong: false,
|
||||
selectedOption: parseInt(changeEvent.target.value, 10)
|
||||
submittedMcqAnswers: this.state.selectedMcqOptions,
|
||||
showFeedback: true
|
||||
});
|
||||
|
||||
const allMcqAnswersCorrect = isEqual(
|
||||
mcqSolutions,
|
||||
this.state.selectedMcqOptions
|
||||
);
|
||||
|
||||
if (allMcqAnswersCorrect) {
|
||||
openCompletionModal();
|
||||
}
|
||||
};
|
||||
|
||||
handleMcqOptionChange = (
|
||||
questionIndex: number,
|
||||
answerIndex: number
|
||||
): void => {
|
||||
this.setState(state => ({
|
||||
selectedMcqOptions: state.selectedMcqOptions.map((option, index) =>
|
||||
index === questionIndex ? answerIndex : option
|
||||
)
|
||||
}));
|
||||
};
|
||||
|
||||
onVideoLoad = () => {
|
||||
@@ -204,7 +229,6 @@ class ShowVideo extends Component<ShowVideoProps, ShowVideoState> {
|
||||
}
|
||||
}
|
||||
},
|
||||
openCompletionModal,
|
||||
openHelpModal,
|
||||
pageContext: {
|
||||
challengeMeta: { nextChallengePath, prevChallengePath }
|
||||
@@ -213,18 +237,13 @@ class ShowVideo extends Component<ShowVideoProps, ShowVideoState> {
|
||||
isChallengeCompleted
|
||||
} = this.props;
|
||||
|
||||
const question = questions[0];
|
||||
const { solution } = question;
|
||||
|
||||
const blockNameTitle = `${t(
|
||||
`intro:${superBlock}.blocks.${block}.title`
|
||||
)} - ${title}`;
|
||||
|
||||
return (
|
||||
<Hotkeys
|
||||
executeChallenge={() => {
|
||||
this.handleSubmit(solution, openCompletionModal);
|
||||
}}
|
||||
executeChallenge={this.handleSubmit}
|
||||
containerRef={this.container}
|
||||
nextChallengePath={nextChallengePath}
|
||||
prevChallengePath={prevChallengePath}
|
||||
@@ -260,19 +279,18 @@ class ShowVideo extends Component<ShowVideoProps, ShowVideoState> {
|
||||
<ChallengeDescription description={description} />
|
||||
<ObserveKeys>
|
||||
<MultipleChoiceQuestions
|
||||
questions={question}
|
||||
selectedOption={this.state.selectedOption}
|
||||
isWrongAnswer={this.state.showWrong}
|
||||
handleOptionChange={this.handleOptionChange}
|
||||
questions={questions}
|
||||
selectedOptions={this.state.selectedMcqOptions}
|
||||
handleOptionChange={this.handleMcqOptionChange}
|
||||
submittedMcqAnswers={this.state.submittedMcqAnswers}
|
||||
showFeedback={this.state.showFeedback}
|
||||
/>
|
||||
</ObserveKeys>
|
||||
<Spacer size='medium' />
|
||||
<Button
|
||||
block={true}
|
||||
variant='primary'
|
||||
onClick={() =>
|
||||
this.handleSubmit(solution, openCompletionModal)
|
||||
}
|
||||
onClick={this.handleSubmit}
|
||||
>
|
||||
{t('buttons.check-answer')}
|
||||
</Button>
|
||||
|
||||
10
curriculum/challenges/_meta/lecture-what-is-html/meta.json
Normal file
10
curriculum/challenges/_meta/lecture-what-is-html/meta.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "What is HTML?",
|
||||
"isUpcomingChange": true,
|
||||
"dashedName": "lecture-what-is-html",
|
||||
"order": 1,
|
||||
"superBlock": "front-end-development",
|
||||
"challengeOrder": [{ "id": "66f6db08d55022680a3cfbc9", "title": "What is HTML and what role does it play on the web?" }],
|
||||
"helpCategory": "HTML-CSS",
|
||||
"blockType": "lecture"
|
||||
}
|
||||
@@ -10,5 +10,13 @@
|
||||
{
|
||||
"id": "64afc37bf3b37856e035b85e",
|
||||
"title": "Upcoming Python Project"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "6703d8f42ebd112db6f7788a",
|
||||
"title": "Video Layout"
|
||||
},
|
||||
{
|
||||
"id": "6703d9382ebd112db6f7788b",
|
||||
"title": "Odin Layout"
|
||||
}
|
||||
]}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
---
|
||||
id: 6703d8f42ebd112db6f7788a
|
||||
title: Video Layout
|
||||
challengeType: 11
|
||||
videoId: nVAaxZ34khk
|
||||
dashedName: video-layout
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Watch the video and answer the questions below.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question 1?
|
||||
|
||||
## --answers--
|
||||
|
||||
`answer 1`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 2`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 3`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 4`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
|
||||
## --text--
|
||||
|
||||
Question 2?
|
||||
|
||||
## --answers--
|
||||
|
||||
`answer 1`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 2`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 3`
|
||||
|
||||
---
|
||||
|
||||
`answer 4`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
|
||||
## --text--
|
||||
|
||||
Question 3?
|
||||
|
||||
## --answers--
|
||||
|
||||
`answer 1`
|
||||
|
||||
---
|
||||
|
||||
`answer 2`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 3`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 4`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
@@ -0,0 +1,133 @@
|
||||
---
|
||||
id: 6703d9382ebd112db6f7788b
|
||||
title: Odin Layout
|
||||
challengeType: 19
|
||||
videoId: nVAaxZ34khk
|
||||
dashedName: odin-layout
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Watch the video and answer the questions below.
|
||||
|
||||
# --assignment--
|
||||
|
||||
assignment 1
|
||||
|
||||
---
|
||||
|
||||
assignemnt 2
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Question 1?
|
||||
|
||||
## --answers--
|
||||
|
||||
`answer 1`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Here's some `feedback`.
|
||||
|
||||
---
|
||||
|
||||
`answer 2`
|
||||
|
||||
### --feedback--
|
||||
|
||||
More JS feedback:
|
||||
|
||||
```js
|
||||
console.log('incorrect');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
`answer 3`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 4`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
|
||||
## --text--
|
||||
|
||||
Question 2?
|
||||
|
||||
## --answers--
|
||||
|
||||
`answer 1`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 2`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 3`
|
||||
|
||||
---
|
||||
|
||||
`answer 4`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
|
||||
## --text--
|
||||
|
||||
Question 3?
|
||||
|
||||
## --answers--
|
||||
|
||||
`answer 1`
|
||||
|
||||
---
|
||||
|
||||
`answer 2`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 3`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
---
|
||||
|
||||
`answer 4`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Feedback.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
@@ -0,0 +1,121 @@
|
||||
---
|
||||
id: 66f6db08d55022680a3cfbc9
|
||||
title: What Is HTML and What Role Does It Play on the Web?
|
||||
challengeType: 11
|
||||
videoId: nVAaxZ34khk
|
||||
dashedName: what-is-html-and-what-role-does-it-play-on-the-web
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Watch the video and answer the questions below.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What does HTML stand for?
|
||||
|
||||
## --answers--
|
||||
|
||||
HyperText Maker Language
|
||||
|
||||
### --feedback--
|
||||
|
||||
Focus on the term for describing the structure and presentation of web pages.
|
||||
|
||||
---
|
||||
|
||||
HyperText Marker Language
|
||||
|
||||
### --feedback--
|
||||
|
||||
Focus on the term for describing the structure and presentation of web pages.
|
||||
|
||||
---
|
||||
|
||||
HyperText Markdown Language
|
||||
|
||||
### --feedback--
|
||||
|
||||
Focus on the term for describing the structure and presentation of web pages.
|
||||
|
||||
---
|
||||
|
||||
HyperText Markup Language
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is the correct syntax for a closing tag?
|
||||
|
||||
## --answers--
|
||||
|
||||
`<;p>`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Think about the additional symbol for defining tags apart from left-angle and right-angle brackets.
|
||||
|
||||
---
|
||||
|
||||
`<p>`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Think about the additional symbol for defining tags apart from left-angle and right-angle brackets.
|
||||
|
||||
---
|
||||
|
||||
`</p>`
|
||||
|
||||
---
|
||||
|
||||
`<///p/>`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Think about the additional symbol for defining tags apart from left-angle and right-angle brackets.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is a valid attribute used inside image elements?
|
||||
|
||||
## --answers--
|
||||
|
||||
`src`
|
||||
|
||||
---
|
||||
|
||||
`bold`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Consider what you often use inside an opening tag to supply additional information to the element.
|
||||
|
||||
---
|
||||
|
||||
`closing`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Consider what you often use inside an opening tag to supply additional information to the element.
|
||||
|
||||
---
|
||||
|
||||
`div`
|
||||
|
||||
### --feedback--
|
||||
|
||||
Consider what you often use inside an opening tag to supply additional information to the element.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
Reference in New Issue
Block a user