Skip to content

Commit 07f69c2

Browse files
authored
Merge pull request #2504 from codecrafters-io/stage-1-experiments
Experiment: Stage 1 - Show All Steps At Once
2 parents d2f5b46 + 4071e9d commit 07f69c2

File tree

5 files changed

+142
-38
lines changed

5 files changed

+142
-38
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,102 @@
1-
<CoursePage::InstructionsCard @title="How to pass this stage" id="first-stage-tutorial-card" ...attributes>
2-
<:content>
3-
<div class="prose dark:prose-invert mb-5">
4-
<p>
5-
Since this is the first stage, we've included some commented code to help you get started. To pass this stage, simply uncomment the code and
6-
submit your changes.
7-
</p>
8-
</div>
1+
{{#if this.shouldShowAllStepsAtOnceForStage1}}
2+
<CoursePage::InstructionsCard @title="How to pass this stage" id="first-stage-tutorial-card" ...attributes>
3+
<:content>
4+
<div class="prose dark:prose-invert mb-5">
5+
<p>
6+
Since this is the first stage, we've included some commented code to help you get started. To pass this stage, simply uncomment the code and
7+
submit your changes.
8+
</p>
9+
</div>
910

10-
<ExpandableStepList @steps={{this.steps}} @onManualStepComplete={{this.handleStepCompletedManually}} class="scroll-mt-32" as |stepList|>
11-
{{#if (eq stepList.expandedStep.id "navigate-to-file")}}
12-
<CoursePage::CourseStageStep::FirstStageTutorialCard::NavigateToFileStep
13-
@repository={{@repository}}
14-
@courseStage={{@courseStage}}
15-
@isComplete={{this.navigateToFileStepIsComplete}}
16-
/>
17-
{{else if (eq stepList.expandedStep.id "uncomment-code")}}
11+
<div class="prose dark:prose-invert mb-3">
12+
<div class="inline-flex items-center gap-1">
13+
{{#if this.hasPassedTests}}
14+
{{svg-jar "check-circle" class="w-6 h-6 text-teal-500 inline-flex mb-0.5"}}
15+
{{else}}
16+
<b class="text-teal-600">Step 1:</b>
17+
{{/if}}
18+
Open a file
19+
</div>
20+
</div>
21+
<CoursePage::CourseStageStep::FirstStageTutorialCard::NavigateToFileStep
22+
@repository={{@repository}}
23+
@courseStage={{@courseStage}}
24+
@isComplete={{false}}
25+
/>
26+
27+
<div class="prose dark:prose-invert mt-6 mb-3 pt-4 border-t dark:border-white/5">
28+
<div class="inline-flex items-center gap-1">
29+
{{#if this.hasPassedTests}}
30+
{{svg-jar "check-circle" class="w-6 h-6 text-teal-500 inline-flex mb-0.5"}}
31+
{{else}}
32+
<b class="text-teal-600">Step 2:</b>
33+
{{/if}}
34+
Uncomment code
35+
</div>
36+
</div>
37+
<div class="max-w-2xl">
1838
<CoursePage::CourseStageStep::FirstStageTutorialCard::UncommentCodeStep
1939
@repository={{@repository}}
2040
@courseStage={{@courseStage}}
21-
@isComplete={{this.uncommentCodeStepIsComplete}}
41+
@isComplete={{false}}
2242
/>
23-
{{else if (eq stepList.expandedStep.id "submit-code")}}
24-
<CoursePage::CourseStageStep::FirstStageTutorialCard::SubmitCodeStep @isComplete={{this.submitCodeStepIsComplete}} />
25-
{{/if}}
26-
</ExpandableStepList>
43+
</div>
2744

28-
{{! After step 2, step 3 already contains a note on Tests Failed, so we can hide this !}}
29-
{{#unless this.uncommentCodeStepIsComplete}}
30-
<div class="prose dark:prose-invert prose-sm prose-compact mt-5">
45+
<div class="prose dark:prose-invert mt-8 mb-3 pt-4 border-t dark:border-white/5">
46+
<div class="inline-flex items-center gap-1">
47+
{{#if this.hasPassedTests}}
48+
{{svg-jar "check-circle" class="w-6 h-6 text-teal-500 inline-flex mb-0.5"}}
49+
{{else}}
50+
<b class="text-teal-600">Step 3:</b>
51+
{{/if}}
52+
Submit changes
53+
</div>
54+
</div>
55+
<CoursePage::CourseStageStep::FirstStageTutorialCard::SubmitCodeStep @isComplete={{this.hasPassedTests}} />
56+
</:content>
57+
</CoursePage::InstructionsCard>
58+
{{else}}
59+
<CoursePage::InstructionsCard @title="How to pass this stage" id="first-stage-tutorial-card" ...attributes>
60+
<:content>
61+
<div class="prose dark:prose-invert mb-5">
3162
<p>
32-
{{svg-jar "information-circle" class="w-5 h-5 mb-1 inline-flex text-sky-500"}}
33-
<b>Note:</b>
34-
After your first Git push, you should see
35-
<code class="font-semibold text-red-700 dark:text-red-300 bg-red-100 dark:bg-red-900/30 border border-red-200 dark:border-red-800/40">Tests
36-
failed</code>
37-
in the bar below this card. This is expected! Complete the steps above to pass the tests.
63+
Since this is the first stage, we've included some commented code to help you get started. To pass this stage, simply uncomment the code and
64+
submit your changes.
3865
</p>
3966
</div>
40-
{{/unless}}
41-
</:content>
42-
</CoursePage::InstructionsCard>
67+
68+
<ExpandableStepList @steps={{this.steps}} @onManualStepComplete={{this.handleStepCompletedManually}} class="scroll-mt-32" as |stepList|>
69+
{{#if (eq stepList.expandedStep.id "navigate-to-file")}}
70+
<CoursePage::CourseStageStep::FirstStageTutorialCard::NavigateToFileStep
71+
@repository={{@repository}}
72+
@courseStage={{@courseStage}}
73+
@isComplete={{this.navigateToFileStepIsComplete}}
74+
/>
75+
{{else if (eq stepList.expandedStep.id "uncomment-code")}}
76+
<CoursePage::CourseStageStep::FirstStageTutorialCard::UncommentCodeStep
77+
@repository={{@repository}}
78+
@courseStage={{@courseStage}}
79+
@isComplete={{this.uncommentCodeStepIsComplete}}
80+
/>
81+
{{else if (eq stepList.expandedStep.id "submit-code")}}
82+
<CoursePage::CourseStageStep::FirstStageTutorialCard::SubmitCodeStep @isComplete={{this.submitCodeStepIsComplete}} />
83+
{{/if}}
84+
</ExpandableStepList>
85+
86+
{{! After step 2, step 3 already contains a note on Tests Failed, so we can hide this !}}
87+
{{#unless this.uncommentCodeStepIsComplete}}
88+
<div class="prose dark:prose-invert prose-sm prose-compact mt-5">
89+
<p>
90+
{{svg-jar "information-circle" class="w-5 h-5 mb-1 inline-flex text-sky-500"}}
91+
<b>Note:</b>
92+
After your first Git push, you should see
93+
<code
94+
class="font-semibold text-red-700 dark:text-red-300 bg-red-100 dark:bg-red-900/30 border border-red-200 dark:border-red-800/40"
95+
>Tests failed</code>
96+
in the bar below this card. This is expected! Complete the steps above to pass the tests.
97+
</p>
98+
</div>
99+
{{/unless}}
100+
</:content>
101+
</CoursePage::InstructionsCard>
102+
{{/if}}

app/components/course-page/course-stage-step/first-stage-tutorial-card.ts

+11
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ import Store from '@ember-data/store';
66
import type CourseStageModel from 'codecrafters-frontend/models/course-stage';
77
import type RepositoryModel from 'codecrafters-frontend/models/repository';
88
import type { Step } from 'codecrafters-frontend/components/expandable-step-list';
9+
import type CourseStageStep from 'codecrafters-frontend/utils/course-page-step-list/course-stage-step';
910
import { action } from '@ember/object';
1011
import { inject as service } from '@ember/service';
12+
1113
interface Signature {
1214
Element: HTMLDivElement;
1315

1416
Args: {
1517
repository: RepositoryModel;
1618
courseStage: CourseStageModel;
19+
currentStep: CourseStageStep;
1720
};
1821
}
1922

@@ -70,6 +73,10 @@ export default class FirstStageTutorialCardComponent extends Component<Signature
7073
@service declare featureFlags: FeatureFlagsService;
7174
@service declare store: Store;
7275

76+
get hasPassedTests() {
77+
return this.args.currentStep.testsStatus === 'passed' || this.args.currentStep.status === 'complete';
78+
}
79+
7380
get navigateToFileStepIsComplete() {
7481
return this.navigateToFileStepWasMarkedAsComplete || this.uncommentCodeStepIsComplete;
7582
}
@@ -78,6 +85,10 @@ export default class FirstStageTutorialCardComponent extends Component<Signature
7885
return this.coursePageState.manuallyCompletedStepIdsInFirstStageInstructions.includes('navigate-to-file');
7986
}
8087

88+
get shouldShowAllStepsAtOnceForStage1() {
89+
return this.featureFlags.canSeeAllStepsAtOnceForStage1;
90+
}
91+
8192
get steps() {
8293
return [
8394
new NavigateToFileStep(this.args.repository, this.navigateToFileStepIsComplete),

app/controllers/course/stage/instructions.ts

+8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ export default class CourseStageInstructionsController extends Controller {
3131
});
3232
}
3333

34+
get currentCourse() {
35+
return this.model.courseStage.course;
36+
}
37+
3438
get currentStep(): CourseStageStep {
3539
return this.coursePageState.currentStep as CourseStageStep;
3640
}
@@ -55,6 +59,10 @@ export default class CourseStageInstructionsController extends Controller {
5559
return !!this.prerequisiteInstructionsMarkdown;
5660
}
5761

62+
get shouldShowStage1ForumLinkCTA() {
63+
return this.model.courseStage.isFirst && this.currentStep.testsStatus !== 'passed' && this.currentStep.status !== 'complete';
64+
}
65+
5866
get shouldShowTestRunnerCard() {
5967
return this.isCurrentStage && this.currentStep.status !== 'complete';
6068
}

app/services/feature-flags.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export default class FeatureFlagsService extends Service {
1010
this.notifiedFeatureFlags = new Set();
1111
}
1212

13+
get canSeeAllStepsAtOnceForStage1() {
14+
return this.currentUser?.isStaff || this.getFeatureFlagValue('can-see-all-steps-at-once-for-stage-1') === 'test';
15+
}
16+
1317
get canSeeConceptsIndex() {
1418
return this.currentUser && (this.currentUser.isStaff || this.currentUser.isConceptAuthor);
1519
}
@@ -18,10 +22,6 @@ export default class FeatureFlagsService extends Service {
1822
return this.currentUser?.isStaff || this.getFeatureFlagValue('can-see-short-instructions-for-stage-2') === 'test';
1923
}
2024

21-
get canSeeTweaksForStage1() {
22-
return this.currentUser?.isStaff || this.getFeatureFlagValue('can-see-tweaks-for-stage-1') === 'test';
23-
}
24-
2525
get currentUser() {
2626
return this.authenticator.currentUser;
2727
}

app/templates/course/stage/instructions.hbs

+26-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@
3333
{{/if}}
3434

3535
{{#if @model.courseStage.isFirst}}
36-
<CoursePage::CourseStageStep::FirstStageTutorialCard @repository={{@model.activeRepository}} @courseStage={{@model.courseStage}} class="mb-6" />
36+
<CoursePage::CourseStageStep::FirstStageTutorialCard
37+
@repository={{@model.activeRepository}}
38+
@courseStage={{@model.courseStage}}
39+
@currentStep={{this.currentStep}}
40+
class="mb-6"
41+
/>
3742
{{/if}}
3843

3944
{{#if @model.courseStage.isSecond}}
@@ -78,6 +83,26 @@
7883
</div>
7984
{{/if}}
8085

86+
{{#if this.shouldShowStage1ForumLinkCTA}}
87+
<div class="prose dark:prose-invert prose-sm prose-compact ml-4 mb-10">
88+
<p>
89+
Need help?
90+
<a
91+
href="https://forum.codecrafters.io/new-topic?category=Challenges&tags=challenge%3A{{this.currentCourse.slug}}&title=%5B{{this.currentCourse.shortName}}%5D%20How%20to%20pass%20the%20first%20stage%3F&body=Checklist%3A%0A%0A1.%20%E2%9C%85%20or%20%E2%9D%8C%3A%20I%27ve%20uncommented%20the%20code.%0A2.%20%E2%9C%85%20or%20%E2%9D%8C%3A%20I%27ve%20saved%20the%20changes.%0A3.%20%E2%9C%85%20or%20%E2%9D%8C%3A%20I%27ve%20run%20the%20git%20commands%3A%0A%0A%60%60%60%0Agit%20commit%20-am%20%22%5Bseeking%20help%20on%20forum%5D%22%0Agit%20push%20origin%20master%0A%60%60%60%0A%0A---%0A%0AHere%E2%80%99s%20a%20screenshot%20showing%20the%20output%20from%20running%20the%20Git%20commands%3A%0A%0A%5BAttach%20screenshot%20here%5D%0A%0A%5BShare%20other%20details%20here%5D"
92+
target="_blank"
93+
rel="noopener noreferrer"
94+
>
95+
Post your issue</a>
96+
on the forum —
97+
<img
98+
alt="avatar"
99+
src="https://avatars.githubusercontent.com/u/1450947"
100+
class="inline-block ml-1 mr-1.5 my-0 -translate-y-px overflow-hidden rounded-full size-4 filter drop-shadow-sm ring-1 ring-white dark:ring-white/5 shadow"
101+
/>Andy usually replies within 6 hours.
102+
</p>
103+
</div>
104+
{{/if}}
105+
81106
{{! TODO: Remove this temporary card }}
82107
{{#if (and @model.courseStage.isSecond (eq @model.courseStage.course.slug "shell"))}}
83108
<div class="my-10 mx-6 flex items-start gap-4">

0 commit comments

Comments
 (0)