Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add file upload to home component #33

Merged
merged 8 commits into from
May 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions components/experiment.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button, Card, CardContent, Grid, Snackbar, Typography } from '@material-ui/core'
import { Box, Button, Card, CardContent, CircularProgress, Grid, Snackbar, Typography } from '@material-ui/core'
import Layout from './layout'
import OptimizerModel from './optimizer-model';
import OptimizerConfigurator from './optimizer-configurator';
Expand All @@ -9,9 +9,10 @@ import { useStyles } from '../styles/experiment.style';
import { useExperiment, saveExperiment, runExperiment } from '../context/experiment-context';
import React, { useState, useEffect } from 'react';
import { ValueVariableType, CategoricalVariableType, OptimizerConfig, DataPointType } from '../types/common';
import LoadingExperiment from './loading-experiment';

export default function Experiment() {
const classes = useStyles();
const classes = useStyles()
const { state: {
experiment
}, dispatch, loading } = useExperiment()
Expand Down Expand Up @@ -45,7 +46,6 @@ export default function Experiment() {
} catch (error) {
console.error('fetch error', error)
}

}

function handleCloseSnackbar() {
Expand All @@ -54,9 +54,11 @@ export default function Experiment() {

const valueVariables = experiment.valueVariables
const categoricalVariables = experiment.categoricalVariables

if (loading) {
return <>Loading experiment...</>
return <LoadingExperiment />
}

return (
<Layout>
<Card className={[classes.experimentContainer, isDirty ? classes.experimentContainerDirty : ''].join(' ')}>
Expand Down
123 changes: 123 additions & 0 deletions components/home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { Box, Card, CardContent, List, ListItem, ListItemText, Typography } from "@material-ui/core";
import { useCallback, useState } from "react";
import { useDropzone } from 'react-dropzone';
import Layout from "../components/layout";
import useStyles from "../styles/home.style";
import { NextRouter, useRouter } from 'next/router'
import SystemUpdateAltIcon from '@material-ui/icons/SystemUpdateAlt';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import { paths } from "../paths";
import { ExperimentType } from "../types/common";
import { useGlobal } from "../context/global-context";
import { saveExperiment } from '../context/experiment-context';

export default function Home() {
const classes = useStyles()
const router: NextRouter = useRouter()
const [uploadMessage, setUploadMessage] = useState("Drag file here")
const { state } = useGlobal()

const onDrop = useCallback(acceptedFiles => {
const reader = new FileReader()
reader.onabort = () => setUploadMessage('Upload aborted')
reader.onerror = () => setUploadMessage('Upload failed')
reader.onprogress = () => setUploadMessage('Loading file...')
reader.onload = () => load(reader)
reader.readAsText(acceptedFiles[0])
}, [])

const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop })

const load = (reader: FileReader) => {
const binaryResult: string | ArrayBuffer = reader.result
try {
const experiment: ExperimentType = JSON.parse(binaryResult as string)
if (experiment.id === undefined) {
setUploadMessage('Id not found')
} else {
saveAndRedirect(experiment)
}
} catch (e) {
console.error('File parsing failed', e)
setUploadMessage('Upload failed')
}
}

const saveAndRedirect = async (experiment: ExperimentType) => {
const id: string = experiment.id
if (state.useLocalStorage) {
try {
localStorage.setItem(id, JSON.stringify({ experiment }))
router.push(`${paths.experiment}/${id}`)
} catch (e) {
console.error('Unable to use local storage')
setUploadMessage('Upload failed')
}
} else {
await saveExperiment(experiment)
router.push(`${paths.experiment}/${id}`)
}
}

return (
<Layout>
<Card className={classes.mainContainer}>
<CardContent className={classes.mainContent}>

<Box p={3}>
<Typography variant="h4">
Get started
</Typography>
</Box>

<Box p={0} pl={1} mb={1} className={classes.box}>
<List component="nav">
<ListItem button>
<ListItemText primaryTypographyProps={{ variant: "h6" }} primary="Create new experiment" />
<ChevronRightIcon />
</ListItem>
</List>
</Box>

<Box p={3} pb={1} mb={1} className={classes.box}>
<Typography variant="h6">
Upload experiment file
</Typography>
<Box mb={5} className={classes.uploadBox} {...getRootProps()}>
<SystemUpdateAltIcon className={classes.uploadIcon} />
<input {...getInputProps()} />
<div className={classes.uploadBoxInner}>
<Typography variant="body1">
{uploadMessage}
</Typography>
</div>
</Box>
</Box>

<Box p={3} className={classes.box}>
<Typography variant="h6">
Saved experiments
</Typography>
<Box mb={1}>
<List component="nav">
<ListItem button>
<ListItemText primary="Pandekager (id: 1239812084)" />
<ChevronRightIcon />
</ListItem>
<ListItem button>
<ListItemText primary="Chokoladekage (id: 2847247282)" />
<ChevronRightIcon />
</ListItem>
<ListItem button>
<ListItemText primary="Secret experiment X (id: 2388853929230)" />
<ChevronRightIcon />
</ListItem>
</List>
</Box>
</Box>

</CardContent>
</Card>
</Layout>
);
}
6 changes: 3 additions & 3 deletions components/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AppBar, Button, Switch, Toolbar, Typography } from '@material-ui/core'
import { AppBar, Box, Button, Switch, Toolbar, Typography } from '@material-ui/core'
import Link from 'next/link'
import useStyles from '../styles/layout.style'
import Image from 'next/image'
Expand Down Expand Up @@ -33,10 +33,10 @@ export default function Layout ( {children} ) {
</div>
</Toolbar>
</AppBar>
<div className={classes.mainContent}>
<Box ml={1} mr={1} mb={1} mt={7}>
{state.debug && <pre>{JSON.stringify(state, null, 2)}</pre>}
{children}
</div>
</Box>
</>
)
}
19 changes: 19 additions & 0 deletions components/loading-experiment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Box, Card, CardContent, CircularProgress, Typography } from "@material-ui/core";
import useStyles from "../styles/loading-experiment.style";
import Layout from "./layout";

