Skip to content

Commit

Permalink
translate remaining parts of the app
Browse files Browse the repository at this point in the history
  • Loading branch information
filipKovachev committed Dec 3, 2024
1 parent feef671 commit f491f35
Show file tree
Hide file tree
Showing 17 changed files with 2,005 additions and 1,197 deletions.
144 changes: 68 additions & 76 deletions examples/ecommerce-jewellery-store/src/components/FilterComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,118 +1,108 @@
import React, { useEffect } from "react";
import React, { useEffect, useState, useCallback } from "react";
import { MultiSelect, DropDownList } from "@progress/kendo-react-dropdowns";
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";
import { FilterDescriptor, State } from "@progress/kendo-data-query";
import { useStore } from "@nanostores/react";
import { selectedLanguage } from "../helpers/languageStore";
import enMessages from "../data/messages/en";
import frMessages from "../data/messages/fr";
import esMessages from "../data/messages/es";

const translations = {
en: enMessages,
fr: frMessages,
es: esMessages,
};

const chips = ["Bracelets", "Rings", "Earrings", "Watches", "Necklaces"];
const statuses = ["Sale", "Recommended", "Must Have"];
const materials = ["Gold", "Silver"];
const getTranslations = (language: string) => {
return translations[language] || translations["en"];
};

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

export const FilterComponent: React.FC<FilterComponentProps> = ({ updateUI }) => {
const { selectedCategory, setSelectedCategory } = useCategoriesContext();
const [categoryValue, setCategoryValue] = React.useState<string[]>([]);
const [statusValue, setStatusValue] = React.useState<string>("Recommended");
const [materialValue, setMaterialValue] = React.useState<string>("Material");

useEffect(() => {
if (selectedCategory) {
setCategoryValue([selectedCategory]);
applyCategoryFilter([selectedCategory]);
} else {
setCategoryValue([]);
applyCategoryFilter([]);
}
}, [selectedCategory]);
const language = useStore(selectedLanguage);
const t = getTranslations(language);

const applyCategoryFilter = (categories: string[]) => {
const filters = categories.map((category) => ({
field: "category",
operator: "eq",
value: category,
}));
const [categoryValue, setCategoryValue] = useState<string[]>([]);
const [statusValue, setStatusValue] = useState<string>(t.statusesData[0]);
const [materialValue, setMaterialValue] = useState<string>(t.materialPlaceholder);

const customCompositeFilters: State = {
filter: {
logic: "or",
filters,
},
sort: undefined,
};
const chips = t.categoriesData || [];
const statuses = t.statusesData || [];
const materials = t.materialsData || [];

updateUI(customCompositeFilters);
};
useEffect(() => {
setCategoryValue([]);
setStatusValue(t.statusesData[0]);
setMaterialValue(t.materialPlaceholder);
updateUI({ filter: undefined, sort: undefined });
}, [language, t, updateUI]);

const onCategoryChange = (e: any) => {
setCategoryValue(e.value);
applyCategoryFilter(e.value);
setSelectedCategory(e.value.length > 0 ? e.value[0] : null);
};
const applyFilters = useCallback(() => {
const filters: FilterDescriptor[] = [];

const onStatusChange = (e: any) => {
setStatusValue(e.value);
if (categoryValue.length > 0) {
filters.push({
field: "category",
operator: "eq",
value: categoryValue[0],
});
}

const newSorts: SortDescriptor[] = [
{
if (statusValue !== t.statusesData[0]) {
filters.push({
field: "status",
dir: "desc",
},
];

const customCompositeFilters: State = {
filter: undefined,
sort: newSorts,
};

updateUI(customCompositeFilters);
};

const onMaterialChange = (e: any) => {
setMaterialValue(e.value);
operator: "eq",
value: statusValue,
});
}

const newFilter: FilterDescriptor[] = [
{
if (materialValue !== t.materialPlaceholder) {
filters.push({
field: "material",
operator: "eq",
value: e.value,
},
];
value: materialValue,
});
}

const customCompositeFilters: State = {
filter: {
logic: "or",
filters: newFilter,
},
filter: filters.length > 0 ? { logic: "and", filters } : undefined,
sort: undefined,
};

updateUI(customCompositeFilters);
setCategoryValue([]);
};
}, [categoryValue, statusValue, materialValue, t, updateUI]);

useEffect(() => {
applyFilters();
}, [categoryValue, statusValue, materialValue, applyFilters]);

const onCategoryChange = (e: any) => setCategoryValue(e.value);
const onStatusChange = (e: any) => setStatusValue(e.value);
const onMaterialChange = (e: any) => setMaterialValue(e.value);

const clearFilters = () => {
setCategoryValue([]);
setStatusValue("Recommended");
setMaterialValue("Material");
setSelectedCategory(null);
setStatusValue(t.statusesData[0]);
setMaterialValue(t.materialPlaceholder);
updateUI({ filter: undefined, sort: undefined });
};

return (
<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 +113,15 @@ 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>
);
};
127 changes: 77 additions & 50 deletions examples/ecommerce-jewellery-store/src/pages/AllProductsListView.tsx
Original file line number Diff line number Diff line change
@@ -1,99 +1,126 @@
import * as React from "react";

