Material Redesign #1
@ -1,25 +1,49 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
|
import { Route, Link, Switch } from "react-router-dom";
|
||||||
const axios = require('axios');
|
import { Paper, Tabs, Tab} from '@material-ui/core';
|
||||||
|
|
||||||
|
|
||||||
import Lock from "./Lock.js";
|
import Lock from "./Lock.js";
|
||||||
import Functions from "./Functions.js";
|
import Functions from "./Functions.js";
|
||||||
import Tasks from "./Tasks.js";
|
import Tasks from "./Tasks.js";
|
||||||
|
|
||||||
class Admin extends Component {
|
class Admin extends Component {
|
||||||
|
|
||||||
|
constructor(props){
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
tab: 0
|
||||||
|
}
|
||||||
|
this.handleChange = this.handleChange.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChange(e, newValue){
|
||||||
|
this.setState({
|
||||||
|
tab: newValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ul className="navbar" style={{width: "100%"}}>
|
<Paper>
|
||||||
<li><Link to={`${this.props.match.url}/lock`}>Lock Accounts</Link></li>
|
<Tabs
|
||||||
<li><Link to={`${this.props.match.url}/functions`}>Functions</Link></li>
|
value={this.state.tab}
|
||||||
<li><Link to={`${this.props.match.url}/tasks`}>Tasks</Link></li>
|
onChange={this.handleChange}
|
||||||
</ul>
|
indicatorColor="primary"
|
||||||
|
centered
|
||||||
|
width="50%"
|
||||||
|
>
|
||||||
|
<Tab label="Lock Accounts" component={Link} to={`${this.props.match.url}/lock`} />
|
||||||
|
<Tab label="Functions" component={Link} to={`${this.props.match.url}/functions`} />
|
||||||
|
<Tab label="Tasks" component={Link} to={`${this.props.match.url}/tasks`} />
|
||||||
|
</Tabs>
|
||||||
|
</Paper>
|
||||||
|
<Switch>
|
||||||
<Route path={`${this.props.match.url}/lock`} component={Lock} />
|
<Route path={`${this.props.match.url}/lock`} component={Lock} />
|
||||||
<Route path={`${this.props.match.url}/functions`} component={Functions} />
|
<Route path={`${this.props.match.url}/functions`} component={Functions} />
|
||||||
<Route path={`${this.props.match.url}/tasks`} component={Tasks} />
|
<Route path={`${this.props.match.url}/tasks`} component={Tasks} />
|
||||||
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import React, { Component } from "react";
|
|||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
import showMessage from "../Toast.js"
|
import showMessage from "../Toast.js"
|
||||||
|
import { Card, Button, ButtonGroup, CardContent, CardActions, Typography } from "@material-ui/core";
|
||||||
|
|
||||||
class Functions extends Component {
|
class Functions extends Component {
|
||||||
|
|
||||||
@ -34,27 +35,20 @@ class Functions extends Component {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<table className="app-table max-width">
|
<div style={{maxWidth: '1000px', margin: 'auto', marginTop: '20px'}}>
|
||||||
<thead>
|
<Card align="center">
|
||||||
<tr>
|
<CardContent>
|
||||||
<th>
|
<Typography variant="h4" color="textPrimary">Admin Functions</Typography>
|
||||||
<h1 className="text-no-select full-width center-text ui-text">Admin Functions</h1>
|
</CardContent>
|
||||||
</th>
|
<CardActions>
|
||||||
</tr>
|
<ButtonGroup variant="contained" color="primary" className="full-width">
|
||||||
</thead>
|
<Button className="full-width button" onClick={this.runAllUsers}>Run All Users</Button>
|
||||||
<tbody>
|
<Button className="full-width button" onClick={this.runStats}>Run Stats</Button>
|
||||||
<tr>
|
</ButtonGroup>
|
||||||
<td>
|
</CardActions>
|
||||||
<button className="full-width button" onClick={this.runAllUsers}>Run All Users</button>
|
</Card>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
);
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<button className="full-width button" onClick={this.runStats}>Run Stats</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,18 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
|
import { Card, Button, CardActions, CardContent, Typography, Grid } from '@material-ui/core';
|
||||||
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
|
||||||
import showMessage from "../Toast.js"
|
import showMessage from "../Toast.js"
|
||||||
|
|
||||||
|
const useStyles = makeStyles({
|
||||||
|
root: {
|
||||||
|
background: '#9e9e9e',
|
||||||
|
color: '#212121'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
class Lock extends Component {
|
class Lock extends Component {
|
||||||
|
|
||||||
constructor(props){
|
constructor(props){
|
||||||
@ -46,42 +56,38 @@ class Lock extends Component {
|
|||||||
|
|
||||||
const loadingMessage = <p className="center-text text-no-select">loading...</p>;
|
const loadingMessage = <p className="center-text text-no-select">loading...</p>;
|
||||||
|
|
||||||
return this.state.isLoading ? loadingMessage :
|
return this.state.isLoading ? loadingMessage :
|
||||||
<div>
|
<div style={{maxWidth: '1000px', margin: 'auto', marginTop: '20px'}}>
|
||||||
<table className="app-table max-width">
|
<Card align="center">
|
||||||
<thead>
|
<CardContent>
|
||||||
<tr>
|
<Typography variant="h4" color="textPrimary">Account Locks</Typography>
|
||||||
<th colSpan='3'>
|
<Grid container spacing={3}>
|
||||||
<h1 className="text-no-select">
|
{ this.state.accounts.map((account) => <Row account={account} handler={this.handleLock}
|
||||||
Account Locks
|
key= {account.username}/>) }
|
||||||
</h1>
|
</Grid>
|
||||||
</th>
|
</CardContent>
|
||||||
</tr>
|
</Card>
|
||||||
</thead>
|
</div>
|
||||||
<tbody>
|
|
||||||
{ this.state.accounts.map((account) => <Row account={account} handler={this.handleLock}
|
|
||||||
key= {account.username}/>) }
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Row(props){
|
function Row(props){
|
||||||
|
const classes = useStyles();
|
||||||
return (
|
return (
|
||||||
<tr>
|
<Grid item xs={12} sm={3} md={2}>
|
||||||
<td className="ui-text center-text text-no-select" style={{width: "40%"}}>{ props.account.username }</td>
|
<Card variant="outlined" className={classes.root}>
|
||||||
<td className="ui-text center-text text-no-select" style={{width: "30%"}}>
|
<CardContent>
|
||||||
{ props.account.last_login }
|
<Typography variant="h5" color="textSecondary" className={classes.root}>{ props.account.username }</Typography>
|
||||||
</td>
|
<Typography variant="body2" color="textSecondary" className={classes.root}>{ props.account.last_login }</Typography>
|
||||||
<td style={{width: "30%"}}>
|
</CardContent>
|
||||||
<button className="button full-width"
|
<CardActions>
|
||||||
onClick={(e) => props.handler(e, props.account.username, !props.account.locked)}>
|
<Button className="full-width" color="secondary" variant="contained" aria-label="delete" onClick={(e) => props.handler(e, props.account.username, !props.account.locked)}>
|
||||||
{props.account.locked ? "Unlock" : "Lock"}
|
{props.account.locked ? "Unlock" : "Lock"}
|
||||||
</button>
|
</Button>
|
||||||
</td>
|
</CardActions>
|
||||||
</tr>
|
</Card>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
|
import { Card, CardContent, Typography, Grid } from '@material-ui/core';
|
||||||
|
|
||||||
import showMessage from "../Toast.js"
|
import showMessage from "../Toast.js"
|
||||||
|
|
||||||
class Tasks extends Component {
|
class Tasks extends Component {
|
||||||
@ -30,41 +32,26 @@ class Tasks extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<table className="app-table max-width">
|
<div style={{maxWidth: '1000px', margin: 'auto', marginTop: '20px'}}>
|
||||||
<thead>
|
<Grid container spacing={4}>
|
||||||
<tr>
|
{ this.state.tasks.map((entry) => <TaskType url={entry.url} count={entry.count} times={entry.scheduled_times} key={entry.url}/>)}
|
||||||
<th>
|
</Grid>
|
||||||
<h1 className="text-no-select full-width center-text ui-text">Running Tasks</h1>
|
</div>
|
||||||
</th>
|
);
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
{ this.state.tasks.map((entry) => <TaskType url={entry.url} count={entry.count} times={entry.scheduled_times} key={entry.url}/>)}
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td className="text-no-select full-width center-text ui-text" colSpan='2'>
|
|
||||||
<b>{this.state.total_tasks}</b> Currently Running
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function TaskType(props) {
|
function TaskType(props) {
|
||||||
return (
|
return (
|
||||||
<tbody>
|
<Grid item xs={12} sm={6} md={4}>
|
||||||
<tr>
|
<Card align="center">
|
||||||
<td className="text-no-select full-width center-text ui-text" colSpan='2'>
|
<CardContent>
|
||||||
{props.url}: {props.count}
|
<Typography variant="body2" color="textSecondary">{props.url}: {props.count}</Typography>
|
||||||
</td>
|
{props.times.map((entry) => <Typography variant="body2" color="textSecondary">{entry}</Typography>)}
|
||||||
</tr>
|
</CardContent>
|
||||||
{props.times.map((entry) => <tr key={entry}>
|
</Card>
|
||||||
<td colSpan='2' className="text-no-select full-width center-text ui-text">
|
</Grid>
|
||||||
{entry}
|
|
||||||
</td>
|
|
||||||
</tr>)}
|
|
||||||
</tbody>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,21 +1,12 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { BrowserRouter as Route, Link} from "react-router-dom";
|
import { BrowserRouter as Route} from "react-router-dom";
|
||||||
|
|
||||||
import Count from "./Count.js";
|
import Count from "./Count.js";
|
||||||
|
|
||||||
class Maths extends Component {
|
class Maths extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return <Route path={`${this.props.match.url}/count`} render={(props) => <Count {...props} name={this.props.match.params.name}/>} />;
|
||||||
|
|
||||||
<div>
|
|
||||||
<ul className="navbar" style={{width: "100%"}}>
|
|
||||||
<li><Link to={`${this.props.match.url}/count`}>count</Link></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<Route path={`${this.props.match.url}/count`} render={(props) => <Count {...props} name={this.props.match.params.name}/>} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,10 @@ class PieChart extends Component {
|
|||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
legend : {
|
legend : {
|
||||||
display : true
|
display : true,
|
||||||
|
labels: {
|
||||||
|
fontColor: 'white'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
elements: {
|
elements: {
|
||||||
arc : {
|
arc : {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { BrowserRouter as Router, Route, Link, Switch, Redirect} from "react-router-dom";
|
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
|
||||||
|
|
||||||
import NotFound from "./Error/NotFound.js";
|
import NotFound from "./Error/NotFound.js";
|
||||||
|
|
||||||
@ -80,7 +80,6 @@ class MusicTools extends Component {
|
|||||||
render(){
|
render(){
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
<div className="card pad-12">
|
|
||||||
<ThemeProvider theme={GlobalTheme}>
|
<ThemeProvider theme={GlobalTheme}>
|
||||||
<AppBar position="static">
|
<AppBar position="static">
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
@ -143,7 +142,6 @@ class MusicTools extends Component {
|
|||||||
</List>
|
</List>
|
||||||
</div>
|
</div>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</ThemeProvider>
|
|
||||||
<div className="full-width">
|
<div className="full-width">
|
||||||
<Switch>
|
<Switch>
|
||||||
<React.Suspense fallback={<LoadingMessage/>}>
|
<React.Suspense fallback={<LoadingMessage/>}>
|
||||||
@ -157,7 +155,7 @@ class MusicTools extends Component {
|
|||||||
<Route component={NotFound} />
|
<Route component={NotFound} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</ThemeProvider>
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
|
import { Route, Switch } from "react-router-dom";
|
||||||
|
|
||||||
import PlaylistsView from "./PlaylistsList.js"
|
import PlaylistsView from "./PlaylistsList.js"
|
||||||
import NewPlaylist from "./New.js";
|
import NewPlaylist from "./New.js";
|
||||||
@ -8,12 +8,7 @@ import ScratchView from "./ScratchView.js";
|
|||||||
class Playlists extends Component {
|
class Playlists extends Component {
|
||||||
render(){
|
render(){
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ul className="navbar" style={{width: "100%"}}>
|
|
||||||
<li><Link to={`${this.props.match.url}/new`}>New</Link></li>
|
|
||||||
<li><Link to={`${this.props.match.url}/play`}>Play</Link></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path={`${this.props.match.url}/`} component={PlaylistsView} />
|
<Route exact path={`${this.props.match.url}/`} component={PlaylistsView} />
|
||||||
<Route path={`${this.props.match.url}/new`} component={NewPlaylist} />
|
<Route path={`${this.props.match.url}/new`} component={NewPlaylist} />
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
|
import { Card, Button, FormControl, TextField, InputLabel, Select, CardActions, CardContent, Typography, Grid } from '@material-ui/core';
|
||||||
|
|
||||||
import showMessage from "../Toast.js"
|
import showMessage from "../Toast.js"
|
||||||
|
|
||||||
class NewPlaylist extends Component {
|
class NewPlaylist extends Component {
|
||||||
@ -81,44 +83,46 @@ class NewPlaylist extends Component {
|
|||||||
|
|
||||||
render(){
|
render(){
|
||||||
return (
|
return (
|
||||||
<table className="app-table max-width">
|
<Card align="center">
|
||||||
<thead>
|
<CardContent>
|
||||||
<tr>
|
<Grid container>
|
||||||
<th colSpan="2">
|
<Grid item xs={12}>
|
||||||
<h1 className="ui-text center-text text-no-select">New Playlist</h1>
|
<Typography variant="h3">New</Typography>
|
||||||
</th>
|
</Grid>
|
||||||
</tr>
|
<Grid item xs={4}>
|
||||||
</thead>
|
<FormControl variant="filled">
|
||||||
<tbody>
|
<InputLabel htmlFor="type-select">Type</InputLabel>
|
||||||
<tr>
|
<Select
|
||||||
<td>
|
native
|
||||||
<select className="full-width" name="type" onChange={this.handleInputChange}>
|
value={this.state.type}
|
||||||
<option value="default">Default</option>
|
|
||||||
<option value="recents">Recents</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<input
|
|
||||||
className="full-width"
|
|
||||||
name="name"
|
|
||||||
type="text"
|
|
||||||
value={this.state.name}
|
|
||||||
onChange={this.handleInputChange}
|
onChange={this.handleInputChange}
|
||||||
placeholder="Name"/>
|
inputProps={{
|
||||||
</td>
|
name: 'type',
|
||||||
</tr>
|
id: 'type-select',
|
||||||
<tr>
|
}}
|
||||||
<td colSpan="2">
|
>
|
||||||
<input type="submit" className="button full-width" onClick={this.handleSubmit} value="Create" />
|
<option value="default">Default</option>
|
||||||
</td>
|
<option value="recents">Recents</option>
|
||||||
</tr>
|
</Select>
|
||||||
<tr>
|
</FormControl>
|
||||||
<td colSpan="2" className="ui-text text-no-select center-text">
|
</Grid>
|
||||||
<br></br>{this.state.description}
|
<Grid item xs={8}>
|
||||||
</td>
|
<TextField
|
||||||
</tr>
|
label="Name"
|
||||||
</tbody>
|
variant="outlined"
|
||||||
</table>
|
onChange={this.handleInputChange}
|
||||||
|
name="name"
|
||||||
|
value={this.state.name} />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body2" color="textSecondary">{ this.state.description }</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</CardContent>
|
||||||
|
<CardActions>
|
||||||
|
<Button variant="contained" color="primary" className="full-width" onClick={this.handleSubmit}>Create</Button>
|
||||||
|
</CardActions>
|
||||||
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,11 +3,9 @@ import { Link } from "react-router-dom";
|
|||||||
import { Button, ButtonGroup, Typography, Card, Grid, CircularProgress } from '@material-ui/core';
|
import { Button, ButtonGroup, Typography, Card, Grid, CircularProgress } from '@material-ui/core';
|
||||||
import CardActions from '@material-ui/core/CardActions';
|
import CardActions from '@material-ui/core/CardActions';
|
||||||
import CardContent from '@material-ui/core/CardContent';
|
import CardContent from '@material-ui/core/CardContent';
|
||||||
import { ThemeProvider } from '@material-ui/core/styles';
|
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
import showMessage from "../Toast.js"
|
import showMessage from "../Toast.js"
|
||||||
import GlobalTheme from "../Theme.js"
|
|
||||||
|
|
||||||
class PlaylistsView extends Component {
|
class PlaylistsView extends Component {
|
||||||
|
|
||||||
@ -106,26 +104,32 @@ class PlaylistsView extends Component {
|
|||||||
|
|
||||||
function PlaylistGrid(props){
|
function PlaylistGrid(props){
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={GlobalTheme}>
|
|
||||||
<Grid container
|
<Grid container
|
||||||
spacing={3}
|
spacing={3}
|
||||||
direction="row"
|
direction="row"
|
||||||
justify="flex-start"
|
justify="flex-start"
|
||||||
alignItems="flex-start"
|
alignItems="flex-start"
|
||||||
style={{padding: '24px'}}>
|
style={{padding: '24px'}}>
|
||||||
|
<Grid item xs>
|
||||||
|
<ButtonGroup
|
||||||
|
color="primary"
|
||||||
|
orientation="vertical"
|
||||||
|
className="full-width">
|
||||||
|
<Button component={Link} to='playlists/new' >New</Button>
|
||||||
|
<Button onClick={props.handleRunAll}>Run All</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
</Grid>
|
||||||
{ props.playlists.length == 0 ? (
|
{ props.playlists.length == 0 ? (
|
||||||
<Grid item item xs={12} sm={6} md={3}>
|
<Grid item xs={12} sm={6} md={3}>
|
||||||
<Typography variant="h5" component="h2">No Playlists</Typography>
|
<Typography variant="h5" component="h2">No Playlists</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
) : (
|
) : (
|
||||||
props.playlists.map((playlist) => <PlaylistCard playlist={ playlist }
|
props.playlists.map((playlist) => <PlaylistCard playlist={ playlist }
|
||||||
handleRunPlaylist={props.handleRunPlaylist}
|
handleRunPlaylist={props.handleRunPlaylist}
|
||||||
handleDeletePlaylist={props.handleDeletePlaylist}
|
handleDeletePlaylist={props.handleDeletePlaylist}
|
||||||
key={ playlist.name }/>)
|
key={ playlist.name }/>)
|
||||||
)}
|
)}
|
||||||
<Grid item xs><Button variant="contained" color="secondary" className="full-width" onClick={props.handleRunAll}>Run All</Button></Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ThemeProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,10 +143,12 @@ function PlaylistCard(props){
|
|||||||
</Typography>
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardActions>
|
<CardActions>
|
||||||
<ButtonGroup color="primary">
|
<ButtonGroup
|
||||||
<Button variant="contained" component={Link} to={getPlaylistLink(props.playlist.name)}>View</Button>
|
color="primary"
|
||||||
<Button variant="contained" onClick={(e) => props.handleRunPlaylist(props.playlist.name, e)}>Run</Button>
|
variant="contained">
|
||||||
<Button variant="contained" onClick={(e) => props.handleDeletePlaylist(props.playlist.name, e)}>Delete</Button>
|
<Button component={Link} to={getPlaylistLink(props.playlist.name)}>View</Button>
|
||||||
|
<Button onClick={(e) => props.handleRunPlaylist(props.playlist.name, e)}>Run</Button>
|
||||||
|
<Button onClick={(e) => props.handleDeletePlaylist(props.playlist.name, e)}>Delete</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</CardActions>
|
</CardActions>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { ThemeProvider, Typography } from "@material-ui/core";
|
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
|
import { Card, Button, CardActions, CardContent, Typography, Grid } from '@material-ui/core';
|
||||||
|
|
||||||
import showMessage from "../../Toast.js"
|
import showMessage from "../../Toast.js"
|
||||||
import GlobalTheme from "../../Theme";
|
|
||||||
|
|
||||||
const LazyPieChart = React.lazy(() => import("../../Maths/PieChart"))
|
const LazyPieChart = React.lazy(() => import("../../Maths/PieChart"))
|
||||||
|
|
||||||
@ -67,35 +67,35 @@ export class Count extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<tbody>
|
<div style={{margin: 'auto', marginTop: '20px'}}>
|
||||||
<tr>
|
<Card align="center">
|
||||||
<td className="ui-text center-text text-no-select">Scrobble Count: <b>{this.state.playlist.lastfm_stat_count.toLocaleString()} / {this.state.playlist.lastfm_stat_percent}%</b></td>
|
<CardContent>
|
||||||
</tr>
|
<Grid container>
|
||||||
<tr>
|
<Grid item xs={12}>
|
||||||
<td className="ui-text center-text text-no-select">Album Count: <b>{this.state.playlist.lastfm_stat_album_count.toLocaleString()} / {this.state.playlist.lastfm_stat_album_percent}%</b></td>
|
<Typography variant="body2">Scrobble Count: <b>{this.state.playlist.lastfm_stat_count.toLocaleString()} / {this.state.playlist.lastfm_stat_percent}%</b></Typography>
|
||||||
</tr>
|
</Grid>
|
||||||
<tr>
|
<Grid item xs={12}>
|
||||||
<td className="ui-text center-text text-no-select">Artist Count: <b>{this.state.playlist.lastfm_stat_artist_count.toLocaleString()} / {this.state.playlist.lastfm_stat_artist_percent}%</b></td>
|
<Typography variant="body2">Album Count: <b>{this.state.playlist.lastfm_stat_album_count.toLocaleString()} / {this.state.playlist.lastfm_stat_album_percent}%</b></Typography>
|
||||||
</tr>
|
</Grid>
|
||||||
<tr>
|
<Grid item xs={12}>
|
||||||
<td className="ui-text center-text text-no-select">Last Updated <b>{this.state.playlist.lastfm_stat_last_refresh.toLocaleString()}</b></td>
|
<Typography variant="body2">Artist Count: <b>{this.state.playlist.lastfm_stat_artist_count.toLocaleString()} / {this.state.playlist.lastfm_stat_artist_percent}%</b></Typography>
|
||||||
</tr>
|
</Grid>
|
||||||
<React.Suspense fallback={<LoadingMessage/>}>
|
<Grid item xs={12}>
|
||||||
<tr>
|
<Typography variant="body2">Last Updated <b>{this.state.playlist.lastfm_stat_last_refresh.toLocaleString()}</b></Typography>
|
||||||
<td>
|
</Grid>
|
||||||
<LazyPieChart data={[{
|
<React.Suspense fallback={<LoadingMessage/>}>
|
||||||
"label": `${this.state.playlist.name} Tracks`,
|
<Grid item xs={12} sm={12} md={4}>
|
||||||
"value": this.state.playlist.lastfm_stat_percent
|
<LazyPieChart data={[{
|
||||||
},{
|
"label": `${this.state.playlist.name} Tracks`,
|
||||||
"label": 'Other',
|
"value": this.state.playlist.lastfm_stat_percent
|
||||||
"value": 100 - this.state.playlist.lastfm_stat_percent
|
},{
|
||||||
}]}
|
"label": 'Other',
|
||||||
title={this.state.playlist.name}/>
|
"value": 100 - this.state.playlist.lastfm_stat_percent
|
||||||
</td>
|
}]}
|
||||||
</tr>
|
title={this.state.playlist.name}/>
|
||||||
<tr>
|
</Grid>
|
||||||
<td>
|
<Grid item xs={12} sm={12} md={4}>
|
||||||
<LazyPieChart data={[{
|
<LazyPieChart data={[{
|
||||||
"label": `${this.state.playlist.name} Albums`,
|
"label": `${this.state.playlist.name} Albums`,
|
||||||
"value": this.state.playlist.lastfm_stat_album_percent
|
"value": this.state.playlist.lastfm_stat_album_percent
|
||||||
},{
|
},{
|
||||||
@ -103,31 +103,29 @@ export class Count extends Component {
|
|||||||
"value": 100 - this.state.playlist.lastfm_stat_album_percent
|
"value": 100 - this.state.playlist.lastfm_stat_album_percent
|
||||||
}]}
|
}]}
|
||||||
title={this.state.playlist.name}/>
|
title={this.state.playlist.name}/>
|
||||||
</td>
|
</Grid>
|
||||||
</tr>
|
<Grid item xs={12} sm={12} md={4}>
|
||||||
<tr>
|
<LazyPieChart data={[{
|
||||||
<td>
|
"label": `${this.state.playlist.name} Artists`,
|
||||||
<LazyPieChart data={[{
|
"value": this.state.playlist.lastfm_stat_artist_percent
|
||||||
"label": `${this.state.playlist.name} Artists`,
|
},{
|
||||||
"value": this.state.playlist.lastfm_stat_artist_percent
|
"label": 'Other',
|
||||||
},{
|
"value": 100 - this.state.playlist.lastfm_stat_artist_percent
|
||||||
"label": 'Other',
|
}]}
|
||||||
"value": 100 - this.state.playlist.lastfm_stat_artist_percent
|
title={this.state.playlist.name}/>
|
||||||
}]}
|
</Grid>
|
||||||
title={this.state.playlist.name}/>
|
</React.Suspense>
|
||||||
</td>
|
</Grid>
|
||||||
</tr>
|
</CardContent>
|
||||||
<tr>
|
<CardActions>
|
||||||
<td colSpan="2">
|
<Button variant="contained" color="primary" className="full-width" onClick={this.updateStats}>Update</Button>
|
||||||
<button style={{width: "100%"}} className="button" onClick={this.updateStats}>Update</button>
|
</CardActions>
|
||||||
</td>
|
</Card>
|
||||||
</tr>
|
</div>
|
||||||
</React.Suspense>
|
|
||||||
</tbody>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function LoadingMessage(props) {
|
function LoadingMessage(props) {
|
||||||
return <tr><td><ThemeProvider theme={GlobalTheme}><Typography variant="h5" component="h2" className="ui-text center-text">Loading...</Typography></ThemeProvider></td></tr>;
|
return <Typography variant="h5" component="h2" className="ui-text center-text">Loading...</Typography>;
|
||||||
}
|
}
|
@ -1,10 +1,10 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
import { Card, Paper, Button, CircularProgress, FormControl, TextField, Input, InputLabel, Select, Checkbox, FormControlLabel, IconButton, InputAdornment } from '@material-ui/core';
|
import { Card, Button, CircularProgress, FormControl, TextField, InputLabel, Select, Checkbox, FormControlLabel,
|
||||||
import { ThemeProvider } from '@material-ui/core/styles';
|
CardActions, CardContent, Typography, Grid } from '@material-ui/core';
|
||||||
import { Add, Delete } from '@material-ui/icons';
|
import { Delete } from '@material-ui/icons';
|
||||||
import GlobalTheme from "../../Theme.js"
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
|
||||||
import showMessage from "../../Toast.js";
|
import showMessage from "../../Toast.js";
|
||||||
|
|
||||||
@ -38,6 +38,14 @@ var lastMonth = [
|
|||||||
'november'
|
'november'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const useStyles = makeStyles({
|
||||||
|
root: {
|
||||||
|
background: '#9e9e9e',
|
||||||
|
color: '#212121'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export class Edit extends Component{
|
export class Edit extends Component{
|
||||||
|
|
||||||
constructor(props){
|
constructor(props){
|
||||||
@ -398,155 +406,164 @@ export class Edit extends Component{
|
|||||||
var date = new Date();
|
var date = new Date();
|
||||||
|
|
||||||
const table = (
|
const table = (
|
||||||
<ThemeProvider theme={GlobalTheme}>
|
<div style={{maxWidth: '1000px', margin: 'auto', marginTop: '20px'}}>
|
||||||
<Card>
|
<Card align="center">
|
||||||
{ this.state.playlist_references.length > 0 && <tr><td colSpan="2" className="ui-text center-text text-no-select" style={{fontStyle: 'italic'}}>Managed</td></tr> }
|
<CardContent>
|
||||||
{ this.state.playlist_references.length > 0 && <ListBlock handler={this.handleRemoveReference} list={this.state.playlist_references}/> }
|
<Typography variant="h2" color="textPrimary">{this.state.name}</Typography>
|
||||||
|
<Grid container spacing={5}>
|
||||||
|
|
||||||
|
{ this.state.playlist_references.length > 0 && <Grid item xs={12} ><Typography color="textSecondary" variant="h4">Managed</Typography></Grid> }
|
||||||
|
{ this.state.playlist_references.length > 0 && <ListBlock handler={this.handleRemoveReference} list={this.state.playlist_references}/> }
|
||||||
|
|
||||||
{ this.state.parts.length > 0 && <tr><td colSpan="2" className="ui-text center-text text-no-select" style={{fontStyle: 'italic'}}>Spotify</td></tr> }
|
{ this.state.parts.length > 0 && <Grid item xs={12} ><Typography color="textSecondary" variant="h4">Spotify</Typography></Grid> }
|
||||||
{ this.state.parts.length > 0 && <ListBlock handler={this.handleRemovePart} list={this.state.parts}/> }
|
{ this.state.parts.length > 0 && <ListBlock handler={this.handleRemovePart} list={this.state.parts}/> }
|
||||||
<tr>
|
<Grid item xs={12} ><Typography variant="body2" color="textSecondary">Spotify playlist can be the name of either your own created playlist or one you follow, names are case sensitive</Typography></Grid>
|
||||||
<td colSpan="2" className="center-text ui-text text-no-select" style={{fontStyle: "italic"}}>
|
<Grid item xs={8} sm={8} md={3}>
|
||||||
<br></br>Spotify playlist can be the name of either your own created playlist or one you follow, names are case sensitive
|
<TextField
|
||||||
</td>
|
name="newPlaylistName"
|
||||||
</tr>
|
label="Spotify Playlist"
|
||||||
<FormControl>
|
value={this.state.newPlaylistName}
|
||||||
<InputLabel htmlFor="newPlaylistName">Spotify Playlist</InputLabel>
|
onChange={this.handleInputChange}
|
||||||
<Input
|
|
||||||
id="newPlaylistName"
|
/>
|
||||||
name="newPlaylistName"
|
</Grid>
|
||||||
type="text"
|
<Grid item xs={4} sm={4} md={3}>
|
||||||
value={this.state.newPlaylistName}
|
<Button variant="contained" className="full-width" onClick={this.handleAddPart} style={{verticalAlign: 'middle'}}>Add</Button>
|
||||||
onChange={this.handleInputChange}
|
</Grid>
|
||||||
endAdornment={
|
<Grid item xs={8} sm={8} md={3}>
|
||||||
<InputAdornment position="end">
|
<FormControl variant="filled" style={{verticalAlign: 'middle'}}>
|
||||||
<IconButton onClick={this.handleAddPart} >
|
<InputLabel htmlFor="chart_range">Managed Playlist</InputLabel>
|
||||||
<Add/>
|
<Select
|
||||||
</IconButton>
|
native
|
||||||
</InputAdornment>
|
value={this.state.newReferenceName}
|
||||||
|
onChange={this.handleInputChange}
|
||||||
|
inputProps={{
|
||||||
|
name: "newReferenceName",
|
||||||
|
id: "newReferenceName",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ this.state.playlists
|
||||||
|
.filter((entry) => entry.name != this.state.name)
|
||||||
|
.map((entry) => <ReferenceEntry name={entry.name} key={entry.name} />) }
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={4} sm={4} md={3}>
|
||||||
|
<Button variant="contained" className="full-width" onClick={this.handleAddReference} style={{verticalAlign: 'middle'}}>Add</Button>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox color="primary" checked={this.state.shuffle} onChange={this.handleShuffleChange} />
|
||||||
|
}
|
||||||
|
labelPlacement="bottom"
|
||||||
|
label="Shuffle"/>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox color="primary" checked={this.state.include_recommendations} onChange={this.handleIncludeRecommendationsChange} />
|
||||||
|
}
|
||||||
|
labelPlacement="bottom"
|
||||||
|
label="Recommendations"/>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox color="primary" checked={this.state.include_library_tracks} onChange={this.handleIncludeLibraryTracksChange} />
|
||||||
|
}
|
||||||
|
labelPlacement="bottom"
|
||||||
|
label="Library Tracks"/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<TextField type="number"
|
||||||
|
name="recommendation_sample"
|
||||||
|
label="Recommendation Size"
|
||||||
|
value={this.state.recommendation_sample}
|
||||||
|
onChange={this.handleInputChange}></TextField>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{ this.state.type == 'fmchart' &&
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<TextField type="number"
|
||||||
|
name="chart_limit"
|
||||||
|
label="Chart Size"
|
||||||
|
value={this.state.chart_limit}
|
||||||
|
onChange={this.handleInputChange}></TextField>
|
||||||
|
</Grid>
|
||||||
}
|
}
|
||||||
/>
|
{ this.state.type == 'fmchart' &&
|
||||||
</FormControl>
|
<Grid item xs={12}>
|
||||||
<tr>
|
<FormControl variant="filled">
|
||||||
<td>
|
<InputLabel htmlFor="chart_range">Chart Range</InputLabel>
|
||||||
<FormControl variant="filled">
|
<Select
|
||||||
<InputLabel htmlFor="chart_range">Managed Playlist</InputLabel>
|
native
|
||||||
<Select
|
value={this.state.chart_range}
|
||||||
native
|
onChange={this.handleInputChange}
|
||||||
value={this.state.newReferenceName}
|
inputProps={{
|
||||||
onChange={this.handleInputChange}
|
name: "chart_range",
|
||||||
inputProps={{
|
id: "chart_range",
|
||||||
name: "newReferenceName",
|
}}
|
||||||
id: "newReferenceName",
|
>
|
||||||
}}
|
<option value="WEEK">7 Day</option>
|
||||||
>
|
<option value="MONTH">30 Day</option>
|
||||||
{ this.state.playlists
|
<option value="QUARTER">90 Day</option>
|
||||||
.filter((entry) => entry.name != this.state.name)
|
<option value="HALFYEAR">180 Day</option>
|
||||||
.map((entry) => <ReferenceEntry name={entry.name} key={entry.name} />) }
|
<option value="YEAR">365 Day</option>
|
||||||
</Select>
|
<option value="OVERALL">Overall</option>
|
||||||
</FormControl>
|
</Select>
|
||||||
</td>
|
</FormControl>
|
||||||
<td>
|
</Grid>
|
||||||
<Button className="full-width" onClick={this.handleAddReference}>Add</Button>
|
}
|
||||||
</td>
|
{ this.state.type == 'recents' &&
|
||||||
</tr>
|
<Grid item xs={12}>
|
||||||
<FormControlLabel
|
<TextField type="number"
|
||||||
control={
|
name="day_boundary"
|
||||||
<Checkbox checked={this.state.shuffle} onChange={this.handleShuffleChange} />
|
// className="full-width"
|
||||||
}
|
label="Added Since (days)"
|
||||||
labelPlacement="bottom"
|
value={this.state.day_boundary}
|
||||||
label="Shuffle"/>
|
onChange={this.handleInputChange} />
|
||||||
<FormControlLabel
|
</Grid>
|
||||||
control={
|
}
|
||||||
<Checkbox checked={this.state.include_recommendations} onChange={this.handleIncludeRecommendationsChange} />
|
{ this.state.type == 'recents' &&
|
||||||
}
|
<Grid item xs={12}>
|
||||||
labelPlacement="bottom"
|
<FormControlLabel
|
||||||
label="Recommendations"/>
|
control={
|
||||||
<FormControlLabel
|
<Checkbox color="primary" checked={this.state.add_this_month} onChange={this.handleThisMonthChange} />
|
||||||
control={
|
}
|
||||||
<Checkbox checked={this.state.include_library_tracks} onChange={this.handleIncludeLibraryTracksChange} />
|
label="This Month"
|
||||||
}
|
labelPlacement="bottom"
|
||||||
labelPlacement="bottom"
|
/>
|
||||||
label="Library Tracks"/>
|
<FormControlLabel
|
||||||
<TextField type="number"
|
control={
|
||||||
name="recommendation_sample"
|
<Checkbox color="primary" checked={this.state.add_last_month} onChange={this.handleLastMonthChange} />
|
||||||
// className="full-width"
|
}
|
||||||
label="Recommendation Size"
|
label="Last Month"
|
||||||
value={this.state.recommendation_sample}
|
labelPlacement="bottom"
|
||||||
onChange={this.handleInputChange}></TextField>
|
/>
|
||||||
|
</Grid>
|
||||||
{ this.state.type == 'fmchart' &&
|
}
|
||||||
<TextField type="number"
|
<Grid item xs={12}>
|
||||||
name="chart_limit"
|
<FormControl variant="filled">
|
||||||
// className="full-width"
|
<InputLabel htmlFor="type-select">Type</InputLabel>
|
||||||
label="Chart Size"
|
<Select
|
||||||
value={this.state.chart_limit}
|
native
|
||||||
onChange={this.handleInputChange}></TextField>
|
value={this.state.type}
|
||||||
}
|
onChange={this.handleInputChange}
|
||||||
{ this.state.type == 'fmchart' &&
|
inputProps={{
|
||||||
<FormControl variant="filled">
|
name: 'type',
|
||||||
<InputLabel htmlFor="chart_range">Chart Range</InputLabel>
|
id: 'type-select',
|
||||||
<Select
|
}}
|
||||||
native
|
>
|
||||||
value={this.state.chart_range}
|
<option value="default">Default</option>
|
||||||
onChange={this.handleInputChange}
|
<option value="recents">Recents</option>
|
||||||
inputProps={{
|
<option value="fmchart">Last.fm Chart</option>
|
||||||
name: "chart_range",
|
</Select>
|
||||||
id: "chart_range",
|
</FormControl>
|
||||||
}}
|
</Grid>
|
||||||
>
|
</Grid>
|
||||||
<option value="WEEK">7 Day</option>
|
</CardContent>
|
||||||
<option value="MONTH">30 Day</option>
|
<CardActions>
|
||||||
<option value="QUARTER">90 Day</option>
|
<Button onClick={this.handleRun} variant="contained" color="primary" className="full-width" >Run</Button>
|
||||||
<option value="HALFYEAR">180 Day</option>
|
</CardActions>
|
||||||
<option value="YEAR">365 Day</option>
|
|
||||||
<option value="OVERALL">Overall</option>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
}
|
|
||||||
{ this.state.type == 'recents' &&
|
|
||||||
<TextField type="number"
|
|
||||||
name="day_boundary"
|
|
||||||
// className="full-width"
|
|
||||||
label="Added Since (days)"
|
|
||||||
value={this.state.day_boundary}
|
|
||||||
onChange={this.handleInputChange}></TextField>
|
|
||||||
}
|
|
||||||
{ this.state.type == 'recents' &&
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox checked={this.state.add_this_month} onChange={this.handleThisMonthChange} />
|
|
||||||
}
|
|
||||||
label="This Month"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
{ this.state.type == 'recents' &&
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox checked={this.state.add_last_month} onChange={this.handleLastMonthChange} />
|
|
||||||
}
|
|
||||||
label="Last Month"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
<FormControl variant="filled">
|
|
||||||
<InputLabel htmlFor="type-select">Type</InputLabel>
|
|
||||||
<Select
|
|
||||||
native
|
|
||||||
value={this.state.type}
|
|
||||||
onChange={this.handleInputChange}
|
|
||||||
inputProps={{
|
|
||||||
name: 'type',
|
|
||||||
id: 'type-select',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<option value="default">Default</option>
|
|
||||||
<option value="recents">Recents</option>
|
|
||||||
<option value="fmchart">Last.fm Chart</option>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<Button onClick={this.handleRun} variant="contained" color="primary">Run</Button>
|
|
||||||
</Card>
|
</Card>
|
||||||
</ThemeProvider>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
return this.state.isLoading ? <CircularProgress /> : table;
|
return this.state.isLoading ? <CircularProgress /> : table;
|
||||||
@ -559,18 +576,30 @@ function ReferenceEntry(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ListBlock(props) {
|
function ListBlock(props) {
|
||||||
return props.list.map((part) => <Row part={ part } key={ part } handler={props.handler}/>);
|
return <Grid container
|
||||||
|
spacing={3}
|
||||||
|
direction="row"
|
||||||
|
justify="flex-start"
|
||||||
|
alignItems="flex-start"
|
||||||
|
style={{padding: '24px'}}>
|
||||||
|
{props.list.map((part) => <BlockGridItem part={ part } key={ part } handler={props.handler}/>)}
|
||||||
|
</Grid>
|
||||||
}
|
}
|
||||||
|
|
||||||
function Row (props) {
|
function BlockGridItem (props) {
|
||||||
|
const classes = useStyles();
|
||||||
return (
|
return (
|
||||||
<tr>
|
<Grid item xs={12} sm={3} md={2}>
|
||||||
<td className="ui-text center-text text-no-select">{ props.part }</td>
|
<Card variant="outlined" className={classes.root}>
|
||||||
<td>
|
<CardContent>
|
||||||
<IconButton aria-label="delete" onClick={(e) => props.handler(props.part, e)}>
|
<Typography variant="h5" color="textSecondary" className={classes.root}>{ props.part }</Typography>
|
||||||
<Delete />
|
</CardContent>
|
||||||
</IconButton>
|
<CardActions>
|
||||||
</td>
|
<Button className="full-width" color="secondary" variant="contained" aria-label="delete" onClick={(e) => props.handler(props.part, e)} startIcon={<Delete />}>
|
||||||
</tr>
|
Delete
|
||||||
|
</Button>
|
||||||
|
</CardActions>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,10 +1,7 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { Route, Link, Switch } from "react-router-dom";
|
import { Route, Link, Switch } from "react-router-dom";
|
||||||
import { ThemeProvider } from '@material-ui/core/styles';
|
import { Paper, Tabs, Tab} from '@material-ui/core';
|
||||||
|
|
||||||
import { Paper, Tabs, Tab } from '@material-ui/core';
|
|
||||||
|
|
||||||
import GlobalTheme from "../../Theme.js"
|
|
||||||
|
|
||||||
import {Edit} from "./Edit.js";
|
import {Edit} from "./Edit.js";
|
||||||
import {Count} from "./Count.js";
|
import {Count} from "./Count.js";
|
||||||
@ -28,20 +25,18 @@ class View extends Component{
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ThemeProvider theme={GlobalTheme}>
|
<Paper>
|
||||||
<Paper>
|
<Tabs
|
||||||
<Tabs
|
value={this.state.tab}
|
||||||
value={this.state.tab}
|
onChange={this.handleChange}
|
||||||
onChange={this.handleChange}
|
indicatorColor="primary"
|
||||||
indicatorColor="primary"
|
centered
|
||||||
textColor="secondary"
|
width="50%"
|
||||||
centered
|
>
|
||||||
>
|
<Tab label="Edit" component={Link} to={`${this.props.match.url}/edit`} />
|
||||||
<Tab label="Edit" component={Link} to={`${this.props.match.url}/edit`} />
|
<Tab label="Count" component={Link} to={`${this.props.match.url}/count`} />
|
||||||
<Tab label="Count" component={Link} to={`${this.props.match.url}/count`} />
|
</Tabs>
|
||||||
</Tabs>
|
</Paper>
|
||||||
</Paper>
|
|
||||||
</ThemeProvider>
|
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path={`${this.props.match.url}/edit`} render={(props) => <Edit {...props} name={this.props.match.params.name}/>} />
|
<Route path={`${this.props.match.url}/edit`} render={(props) => <Edit {...props} name={this.props.match.params.name}/>} />
|
||||||
<Route path={`${this.props.match.url}/count`} render={(props) => <Count {...props} name={this.props.match.params.name}/>} />
|
<Route path={`${this.props.match.url}/count`} render={(props) => <Count {...props} name={this.props.match.params.name}/>} />
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { BrowserRouter as Router, Route, Link, Switch, Redirect} from "react-router-dom";
|
import { BrowserRouter as Route, Link } from "react-router-dom";
|
||||||
|
|
||||||
import ChangePassword from "./ChangePassword.js";
|
import ChangePassword from "./ChangePassword.js";
|
||||||
import SpotifyLink from "./SpotifyLink.js";
|
import SpotifyLink from "./SpotifyLink.js";
|
||||||
|
@ -5,8 +5,8 @@ let GlobalTheme = createMuiTheme({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
spacing: 20
|
|
||||||
},
|
},
|
||||||
|
spacing: 4,
|
||||||
typography: {
|
typography: {
|
||||||
button: {
|
button: {
|
||||||
fontSize: '1rem',
|
fontSize: '1rem',
|
||||||
@ -17,16 +17,20 @@ let GlobalTheme = createMuiTheme({
|
|||||||
spacing: 5
|
spacing: 5
|
||||||
},
|
},
|
||||||
card: {
|
card: {
|
||||||
|
marginTop: 24,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
spacing: 5
|
spacing: 5
|
||||||
},
|
},
|
||||||
palette: {
|
palette: {
|
||||||
type: 'dark',
|
type: 'dark',
|
||||||
primary: {
|
primary: {
|
||||||
main: '#1a237e',
|
main: '#1976d2',
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
main: '#2196f3',
|
main: '#dc004e',
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
main: '#f44336'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
|
Loading…
Reference in New Issue
Block a user