Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[Demo] use stepper for customer actions #5472

Merged
merged 1 commit into from
Nov 2, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
279 changes: 139 additions & 140 deletions examples/demo/src/visitors/Aside.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,29 @@ import {
DateField,
useTranslate,
useGetList,
linkToRecord,
Record,
RecordMap,
Identifier,
ReferenceField,
useLocale,
} from 'react-admin';
import {
Tooltip,
Typography,
Card,
CardContent,
CardHeader,
Avatar,
IconButton,
Box,
Link,
Stepper,
Step,
StepLabel,
StepContent,
} from '@material-ui/core';
import { Link } from 'react-router-dom';
import { Link as RouterLink } from 'react-router-dom';
import AccessTimeIcon from '@material-ui/icons/AccessTime';
import ContentCreate from '@material-ui/icons/Create';
import { makeStyles } from '@material-ui/core/styles';

import order from '../orders';
import review from '../reviews';
import ProductReferenceField from '../products/ProductReferenceField';
import StarRatingField from '../reviews/StarRatingField';
import { Order as OrderRecord, Review as ReviewRecord } from '../types';

Expand Down Expand Up @@ -65,8 +65,19 @@ interface EventListProps {
record?: Record;
basePath?: string;
}

const useEventStyles = makeStyles({
stepper: {
background: 'none',
border: 'none',
marginLeft: '0.3em',
},
});