export default function LoadingExperiment() {
const classes = useStyles()
return <Layout>
<Card className={classes.loadingContainer}>
<CardContent>
<Box mt={8}>
<CircularProgress disableShrink className={classes.progress}/>
<Typography variant="body2">
Loading experiment...
</Typography>
</Box>
</CardContent>
</Card>
</Layout>
}
5 changes: 1 addition & 4 deletions hooks/useLocalStorageReducer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { useCallback, useReducer } from 'react'
import { ExperimentAction } from '../reducers/experiment-reducers'
import { Action } from '../reducers/reducers'
import { State } from '../store'
import { useReducer } from 'react'

const init = (localStorageKey: string) => <S> (initialState: S) => {
try {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"next": "^10.2.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-dropzone": "^11.3.2",
"react-hook-form": "^6.15.1",
"swr": "^0.4.2",
"uuid": "^8.3.2"
Expand Down
2 changes: 1 addition & 1 deletion pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function App({ Component, pageProps }: AppProps) {
return (
<SafeHydrate>
<Head>
<title>My page</title>
<title>BrownieBee</title>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
</Head>
<ThemeProvider theme={theme}>
Expand Down
3 changes: 2 additions & 1 deletion pages/experiment/[experimentid].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { ExperimentProvider } from "../../context/experiment-context";
import Experiment from "../../components/experiment";
import DebugExperiment from "../../components/debugexperiment";
import { useGlobal } from "../../context/global-context";
import LoadingExperiment from "../../components/loading-experiment";

export default function ExperimentContainer() {
const router = useRouter();
const { experimentid } = router.query;
const { state } = useGlobal()

if (!experimentid) {
return <div>Loading experiment</div>;
return <LoadingExperiment />
}
return (
<>
Expand Down
17 changes: 3 additions & 14 deletions pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
import Head from "next/head";
import Layout from "../components/layout";
import Home from "../components/home";

export default function Home() {
return (
<div>
<Head>
<title>Brownie Bee</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Layout>
<h1>Welcome!</h1>
</Layout>
</div>
);
export default function Index() {
return <Home />
}
3 changes: 3 additions & 0 deletions paths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const paths = {
experiment: 'experiment'
}
6 changes: 3 additions & 3 deletions styles/experiment.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { makeStyles } from "@material-ui/core";
export const useStyles = makeStyles(theme => ({
experimentContainer: {
marginTop: theme.spacing(4),
minWidth: 1200,
maxWidth: 1800,
minWidth: theme.sizes.mainWidthMin,
maxWidth: theme.sizes.mainWidthMax,
background: theme.palette.custom.background.main,
color: 'white',
},
Expand Down Expand Up @@ -32,7 +32,7 @@ export const useStyles = makeStyles(theme => ({
'100%': {
backgroundColor: theme.palette.primary.main,
}
}
},
}));

export default useStyles
35 changes: 35 additions & 0 deletions styles/home.style.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { makeStyles } from "@material-ui/core";

export const useStyles = makeStyles(theme => ({
mainContainer: {
maxWidth: 500,
background: theme.palette.custom.background.main,
color: 'white',
},
mainContent: {
padding: 0,
},
box: {
backgroundColor: 'rgba(255,255,255,0.15)',
},
uploadBox: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: 200,
height: 180,
borderRadius: 4,
padding: theme.spacing(4),
},
uploadBoxInner: {
marginTop: 108,
color: 'white',
},
uploadIcon: {
position: 'absolute',
fontSize: '13rem',
opacity: .35
}
}));

export default useStyles
3 changes: 0 additions & 3 deletions styles/layout.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ export const useStyles = makeStyles(theme => ({
link: {
color: "white",
},
mainContent: {
marginTop: 56,
},
logo: {
marginRight: theme.spacing(1),
}
Expand Down
18 changes: 18 additions & 0 deletions styles/loading-experiment.style.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { makeStyles } from "@material-ui/core";

export const useStyles = makeStyles(theme => ({
loadingContainer: {
marginTop: theme.spacing(4),
minWidth: theme.sizes.mainWidthMin,
maxWidth: theme.sizes.mainWidthMax,
background: theme.palette.custom.background.main,
color: 'white',
textAlign: 'center',
height: '50vh',
},
progress: {
color: 'white',
}
}));

export default useStyles
Loading