Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
55 changes: 29 additions & 26 deletions examples/ecommerce-jewellery-store/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Header from "./components/Header";
import Footer from "./components/Footer";
import { ShoppingCartList } from "./components/ShoppingCartList";
import Contacts from "./pages/Contacts";
import ThankYou from "./pages/ThankYou";
import PaymentDetails from "./pages/PaymentDetails";
Expand All @@ -14,35 +15,37 @@ import { CartProvider } from "./helpers/CartContext";
import { AdminProvider } from './helpers/AdminContext';
import { CategoriesProvider } from './helpers/CategoriesContext';
import { ThemeProvider } from './helpers/ThemeContext';
import { ShoppingCartList } from "./components/ShoppingCartList";
import { LanguageProvider } from "./helpers/LanguageContext";

function App() {
return (
<ThemeProvider>
<CartProvider>
<AdminProvider>
<CategoriesProvider>
<Router basename="/kendo-react/ecommerce-jewellery-store">
<Header />
<SizedParent>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/paymentdetails" element={<PaymentDetails />} />
<Route path="/thankyou" element={<ThankYou />} />
<Route path="/contacts" element={<Contacts />} />
<Route path="/products" element={<AllProductsListView />} />
<Route path="/category" element={<DetailedCategory />} />
<Route path="/product/:id" element={<ProductDetails />} />
<Route path="/shoppingcart" element={<ShoppingCartList />} />
</Routes>
</SizedParent>
<Footer />
</Router>
</CategoriesProvider>
</AdminProvider>
</CartProvider>
</ThemeProvider>
<LanguageProvider>
<ThemeProvider>
<CartProvider>
<AdminProvider>
<CategoriesProvider>
<Router basename="/kendo-react/ecommerce-jewellery-store">
<Header />
<SizedParent>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/paymentdetails" element={<PaymentDetails />} />
<Route path="/thankyou" element={<ThankYou />} />
<Route path="/contacts" element={<Contacts />} />
<Route path="/products" element={<AllProductsListView />} />
<Route path="/category" element={<DetailedCategory />} />
<Route path="/product/:id" element={<ProductDetails />} />
<Route path="/shoppingcart" element={<ShoppingCartList />} />
</Routes>
</SizedParent>
<Footer />
</Router>
</CategoriesProvider>
</AdminProvider>
</CartProvider>
</ThemeProvider>
</LanguageProvider>
);
}

export default App;
export default App;
82 changes: 50 additions & 32 deletions examples/ecommerce-jewellery-store/src/components/AdminView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { getter } from '@progress/kendo-react-common';
import * as React from "react";
import { getter } from "@progress/kendo-react-common";
import {
Grid,
GridColumn,
Expand All @@ -10,16 +10,21 @@ import {
getSelectedStateFromKeyDown,
GridSortChangeEvent,
GridPageChangeEvent,
} from '@progress/kendo-react-grid';
} from "@progress/kendo-react-grid";
import {
ChartWizard,
ChartWizardDataRow,
getWizardDataFromGridSelection,
} from '@progress/kendo-react-chart-wizard';
import { Button } from '@progress/kendo-react-buttons';
import { orderBy } from '@progress/kendo-data-query';
import { chartAreaStackedIcon } from '@progress/kendo-svg-icons';
import { sampleData } from '../data/shared-gd-sampleChartData';
} from "@progress/kendo-react-chart-wizard";
import { Button } from "@progress/kendo-react-buttons";
import { orderBy } from "@progress/kendo-data-query";
import { chartAreaStackedIcon } from "@progress/kendo-svg-icons";
import { sampleData } from "../data/shared-gd-sampleChartData";
import { useLanguageContext } from "../helpers/LanguageContext";
import { LocalizationProvider, loadMessages } from "@progress/kendo-react-intl";
import esMessages from "../data/messages/es";
import frMessages from "../data/messages/fr";
import enMessages from "../data/messages/en";

