Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Order list view #10

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d07d871
add order list view
adguernier Jun 14, 2023
1abbb91
Merge remote-tracking branch 'origin/main' into order-list-view
adguernier Jun 14, 2023
de95c8b
add tabs from Mui
adguernier Jun 14, 2023
ca1888e
add filters on status to inspect query
adguernier Jun 14, 2023
820ebf4
Merge remote-tracking branch 'origin/main' into order-list-view
adguernier Jun 15, 2023
49205e8
use filter to filter tab
adguernier Jun 15, 2023
8dd2413
display total in tabs
adguernier Jun 15, 2023
c551e67
Merge remote-tracking branch 'origin/main' into order-list-view
adguernier Jun 15, 2023
454fde1
add columns button and display toolbar before tabs
adguernier Jun 16, 2023
cbfc210
default omit some columns
adguernier Jun 16, 2023
ac3dd18
fix order type: missing date property
adguernier Jun 16, 2023
fea202c
display column based on tabs
adguernier Jun 16, 2023
e75437c
add InspectorButton on AppBar
adguernier Jun 16, 2023
8e31159
fullWidth tabs
adguernier Jun 16, 2023
798d8f8
use a single state
adguernier Jun 16, 2023
fb975b4
use map loop to create tabs
adguernier Jun 16, 2023
faaa638
remove switch and use tabs to create filter
adguernier Jun 16, 2023
1371e90
use destructuring for customer resource
adguernier Jun 16, 2023
74d3aee
use destructuring for invoice resource
adguernier Jun 16, 2023
8158ff2
use destructuring for order resource
adguernier Jun 16, 2023
2c1793d
display avatar and name for customer
adguernier Jun 16, 2023
e33a356
add EditGuesser and ShowGuesser for customer
adguernier Jun 16, 2023
a5a5086
display customer address in order list
adguernier Jun 16, 2023
be5d3d6
use <Typography> in AddressField
adguernier Jun 16, 2023
a428991
add item number in basket
adguernier Jun 16, 2023
6d40fd9
add filter for customers
adguernier Jun 16, 2023
1a0f2ae
add some filters
adguernier Jun 16, 2023
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
18 changes: 4 additions & 14 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,16 @@ import {
} from "react-admin";
import { dataProvider } from "./dataProvider";
import { authProvider } from "./authProvider";
import { AppLayout, CustomerList, InvoiceList } from "./ui";
import { AppLayout, customer, invoice, order } from "./ui";

export const App = () => (
<Admin
dataProvider={dataProvider}
authProvider={authProvider}
layout={AppLayout}
>
<Resource name="invoices" list={InvoiceList} />
<Resource
name="commands"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource name="invoices" {...invoice} />
<Resource name="commands" {...order} />
<Resource
name="products"
list={ListGuesser}
Expand All @@ -34,12 +29,7 @@ export const App = () => (
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="customers"
list={CustomerList}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource name="customers" {...customer} />
<Resource
name="reviews"
list={ListGuesser}
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export interface Order {
id: number;
reference: string;
string: string;
date: string;
customer_id: number;
basket: BasketItem[];
total_ex_taxes: number;
Expand Down
3 changes: 2 additions & 1 deletion src/ui/AppBar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TitlePortal, AppBar as RaAppBar } from "react-admin";
import { TitlePortal, AppBar as RaAppBar, InspectorButton } from "react-admin";
import { Box } from "@mui/material";
import Logo from "./Logo";
export const AppBar = () => {
Expand All @@ -7,6 +7,7 @@ export const AppBar = () => {
<TitlePortal />
<Logo />
<Box flex="1" />
<InspectorButton />
</RaAppBar>
);
};
12 changes: 12 additions & 0 deletions src/ui/customField/AddressField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useRecordContext } from "react-admin";
import Typography from "@mui/material/Typography";
import { Customer } from "../../types";

export const AddressField = () => {
const customer = useRecordContext<Customer>();
return (
<Typography>
{customer.address} {customer.zipcode} {customer.city}
</Typography>
);
};
12 changes: 12 additions & 0 deletions src/ui/customField/FullNameField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useRecordContext } from "react-admin";
import Typography from "@mui/material/Typography";
import { Customer } from "../../types";

export const FullNameField = () => {
const customer = useRecordContext<Customer>();
return (
<Typography>
{customer.first_name} {customer.last_name}
</Typography>
);
};
2 changes: 2 additions & 0 deletions src/ui/customField/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./AddressField";
export * from "./FullNameField";
16 changes: 16 additions & 0 deletions src/ui/customer/RecordRepresentation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Avatar from "@mui/material/Avatar";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import { Customer } from "../../types";

export const RecordRepresentation = (record: Customer) => {
return (
<Stack direction="row" spacing={2} alignItems="center">
<Avatar
alt={`${record.first_name} ${record.last_name}`}
src={record.avatar}
/>
<Typography>{`${record.first_name} ${record.last_name}`}</Typography>
</Stack>
);
};
11 changes: 10 additions & 1 deletion src/ui/customer/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
export * from "./CustomerList";
import { EditGuesser, ShowGuesser } from "react-admin";
import { CustomerList } from "./CustomerList";
import { RecordRepresentation } from "./RecordRepresentation";

