diff --git a/web-app/src/containers/SelectTutorial/LoadTutorialSummary.tsx b/web-app/src/containers/SelectTutorial/LoadTutorialSummary.tsx
index 898deceb..87cf0118 100644
--- a/web-app/src/containers/SelectTutorial/LoadTutorialSummary.tsx
+++ b/web-app/src/containers/SelectTutorial/LoadTutorialSummary.tsx
@@ -1,13 +1,11 @@
import * as React from 'react'
import useFetch from '../../services/hooks/useFetch'
import * as TT from 'typings/tutorial'
-import TutorialOverview from '../../components/TutorialOverview'
import Loading from '../Loading'
interface Props {
url: string
- send: any
- onClear(): void
+ onLoadSummary(data: TT.Tutorial): void
}
const LoadTutorialSummary = (props: Props) => {
@@ -22,15 +20,8 @@ const LoadTutorialSummary = (props: Props) => {
if (!data) {
return
No data returned for tutorial
}
- const onNext = () => {
- props.send({
- type: 'TUTORIAL_START',
- payload: {
- tutorial: data,
- },
- })
- }
- return
+ props.onLoadSummary(data)
+ return null
}
export default LoadTutorialSummary
diff --git a/web-app/src/containers/SelectTutorial/SelectTutorialForm.tsx b/web-app/src/containers/SelectTutorial/SelectTutorialForm.tsx
index 4e4b568e..b65972f2 100644
--- a/web-app/src/containers/SelectTutorial/SelectTutorialForm.tsx
+++ b/web-app/src/containers/SelectTutorial/SelectTutorialForm.tsx
@@ -1,7 +1,9 @@
+import * as TT from 'typings/tutorial'
import * as React from 'react'
import { Radio } from '@alifd/next'
import TutorialSelect from './forms/TutorialSelect'
import TutorialUrl from './forms/TutorialUrl'
+import TutorialFile from './forms/TutorialFile'
const styles = {
formWrapper: {
@@ -15,7 +17,8 @@ interface Props {
tab: string
setTab(tab: 'list' | 'url'): void
url: string | null
- onTutorialLoad(url: string): void
+ onTutorialLoadFromUrl(url: string): void
+ onLoadSummary(data: TT.Tutorial | null): void
}
const SelectTutorialForm = (props: Props) => {
@@ -30,12 +33,13 @@ const SelectTutorialForm = (props: Props) => {
>
List
URL
- {/* File */}
+ File
- {props.tab === 'list' && }
- {props.tab === 'url' && }
+ {props.tab === 'list' && }
+ {props.tab === 'url' && }
+ {props.tab === 'file' && }
)
}
diff --git a/web-app/src/containers/SelectTutorial/forms/TutorialFile.tsx b/web-app/src/containers/SelectTutorial/forms/TutorialFile.tsx
new file mode 100644
index 00000000..da257446
--- /dev/null
+++ b/web-app/src/containers/SelectTutorial/forms/TutorialFile.tsx
@@ -0,0 +1,56 @@
+import * as React from 'react'
+import * as TT from 'typings/tutorial'
+import { Form } from '@alifd/next'
+
+const FormItem = Form.Item
+
+interface Props {
+ onLoadSummary(data: TT.Tutorial): void
+}
+
+const styles = {
+ uploadFileButton: {
+ padding: '0.3rem 0.5rem',
+ outline: '1px dotted rgb(51, 51, 51)',
+ borderRadius: '0.2rem',
+ fontWeight: 400,
+ fontFamily:
+ '-apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;',
+ },
+}
+
+const TutorialFile = (props: Props) => {
+ const onChange = (evt: any) => {
+ evt.preventDefault()
+ const files = evt.target.files
+
+ if (!files.length) {
+ alert('No file select')
+ return
+ }
+ const uploadedFile = files[0]
+ const reader = new FileReader()
+ reader.onload = (e: any) => {
+ // TODO: handle errors from invalid JSON
+ const fileJson: TT.Tutorial = JSON.parse(e.target.result)
+ props.onLoadSummary(fileJson)
+ }
+ reader.readAsText(uploadedFile)
+ }
+
+ return (
+
+ )
+}
+
+export default TutorialFile
diff --git a/web-app/src/containers/SelectTutorial/forms/TutorialUrl.tsx b/web-app/src/containers/SelectTutorial/forms/TutorialUrl.tsx
index f9727261..9693f3bc 100644
--- a/web-app/src/containers/SelectTutorial/forms/TutorialUrl.tsx
+++ b/web-app/src/containers/SelectTutorial/forms/TutorialUrl.tsx
@@ -1,5 +1,5 @@
import * as React from 'react'
-import { Button, Form, Radio, Input } from '@alifd/next'
+import { Button, Form, Input } from '@alifd/next'
const FormItem = Form.Item
diff --git a/web-app/src/containers/SelectTutorial/index.tsx b/web-app/src/containers/SelectTutorial/index.tsx
index 34e1155c..ee4bafae 100644
--- a/web-app/src/containers/SelectTutorial/index.tsx
+++ b/web-app/src/containers/SelectTutorial/index.tsx
@@ -1,5 +1,7 @@
+import * as TT from 'typings/tutorial'
import * as React from 'react'
import SelectTutorialForm from './SelectTutorialForm'
+import TutorialOverview from '../../components/TutorialOverview'
import LoadTutorialSummary from './LoadTutorialSummary'
const styles = {
@@ -19,17 +21,44 @@ interface Props {
}
const SelectTutorialPage = (props: Props) => {
- const [page, setPage] = React.useState<'form' | 'summary'>('form')
+ const [data, setData] = React.useState()
+ const [page, setPage] = React.useState<'form' | 'loading' | 'summary'>('form')
const [tab, setTab] = React.useState<'list' | 'url'>('list')
const [url, setUrl] = React.useState(null)
- const onTutorialLoad = (url: string) => {
+
+ const onNext = () => {
+ props.send({
+ type: 'TUTORIAL_START',
+ payload: {
+ tutorial: data,
+ },
+ })
+ }
+ const onTutorialLoadFromUrl = (url: string) => {
setUrl(url)
+ setPage('loading')
+ }
+ const onLoadSummary = (d: TT.Tutorial) => {
+ setData(d)
setPage('summary')
}
+ const onClear = () => {
+ setData(null)
+ setPage('form')
+ }
return (
- {page === 'form' && }
- {page === 'summary' && url && setPage('form')} />}
+ {page === 'form' && (
+
+ )}
+ {page === 'loading' && url && }
+ {page === 'summary' && data && }
)
}