File tree
Expand file treeCollapse file tree3 files changed
+30
-6
lines changed web-app/src/containers/SelectTutorial
Expand file treeCollapse file tree3 files changed
+30
-6
lines changed Original file line number | Diff line number | Diff line change |
---|
|
1 | 1 | import * as React from 'react'
|
| 2 | +import { Dialog } from '@alifd/next' |
2 | 3 | import useFetch from '../../services/hooks/useFetch'
|
3 | 4 | import * as TT from 'typings/tutorial'
|
4 | 5 | import LoadingPage from '../Loading'
|
5 | 6 |
|
6 | 7 | interface Props {
|
7 | 8 | url: string
|
8 | 9 | onLoadSummary(data: TT.Tutorial): void
|
| 10 | +onReturnToSelection(): void |
9 | 11 | }
|
10 | 12 |
|
11 | 13 | const LoadTutorialSummary = (props: Props) => {
|
12 | 14 | const { data, error, loading } = useFetch<TT.Tutorial>(props.url)
|
| 15 | +if (!data) { |
| 16 | +return ( |
| 17 | +<Dialog |
| 18 | +title="Tutorial Not Found" |
| 19 | +visible={true} |
| 20 | +closeable={false} |
| 21 | +footerActions={['ok']} |
| 22 | +onOk={props.onReturnToSelection} |
| 23 | +> |
| 24 | +No data returned for tutorial |
| 25 | +</Dialog> |
| 26 | +) |
| 27 | +} |
13 | 28 | if (loading) {
|
14 | 29 | return <LoadingPage text="Loading tutorial summary..." />
|
15 | 30 | }
|
16 | 31 | if (error) {
|
17 | 32 | console.log(`Failed to load tutorial summary: ${error}`)
|
18 | 33 | return <div>Error loading summary</div>
|
19 | 34 | }
|
20 |
| -if (!data) { |
21 |
| -return <div>No data returned for tutorial</div> |
22 |
| -} |
23 | 35 | props.onLoadSummary(data)
|
24 | 36 | return null
|
25 | 37 | }
|
|
Original file line number | Diff line number | Diff line change |
---|
@@ -9,14 +9,23 @@ interface Props {
|
9 | 9 | onTutorialLoad(url: string): void
|
10 | 10 | }
|
11 | 11 |
|
| 12 | +const urlRegex = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)\.json/ |
| 13 | + |
12 | 14 | const TutorialUrl = (props: Props) => {
|
13 | 15 | const [url, setUrl] = React.useState(props.defaultUrl)
|
| 16 | +const [inputState, setInputState] = React.useState<undefined | 'success' | 'error'>() |
| 17 | + |
14 | 18 | const onSubmit = (e: any) => {
|
15 | 19 | e.preventDefault()
|
16 | 20 | logger(`Tutorial url: ${url}`)
|
17 | 21 | props.onTutorialLoad(url)
|
18 | 22 | }
|
19 | 23 |
|
| 24 | +const handleChange = (text: string) => { |
| 25 | +setUrl(text) |
| 26 | +!!text.match(urlRegex) ? setInputState('success') : setInputState('error') |
| 27 | +} |
| 28 | + |
20 | 29 | return (
|
21 | 30 | // @ts-ignore seems to be an onSubmit event ts error in lib
|
22 | 31 | <Form style={{ maxWidth: '600px' }} onSubmit={onSubmit}>
|
@@ -25,11 +34,12 @@ const TutorialUrl = (props: Props) => {
|
25 | 34 | size="large"
|
26 | 35 | placeholder="https://raw.usercontent.com/coderoad/fcc-learn-npm/master/coderoad-config.json"
|
27 | 36 | defaultValue={props.defaultUrl}
|
28 |
| -onChange={setUrl} |
| 37 | +onChange={handleChange} |
| 38 | +state={inputState} |
29 | 39 | aria-label="input url path to coderoad config.json"
|
30 | 40 | />
|
31 | 41 | </FormItem>
|
32 |
| -<Button htmlType="submit" type="primary"> |
| 42 | +<Button htmlType="submit" type="primary" disabled={inputState !== 'success'}> |
33 | 43 | Load
|
34 | 44 | </Button>{' '}
|
35 | 45 |
|
|
Original file line number | Diff line number | Diff line change |
---|
@@ -58,7 +58,9 @@ const SelectTutorialPage = (props: Props) => {
|
58 | 58 | setTab={setTab}
|
59 | 59 | />
|
60 | 60 | )}
|
61 |
| -{page === 'loading' && url && <LoadTutorialSummary url={url} onLoadSummary={onLoadSummary} />} |
| 61 | +{page === 'loading' && url && ( |
| 62 | +<LoadTutorialSummary url={url} onLoadSummary={onLoadSummary} onReturnToSelection={() => setPage('form')} /> |
| 63 | +)} |
62 | 64 | {page === 'summary' && data && <TutorialOverview onNext={onNext} tutorial={data} onClear={onClear} />}
|
63 | 65 | </div>
|
64 | 66 | )
|
|
You can’t perform that action at this time.
0 commit comments