Skip to content

Commit 05a5feb

Browse files
committed
docs: first version on 'Provide feedback to user when lesson is solved' docs
1 parent b58c1f5 commit 05a5feb

File tree

1 file changed

+108
-6
lines changed

1 file changed

+108
-6
lines changed

docs/tutorialkit.dev/src/content/docs/guides/how-to-use-tutorialkit-api.mdx

Lines changed: 108 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ description: "Examples showing how to utilize TutorialKit APIs"
55

66
import { Tabs, TabItem } from '@astrojs/starlight/components';
77

8+
TutorialKit's API can be used in custom components to provide highly custom experience in the tutorials.
9+
Below are listed few examples to solve real-world use cases. See [TutorialKit API](/reference/tutorialkit-api/) for API documentation.
10+
811
## Access tutorial state
912

1013
In this example we'll read contents of `index.js` using Tutorial Store APIs.
@@ -74,7 +77,7 @@ function verifyIndexJs(code: string) {
7477
</TabItem>
7578
<TabItem label="content.mdx">
7679

77-
```mdx title=" title="src/content/tutorial/chapter/part/lesson/content.mdx"
80+
```mdx title="src/content/tutorial/chapter/part/lesson/content.mdx"
7881
---
7982
type: lesson
8083
title: TutorialKit API usage example
@@ -129,9 +132,9 @@ export default function TerminalWriter() {
129132
}
130133
```
131134

132-
</TabItem>
135+
</TabItem>
133136

134-
<TabItem label="content.mdx">
137+
<TabItem label="content.mdx">
135138

136139
```mdx title="src/content/tutorial/chapter/part/lesson/content.mdx"
137140
---
@@ -148,11 +151,110 @@ Fix <code>counter.js</code> and run the tests!
148151
<TerminalWriter client:load />
149152
```
150153

151-
</TabItem>
152-
154+
</TabItem>
153155
</Tabs>
154156

155157
## Provide feedback to user when lesson is solved
156158

157-
## How to watch a file for changes
159+
In this example we'll congratulate user when they solve the lesson code.
160+
161+
Every time user edits the `math.js`, we run `node check-lesson.js` in the webcontainer and see if the process exits with non-erroneous exit code.
162+
Once the exit code indicates success, we inform user with message.
163+
164+
<a class="my-4 inline-block" href="https://stackblitz.com/edit/stackblitz-starters-b9ie5x?file=src/components/LessonChecker.tsx&file=src/templates/default/check-lesson.mjs&file=src/content/tutorial/1-basics/1-introduction/1-welcome/content.mdx">
165+
<img alt="Open in StackBlitz" src="https://developer.stackblitz.com/img/open_in_stackblitz.svg" />
166+
</a>
167+
168+
<Tabs>
169+
<TabItem label="LessonChecker.tsx">
170+
171+
```tsx title="src/components/LessonChecker.tsx"
172+
import { Dialog } from '@tutorialkit/react';
173+
import { useEffect, useState } from 'react';
174+
import { webcontainer } from 'tutorialkit:core';
175+
import tutorialStore from 'tutorialkit:store';
176+
177+
export default function LessonChecker() {
178+
const [success, setSuccess] = useState(false);
179+
180+
useEffect(() => {
181+
let timeout: ReturnType<typeof setTimeout> | undefined = undefined;
182+
183+
const unsubscribe = tutorialStore.onDocumentChanged('/math.js', () => {
184+
clearTimeout(timeout);
185+
186+
timeout = setTimeout(async () => {
187+
if (await checkLesson()) {
188+
setSuccess(true);
189+
unsubscribe();
190+
}
191+
}, 250);
192+
});
193+
194+
return function cleanup() {
195+
unsubscribe();
196+
clearTimeout(timeout);
197+
};
198+
}, []);
199+
200+
return (
201+
<>
202+
{success && (
203+
<Dialog title="Lesson complete" confirmText="OK" onClose={() => setSuccess(false)}>
204+
Lesson complete, congratulations! 🎉
205+
</Dialog>
206+
)}
207+
</>
208+
);
209+
}
210+
211+
async function checkLesson(): Promise<boolean> {
212+
const webcontainerInstance = await webcontainer;
213+
const process = await webcontainerInstance.spawn('node', ['./check-lesson.mjs']);
158214

215+
const exitCode = await process.exit;
216+
217+
return exitCode === 0;
218+
}
219+
```
220+
221+
</TabItem>
222+
223+
<TabItem label="check-lesson.mjs">
224+
225+
```js title="src/templates/default/check-lesson.mjs"
226+
import * as math from './math.js';
227+
228+
if (math.sum(25, 32) !== 57) {
229+
process.exit(1);
230+
}
231+
232+
if (math.multiply(3, 25) !== 75) {
233+
process.exit(1);
234+
}
235+
236+
process.exit(0);
237+
```
238+
239+
</TabItem>
240+
241+
<TabItem label="content.mdx">
242+
243+
```mdx title="src/content/tutorial/chapter/part/lesson/content.mdx"
244+
---
245+
type: lesson
246+
title: TutorialKit API usage example
247+
focus: /math.js
248+
---
249+
250+
import LessonChecker from '@components/LessonChecker';
251+
252+
# TutorialKit API usage example
253+
254+
Solve <code>math.js</code> and you'll see notification about completed lesson!
255+
256+
<LessonChecker client:load />
257+
```
258+
259+
</TabItem>
260+
</Tabs>

0 commit comments

Comments
 (0)