export const customer: Partial<ResourceProps> = {
list: CustomerList,
edit: EditGuesser,
show: ShowGuesser,
recordRepresentation: RecordRepresentation,
};
10 changes: 8 additions & 2 deletions src/ui/invoice/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
export * from "./InvoiceList";
export * from "./InvoiceShow";
import { ResourceProps } from "react-admin";
import { InvoiceList } from "./InvoiceList";
import { InvoiceShow } from "./InvoiceShow";

export const invoice: Partial<ResourceProps> = {
list: InvoiceList,
show: InvoiceShow,
};
195 changes: 195 additions & 0 deletions src/ui/order/OrderList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import { SyntheticEvent, useState } from "react";
import {
AutocompleteInput,
BooleanField,
Count,
DatagridConfigurable,
DatagridConfigurableProps,
DateField,
DateInput,
ExportButton,
FilterButton,
FunctionField,
List,
NumberField,
NumberInput,
ReferenceField,
ReferenceInput,
SearchInput,
SelectColumnsButton,
SelectInput,
TextField,
TopToolbar,
} from "react-admin";
import Tabs from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
import Box from "@mui/material/Box";
import { AddressField, FullNameField } from "../customField";
import { Order } from "../../types";

interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}

const a11yProps = (index: number) => {
return {
id: `simple-tab-${index}`,
"aria-controls": `simple-tabpanel-${index}`,
};
};

const TabPanel = (props: TabPanelProps) => {
const { children, value, index, ...other } = props;

return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && <Box sx={{ p: 3 }}>{children}</Box>}
</div>
);
};

const tabs = ["ordered", "delivered", "cancelled"];

const defaultOmits = [
"basket",
"total_ex_taxes",
"delivery_fees",
"tax_rate",
"taxes",
"returned",
];

export const OrderList = () => {
const [value, setValue] = useState(0);
const filter = { status: tabs[value] };

const handleChange = (event: SyntheticEvent, newValue: number) => {
setValue(newValue);
};
adguernier marked this conversation as resolved.
Show resolved Hide resolved

return (
<Box sx={{ width: "100%" }}>
<List
filter={filter}
filters={[
<SearchInput source="q" alwaysOn key="q" />,
<ReferenceInput
reference="customers"
source="customer_id"
key="customer"
>
<AutocompleteInput
label="Customer"
optionText={<FullNameField />}
inputText={(choice) => `${choice.first_name} ${choice.last_name}`}
/>
</ReferenceInput>,
<SelectInput
source="returned"
choices={[
{ id: true, name: "Yes" },
{ id: false, name: "No" },
]}
key="returned"
/>,
<NumberInput source="total_gte" key="total" label="Min amount" />,
<DateInput source="date_gte" key="date_gte" label="Passed since" />,
<DateInput source="date_lte" key="date_lte" label="Passed before" />,
]}
actions={
<TopToolbar>
<SelectColumnsButton preferenceKey={filter.status} />
<FilterButton />
<ExportButton />
</TopToolbar>
}
>
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
<Tabs
value={value}
onChange={handleChange}
aria-label="basic tabs example"
variant="fullWidth"
>
{tabs.map((tab, index) => (
<Tab
key={index}
label={<TabLabel filter={tab} />}
{...a11yProps(index)}
/>
))}
</Tabs>
</Box>

{tabs.map((tab, index) => (
<TabPanel value={value} index={index} key={index}>
<TabList preferenceKey={tab} omit={defaultOmits} />
</TabPanel>
))}
</List>
</Box>
);
};

interface TabLabelProps {
children?: React.ReactNode;
filter: string;
}

const TabLabel = (props: TabLabelProps) => {
const { filter, children, ...rest } = props;
const count = <Count filter={{ status: filter }} />;
return (
<span>
{filter.toUpperCase()} ({count}) {children}
</span>
);
};

const TabList = (props: DatagridConfigurableProps) => {
return (
<DatagridConfigurable
rowClick="edit"
omit={
props.preferenceKey === "delivered"
? props.omit?.filter((omit) => omit !== "returned")
: props.omit
}
{...props}
>
<DateField source="date" />
<TextField source="reference" />
<ReferenceField source="customer_id" reference="customers" />
<ReferenceField
source="customer_id"
reference="customers"
label="Address"
link={false}
>
<AddressField />
</ReferenceField>
<FunctionField
label="Nb Items"
render={(record: Order) => {
return record.basket.length;
}}
/>
<NumberField source="total_ex_taxes" />
<NumberField source="delivery_fees" />
<NumberField source="tax_rate" />
<NumberField source="taxes" />
<NumberField source="total" />
{props.preferenceKey === "delivered" && (
<BooleanField source="returned" />
)}
</DatagridConfigurable>
);
};
7 changes: 7 additions & 0 deletions src/ui/order/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
import { ResourceProps } from "react-admin";
import { OrderList } from "./OrderList";

export * from "./BasketDetail";

export const order: Partial<ResourceProps> = {
list: OrderList,
};