import React, { useCallback, useState } from 'react';
import { Toast } from 'devextreme-react/toast';
import type { ToastTypes } from 'devextreme-react/toast';
import type { CheckBoxTypes } from 'devextreme-react/check-box';
import { ProductItem } from './ProductItem.tsx';
import { products } from './data.ts';
import type { Product, ToastConfig } from './types.ts';
function App() {
const [toastConfig, setToastConfig] = useState<ToastConfig>({
isVisible: false,
type: 'info',
message: '',
});
const checkAvailability = useCallback((e: CheckBoxTypes.ValueChangedEvent, product: Product): void => {
const type: ToastTypes.ToastType = e.value ? 'success' : 'error';
const message = product.Name + (e.value ? ' is available' : ' is not available');
setToastConfig({
...toastConfig,
isVisible: true,
type,
message,
});
}, [toastConfig]);
const onHiding = useCallback(() => {
setToastConfig({
...toastConfig,
isVisible: false,
});
}, [toastConfig]);
const items = products.map((product: Product) => (
<li key={product.ID}>
<ProductItem product={product} checkAvailability={checkAvailability} />
</li>
));
return (
<div id="product-list">
<div className="header">Product List</div>
<ul>{items}</ul>
<Toast
visible={toastConfig.isVisible}
message={toastConfig.message}
type={toastConfig.type}
onHiding={onHiding}
displayTime={600}
/>
</div>
);
}
export default App;
import React, { useCallback, useState } from 'react';
import { Toast } from 'devextreme-react/toast';
import { ProductItem } from './ProductItem.js';
import { products } from './data.js';
function App() {
const [toastConfig, setToastConfig] = useState({
isVisible: false,
type: 'info',
message: '',
});
const checkAvailability = useCallback(
(e, product) => {
const type = e.value ? 'success' : 'error';
const message = product.Name + (e.value ? ' is available' : ' is not available');
setToastConfig({
...toastConfig,
isVisible: true,
type,
message,
});
},
[toastConfig],
);
const onHiding = useCallback(() => {
setToastConfig({
...toastConfig,
isVisible: false,
});
}, [toastConfig]);
const items = products.map((product) => (
<li key={product.ID}>
<ProductItem
product={product}
checkAvailability={checkAvailability}
/>
</li>
));
return (
<div id="product-list">
<div className="header">Product List</div>
<ul>{items}</ul>
<Toast
visible={toastConfig.isVisible}
message={toastConfig.message}
type={toastConfig.type}
onHiding={onHiding}
displayTime={600}
/>
</div>
);
}
export default App;
import React, { useCallback } from 'react';
import { CheckBox } from 'devextreme-react/check-box';
import type { CheckBoxTypes } from 'devextreme-react/check-box';
import type { Product } from './types.ts';
interface ProductItemProps {
product: Product;
checkAvailability: (e: CheckBoxTypes.ValueChangedEvent, product: Product) => void;
}
export function ProductItem({ product, checkAvailability }: ProductItemProps) {
const onValueChanged = useCallback((e: CheckBoxTypes.ValueChangedEvent): void => {
checkAvailability(e, product);
}, [product, checkAvailability]);
return (
<>
<img alt={product.Name} src={product.ImageSrc} />
<div>{product.Name}</div>
<CheckBox
text="Available"
onValueChanged={onValueChanged}
/>
</>
);
}
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.tsx';
ReactDOM.render(
<App />,
document.getElementById('app'),
);
import type { Product } from './types.ts';
export const products: Product[] = [{
ID: 4,
Name: 'SuperLED 50',
Price: 1600,
Current_Inventory: 77,
Backorder: 0,
Manufacturing: 55,
Category: 'Televisions',
ImageSrc: '../../../../images/products/4.png',
}, {
ID: 5,
Name: 'SuperLED 42',
Price: 1450,
Current_Inventory: 445,
Backorder: 0,
Manufacturing: 0,
Category: 'Televisions',
ImageSrc: '../../../../images/products/5.png',
}, {
ID: 6,
Name: 'SuperLCD 55',
Price: 1350,
Current_Inventory: 345,
Backorder: 0,
Manufacturing: 5,
Category: 'Televisions',
ImageSrc: '../../../../images/products/6.png',
}, {
ID: 7,
Name: 'SuperLCD 42',
Price: 1200,
Current_Inventory: 210,
Backorder: 0,
Manufacturing: 20,
Category: 'Televisions',
ImageSrc: '../../../../images/products/7.png',
}];
import type { ToastTypes } from 'devextreme-react/toast';
export type Product = {
ID: number;
Name: string;
Price: number;
Current_Inventory: number;
Backorder: number;
Manufacturing: number;
Category: string;
ImageSrc: string;
};
export type ToastConfig = {
isVisible: boolean;
type: ToastTypes.ToastType;
message: string;
};
import React, { useCallback } from 'react';
import { CheckBox } from 'devextreme-react/check-box';
export function ProductItem({ product, checkAvailability }) {
const onValueChanged = useCallback(
(e) => {
checkAvailability(e, product);
},
[product, checkAvailability],
);
return (
<>
<img
alt={product.Name}
src={product.ImageSrc}
/>
<div>{product.Name}</div>
<CheckBox
text="Available"
onValueChanged={onValueChanged}
/>
</>
);
}
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
ReactDOM.render(<App />, document.getElementById('app'));
export const products = [
{
ID: 4,
Name: 'SuperLED 50',
Price: 1600,
Current_Inventory: 77,
Backorder: 0,
Manufacturing: 55,
Category: 'Televisions',
ImageSrc: '../../../../images/products/4.png',
},
{
ID: 5,
Name: 'SuperLED 42',
Price: 1450,
Current_Inventory: 445,
Backorder: 0,
Manufacturing: 0,
Category: 'Televisions',
ImageSrc: '../../../../images/products/5.png',
},
{
ID: 6,
Name: 'SuperLCD 55',
Price: 1350,
Current_Inventory: 345,
Backorder: 0,
Manufacturing: 5,
Category: 'Televisions',
ImageSrc: '../../../../images/products/6.png',
},
{
ID: 7,
Name: 'SuperLCD 42',
Price: 1200,
Current_Inventory: 210,
Backorder: 0,
Manufacturing: 20,
Category: 'Televisions',
ImageSrc: '../../../../images/products/7.png',
},
];
<!DOCTYPE html>
<html lang="en">
<head>
<title>DevExtreme Demo</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/26.1.5/css/dx.light.css" />
<link rel="stylesheet" type="text/css" href="./bundle.css" />
</head>
<body class="dx-viewport">
<div class="demo-container">
<div id="app"></div>
</div>
<script src="bundles/vendor/react.vendor.js"></script>
<script src="./bundle.js"></script>
</body>
</html>
.header {
font-size: 34px;
text-align: center;
}
#product-list {
padding: 10px;
}
#product-list ul {
text-align: center;
list-style-type: none;
margin: 20px 0;
}
#product-list ul li {
display: inline-block;
width: 160px;
margin: 10px;
}
#product-list ul li img {
width: 100px;
}
.dx-toast-content {
min-width: 300px;
max-width: 400px;
}