Skip to content

Commit

Permalink
Merge pull request #4415 from developerium/demo_typescript_components
Browse files Browse the repository at this point in the history
Migrate Dashboard demo components to TypeScript
  • Loading branch information
fzaninotto authored Feb 14, 2020
2 parents dfca371 + a3dbeaf commit 149a439
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import React from 'react';
import React, { FC, ComponentType } from 'react';
import Card from '@material-ui/core/Card';
import { makeStyles } from '@material-ui/core/styles';
import { SvgIconProps } from '@material-ui/core/SvgIcon';

interface Props {
bgColor: string;
Icon: ComponentType<SvgIconProps>;
}

const useStyles = makeStyles({
card: {
Expand All @@ -18,7 +24,7 @@ const useStyles = makeStyles({
},
});

const CardIcon = ({ Icon, bgColor }) => {
const CardIcon: FC<Props> = ({ Icon, bgColor }) => {
const classes = useStyles();
return (
<Card className={classes.card} style={{ backgroundColor: bgColor }}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import React, { useState, useEffect, useCallback } from 'react';
import React, {
useState,
useEffect,
useCallback,
FC,
CSSProperties,
} from 'react';
import { useVersion, useDataProvider } from 'react-admin';
import { useMediaQuery } from '@material-ui/core';
import { useMediaQuery, Theme } from '@material-ui/core';

import Welcome from './Welcome';
import MonthlyRevenue from './MonthlyRevenue';
Expand All @@ -9,6 +15,28 @@ import PendingOrders from './PendingOrders';
import PendingReviews from './PendingReviews';
import NewCustomers from './NewCustomers';

import { Customer, Order, Review } from '../types';

interface OrderStats {
revenue: number;
nbNewOrders: number;
pendingOrders: Order[];
}

interface CustomerData {
[key: string]: Customer;
}

interface State {
nbNewOrders?: number;
nbPendingReviews?: number;
pendingOrders?: Order[];
pendingOrdersCustomers?: CustomerData;
pendingReviews?: Review[];
pendingReviewsCustomers?: CustomerData;
revenue?: number;
}

const styles = {
flex: { display: 'flex' },
flexColumn: { display: 'flex', flexDirection: 'column' },
Expand All @@ -17,12 +45,16 @@ const styles = {
singleCol: { marginTop: '2em', marginBottom: '2em' },
};

const Dashboard = () => {
const [state, setState] = useState({});
const Dashboard: FC = () => {
const [state, setState] = useState({} as State);
const version = useVersion();
const dataProvider = useDataProvider();
const isXSmall = useMediaQuery(theme => theme.breakpoints.down('xs'));
const isSmall = useMediaQuery(theme => theme.breakpoints.down('sm'));
const isXSmall = useMediaQuery((theme: Theme) =>
theme.breakpoints.down('xs')
);
const isSmall = useMediaQuery((theme: Theme) =>
theme.breakpoints.down('sm')
);

const fetchOrders = useCallback(async () => {
const aMonthAgo = new Date();
Expand All @@ -33,9 +65,9 @@ const Dashboard = () => {
pagination: { page: 1, perPage: 50 },
});
const aggregations = recentOrders
.filter(order => order.status !== 'cancelled')
.filter((order: Order) => order.status !== 'cancelled')
.reduce(
(stats, order) => {
(stats: OrderStats, order: Order) => {
if (order.status !== 'cancelled') {
stats.revenue += order.total;
stats.nbNewOrders++;
Expand Down Expand Up @@ -63,14 +95,19 @@ const Dashboard = () => {
pendingOrders: aggregations.pendingOrders,
}));
const { data: customers } = await dataProvider.getMany('customers', {
ids: aggregations.pendingOrders.map(order => order.customer_id),
ids: aggregations.pendingOrders.map(
(order: Order) => order.customer_id
),
});
setState(state => ({
...state,
pendingOrdersCustomers: customers.reduce((prev, customer) => {
prev[customer.id] = customer; // eslint-disable-line no-param-reassign
return prev;
}, {}),
pendingOrdersCustomers: customers.reduce(
(prev: CustomerData, customer: Customer) => {
prev[customer.id] = customer; // eslint-disable-line no-param-reassign
return prev;
},
{}
),
}));
}, [dataProvider]);

Expand All @@ -80,18 +117,21 @@ const Dashboard = () => {
sort: { field: 'date', order: 'DESC' },
pagination: { page: 1, perPage: 100 },
});
const nbPendingReviews = reviews.reduce(nb => ++nb, 0);
const nbPendingReviews = reviews.reduce((nb: number) => ++nb, 0);
const pendingReviews = reviews.slice(0, Math.min(10, reviews.length));
setState(state => ({ ...state, pendingReviews, nbPendingReviews }));
const { data: customers } = await dataProvider.getMany('customers', {
ids: pendingReviews.map(review => review.customer_id),
ids: pendingReviews.map((review: Review) => review.customer_id),
});
setState(state => ({
...state,
pendingReviewsCustomers: customers.reduce((prev, customer) => {
prev[customer.id] = customer; // eslint-disable-line no-param-reassign
return prev;
}, {}),
pendingReviewsCustomers: customers.reduce(
(prev: CustomerData, customer: Customer) => {
prev[customer.id] = customer; // eslint-disable-line no-param-reassign
return prev;
},
{}
),
}));
}, [dataProvider]);

Expand All @@ -111,7 +151,7 @@ const Dashboard = () => {
} = state;
return isXSmall ? (
<div>
<div style={styles.flexColumn}>
<div style={styles.flexColumn as CSSProperties}>
<div style={{ marginBottom: '2em' }}>
<Welcome />
</div>
Expand All @@ -128,7 +168,7 @@ const Dashboard = () => {
</div>
</div>
) : isSmall ? (
<div style={styles.flexColumn}>
<div style={styles.flexColumn as CSSProperties}>
<div style={styles.singleCol}>
<Welcome />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { FC } from 'react';
import Card from '@material-ui/core/Card';
import DollarIcon from '@material-ui/icons/AttachMoney';
import { makeStyles } from '@material-ui/core/styles';
Expand All @@ -7,6 +7,10 @@ import { useTranslate } from 'react-admin';

import CardIcon from './CardIcon';

interface Props {
value: number;
}

const useStyles = makeStyles({
main: {
flex: '1',
Expand All @@ -19,9 +23,10 @@ const useStyles = makeStyles({
padding: 16,
minHeight: 52,
},
title: {},
});

const MonthlyRevenue = ({ value }) => {
const MonthlyRevenue: FC<Props> = ({ value }) => {
const translate = useTranslate();
const classes = useStyles();
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { FC } from 'react';
import Card from '@material-ui/core/Card';
import ShoppingCartIcon from '@material-ui/icons/ShoppingCart';
import { makeStyles } from '@material-ui/core/styles';
Expand All @@ -7,6 +7,10 @@ import { useTranslate } from 'react-admin';

import CardIcon from './CardIcon';

interface Props {
value: number;
}

const useStyles = makeStyles({
main: {
flex: '1',
Expand All @@ -19,9 +23,10 @@ const useStyles = makeStyles({
padding: 16,
minHeight: 52,
},
title: {},
});

const NbNewOrders = ({ value }) => {
const NbNewOrders: FC<Props> = ({ value }) => {
const translate = useTranslate();
const classes = useStyles();
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Link } from 'react-router-dom';
import { useTranslate, useQueryWithStore } from 'react-admin';

import CardIcon from './CardIcon';
import { Customer } from '../types';

const useStyles = makeStyles({
main: {
Expand Down Expand Up @@ -62,7 +63,7 @@ const NewCustomers = () => {

if (!loaded) return null;

const nb = visitors ? visitors.reduce(nb => ++nb, 0) : 0;
const nb = visitors ? visitors.reduce((nb: number) => ++nb, 0) : 0;
return (
<div className={classes.main}>
<CardIcon Icon={CustomerIcon} bgColor="#4caf50" />
Expand All @@ -80,7 +81,7 @@ const NewCustomers = () => {
<Divider />
<List>
{visitors
? visitors.map(record => (
? visitors.map((record: Customer) => (
<ListItem
button
to={`/customers/${record.id}`}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { FC } from 'react';
import Card from '@material-ui/core/Card';
import CardHeader from '@material-ui/core/CardHeader';
import List from '@material-ui/core/List';
Expand All @@ -10,6 +10,12 @@ import Avatar from '@material-ui/core/Avatar';
import { makeStyles } from '@material-ui/core/styles';
import { Link } from 'react-router-dom';
import { useTranslate } from 'react-admin';
import { Customer, Order } from '../types';

interface Props {
orders: Order[];
customers: { [key: string]: Customer };
}

const useStyles = makeStyles(theme => ({
root: {
Expand All @@ -21,7 +27,7 @@ const useStyles = makeStyles(theme => ({
},
}));

const PendingOrders = ({ orders = [], customers = {} }) => {
const PendingOrders: FC<Props> = ({ orders = [], customers = {} }) => {
const classes = useStyles();
const translate = useTranslate();
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { FC } from 'react';
import Card from '@material-ui/core/Card';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
Expand All @@ -15,6 +15,13 @@ import { useTranslate } from 'react-admin';
import CardIcon from './CardIcon';

import StarRatingField from '../reviews/StarRatingField';
import { Customer, Review } from '../types';

interface Props {
reviews: Review[];
customers: { [key: string]: Customer };
nb: number;
}

const useStyles = makeStyles(theme => ({
main: {
Expand All @@ -36,7 +43,7 @@ const useStyles = makeStyles(theme => ({
minHeight: 48,
},
avatar: {
background: theme.palette.background.avatar,
background: theme.palette.background.paper,
},
listItemText: {
overflowY: 'hidden',
Expand All @@ -52,7 +59,7 @@ const location = {
query: { filter: JSON.stringify({ status: 'pending' }) },
};

const PendingReviews = ({ reviews = [], customers = {}, nb }) => {
const PendingReviews: FC<Props> = ({ reviews = [], customers = {}, nb }) => {
const classes = useStyles();
const translate = useTranslate();
return (
Expand All @@ -73,7 +80,7 @@ const PendingReviews = ({ reviews = [], customers = {}, nb }) => {
</Typography>
<Divider />
<List>
{reviews.map(record => (
{reviews.map((record: Review) => (
<ListItem
key={record.id}
button
Expand All @@ -95,7 +102,12 @@ const PendingReviews = ({ reviews = [], customers = {}, nb }) => {
</ListItemAvatar>

<ListItemText
primary={<StarRatingField record={record} />}
primary={
<StarRatingField
record={record}
size="small"
/>
}
secondary={record.comment}
className={classes.listItemText}
style={{ paddingRight: 0 }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { FC } from 'react';
import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
Expand All @@ -17,11 +17,11 @@ const useStyles = makeStyles({
});

const mediaUrl = `https://marmelab.com/posters/beard-${parseInt(
Math.random() * 10,
(Math.random() * 10).toString(),
10
) + 1}.jpeg`;

const Welcome = () => {
const Welcome: FC = () => {
const translate = useTranslate();
const classes = useStyles();
return (
Expand Down
File renamed without changes.
4 changes: 4 additions & 0 deletions examples/demo/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ export interface FieldProps<T extends Record = Record> {
record?: T;
source?: string;
}

export interface Review extends Record {
customer_id: string;
}

0 comments on commit 149a439

Please sign in to comment.