Merge pull request #22 from status-im/feat/project-list
Add base project list
This commit is contained in:
commit
b54db82264
|
@ -23,7 +23,7 @@ const createDelegate = (newDelegate, delegateInfo, pledge, profile, idx) => {
|
||||||
const delegateRecordExists = (profile, pledge, idx, existing) => {
|
const delegateRecordExists = (profile, pledge, idx, existing) => {
|
||||||
const record = existing.find(delegate => {
|
const record = existing.find(delegate => {
|
||||||
const { delegateIndex } = delegate
|
const { delegateIndex } = delegate
|
||||||
if (
|
if (profile &&
|
||||||
profile.id === delegate.profile.id &&
|
profile.id === delegate.profile.id &&
|
||||||
pledge.idPledge === delegate.idPledge &&
|
pledge.idPledge === delegate.idPledge &&
|
||||||
idx === delegateIndex
|
idx === delegateIndex
|
||||||
|
|
|
@ -18,11 +18,13 @@ import ListItem from '@material-ui/core/ListItem';
|
||||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||||
import ListItemText from '@material-ui/core/ListItemText';
|
import ListItemText from '@material-ui/core/ListItemText';
|
||||||
import InboxIcon from '@material-ui/icons/MoveToInbox';
|
import InboxIcon from '@material-ui/icons/MoveToInbox';
|
||||||
|
import ProjectIcon from '@material-ui/icons/Work';
|
||||||
import { ScaleLoader } from 'react-spinners'
|
import { ScaleLoader } from 'react-spinners'
|
||||||
import FundsManagement from './FundsManagement'
|
import FundsManagement from './FundsManagement'
|
||||||
import ContractAdmin from './ContractAdmin'
|
import ContractAdmin from './ContractAdmin'
|
||||||
import TransferGraph from './TransfersGraph'
|
import TransferGraph from './TransfersGraph'
|
||||||
import Dashboard from './Dashboard'
|
import Dashboard from './Dashboard'
|
||||||
|
import Projects from './projects/Projects'
|
||||||
import Project from './projects/Project'
|
import Project from './projects/Project'
|
||||||
import BackProject from './projects/BackProject'
|
import BackProject from './projects/BackProject'
|
||||||
import CreateProject from './projects/CreateProject'
|
import CreateProject from './projects/CreateProject'
|
||||||
|
@ -92,6 +94,15 @@ const styles = theme => ({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const MenuItem = ({to, name, className, icon}) => (
|
||||||
|
<Link to={to} className={className}>
|
||||||
|
<ListItem button>
|
||||||
|
<ListItemIcon>{icon}</ListItemIcon>
|
||||||
|
<ListItemText primary={name}/>
|
||||||
|
</ListItem>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
|
||||||
class PersistentDrawerLeft extends React.Component {
|
class PersistentDrawerLeft extends React.Component {
|
||||||
state = {
|
state = {
|
||||||
open: false,
|
open: false,
|
||||||
|
@ -153,40 +164,15 @@ class PersistentDrawerLeft extends React.Component {
|
||||||
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
|
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
<Divider />
|
<Divider/>
|
||||||
<List>
|
<List>
|
||||||
<Link to="/dashboard" className={classes.link}>
|
<MenuItem name="Dashboard" to="/dashboard" className={classes.link} icon={<InboxIcon/>}/>
|
||||||
<ListItem button>
|
<MenuItem name="Projects" to="/projects" className={classes.link} icon={<ProjectIcon/>}/>
|
||||||
<ListItemIcon><InboxIcon /></ListItemIcon>
|
<MenuItem name="Funds Management" to="/funds-management" className={classes.link} icon={<InboxIcon/>}/>
|
||||||
<ListItemText primary="Dashboard" />
|
<MenuItem name="Insights" to="/insights/" className={classes.link} icon={<InboxIcon/>}/>
|
||||||
</ListItem>
|
<MenuItem name="Admin" to="/admin/" className={classes.link} icon={<InboxIcon/>}/>
|
||||||
</Link>
|
|
||||||
</List>
|
</List>
|
||||||
<List>
|
<Divider/>
|
||||||
<Link to="/funds-management/" className={classes.link}>
|
|
||||||
<ListItem button>
|
|
||||||
<ListItemIcon><InboxIcon /></ListItemIcon>
|
|
||||||
<ListItemText primary="Funds Management" />
|
|
||||||
</ListItem>
|
|
||||||
</Link>
|
|
||||||
</List>
|
|
||||||
<List>
|
|
||||||
<Link to="/insights/" className={classes.link}>
|
|
||||||
<ListItem button>
|
|
||||||
<ListItemIcon><InboxIcon /></ListItemIcon>
|
|
||||||
<ListItemText primary="Insights" />
|
|
||||||
</ListItem>
|
|
||||||
</Link>
|
|
||||||
</List>
|
|
||||||
<List>
|
|
||||||
<Link to="/admin/" className={classes.link}>
|
|
||||||
<ListItem button>
|
|
||||||
<ListItemIcon><InboxIcon /></ListItemIcon>
|
|
||||||
<ListItemText primary="Admin" />
|
|
||||||
</ListItem>
|
|
||||||
</Link>
|
|
||||||
</List>
|
|
||||||
<Divider />
|
|
||||||
</Drawer>
|
</Drawer>
|
||||||
<main
|
<main
|
||||||
className={classNames(classes.content, {
|
className={classNames(classes.content, {
|
||||||
|
@ -200,6 +186,7 @@ class PersistentDrawerLeft extends React.Component {
|
||||||
<Route path="/admin" component={ContractAdmin} />
|
<Route path="/admin" component={ContractAdmin} />
|
||||||
<Route path="/funds-management" render={() => <FundsManagement open={open} />} />
|
<Route path="/funds-management" render={() => <FundsManagement open={open} />} />
|
||||||
<Route path="/insights" component={TransferGraph} />
|
<Route path="/insights" component={TransferGraph} />
|
||||||
|
<Route path="/projects" component={Projects} />
|
||||||
<Route path="/project/:id" component={Project} />
|
<Route path="/project/:id" component={Project} />
|
||||||
<Route path="/create-project/" render={(props) => <CreateProject {...props} />} />
|
<Route path="/create-project/" render={(props) => <CreateProject {...props} />} />
|
||||||
<Route path="/back-project/:id" component={BackProject} />
|
<Route path="/back-project/:id" component={BackProject} />
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
import React, {Fragment, useState} from 'react'
|
||||||
|
import { withStyles } from '@material-ui/core/styles'
|
||||||
|
import {withDatabase} from "@nozbe/watermelondb/DatabaseProvider";
|
||||||
|
import withObservables from "@nozbe/with-observables";
|
||||||
|
import {Q} from "@nozbe/watermelondb";
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import {useProjectData} from "./hooks";
|
||||||
|
import Loading from "../base/Loading";
|
||||||
|
import Grid from '@material-ui/core/Grid';
|
||||||
|
import {Link} from "react-router-dom";
|
||||||
|
import Radio from '@material-ui/core/Radio';
|
||||||
|
import RadioGroup from '@material-ui/core/RadioGroup';
|
||||||
|
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||||
|
import FormControl from '@material-ui/core/FormControl';
|
||||||
|
import FormLabel from '@material-ui/core/FormLabel';
|
||||||
|
|
||||||
|
const SORT_TYPES = {
|
||||||
|
date: 'date',
|
||||||
|
name: 'name'
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = theme => ({
|
||||||
|
root: {
|
||||||
|
margin: '1.75rem 4.5rem',
|
||||||
|
...theme.typography.body1
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
textDecoration: 'none',
|
||||||
|
...theme.typography.body1,
|
||||||
|
'&:hover': {
|
||||||
|
textDecoration: 'underline',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function sortByTitle(a, b) {
|
||||||
|
if (!a.manifest || !b.manifest) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return a.manifest.title.localeCompare(b.manifest.title)
|
||||||
|
}
|
||||||
|
|
||||||
|
// No date field, but we can use the ID
|
||||||
|
function sortByDate(a, b) {
|
||||||
|
if (parseInt(a.projectId, 10) > parseInt(b.projectId, 10)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Projects({projectAddedEvents, classes}) {
|
||||||
|
const [sortType, setSortType] = useState(SORT_TYPES.date);
|
||||||
|
|
||||||
|
const projects = projectAddedEvents.map(event => {
|
||||||
|
return Object.assign({projectId: event.returnValues.idProject}, useProjectData(event.returnValues.idProject, '', projectAddedEvents));
|
||||||
|
})
|
||||||
|
|
||||||
|
let sortFunction = (sortType === SORT_TYPES.name) ? sortByTitle : sortByDate;
|
||||||
|
projects.sort(sortFunction);
|
||||||
|
|
||||||
|
return (<div className={classes.root}>
|
||||||
|
<h2>Projects</h2>
|
||||||
|
{projects.length === 0 && <Loading/>}
|
||||||
|
{projects.length > 0 &&
|
||||||
|
<Fragment>
|
||||||
|
<FormControl component="fieldset" className={classes.formControl}>
|
||||||
|
<FormLabel component="legend">Sort by</FormLabel>
|
||||||
|
<RadioGroup
|
||||||
|
aria-label="Sort"
|
||||||
|
name="sort"
|
||||||
|
className={classes.group}
|
||||||
|
value={sortType}
|
||||||
|
onChange={(e, value) => setSortType(value)}
|
||||||
|
>
|
||||||
|
<FormControlLabel value={SORT_TYPES.date} control={<Radio />} label="Date" />
|
||||||
|
<FormControlLabel value={SORT_TYPES.name} control={<Radio />} label="Name" />
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
<Grid container spacing={40}>
|
||||||
|
{projects.map((project, index) => {
|
||||||
|
if (!project.manifest) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Grid key={'project-' + index} item xs={12} sm={6} md={4} className="project-list-item">
|
||||||
|
<Link to={`/project/${project.projectId}`} className={classes.link}>
|
||||||
|
<h3>{project.manifest.title}</h3>
|
||||||
|
<p>{project.manifest.subtitle}</p>
|
||||||
|
<p>{project.manifest.description}</p>
|
||||||
|
<p>{project.manifest.avatar &&
|
||||||
|
<img alt="avatar" src={project.manifest.avatar} width={20} height={20}/>}{project.manifest.creator}</p>
|
||||||
|
</Link>
|
||||||
|
</Grid>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Grid>
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
|
</div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
Projects.propTypes = {
|
||||||
|
projectAddedEvents: PropTypes.array,
|
||||||
|
classes: PropTypes.object
|
||||||
|
}
|
||||||
|
|
||||||
|
const StyledProject = withStyles(styles)(Projects)
|
||||||
|
export default withDatabase(withObservables([], ({ database }) => ({
|
||||||
|
projectAddedEvents: database.collections.get('lp_events').query(
|
||||||
|
Q.where('event', 'ProjectAdded')
|
||||||
|
).observe()
|
||||||
|
}))(StyledProject))
|
Loading…
Reference in New Issue