Update customer note design

This commit is contained in:
dominik-zeglen 2019-11-12 13:21:37 +01:00
parent 8170f9e14e
commit 4ab886a7ca
7 changed files with 171 additions and 66 deletions

View file

@ -23,6 +23,7 @@ const useStyles = makeStyles(theme => ({
}), }),
title: { title: {
flex: 1, flex: 1,
fontWeight: 500,
lineHeight: 1 lineHeight: 1
}, },
toolbar: { toolbar: {

View file

@ -4,6 +4,7 @@ import React from "react";
import Checkbox from "./Checkbox"; import Checkbox from "./Checkbox";
interface ControlledCheckboxProps { interface ControlledCheckboxProps {
className?: string;
name: string; name: string;
label?: React.ReactNode; label?: React.ReactNode;
checked: boolean; checked: boolean;
@ -16,7 +17,8 @@ export const ControlledCheckbox: React.FC<ControlledCheckboxProps> = ({
disabled, disabled,
name, name,
label, label,
onChange onChange,
...props
}) => ( }) => (
<FormControlLabel <FormControlLabel
disabled={disabled} disabled={disabled}
@ -29,6 +31,7 @@ export const ControlledCheckbox: React.FC<ControlledCheckboxProps> = ({
/> />
} }
label={label} label={label}
{...props}
/> />
); );
ControlledCheckbox.displayName = "ControlledCheckbox"; ControlledCheckbox.displayName = "ControlledCheckbox";

View file

@ -9,39 +9,34 @@ import { FormattedMessage, useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox"; import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
import { FormSpacer } from "@saleor/components/FormSpacer";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import { commonMessages } from "@saleor/intl"; import { maybe } from "@saleor/misc";
import { FormErrors } from "@saleor/types";
import { CustomerDetails_user } from "../../types/CustomerDetails"; import { CustomerDetails_user } from "../../types/CustomerDetails";
const useStyles = makeStyles(theme => ({ const useStyles = makeStyles(theme => ({
cardTitle: { cardTitle: {
height: 64 height: 72
}, },
root: { checkbox: {
display: "grid" as "grid", marginBottom: theme.spacing()
gridColumnGap: theme.spacing(2), },
gridRowGap: theme.spacing(3), content: {
gridTemplateColumns: "1fr 1fr" paddingTop: theme.spacing()
},
subtitle: {
marginTop: theme.spacing()
} }
})); }));
export interface CustomerDetailsProps { export interface CustomerDetailsProps {
customer: CustomerDetails_user; customer: CustomerDetails_user;
data: { data: {
firstName: string;
lastName: string;
email: string;
isActive: boolean; isActive: boolean;
note: string; note: string;
}; };
disabled: boolean; disabled: boolean;
errors: { errors: FormErrors<"isActive" | "note">;
firstName?: string;
lastName?: string;
email?: string;
note?: string;
};
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;
} }
@ -57,11 +52,15 @@ const CustomerDetails: React.FC<CustomerDetailsProps> = props => {
className={classes.cardTitle} className={classes.cardTitle}
title={ title={
<> <>
<FormattedMessage {...commonMessages.generalInformations} /> {maybe<React.ReactNode>(() => customer.email, <Skeleton />)}
{customer && customer.dateJoined ? ( {customer && customer.dateJoined ? (
<Typography variant="caption" component="div"> <Typography
className={classes.subtitle}
variant="caption"
component="div"
>
<FormattedMessage <FormattedMessage
defaultMessage="Customer since: {date}" defaultMessage="Active member since {date}"
description="section subheader" description="section subheader"
values={{ values={{
date: moment(customer.dateJoined).format("MMM YYYY") date: moment(customer.dateJoined).format("MMM YYYY")
@ -74,9 +73,10 @@ const CustomerDetails: React.FC<CustomerDetailsProps> = props => {
</> </>
} }
/> />
<CardContent> <CardContent className={classes.content}>
<ControlledCheckbox <ControlledCheckbox
checked={data.isActive} checked={data.isActive}
className={classes.checkbox}
disabled={disabled} disabled={disabled}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "User account active", defaultMessage: "User account active",
@ -85,44 +85,6 @@ const CustomerDetails: React.FC<CustomerDetailsProps> = props => {
name="isActive" name="isActive"
onChange={onChange} onChange={onChange}
/> />
<FormSpacer />
<div className={classes.root}>
<TextField
disabled={disabled}
error={!!errors.firstName}
fullWidth
helperText={errors.firstName}
name="firstName"
type="text"
label={intl.formatMessage(commonMessages.firstName)}
value={data.firstName}
onChange={onChange}
/>
<TextField
disabled={disabled}
error={!!errors.lastName}
fullWidth
helperText={errors.lastName}
name="lastName"
type="text"
label={intl.formatMessage(commonMessages.lastName)}
value={data.lastName}
onChange={onChange}
/>
</div>
<FormSpacer />
<TextField
disabled={disabled}
error={!!errors.email}
fullWidth
helperText={errors.email}
name="email"
type="email"
label={intl.formatMessage(commonMessages.email)}
value={data.email}
onChange={onChange}
/>
<FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!errors.note} error={!!errors.note}

View file

@ -13,10 +13,11 @@ import { sectionNames } from "@saleor/intl";
import { getUserName, maybe } from "../../../misc"; import { getUserName, maybe } from "../../../misc";
import { UserError } from "../../../types"; import { UserError } from "../../../types";
import { CustomerDetails_user } from "../../types/CustomerDetails"; import { CustomerDetails_user } from "../../types/CustomerDetails";
import CustomerAddresses from "../CustomerAddresses/CustomerAddresses"; import CustomerAddresses from "../CustomerAddresses";
import CustomerDetails from "../CustomerDetails/CustomerDetails"; import CustomerDetails from "../CustomerDetails";
import CustomerOrders from "../CustomerOrders/CustomerOrders"; import CustomerInfo from "../CustomerInfo";
import CustomerStats from "../CustomerStats/CustomerStats"; import CustomerOrders from "../CustomerOrders";
import CustomerStats from "../CustomerStats";
export interface CustomerDetailsPageFormData { export interface CustomerDetailsPageFormData {
firstName: string; firstName: string;
@ -82,6 +83,14 @@ const CustomerDetailsPage: React.FC<CustomerDetailsPageProps> = ({
onChange={change} onChange={change}
/> />
<CardSpacer /> <CardSpacer />
<CustomerInfo
customer={customer}
data={data}
disabled={disabled}
errors={formErrors}
onChange={change}
/>
<CardSpacer />
<CustomerOrders <CustomerOrders
orders={maybe(() => orders={maybe(() =>
customer.orders.edges.map(edge => edge.node) customer.orders.edges.map(edge => edge.node)

View file

@ -0,0 +1,128 @@
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import { makeStyles } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField";
import Typography from "@material-ui/core/Typography";
import moment from "moment-timezone";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle";
import Grid from "@saleor/components/Grid";
import Hr from "@saleor/components/Hr";
import Skeleton from "@saleor/components/Skeleton";
import { commonMessages } from "@saleor/intl";
import { CustomerDetails_user } from "../../types/CustomerDetails";
const useStyles = makeStyles(theme => ({
cardTitle: {
height: 64
},
content: {
paddingTop: theme.spacing(2)
},
hr: {
margin: theme.spacing(3, 0)
},
sectionHeader: {
marginBottom: theme.spacing()
}
}));
export interface CustomerDetailsProps {
customer: CustomerDetails_user;
data: {
firstName: string;
lastName: string;
email: string;
};
disabled: boolean;
errors: {
firstName?: string;
lastName?: string;
email?: string;
};
onChange: (event: React.ChangeEvent<any>) => void;
}
const CustomerDetails: React.FC<CustomerDetailsProps> = props => {
const { customer, data, disabled, errors, onChange } = props;
const classes = useStyles(props);
const intl = useIntl();
return (
<Card>
<CardTitle
className={classes.cardTitle}
title={
<>
<FormattedMessage {...commonMessages.generalInformations} />
{customer && customer.dateJoined ? (
<Typography variant="caption" component="div">
<FormattedMessage
defaultMessage="Customer since: {date}"
description="section subheader"
values={{
date: moment(customer.dateJoined).format("MMM YYYY")
}}
/>
</Typography>
) : (
<Skeleton style={{ width: "10rem" }} />
)}
</>
}
/>
<CardContent className={classes.content}>
<Typography className={classes.sectionHeader}>
<FormattedMessage {...commonMessages.generalInformations} />
</Typography>
<Grid variant="uniform">
<TextField
disabled={disabled}
error={!!errors.firstName}
fullWidth
helperText={errors.firstName}
name="firstName"
type="text"
label={intl.formatMessage(commonMessages.firstName)}
value={data.firstName}
onChange={onChange}
/>
<TextField
disabled={disabled}
error={!!errors.lastName}
fullWidth
helperText={errors.lastName}
name="lastName"
type="text"
label={intl.formatMessage(commonMessages.lastName)}
value={data.lastName}
onChange={onChange}
/>
</Grid>
<Hr className={classes.hr} />
<Typography className={classes.sectionHeader}>
<FormattedMessage
defaultMessage="Contact Informations"
description="customer contact section, header"
/>
</Typography>
<TextField
disabled={disabled}
error={!!errors.email}
fullWidth
helperText={errors.email}
name="email"
type="email"
label={intl.formatMessage(commonMessages.email)}
value={data.email}
onChange={onChange}
/>
</CardContent>
</Card>
);
};
CustomerDetails.displayName = "CustomerDetails";
export default CustomerDetails;

View file

@ -0,0 +1,2 @@
export { default } from "./CustomerInfo";
export * from "./CustomerInfo";

View file

@ -397,12 +397,12 @@ export default (colors: IThemeColors): Theme =>
}, },
MuiTableCell: { MuiTableCell: {
body: { body: {
fontSize: ".875rem", fontSize: "1rem",
paddingBottom: 8, paddingBottom: 8,
paddingTop: 8 paddingTop: 8
}, },
head: { head: {
fontSize: ".875rem" fontSize: "1rem"
}, },
paddingCheckbox: { paddingCheckbox: {
"&:first-child": { "&:first-child": {