import bracelets from "@/assets/bracelets.png?url";
import necklace from "@/assets/necklace_1.jfif?url";
import ring from "@/assets/ring_1.jfif?url";
import jewel from "@/assets/1111.jfif?url";
import React, { useState, useEffect, useCallback } from "react";
import { Layout } from "../components/Layout";
import { OrderedImgText } from "../components/OrderedImageCard";
import { CustomSection } from "../components/CustomizedSection";
import { listData } from "../data/listData";
import { FilterComponent } from "../components/FilterComponent";
import { CardsList } from "../components/CardsList";
import { CategoryList } from "../components/CategoryList";
import { CardDescriptor } from "../data/types";
import { DataModel } from "../data/types";

import { Breadcrumb } from "@progress/kendo-react-layout";
import { Button, ButtonGroup } from "@progress/kendo-react-buttons";
import { layout2By2Icon, gridLayoutIcon } from "@progress/kendo-svg-icons";
import { process, State } from "@progress/kendo-data-query";
import getTranslatedListData from "../data/listData";
import { useStore } from "@nanostores/react";
import { selectedLanguage } from "../helpers/languageStore";

import enMessages from "../data/messages/en";
import frMessages from "../data/messages/fr";
import esMessages from "../data/messages/es";

const messages = {
en: enMessages,
fr: frMessages,
es: esMessages,
};

export const AllProductsListView: React.FC = () => {
const language = useStore(selectedLanguage);
const t = messages[language] || messages["en"];
const [translatedData, setTranslatedData] = useState(() => getTranslatedListData());
const [filteredData, setFilteredData] = useState(translatedData);
const [currentLayout, setCurrentLayout] = useState<"grid" | "list">("grid");

export const AllProductsListView = () => {
const title = "Fine Selection";
const subtitle = "Enjoy the real craftsmanship";
const contentText =
"Jewelry is a meaningful form of self-expression that enhances personal style and adds beauty to any occasion.";
const order = "first";
useEffect(() => {
const updatedData = getTranslatedListData();
setTranslatedData(updatedData);
setFilteredData(updatedData);
}, [language]);

const [data, setData] = React.useState(listData);

const updateUI = (newState: State) => {
const newData = process(listData, newState)
setData(newData.data)
};
const updateUI = useCallback(
(newState: State) => {
const updatedData = process(translatedData, newState).data;
setFilteredData(updatedData);
},
[translatedData]
);

const cards: CardDescriptor[] = [
const cards = [
{
img: necklace,
collectionText: 'Collection "SERENE"',
img: "/necklace_1.jfif",
collectionText: t.collectionSerene,
},
{
img: ring,
collectionText: 'Collection "AURELIA"',
img: "/ring_1.jfif",
collectionText: t.collectionAurelia,
},
{
img: jewel,
collectionText: 'Collection "RAVINA"',
img: "/1111.jfif",
collectionText: t.collectionRavina,
},
];

const BreakcrumbData: DataModel[] = [{
text: "Home"
},
{
text: "Jewelry"
}]
const breadcrumbData = [
{ text: t.breadcrumbHome },
{ text: t.breadcrumbJewelry },
];

return (
<>
<Layout>
<section
className="k-d-grid k-grid-cols-12 k-justify-content-center k-align-items-center k-col-span-12"
style={{
paddingTop: "60px",
}}
style={{ paddingTop: "60px" }}
>
<OrderedImgText
title={title}
subtitle={subtitle}
contentText={contentText}
img={bracelets}
order={order}
title={t.allProductsTitle}
subtitle={t.allProductsSubtitle}
contentText={t.allProductsContentText}
img="/bracelets.png"
order="first"
link={null}
/>
</section>
</Layout>

<Layout>
<CustomSection>
<CategoryList title="Our Collections" subtitle="Enjoy an excellent selection of fine jewelry" data={cards}></CategoryList>
<CategoryList
title={t.ourCollectionsTitle}
subtitle={t.ourCollectionsSubtitle}
data={cards}
/>
</CustomSection>
</Layout>

<Layout>
<section className="k-d-flex k-justify-content-between">
<Breadcrumb data={BreakcrumbData}></Breadcrumb>
<section className="k-d-flex k-justify-content-between k-align-items-center k-py-4">
<Breadcrumb data={breadcrumbData} />
<ButtonGroup>
<Button fillMode={"flat"} svgIcon={gridLayoutIcon}></Button>
<Button fillMode={"flat"} svgIcon={layout2By2Icon}></Button>
<Button
fillMode="flat"
svgIcon={gridLayoutIcon}
selected={currentLayout === "grid"}
onClick={() => setCurrentLayout("grid")}
/>
<Button
fillMode="flat"
svgIcon={layout2By2Icon}
selected={currentLayout === "list"}
onClick={() => setCurrentLayout("list")}
/>
</ButtonGroup>
</section>
</Layout>

<Layout>
<FilterComponent updateUI={updateUI}></FilterComponent>
<FilterComponent updateUI={updateUI} />
</Layout>

<Layout>
<CardsList data={data}></CardsList>
<CardsList data={filteredData} layout={currentLayout} />
</Layout>
</>
);
};

export default AllProductsListView;
Loading

0 comments on commit f491f35

Please sign in to comment.