I am working on Mern-Stack Application, and I am facing a challenge with comparing dates in Reacts and Material-UI.
I have an Event Model that has startingDate and closingDate Attribues.
when displaying the EVents on the List. what I want is, if the date for the event has passed then the event should show something like this. Started: Sunday, August 9, 2020, 3 pm Ended: Sunday, August 9, 2020, 6 pm. if the event is upcoming then it should show Starting: Sunday, August 9, 2020, 3 pm Ends: Sunday, August 9, 2020, 6 pm. But if the Event is Live (if it has started but has not ended) then the event should show Live: Sunday, August 9, 2020, 3 pm. `Ends: Sunday, August 9, 2020, 8 pm.
but I don't know why it's not really working as it should, the && operator is not evaluating as it should to make it show Live
This is my Event Schema just for you to understand the data-type I am using for a date.
const eventSchema = new mongoose.Schema({
startingDate: {
type: Date,
required: true
},
closingDate: {
type: Date,
required: true
},
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
createdAt: {
type: Date,
required: true,
default: Date.now
},
eventImage: {
type: String,
require: true
},
});
and this is my Event Component.
export default function EventsList() {
const theme = useTheme();
const [tileData, setTileData] = useState([]);
const useStyles = makeStyles((theme) => ({
root: {
maxWidth: "auto",
},
media: {
height: 350,
paddingTop: "56.25%", // 16:9
// height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
},
expand: {
transform: "rotate(0deg)",
marginLeft: "auto",
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.shortest,
}),
},
expandOpen: {
transform: "rotate(180deg)",
},
avatar: {
backgroundColor: red[500],
},
}));
useEffect(() => {
axios
.get("http://localhost:9000/events/")
.then((response) => {
setTileData([...response.data]);
})
.catch(function (error) {
console.log(error);
});
}, []);
const matches = useMediaQuery(theme.breakpoints.down("xs"));
const classes = useStyles();
return (
<div className={classes.root}>
<GridList
cellHeight={420}
className={classes.gridList}
spacing={12}
cols={matches ? 1 : 3}
>
{tileData.map((event, key) => {
return (
<Card
style={{ paddingBottom: "550px" }}
component={Link}
to={"/events/" + event._id + "/eventcomments"}
key={Math.floor(Math.random() * new Date().getTime())}
>
<h3
style={{
background: " #800000",
color: "white",
textAlign: "center",
}}
>
{event.title}
</h3>
<CardHeader
avatar={
<Avatar aria-label="recipe" className={classes.avatar}>
R
</Avatar>
}
title={
event.startingDate <= new Date() &&
event.closingDate > new Date()
? "Live:" + " " + moment(event.startingDate).format("lll")
: moment(event.startingDate).format("lll") <
moment(new Date()).format("lll")
? "Starting:" +
" " +
moment(event.startingDate).format("lll")
: "Started" + " " + moment(event.startingDate).format("lll")
}
subheader={
"Ends:" + " " + moment(event.closingDate).format("lll")
}
style={{ background: "#DCDCDC" }}
/>
<CardMedia
className={classes.media}
image={event.eventImage}
title="Paella dish"
/>
<CardContent>
<Typography
style={{ color: "black" }}
variant="body2"
color="textSecondary"
component="p"
>
{event.description.substring(0, 100)}
</Typography>
</CardContent>
</Card>
);
})}
;
</GridList>
</div>
);
}
in my DB, this is the default date format in my DB.
"startingDate" : ISODate("2020-08-09T11:03:00Z"), .
"closingDate" : ISODate("2020-08-09T11:06:00Z"),
Is it possible to use if statement inside React and material-UI? what is the best solution to get this to work and to make the Date to compare correctly?
Basically using nested ternaries is a bad practice because its gets messy and became not readable, in cases like this one its commonly solved by using a function that does the work, exp:
const startPast = "2020-08-05T11:03:00Z";
const endPast = "2020-08-06T11:03:00Z";
const startLive = "2020-08-05T11:03:00Z";
const endLive = "2020-08-16T11:03:00Z";
const startFuture = "2020-08-11T11:03:00Z";
const endFuture = "2020-08-13T11:03:00Z";
const nowIso = '2020-08-09T15:12:59.177Z'
const getTitle = (startDateTs, endDateTs) => {
const now = Date.parse(nowIso);
if (endDateTs <= now) {
return "past";
}
if (startDateTs < now && endDateTs > now) {
return "live";
}
return "future";
};
console.log("past", getTitle(Date.parse(startPast), Date.parse(endPast)));
console.log("live", getTitle(Date.parse(startLive), Date.parse(endLive)));
console.log("future", getTitle(Date.parse(startFuture), Date.parse(endFuture)));
could you try this approach ?
Related
I am trying to make a pagination table using an ant table. but I am not getting the result I want. I am always getting a limited number of data. can't really update the data limit dynamically. what i am doing wrong here? I am hardcoded the limit here how to do it dynamically ?? how can i fetch the data from data base i can show only 20 data on each page. also i have to show the available buttons
backend
export const getJourneyDetails = async (req, res) => {
try {
const page = parseInt(req.query.page || 1);
const perPage = parseInt(req.query.perPage || 100);
const search = req.query.search || "";
let JourneyDetails = await journey_details
.find({
Departure_Station_Name: { $regex: search, $options: "i" },
})
.skip((page - 1) * perPage)
.limit(perPage);
if (!JourneyDetails.length) {
JourneyDetails = await journey_details.find().limit(perPage);
}
const totalpages = Math.ceil(
(await journey_details.countDocuments()) / perPage
);
res.status(200).json({ JourneyDetails, totalpages });
frontend
import { CircularProgress } from "#mui/material";
import { useEffect, useState } from "react";
import type { ColumnsType } from "antd/es/table";
import { Table } from "antd";
import axios from "axios";
interface JourneyDetail {
Departure_time: String;
Return_time: String;
Departure_Station_Id: number;
Departure_Station_Name: String;
Return_Station_Id: number;
Return_Station_Name: String;
Distance: number;
Duration: number;
}
const JourneyData: React.FC = () => {
const [journeyDetails, setJourneyDetails] = useState<JourneyDetail[]>([]);
const [totalPages, setTotalPages] = useState(1);
const [searchQuery, setSearchQuery] = useState("");
const fetchData = async (page: number) => {
const { data } = await axios.get(
`https://helisinkicitybike.onrender.com/home/journey/?page=${page}&perPage=20&search=${searchQuery}
`
);
setJourneyDetails(data.JourneyDetails);
setTotalPages(data.totalPages);
};
useEffect(() => {
fetchData(1);
}, [searchQuery]);
const columns: ColumnsType<JourneyDetail> = [
{
title: "Departure time",
dataIndex: "Departure_time",
width: 100,
fixed: "left",
},
{
title: "Departure Station Name",
dataIndex: "Departure_Station_Name",
width: 100,
fixed: "left",
},
{
title: "Return time",
dataIndex: "Return_time",
width: 100,
fixed: "left",
},
{
title: "Return Station Name ",
dataIndex: "Return_Station_Name",
width: 100,
fixed: "left",
},
{
title: " Distance ",
dataIndex: "Distance",
width: 100,
fixed: "left",
},
{
title: "Duration ",
dataIndex: "Duration",
width: 100,
fixed: "left",
},
];
if (!journeyDetails) return <CircularProgress />;
return (
<div className="container mt-5">
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">
Search
</span>
<input
placeholder=" Enter Station Name"
type="text"
className="form-control"
aria-label="Sizing example input"
aria-describedby="inputGroup-sizing-default"
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
<Table
columns={columns}
dataSource={journeyDetails}
pagination={{
pageSize: 10,
total: totalPages,
onChange: (page) => {
fetchData(page);
},
}}
/>
<p style={{ fontSize: "10px", marginTop: "5px" }}>
#Data source Helsinki City Bike, covers the period of May to July 2021.
</p>
</div>
);
};
export default JourneyData;
} catch (error) {
console.error(error);
res.status(500).json({ message: "Error retrieving Journey Details" });
}
};
Getting data back from our API but built in Vuetify search/filter is not working. I think it has to do with the data coming back being nested in an object. When typing in the search filter i get "No matching records found" after the first character, when removing the search term the full data table is displayed. Thanks in advance for any help.
<template>
<v-container
fill-height
fluid
grid-list-xl
>
<v-layout
justify-center
wrap
>
<v-flex
md6
>
<material-card
color="black"
title="Users"
>
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
single-line
hide-details
></v-text-field>
<v-data-table
:headers="headers"
:items="userData"
:search="search"
hide-actions
>
<template
slot="headerCell"
slot-scope="{ header }"
>
<span
class="subheading font-weight-light text-dark text--darken-3"
v-text="header.text"
/>
</template>
<template
slot="items"
slot-scope="{ item }"
>
<td>
<v-avatar slot="offset" class="mx-auto d-block" size="100">
<img v-if="item.ProfileImage==null" src="img/conectrlogo.jpg">
<img v-else v-bind:src= "item.ProfileImage">
</v-avatar></td>
<td><v-btn text-small outlined color="primary" #click= "goToUserProfile(item.Id)">{{ item.Id}}</v-btn></td>
<td>{{ item.Username}}</td>
<td>{{ item.Name}}</td>
</template>
</v-data-table>
</material-card>
</v-flex>
</v-layout>
</v-container>
</template>
Script
<script>
import axios from 'axios'
export default {
mounted()
{
console.log("got into mounted function");
this.getResults();
},
data () {
return {
customFilter: function (items, search, filter, headers) {
search = search.toString().toLowerCase()
if (search.trim() === '') return items
const props = headers.map(h => h.value)
return items.filter(item => props.some(prop => filter(getObjectValueByPath(item, prop, item[prop]), search)))
},
userData:[],
totalUsers:0,
showResults:true,
search:'',
headers:[
{
text: 'User',
value: 'profileimage',
align: 'center',
width: '50px',
sortable:false
},
{
text: 'id',
value: 'id',
align: 'center',
width: '100px',
sortable:false
},
{
text: 'Username', value: 'username',
align: 'left',
sortable: false,
width: '50px'
},
{
text: 'Name', value: 'name',
align: 'left',
sortable: true,
width: '50px'
}
]
}
},
computed:{
},
methods: {
goToUserProfile: function(Id)
{
console.log("avatar clicked:"+Id);
this.$router.push('/user-profile/'+Id)
},
getResults (){
console.log("got into the all users endpoint");
console.log(this.$baseUrl+'/admin/users');
// axios.get(this.$baseUrl+'/admin/users',
// {withCredentials: true}).then ( response => {
// this.userData=response.data.Users;
// this.totalUsers = response.data.UserCount;
// console.log("all user response:"+this.userData);
// });
//this.showResults=true;
axios.defaults.withCredentials = true;
axios(this.$baseUrl+'/admin/users', {
method: 'GET',
withCredentials: true,
crossDomain:true
}).then(res => {
console.log(res);
this.userData=res.data.Users;
this.totalUsers = res.data.UserCount;
console.log("all user response:"+this.userData);
}).catch(err => {
console.log("got an error");
console.log(err);
})
},
initialize()
{
},
}
}
</script>
I was wondering if you could help with something I believe to be pretty simple. Using the Tabulator nested table example(Not Tree), how can I make the child table show/hide on click? I want users to be able to expand for further information if they require it similar to the tree example.
I have seen a few answers to this but they don't seem to work for me.
//define table
var table = new Tabulator("#example-table", {
height:"311px",
layout:"fitColumns",
resizableColumns:false,
data:nestedData,
columns:[
{title:"Make", field:"make"},
{title:"Model", field:"model"},
{title:"Registration", field:"reg"},
{title:"Color", field:"color"},
],
rowFormatter:function(row){
//create and style holder elements
var holderEl = document.createElement("div");
var tableEl = document.createElement("div");
holderEl.style.boxSizing = "border-box";
holderEl.style.padding = "10px 30px 10px 10px";
holderEl.style.borderTop = "1px solid #333";
holderEl.style.borderBotom = "1px solid #333";
holderEl.style.background = "#ddd";
tableEl.style.border = "1px solid #333";
holderEl.appendChild(tableEl);
row.getElement().appendChild(holderEl);
var subTable = new Tabulator(tableEl, {
layout:"fitColumns",
data:row.getData().serviceHistory,
columns:[
{title:"Date", field:"date", sorter:"date"},
{title:"Engineer", field:"engineer"},
{title:"Action", field:"actions"},
]
})
},
});
Using a mix of #dota2pro example here is a nice working solution:
https://jsfiddle.net/ustvnz5a/2/
var nestedData = [{
id: 1,
make: "Ford",
model: "focus",
reg: "P232 NJP",
color: "white",
serviceHistory: [{
date: "01/02/2016",
engineer: "Steve Boberson",
actions: "Changed oli filter"
},
{
date: "07/02/2017",
engineer: "Martin Stevenson",
actions: "Break light broken"
},
]
},
{
id: 2,
make: "BMW",
model: "m3",
reg: "W342 SEF",
color: "red",
serviceHistory: [{
date: "22/05/2017",
engineer: "Jimmy Brown",
actions: "Aligned wheels"
},
{
date: "11/02/2018",
engineer: "Lotty Ferberson",
actions: "Changed Oil"
},
{
date: "04/04/2018",
engineer: "Franco Martinez",
actions: "Fixed Tracking"
},
]
},
]
var hideIcon = function(cell, formatterParams, onRendered){ //plain text value
return "<i class='fa fa-eye-slash'></i>";
};
const table = new Tabulator("#example-table", {
height: "311px",
layout: "fitColumns",
resizableColumns: false,
data: nestedData,
selectable: true,
columns: [{
title: "Make",
field: "make"
},
{
title: "Model",
field: "model"
},
{
title: "Registration",
field: "reg"
},
{
title: "Color",
field: "color"
},
{formatter:hideIcon, align:"center", title:"Hide Sub", headerSort:false, cellClick:function(e, row, formatterParams){
const id = row.getData().id;
$(".subTable" + id + "").toggle();
}
}
],
rowFormatter: function(row, e) {
//create and style holder elements
var holderEl = document.createElement("div");
var tableEl = document.createElement("div");
const id = row.getData().id;
holderEl.style.boxSizing = "border-box";
holderEl.style.padding = "10px 10px 10px 10px";
holderEl.style.borderTop = "1px solid #333";
holderEl.style.borderBotom = "1px solid #333";
holderEl.style.background = "#ddd";
holderEl.setAttribute('class', "subTable" + id + "");
tableEl.style.border = "1px solid #333";
tableEl.setAttribute('class', "subTable" + id + "");
holderEl.appendChild(tableEl);
row.getElement().appendChild(holderEl);
var subTable = new Tabulator(tableEl, {
layout: "fitColumns",
data: row.getData().serviceHistory,
columns: [{
title: "Date",
field: "date",
sorter: "date"
},
{
title: "Engineer",
field: "engineer"
},
{
title: "Action",
field: "actions"
},
]
})
},
});
Check this jsfiddle
selectable: true,
rowClick: function(e, row) {
const id = row.getData().id;
$(".subTable" + id + "").toggle();
},
This is just for help with hiding the expanded sections by default. My solution has 2 parts. One when I load the data and one when the page changes using the pagination controls.
Here is my part when I set the data:
myTable.setData(myData);
myTable.setHeight("100%");
myTable.redraw();
var rows = myTable.getRows();
rows.forEach(function (row) {
var data2 = row.getData();
const id = data2.IDField;
$(".subTable" + id + "").toggle();
});
I use this event to handle page changes:
pageLoaded: function (pageno) {
var rows = myTable.getRows();
rows.forEach(function (row) {
var data = row.getData();
const id = data.AssetNumber;
//use hide, toggle works great first time you view the tab, 2nd time it opens them all
$(".subTable" + id + "").hide();
//$(".subTable" + id + "").toggle();
});
}
Thanks for the great code used everyone else.
I am using high chart version v4.0.4, i have worked bar chart like mentioned below i need output with there bar for every year details given below
I am working on below high chart code
var data_first_vd = 0;
var data_second_vd = 0;
var glb_data_ary = [];
var dynamicval1 = 5.85572581;
var dynamicval2 = 0.16091656;
if((dynamicval1>1) || (dynamicval2>1)){
var data_tit = 'Value';
var data_val = '${value}';
var prdelvalaxis = 1000000;
}else{
prdelvalaxis = 1000;
data_tit = "Value";
data_val = "${value}";
}
data_first_vd=5.86;
data_second_vd =0.16;
var data_first_ud =1397.128;
var data_second_ud = 28.145;
data_first_ud_lbl = '1.40M';
data_second_ud_lbl = '28K';
data_first_vd_lbl = '5.86M';
data_second_vd_lbl = '161K';
data_first_vd_lbl_xaxis = '$5.86M';
data_second_vd_lbl_xaxis = '$161K';
var ud1 = 1397;
var ud2 = 28;
var vd1 = 6;
var vd2 = 0;
$('#id').highcharts({
credits: { enabled: false },
chart: {
type: 'bar',
height: 200,
marginLeft: 120,
marginBottom:50,
marginTop: 47,
marginRight:30,
plotBorderWidth: 0,
},
title: {
text: null
},
xAxis: {
drawHorizontalBorders: false,
labels: {
groupedOptions: [{
rotation: 270,
}],
rotation: 0,
align:'center',
x: -30,
y: 5,
formatter: function () {
if (curYear === this.value) {
return '<span style="color:#6C9CCC;">' + this.value + '</span>';
}
else if (prevYear === this.value) {
return '<span style="color: #ED7D31;">' + this.value + '</span>';
}
else if ('VALUE' === this.value) {
return '<span style="color:#942EE1;">' + this.value + '</span>';
}
else{
return '<span style="color: #E124D2;">' + this.value + '</span>';
}
},
useHTML:true
},
categories: [{
name: "UNITS",
categories: [2017, 2016]
},{
name: "VALUE",
categories: [2017, 2016]
}
],
},
yAxis: [{ // Primary yAxis
labels: {
format: data_val,
formatter: function () {
if(this.value!=0){
return '$'+valueConverter_crt(this.value*prdelvalaxis);
}else{
return this.value;
}
},
style: {
color: '#942EE1'
}
},
title: {
text: "<span style='font-size: 12px;'>"+data_tit+"</span>",
style: {
color: '#942EE1'
},
useHTML:true
}
}, { // Secondary yAxis
title: {
text: "<span style='font-size: 12px;'>Units</span>",
style: {
color: '#E124D2'
},
useHTML:true
},
labels: {
format: '{value}',
formatter: function () {
if(this.value!=0){
return cal_pro_del_xaxis(this.value);
}else{
return this.value;
}
},
style: {
color: '#E124D2'
}
},
opposite: true
}],
tooltip: { enabled: false },
exporting: { enabled: false },
legend: { enabled: false },
plotOptions: {
series: {
dataLabels: {
inside: true,
align: 'left',
enabled: true,
formatter: function () {
return this.point.name;
},
color: '#000000',
},
stacking: false,
pointWidth: 15,
groupPadding: 0.5
},
},
series: [{
yAxis: 1,
data: [{y:1397.128,name:data_first_ud_lbl,color:'#6C9CCC'},{y:28.145,name:data_second_ud_lbl,color:'#ED7D31'}],
}, {
data: [null,null,{y:5.86,name:data_first_vd_lbl_xaxis,color:'#6C9CCC'},{y:0.16,name:data_second_vd_lbl_xaxis,color:'#ED7D31'}],
}]
});
I need out put like below chart This chart i draw in paint.
Here 3 bar added in every year
Please help me to achieve this
I only started studying React a few days ago so please forgive me if this question sounds really stupid.
In this work assignment, I have to implement a 'Like' system using material-ui's GridList. There will be eight pictures in total where users can like them by clicking on the like button. In my current code, users can click on the like button but all the like buttons will be affected instead of just one. Furthermore, the number of likes does not increase.
So my question is, how can I change the number of likes when a user clicks the 'Like' button and make sure only 1 button is affected? I have tried props and even lodash but I just cannot seem to figure out the problem. Below is my entire code for the GridList portion. Any help would be greatly appreciated.
import _ from 'lodash';
import React from 'react';
import {GridList, GridTile} from 'material-ui/GridList';
import Subheader from 'material-ui/Subheader';
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
//GridList style
const styles = {
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
},
gridList: {
width: 1000,
height: 500,
},
};
//data for the GridList
var tilesData = [
{
img: './images/image_01.jpg',
title: 'Breakfast',
likes: 0,
},
{
img: './images/image_02.jpg',
title: 'Tasty burger',
likes: 0,
},
{
img: './images/image_03.jpg',
title: 'Camera',
likes: 0,
},
{
img: './images/image_04.jpg',
title: 'Morning',
likes: 0,
},
{
img: './images/image_05.jpg',
title: 'Hats',
likes: 0,
},
{
img: './images/image_06.jpg',
title: 'Honey',
likes: 0,
},
{
img: './images/image_07.jpg',
title: 'Vegetables',
likes: 0,
},
{
img: './images/image_08.jpg',
title: 'Water plant',
likes: 0,
},
];
export default class Grid extends React.Component {
constructor(props){
super(props);
this.state = {
like: false,
likes: tilesData.likes,
};
this.post = this.post.bind(this);
this.delete = this.delete.bind(this);
}
//if Like button is clicked
post(){
this.setState({ like: true});
let likes = this.state.likes;
likes++;
this.setState({likes: likes});
//this.tilesData.likes = likes;
}
//if Like button is "unclicked"
delete(){
this.setState({ like: false});
let likes = this.state.likes;
likes--;
this.setState({likes: likes});
//this.tilesData.likes = likes;
}
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
render(){
const likeBtn = this.state.like ? <img src="./images/icons/icon_2.png" onClick={this.delete} /> : <img src="./images/icons/icon_1.png" onClick={this.post} />;
return (
<div style={styles.root}>
<GridList
cellHeight={200}
cols={4}
style={styles.gridList}
>
<Subheader>December</Subheader>
{tilesData.map((tile) => (
<GridTile
key={tile.img}
title={tile.title}
subtitle={<span>Likes: <b>{tile.likes}</b></span>}
actionIcon={likeBtn}
>
<img src={tile.img} />
</GridTile>
))}
</GridList>
</div>
);
}
}
Grid.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
}
Problem
'State' of like button is defined outside the loop means same 'state' is shared with all GridTile components(for all images).
When you clicked on 'like' button then you are changing the 'state' of 'like' button in parent component that is Grid and same 'state' is used for all like buttons.
That's why it is impacting all like buttons.
Solution
'state' should be defined separately for each like button. Also delete and post method should be defined inside loop means in GridTile.
But GridTile is part of material-ui library so instead of changing this library create a wrapper on GridTile component.
Grid component will call component lets say it GridTileCustom component inside loop.
Inside GridTileCustom component you need to define delete and post method which you are using in 'onClick' event
So your final code will look like
import React from 'react';
import {GridList, GridTile} from 'material-ui/GridList';
import Subheader from 'material-ui/Subheader';
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import IconButton from 'material-ui/IconButton';
const thumbsIcon = "glyphicon glyphicon-thumbs-up";
const styles = {
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
},
gridList: {
width: 1000,
height: 500,
},
};
var tilesData = [
{
img: './images/image_01.jpg',
title: 'Breakfast',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_02.jpg',
title: 'Tasty burger',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_03.jpg',
title: 'Camera',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_04.jpg',
title: 'Morning',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_05.jpg',
title: 'Hats',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_06.jpg',
title: 'Honey',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_07.jpg',
title: 'Vegetables',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_08.jpg',
title: 'Water plant',
likes: 0,
icon: './images/icons/icon_1.png',
},
];
export default class Grid extends React.Component {
constructor(props){
super(props);
this.state = {
like: false,
likes: tilesData.likes,
};
// this.post = this.post.bind(this);
// this.delete = this.delete.bind(this);
}
// post(){
// this.setState({ like: true});
// let likes = this.state.likes;
// likes++;
// this.setState({likes: likes});
// //this.tilesData.likes = likes;
// }
// delete(){
// this.setState({ like: false});
// let likes = this.state.likes;
// likes--;
// this.setState({likes: likes});
// //this.tilesData.likes = likes;
// }
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
render(){
return (
<div style={styles.root}>
<GridList
cellHeight={200}
cols={4}
style={styles.gridList}
>
<Subheader>December</Subheader>
{tilesData.map((tile) => (
<GridTileInternal
key={tile.img}
img={tile.img}
title={tile.title}
subtitle={tile.likes}
// actionIcon={likeBtn}
>
</GridTileInternal>
))}
</GridList>
</div>
);
}
}
class GridTileInternal extends React.Component {
constructor(props){
super(props);
this.state = {
like: false,
likes: tilesData.likes,
};
this.post = this.post.bind(this);
this.delete = this.delete.bind(this);
}
post(){
this.setState({ like: true});
let likes = this.state.likes;
likes++;
this.setState({likes: likes});
//this.tilesData.likes = likes;
}
delete(){
this.setState({ like: false});
let likes = this.state.likes;
likes--;
this.setState({likes: likes});
//this.tilesData.likes = likes;
}
render(){
const likeBtn = this.state.like ? <img src="./images/icons/icon_2.png" onClick={this.delete} /> : <img src="./images/icons/icon_1.png" onClick={this.post} />;
return (
<GridTile
key={this.props.img}
title={this.props.title}
subtitle={<span>Likes: <b>{this.props.subtitle}</b></span>}
actionIcon={likeBtn}
>
<img src={this.props.img} />
</GridTile>
);
}
}
Grid.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
}