diff --git a/client/gatsby-node.js b/client/gatsby-node.js index 1b5c2e8180b..a199ed413b5 100644 --- a/client/gatsby-node.js +++ b/client/gatsby-node.js @@ -295,22 +295,56 @@ exports.createSchemaCustomization = ({ actions }) => { challenge: Challenge } type Challenge { - blockType: String - blockLayout: String - challengeFiles: [FileContents] - chapter: String - explanation: String - hooks: Hooks - notes: String - url: String assignments: [String] - prerequisites: [PrerequisiteChallenge] + bilibiliIds: BilibiliIds + block: String + blockId: String + blockLayout: String + blockType: String + certification: String + challengeFiles: [FileContents] + challengeOrder: Int + challengeType: Int + chapter: String + dashedName: String + demoType: String + description: String + disableLoopProtectPreview: Boolean + disableLoopProtectTests: Boolean + explanation: String + fillInTheBlank: FillInTheBlank + forumTopicId: Int + hasEditableBoundaries: Boolean + helpCategory: String + hooks: Hooks + id: String + instructions: String + isComingSoon: Boolean + isLastChallengeInBlock: Boolean + isPrivate: Boolean module: String msTrophyId: String - fillInTheBlank: FillInTheBlank - scene: Scene - transcript: String + notes: String + order: Int + prerequisites: [PrerequisiteChallenge] + questions: [Question] quizzes: [Quiz] + required: [RequiredResource] + scene: Scene + solutions: [[FileContents]] + suborder: Int + superBlock: String + superOrder: Int + template: String + tests: [Test] + title: String + transcript: String + translationPending: Boolean + url: String + usesMultifileEditor: Boolean + videoId: String + videoLocaleIds: VideoLocaleIds + videoUrl: String } type FileContents { fileKey: String @@ -320,11 +354,53 @@ exports.createSchemaCustomization = ({ actions }) => { head: String tail: String editableRegionBoundaries: [Int] + path: String + error: String + seed: String + id: String + history: [String] } type PrerequisiteChallenge { id: String title: String } + type VideoLocaleIds { + espanol: String + italian: String + portuguese: String + } + type BilibiliIds { + aid: Int + bvid: String + cid: Int + } + type Question { + text: String + answers: [Answer] + solution: Int + } + type Answer { + answer: String + feedback: String + } + type RequiredResource { + link: String + raw: Boolean + src: String + crossDomain: Boolean + } + type Hooks { + beforeAll: String + beforeEach: String + afterAll: String + afterEach: String + } + type Test { + id: String + text: String + testString: String + title: String + } type FillInTheBlank { sentence: String blanks: [Blank] diff --git a/client/src/pages/learn.tsx b/client/src/pages/learn.tsx index de07a4ed630..fb17832fcb1 100644 --- a/client/src/pages/learn.tsx +++ b/client/src/pages/learn.tsx @@ -57,7 +57,7 @@ interface LearnPageProps { challenge: { fields: Slug; }; - }; + } | null; }; } @@ -67,18 +67,14 @@ function LearnPage({ isSignedIn, fetchState: { pending, complete }, user, - data: { - challengeNode: { - challenge: { - fields: { slug } - } - } - } + data: { challengeNode } }: LearnPageProps) { const { name, completedChallengeCount, isDonating } = user ?? EMPTY_USER; const { t } = useTranslation(); + const slug = challengeNode?.challenge?.fields?.slug || ''; + const onLearnDonationAlertClick = () => { callGA({ event: 'donation_related', diff --git a/client/src/redux/prop-types.ts b/client/src/redux/prop-types.ts index e7e076561a8..e720bf1bf84 100644 --- a/client/src/redux/prop-types.ts +++ b/client/src/redux/prop-types.ts @@ -188,7 +188,6 @@ export type ChallengeNode = { fields: Fields; fillInTheBlank: FillInTheBlank; forumTopicId: number; - guideUrl: string; head: string[]; hasEditableBoundaries: boolean; helpCategory: string; diff --git a/client/src/templates/Introduction/components/super-block-intro.tsx b/client/src/templates/Introduction/components/super-block-intro.tsx index 5c329a3e542..d2419b1a62b 100644 --- a/client/src/templates/Introduction/components/super-block-intro.tsx +++ b/client/src/templates/Introduction/components/super-block-intro.tsx @@ -20,7 +20,7 @@ interface SuperBlockIntroQueryData { slug: string; }; }; - }; + } | null; } type ReduxProps = ConnectedProps; @@ -115,13 +115,7 @@ function SuperBlockIntro({ note: string; }; - const { - challengeNode: { - challenge: { - fields: { slug: firstChallengeSlug } - } - } - } = useStaticQuery(graphql` + const { challengeNode } = useStaticQuery(graphql` query SuperBlockIntroQuery { challengeNode( challenge: { @@ -139,6 +133,7 @@ function SuperBlockIntro({ } `); + const firstChallengeSlug = challengeNode?.challenge?.fields?.slug || ''; const { title: i18nSuperBlock, intro: superBlockIntroText, diff --git a/curriculum/schema/challenge-schema.js b/curriculum/schema/challenge-schema.js index 714a9107eb8..2a2ad63f292 100644 --- a/curriculum/schema/challenge-schema.js +++ b/curriculum/schema/challenge-schema.js @@ -162,7 +162,6 @@ const schema = Joi.object().keys({ }), certification: Joi.string().regex(slugWithSlashRE), challengeType: Joi.number().min(0).max(31).required(), - checksum: Joi.number(), // TODO: require this only for normal challenges, not certs dashedName: Joi.string().regex(slugRE), demoType: Joi.string().valid('onClick', 'onLoad'), @@ -183,7 +182,6 @@ const schema = Joi.object().keys({ then: Joi.string() }), challengeFiles: Joi.array().items(fileJoi), - guideUrl: Joi.string().uri({ scheme: 'https' }), hasEditableBoundaries: Joi.boolean(), helpCategory: Joi.valid( 'JavaScript', @@ -217,7 +215,6 @@ const schema = Joi.object().keys({ otherwise: Joi.string().allow('') }), isComingSoon: Joi.bool(), - isLocked: Joi.bool(), module: Joi.string().when('superBlock', { is: chapterBasedSuperBlocks, then: Joi.required(),