Skip to content

Commit 34aff91

Browse files
authored
Merge pull request #135 from ShMcK/feature/launch-page
Closes #95. Feature/launch page
2 parents d9e5d45 + ca6198e commit 34aff91

File tree

13 files changed

+208
-41
lines changed

13 files changed

+208
-41
lines changed

src/channel/index.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class Channel implements Channel {
5757

5858
// new tutorial
5959
if (!tutorial || !tutorial.id || !tutorial.version) {
60-
this.send({ type: 'NEW_TUTORIAL' })
60+
this.send({ type: 'START_NEW_TUTORIAL' })
6161
return
6262
}
6363

@@ -66,12 +66,12 @@ class Channel implements Channel {
6666

6767
if (progress.complete) {
6868
// tutorial is already complete
69-
this.send({ type: 'NEW_TUTORIAL' })
69+
this.send({ type: 'START_NEW_TUTORIAL' })
7070
return
7171
}
72-
72+
console.log('send LOAD_STORED_TUTORIAL')
7373
// communicate to client the tutorial & stepProgress state
74-
this.send({ type: 'CONTINUE_TUTORIAL', payload: { tutorial, progress, position } })
74+
this.send({ type: 'LOAD_STORED_TUTORIAL', payload: { tutorial, progress, position } })
7575

7676
return
7777
// clear tutorial local storage

typings/index.d.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,18 @@ export interface MachineEvent {
6666

6767
export interface MachineStateSchema {
6868
states: {
69-
Start: {
69+
Setup: {
7070
states: {
7171
Startup: {}
7272
Authenticate: {}
7373
Error: {}
74-
NewOrContinue: {}
74+
LoadStoredTutorial: {}
75+
Start: {}
7576
SelectTutorial: {}
7677
LoadTutorialSummary: {}
7778
Summary: {}
7879
LoadTutorialData: {}
7980
SetupNewTutorial: {}
80-
ContinueTutorial: {}
8181
}
8282
}
8383
Tutorial: {

web-app/src/Routes.tsx

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as React from 'react'
22
import useRouter from './components/Router'
33
import Workspace from './components/Workspace'
4-
import ContinuePage from './containers/Continue'
5-
import LoadingPage from './containers/LoadingPage'
4+
import LoadingPage from './containers/Loading'
5+
import StartPage from './containers/Start'
66
import NewPage from './containers/New'
77
import OverviewPage from './containers/Overview'
88
import CompletedPage from './containers/Tutorial/CompletedPage'
@@ -13,26 +13,26 @@ const Routes = () => {
1313
return (
1414
<Workspace>
1515
<Router>
16-
{/* Start */}
17-
<Route path={['Start.Startup', 'Start.Authenticate', 'Start.NewOrContinue']}>
16+
{/* Setup */}
17+
<Route path={['Setup.Startup', 'Setup.Authenticate', 'Setup.LoadStoredTutorial']}>
1818
<LoadingPage text="Launching..." context={context} />
1919
</Route>
20-
<Route path="Start.ContinueTutorial">
21-
<ContinuePage send={send} context={context} />
20+
<Route path="Setup.Start">
21+
<StartPage send={send} context={context} />
2222
</Route>
23-
<Route path={['Start.LoadTutorialSummary', 'Start.LoadTutorialData', 'Start.SetupNewTutorial']}>
23+
<Route path={['Setup.LoadTutorialSummary', 'Setup.LoadTutorialData', 'Setup.SetupNewTutorial']}>
2424
<LoadingPage text="Loading Tutorial..." context={context} />
2525
</Route>
26-
<Route path="Start.Error">
26+
<Route path="Setup.Error">
2727
<LoadingPage text="Error" context={context} />
2828
</Route>
29-
<Route path="Start.SelectTutorial">
29+
<Route path="Setup.SelectTutorial">
3030
<NewPage send={send} context={context} />
3131
</Route>
32-
<Route path="Start.Summary">
32+
<Route path="Setup.Summary">
3333
<OverviewPage send={send} context={context} />
3434
</Route>
35-
<Route path="Start.SetupNewTutorial">
35+
<Route path="Setup.SetupNewTutorial">
3636
<LoadingPage text="Configuring tutorial..." context={context} />
3737
</Route>
3838
{/* Tutorial */}

web-app/src/containers/LoadingPage.tsx renamed to web-app/src/containers/Loading/LoadingPage.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as React from 'react'
22
import * as T from 'typings'
33
import { css, jsx } from '@emotion/core'
4-
import Loading from '../components/Loading'
5-
import Message from '../components/Message'
4+
import Loading from '../../components/Loading'
5+
import Message from '../../components/Message'
66

77
interface Props {
88
text: string
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as React from 'react'
2+
import * as T from 'typings'
3+
import { css, jsx } from '@emotion/core'
4+
import Loading from '../../components/Loading'
5+
import Message from '../../components/Message'
6+
7+
interface Props {
8+
text: string
9+
context: T.MachineContext
10+
}
11+
12+
const styles = {
13+
page: {
14+
position: 'relative' as 'relative',
15+
display: 'flex',
16+
flexDirection: 'column' as 'column',
17+
alignItems: 'center',
18+
justifyContent: 'center',
19+
width: '100%',
20+
},
21+
}
22+
23+
const LoadingPage = ({ text, context }: Props) => {
24+
const { error } = context
25+
if (error) {
26+
return (
27+
<div css={styles.page}>
28+
<Message type="error" title={error.title} content={error.description} />
29+
</div>
30+
)
31+
}
32+
return (
33+
<div css={styles.page}>
34+
<Loading text={text} />
35+
</div>
36+
)
37+
}
38+
39+
export default LoadingPage

web-app/src/containers/New/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as T from 'typings'
44
import * as G from 'typings/graphql'
55
import ErrorView from '../../components/Error'
66
import queryTutorials from '../../services/apollo/queries/tutorials'
7-
import LoadingPage from '../LoadingPage'
7+
import LoadingPage from '../Loading'
88
import NewPage from './NewPage'
99

1010
interface ContainerProps {

web-app/src/containers/Overview/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as G from 'typings/graphql'
55
import ErrorView from '../../components/Error'
66
import queryTutorial from '../../services/apollo/queries/tutorial'
77
import OverviewPage from './OverviewPage'
8-
import LoadingPage from '../../containers/LoadingPage'
8+
import LoadingPage from '../Loading'
99

1010
interface PageProps {
1111
context: CR.MachineContext
+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import * as React from 'react'
2+
import * as CR from 'typings'
3+
import * as G from 'typings/graphql'
4+
import { Badge } from '@alifd/next'
5+
import { css, jsx } from '@emotion/core'
6+
import Button from '../../components/Button'
7+
8+
const styles = {
9+
page: {
10+
position: 'relative' as 'relative',
11+
display: 'flex' as 'flex',
12+
flexDirection: 'column' as 'column',
13+
width: '100%',
14+
height: window.innerHeight,
15+
},
16+
header: {
17+
flex: 1,
18+
display: 'flex' as 'flex',
19+
flexDirection: 'column' as 'column',
20+
justifyContent: 'flex-end' as 'flex-end',
21+
alignItems: 'center' as 'center',
22+
fontSize: '1rem',
23+
lineHeight: '1rem',
24+
padding: '1rem',
25+
},
26+
title: {
27+
fontSize: '3rem',
28+
},
29+
subtitle: {
30+
fontSize: '1.3rem',
31+
},
32+
options: {
33+
flex: 1,
34+
backgroundColor: '#EBEBEB',
35+
display: 'flex' as 'flex',
36+
flexDirection: 'column' as 'column',
37+
justifyContent: 'flex-start' as 'flex-start',
38+
alignItems: 'center' as 'center',
39+
padding: '1rem',
40+
},
41+
betaBadge: {
42+
backgroundColor: '#6a67ce',
43+
color: '#FFFFFF',
44+
},
45+
buttonContainer: {
46+
margin: '0.5rem',
47+
},
48+
}
49+
50+
interface Props {
51+
onContinue(): void
52+
onNew(): void
53+
tutorial?: G.Tutorial
54+
}
55+
56+
export const StartPage = (props: Props) => (
57+
<div css={styles.page}>
58+
<div css={styles.header}>
59+
<Badge content="beta" style={styles.betaBadge}>
60+
<span css={styles.title}>CodeRoad&nbsp;</span>
61+
</Badge>
62+
<h3 css={styles.subtitle}>Play Interactive Coding Tutorials in VSCode</h3>
63+
</div>
64+
65+
<div css={styles.options}>
66+
<div css={styles.buttonContainer}>
67+
<Button size="large" type="primary" onClick={props.onNew} style={{ width: '12rem' }}>
68+
New Tutorial
69+
</Button>
70+
</div>
71+
{props.tutorial && (
72+
<div css={styles.buttonContainer}>
73+
<Button size="large" onClick={props.onContinue} style={{ width: '12rem' }}>
74+
Continue "{props.tutorial.summary.title}"
75+
</Button>
76+
</div>
77+
)}
78+
</div>
79+
</div>
80+
)
81+
82+
interface ContainerProps {
83+
context: CR.MachineContext
84+
send(action: CR.Action | string): void
85+
}
86+
87+
const StartPageContainer = ({ context, send }: ContainerProps) => {
88+
const tutorial = context.tutorial || undefined
89+
return (
90+
<StartPage onContinue={() => send('CONTINUE_TUTORIAL')} onNew={() => send('NEW_TUTORIAL')} tutorial={tutorial} />
91+
)
92+
}
93+
94+
export default StartPageContainer

web-app/src/services/state/actions/context.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ const contextActions: ActionFunctionMap<T.MachineContext, T.MachineEvent> = {
1515
},
1616
}),
1717
// @ts-ignore
18-
continueTutorial: assign({
18+
storeContinuedTutorial: assign({
1919
tutorial: (context: T.MachineContext, event: T.MachineEvent) => {
20+
console.log('storeContinuedTutorial')
2021
return event.payload.tutorial
2122
},
2223
progress: (context: T.MachineContext, event: T.MachineEvent) => {

web-app/src/services/state/machine.ts

+16-16
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const createMachine = (options: any) => {
1616
return Machine<CR.MachineContext, CR.MachineStateSchema, CR.MachineEvent>(
1717
{
1818
id: 'root',
19-
initial: 'Start',
19+
initial: 'Setup',
2020
context: {
2121
error: null,
2222
env: { machineId: '', sessionId: '', token: '' },
@@ -31,7 +31,7 @@ export const createMachine = (options: any) => {
3131
testStatus: null,
3232
},
3333
states: {
34-
Start: {
34+
Setup: {
3535
initial: 'Startup',
3636
states: {
3737
Startup: {
@@ -46,7 +46,7 @@ export const createMachine = (options: any) => {
4646
Authenticate: {
4747
invoke: {
4848
src: services.authenticate,
49-
onDone: 'NewOrContinue',
49+
onDone: 'LoadStoredTutorial',
5050
onError: {
5151
target: 'Error',
5252
actions: assign({
@@ -56,14 +56,23 @@ export const createMachine = (options: any) => {
5656
},
5757
},
5858
Error: {},
59-
NewOrContinue: {
59+
LoadStoredTutorial: {
6060
onEntry: ['loadStoredTutorial'],
6161
on: {
62-
CONTINUE_TUTORIAL: {
63-
target: 'ContinueTutorial',
64-
actions: ['continueTutorial'],
62+
LOAD_STORED_TUTORIAL: {
63+
target: 'Start',
64+
actions: ['storeContinuedTutorial'],
6565
},
66+
START_NEW_TUTORIAL: 'Start',
67+
},
68+
},
69+
Start: {
70+
on: {
6671
NEW_TUTORIAL: 'SelectTutorial',
72+
CONTINUE_TUTORIAL: {
73+
target: '#tutorial-level',
74+
actions: ['continueConfig'],
75+
},
6776
},
6877
},
6978
SelectTutorial: {
@@ -123,15 +132,6 @@ export const createMachine = (options: any) => {
123132
TUTORIAL_CONFIGURED: '#tutorial',
124133
},
125134
},
126-
ContinueTutorial: {
127-
on: {
128-
TUTORIAL_START: {
129-
target: '#tutorial-level',
130-
actions: ['continueConfig'],
131-
},
132-
TUTORIAL_SELECT: 'SelectTutorial',
133-
},
134-
},
135135
},
136136
},
137137
Tutorial: {

web-app/stories/Loading.stories.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { storiesOf } from '@storybook/react'
22
import React from 'react'
3-
import LoadingPage from '../src/containers/LoadingPage'
3+
import LoadingPage from '../src/containers/Loading'
44
import SideBarDecorator from './utils/SideBarDecorator'
55

66
storiesOf('Components', module)

web-app/stories/New.stories.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const tutorialList = [
2323
},
2424
]
2525

26-
storiesOf('Start', module)
26+
storiesOf('Select Tutorial', module)
2727
.addDecorator(SideBarDecorator)
2828
.add('New Page', () => {
2929
return <NewPage tutorialList={tutorialList} />

web-app/stories/Start.stories.tsx

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { storiesOf } from '@storybook/react'
2+
import { action } from '@storybook/addon-actions'
3+
import React from 'react'
4+
import { css, jsx } from '@emotion/core'
5+
import SideBarDecorator from './utils/SideBarDecorator'
6+
import StartPage from '../src/containers/Start'
7+
8+
const styles = {
9+
container: {},
10+
}
11+
12+
storiesOf('Start', module)
13+
.addDecorator(SideBarDecorator)
14+
.add('New', () => {
15+
return (
16+
<div css={styles.container}>
17+
<StartPage send={action('send')} context={{}} />
18+
</div>
19+
)
20+
})
21+
.add('Continue', () => {
22+
const tutorial = {
23+
summary: {
24+
title: 'Tutorial Title',
25+
summary: 'Tutorial Summary',
26+
},
27+
}
28+
return (
29+
<div css={styles.container}>
30+
<StartPage send={action('send')} context={{ tutorial }} />
31+
</div>
32+
)
33+
})

0 commit comments

Comments
 (0)