interface SampleDataItem {
ID: string;
Expand All @@ -33,8 +38,8 @@ interface SampleDataItem {
URL: string;
}

const DATA_ITEM_KEY = 'ID';
const SELECTED_FIELD = 'selected';
const DATA_ITEM_KEY = "ID";
const SELECTED_FIELD = "selected";
const idGetter = getter(DATA_ITEM_KEY);

interface SelectedState {
Expand All @@ -44,15 +49,27 @@ interface SelectedState {
const AdminView: React.FC = () => {
const gridRef = React.useRef<GridHandle>(null);
const [selectedState, setSelectedState] = React.useState<SelectedState>({});
const [sort, setSort] = React.useState<{ field: string; dir: 'asc' | 'desc' }[]>([
{ field: 'Sales', dir: 'desc' },
const [sort, setSort] = React.useState<{ field: string; dir: "asc" | "desc" }[]>([
{ field: "Sales", dir: "desc" },
]);
const [showChartWizard, setShowChartWizard] = React.useState<boolean>(false);
const [chartData, setChartData] = React.useState<ChartWizardDataRow[]>([]);
const [top3SalesData, setTop3SalesData] = React.useState<ChartWizardDataRow[]>([]);
const [top3Visible, setTop3Visible] = React.useState<boolean>(false);
const [page, setPage] = React.useState<{ skip: number; take: number }>({ skip: 0, take: 4 });

const { t, language } = useLanguageContext();

React.useEffect(() => {
if (language === "es") {
loadMessages(esMessages, "es");
} else if (language === "fr") {
loadMessages(frMessages, "fr");
} else {
loadMessages(enMessages, "en");
}
}, [language]);

const data = sampleData.map((item) => ({
...item,
[SELECTED_FIELD]: selectedState[idGetter(item)],
Expand Down Expand Up @@ -96,7 +113,7 @@ const AdminView: React.FC = () => {
setChartData(chartWizardData);
setShowChartWizard(true);
} else {
console.error('Grid reference is not available.');
console.error("Grid reference is not available.");
}
}, [selectedState]);

Expand All @@ -111,8 +128,8 @@ const AdminView: React.FC = () => {
const sortedTop3Sales = selectedData
.sort(
(a, b) =>
b.find((field) => field.field === 'Total Sales')?.value -
a.find((field) => field.field === 'Total Sales')?.value
b.find((field) => field.field === "Total Sales")?.value -
a.find((field) => field.field === "Total Sales")?.value
)
.slice(0, 3);

Expand All @@ -127,29 +144,30 @@ const AdminView: React.FC = () => {
const imageUrl = field && field in dataItem ? (dataItem as Record<string, any>)[field] : dataItem.URL;
return (
<td>
<img src={imageUrl} alt="Product" style={{ width: '100px', height: 'auto' }} />
<img src={imageUrl} alt="Product" style={{ width: "100px", height: "auto" }} />
</td>
);
};

return (
<>
<div style={{ marginBottom: '10px' }}>
<LocalizationProvider language={language}>
<div style={{ marginBottom: "10px" }}>
<Button
svgIcon={chartAreaStackedIcon}
onClick={handleSelectedChart}
disabled={disabled}
style={{ marginRight: '10px' }}
style={{ marginRight: "10px" }}
>
Chart of Selected Data
{t.chartSelectedDataButton}
</Button>
<Button svgIcon={chartAreaStackedIcon} onClick={handleTop3Sales}>
Top 3 Sales per Category
{t.top3SalesButton}
</Button>
</div>
<Grid
key={language}
ref={gridRef}
style={{ height: '500px' }}
style={{ height: "500px" }}
data={pagedData}
dataItemKey={DATA_ITEM_KEY}
selectedField={SELECTED_FIELD}
Expand All @@ -161,24 +179,24 @@ const AdminView: React.FC = () => {
selectable={{
enabled: true,
drag: true,
mode: 'multiple',
mode: "multiple",
}}
navigatable={true}
onSelectionChange={onSelectionChange}
onKeyDown={onKeyDown}
sortable={true}
sort={sort}
onSortChange={(e: GridSortChangeEvent) => {
setSort(e.sort as { field: string; dir: 'asc' | 'desc' }[]);
setSort(e.sort as { field: string; dir: "asc" | "desc" }[]);
}}
>
<GridColumn field="URL" title="Product" cell={URLImageCell} />
<GridColumn field="Product" title="Name" />
<GridColumn field="SKU" title="SKU" />
<GridColumn field="Category" title="Category" />
<GridColumn field="Price" title="Price" />
<GridColumn field="Quantity" title="Quantity" />
<GridColumn field="Sales" title="Total Sales" />
<GridColumn field="URL" title={t.grid.productTitle} cell={URLImageCell} />
<GridColumn field="Product" title={t.grid.nameTitle} />
<GridColumn field="SKU" title={t.grid.skuTitle} />
<GridColumn field="Category" title={t.grid.categoryTitle} />
<GridColumn field="Price" title={t.grid.priceTitle} />
<GridColumn field="Quantity" title={t.grid.quantityTitle} />
<GridColumn field="Sales" title={t.grid.totalSalesTitle} />
</Grid>

{showChartWizard && (
Expand All @@ -194,7 +212,7 @@ const AdminView: React.FC = () => {
onClose={() => setTop3Visible(false)}
/>
)}
</>
</LocalizationProvider>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@

import { useNavigate } from "react-router-dom";
import { CategoryListProps } from "../data/types";
import { Button } from "@progress/kendo-react-buttons";
import { CardDescriptor } from "../data/types";
import { useLanguageContext } from "../helpers/LanguageContext";

export const CategoryList: React.FC<CategoryListProps> = ({ data, title, subtitle, colSpan = 4 }) => {
const navigate = useNavigate();
const { t } = useLanguageContext();

const onNavigate = (card: CardDescriptor) => {
if (card.collectionText === `Collection "AURELIA"`) {
navigate("/category")
navigate("/category");
}
}
};

return (
<>
Expand Down Expand Up @@ -48,7 +49,7 @@ export const CategoryList: React.FC<CategoryListProps> = ({ data, title, subtitl
}}
>
<Button themeColor={"primary"} size={"large"} onClick={() => onNavigate(card)}>
Buy Now
{t.buyNowButtonText}
</Button>
</div>
</div>
Expand All @@ -57,4 +58,4 @@ export const CategoryList: React.FC<CategoryListProps> = ({ data, title, subtitl
</div>
</>
);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,23 @@ import { SvgIcon } from "@progress/kendo-react-common";
import { filterIcon, sortAscIcon } from "@progress/kendo-svg-icons";
import { FilterDescriptor, SortDescriptor, State } from "@progress/kendo-data-query";
import { useCategoriesContext } from "../helpers/CategoriesContext";

const chips = ["Bracelets", "Rings", "Earrings", "Watches", "Necklaces"];
const statuses = ["Sale", "Recommended", "Must Have"];
const materials = ["Gold", "Silver"];
import { useLanguageContext } from "../helpers/LanguageContext";

interface FilterComponentProps {
updateUI: (state: State) => void;
}

export const FilterComponent: React.FC<FilterComponentProps> = ({ updateUI }) => {
const { selectedCategory, setSelectedCategory } = useCategoriesContext();
const { t } = useLanguageContext();

const [categoryValue, setCategoryValue] = React.useState<string[]>([]);
const [statusValue, setStatusValue] = React.useState<string>("Recommended");
const [materialValue, setMaterialValue] = React.useState<string>("Material");
const [statusValue, setStatusValue] = React.useState<string>(t.statusRecommended);
const [materialValue, setMaterialValue] = React.useState<string>(t.materialPlaceholder);

const chips = t.categoriesData || [];
const statuses = t.statusesData || [];
const materials = t.materialsData || [];

useEffect(() => {
if (selectedCategory) {
Expand Down Expand Up @@ -96,8 +99,8 @@ export const FilterComponent: React.FC<FilterComponentProps> = ({ updateUI }) =>

const clearFilters = () => {
setCategoryValue([]);
setStatusValue("Recommended");
setMaterialValue("Material");
setStatusValue(t.statusRecommended);
setMaterialValue(t.materialPlaceholder);
setSelectedCategory(null);
updateUI({ filter: undefined, sort: undefined });
};
Expand All @@ -106,13 +109,13 @@ export const FilterComponent: React.FC<FilterComponentProps> = ({ updateUI }) =>
<section className="k-d-flex k-justify-content-between k-align-items-center">
<span className="k-d-flex k-align-items-center">
<span className="k-d-flex k-align-items-center k-pr-2">
<SvgIcon icon={filterIcon}></SvgIcon> Filter:
<SvgIcon icon={filterIcon}></SvgIcon> {t.filterLabel}
</span>
<span className="k-pr-2">
<MultiSelect
data={chips}
value={categoryValue}
placeholder="Category"
placeholder={t.categoryPlaceholder}
onChange={onCategoryChange}
style={{ minWidth: "119px" }}
/>
Expand All @@ -123,13 +126,14 @@ export const FilterComponent: React.FC<FilterComponentProps> = ({ updateUI }) =>
</span>
<span className="k-d-flex k-align-items-center">
<span className="k-d-flex k-align-items-center k-pr-2">
<SvgIcon icon={sortAscIcon}></SvgIcon> Sort by:
<SvgIcon icon={sortAscIcon}></SvgIcon> {t.sortByLabel}
</span>
<span>
<DropDownList data={statuses} value={statusValue} onChange={onStatusChange} />
</span>
</span>
<button className="k-button k-button-flat" onClick={clearFilters}>Clear Filters</button>
<button className="k-button k-button-flat" onClick={clearFilters}>{t.clearFiltersButton}</button>
</section>
);
};

Loading