const EventList: FC<EventListProps> = ({ record, basePath }) => {
const translate = useTranslate();
const classes = useEventStyles();
const locale = useLocale();
const { data: orders, ids: orderIds } = useGetList<OrderRecord>(
'commands',
{ page: 1, perPage: 100 },
Expand Down Expand Up @@ -180,22 +191,56 @@ const EventList: FC<EventListProps> = ({ record, basePath }) => {
</CardContent>
</Card>
</Box>

{events.map(event =>
event.type === 'order' ? (
<Order
record={event.data as OrderRecord}
key={`event_${event.data.id}`}
basePath={basePath}
/>
) : (
<Review
record={event.data as ReviewRecord}
key={`review_${event.data.id}`}
basePath={basePath}
/>
)
)}
<Stepper orientation="vertical" classes={{ root: classes.stepper }}>
{events.map(event => (
<Step
key={`${event.type}-${event.data.id}`}
expanded
active
completed
>
<StepLabel
StepIconComponent={() => {
const Component =
event.type === 'order'
? order.icon
: review.icon;
return (
<Component
fontSize="small"
color="disabled"
style={{ paddingLeft: 3 }}
/>
);
}}
>
{new Date(event.date).toLocaleString(locale, {
weekday: 'long',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
})}
</StepLabel>
<StepContent>
{event.type === 'order' ? (
<Order
record={event.data as OrderRecord}
key={`event_${event.data.id}`}
basePath={basePath}
/>
) : (
<Review
record={event.data as ReviewRecord}
key={`review_${event.data.id}`}
basePath={basePath}
/>
)}
</StepContent>
</Step>
))}
</Stepper>
</>
);
};
Expand Down Expand Up @@ -230,80 +275,51 @@ const mixOrdersAndReviews = (
: [];
const events = eventsFromOrders.concat(eventsFromReviews);
events.sort(
(e1, e2) => new Date(e1.date).getTime() - new Date(e2.date).getTime()
(e1, e2) => new Date(e2.date).getTime() - new Date(e1.date).getTime()
);
return events;
};

const useEventStyles = makeStyles({
card: {
margin: '0 0 1em 1em',
},
cardHeader: {
alignItems: 'flex-start',
},
clamp: {
display: '-webkit-box',
'-webkit-line-clamp': 3,
'-webkit-box-orient': 'vertical',
overflow: 'hidden',
},
});

interface OrderProps {
record?: OrderRecord;
basePath?: string;
}

const Order: FC<OrderProps> = ({ record, basePath }) => {
const translate = useTranslate();
const classes = useEventStyles();
return record ? (
<Card className={classes.card}>
<CardHeader
className={classes.cardHeader}
avatar={
<Avatar
aria-label={translate('resources.commands.name', {
smart_count: 1,
})}
>
<order.icon />
</Avatar>
}
action={<EditButton record={record} basePath="/commands" />}
title={`${translate('resources.commands.name', {
smart_count: 1,
})} #${record.reference}`}
subheader={
<>
<Typography variant="body2">{record.date}</Typography>
<Typography variant="body2" color="textSecondary">
{translate('resources.commands.nb_items', {
smart_count: record.basket.length,
_: '1 item |||| %{smart_count} items',
})}
&nbsp;-&nbsp;
<NumberField
source="total"
options={{
style: 'currency',
currency: 'USD',
}}
record={record}
basePath={basePath}
/>
&nbsp;-&nbsp;
<TextField
source="status"
record={record}
basePath={basePath}
/>
</Typography>
</>
}
/>
</Card>
<>
<Typography variant="body2" gutterBottom>
<Link to={`/commands/${record.id}`} component={RouterLink}>
{translate('resources.commands.name', {
smart_count: 1,
})}{' '}
#{record.reference}
</Link>
</Typography>
<Typography variant="body2" color="textSecondary">
{translate('resources.commands.nb_items', {
smart_count: record.basket.length,
_: '1 item |||| %{smart_count} items',
})}
&nbsp;-&nbsp;
<NumberField
source="total"
options={{
style: 'currency',
currency: 'USD',
}}
record={record}
basePath={basePath}
/>
&nbsp;-&nbsp;
<TextField
source="status"
record={record}
basePath={basePath}
/>
</Typography>
</>
) : null;
};

Expand All @@ -312,65 +328,48 @@ interface ReviewProps {
basePath?: string;
}

const useReviewStyles = makeStyles({
clamp: {
display: '-webkit-box',
'-webkit-line-clamp': 3,
'-webkit-box-orient': 'vertical',
overflow: 'hidden',
},
});

const Review: FC<ReviewProps> = ({ record, basePath }) => {
const classes = useReviewStyles();
const translate = useTranslate();
const classes = useEventStyles();
return record ? (
<Card className={classes.card}>
<CardHeader
className={classes.cardHeader}
avatar={
<Avatar
aria-label={translate('resources.reviews.name', {
smart_count: 1,
})}
<>
<Typography variant="body2" gutterBottom>
<Link to={`/reviews/${record.id}`} component={RouterLink}>
{translate('resources.reviews.relative_to_poster')} "
<ReferenceField
source="product_id"
reference="products"
resource="reviews"
record={record}
basePath={basePath}
link={false}
>
<review.icon />
</Avatar>
}
action={<EditButton record={record} basePath="/reviews" />}
title={
<span>
{translate('resources.reviews.relative_to_poster')}{' '}
<ProductReferenceField
resource="reviews"
record={record}
basePath={basePath}
/>
</span>
}
subheader={
<>
<Typography variant="body2">{record.date}</Typography>
<StarRatingField record={record} />
<Typography variant="inherit" className={classes.clamp}>
{record.comment}
</Typography>
</>
}
/>
</Card>
) : null;
};

interface EditButtonProps {
record?: Record;
basePath?: string;
}

const EditButton: FC<EditButtonProps> = ({ record, basePath }) => {
const translate = useTranslate();
return (
<Tooltip title={translate('ra.action.edit')}>
<IconButton
aria-label={translate('ra.action.edit')}
component={Link}
to={linkToRecord(basePath, record && record.id)}
<TextField source="reference" component="span" />
</ReferenceField>
"
</Link>
</Typography>
<Typography variant="body2" color="textSecondary" gutterBottom>
<StarRatingField record={record} />
</Typography>
<Typography
variant="body2"
color="textSecondary"
className={classes.clamp}
>
<ContentCreate />
</IconButton>
</Tooltip>
);
{record.comment}
</Typography>
</>
) : null;
};

export default Aside;