Skip to content

Commit 5cb01f7

Browse files
committed
translate remaining parts of the app
1 parent 41939bb commit 5cb01f7

File tree

17 files changed

+2071
-1199
lines changed

17 files changed

+2071
-1199
lines changed
Lines changed: 68 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,108 @@
1-
import React, { useEffect } from "react";
1+
import React, { useEffect, useState, useCallback } from "react";
22
import { MultiSelect, DropDownList } from "@progress/kendo-react-dropdowns";
33
import { SvgIcon } from "@progress/kendo-react-common";
44
import { filterIcon, sortAscIcon } from "@progress/kendo-svg-icons";
5-
import { FilterDescriptor, SortDescriptor, State } from "@progress/kendo-data-query";
6-
import { useCategoriesContext } from "../helpers/CategoriesContext";
5+
import { FilterDescriptor, State } from "@progress/kendo-data-query";
6+
import { useStore } from "@nanostores/react";
7+
import { selectedLanguage } from "../helpers/languageStore";
8+
import enMessages from "../data/messages/en";
9+
import frMessages from "../data/messages/fr";
10+
import esMessages from "../data/messages/es";
11+
12+
const translations = {
13+
en: enMessages,
14+
fr: frMessages,
15+
es: esMessages,
16+
};
717

8-
const chips = ["Bracelets", "Rings", "Earrings", "Watches", "Necklaces"];
9-
const statuses = ["Sale", "Recommended", "Must Have"];
10-
const materials = ["Gold", "Silver"];
18+
const getTranslations = (language: string) => {
19+
return translations[language] || translations["en"];
20+
};
1121

1222
interface FilterComponentProps {
1323
updateUI: (state: State) => void;
1424
}
1525

1626
export const FilterComponent: React.FC<FilterComponentProps> = ({ updateUI }) => {
17-
const { selectedCategory, setSelectedCategory } = useCategoriesContext();
18-
const [categoryValue, setCategoryValue] = React.useState<string[]>([]);
19-
const [statusValue, setStatusValue] = React.useState<string>("Recommended");
20-
const [materialValue, setMaterialValue] = React.useState<string>("Material");
21-
22-
useEffect(() => {
23-
if (selectedCategory) {
24-
setCategoryValue([selectedCategory]);
25-
applyCategoryFilter([selectedCategory]);
26-
} else {
27-
setCategoryValue([]);
28-
applyCategoryFilter([]);
29-
}
30-
}, [selectedCategory]);
27+
const language = useStore(selectedLanguage);
28+
const t = getTranslations(language);
3129

32-
const applyCategoryFilter = (categories: string[]) => {
33-
const filters = categories.map((category) => ({
34-
field: "category",
35-
operator: "eq",
36-
value: category,
37-
}));
30+
const [categoryValue, setCategoryValue] = useState<string[]>([]);
31+
const [statusValue, setStatusValue] = useState<string>(t.statusesData[0]);
32+
const [materialValue, setMaterialValue] = useState<string>(t.materialPlaceholder);
3833

39-
const customCompositeFilters: State = {
40-
filter: {
41-
logic: "or",
42-
filters,
43-
},
44-
sort: undefined,
45-
};
34+
const chips = t.categoriesData || [];
35+
const statuses = t.statusesData || [];
36+
const materials = t.materialsData || [];
4637

47-
updateUI(customCompositeFilters);
48-
};
38+
useEffect(() => {
39+
setCategoryValue([]);
40+
setStatusValue(t.statusesData[0]);
41+
setMaterialValue(t.materialPlaceholder);
42+
updateUI({ filter: undefined, sort: undefined });
43+
}, [language, t, updateUI]);
4944

50-
const onCategoryChange = (e: any) => {
51-
setCategoryValue(e.value);
52-
applyCategoryFilter(e.value);
53-
setSelectedCategory(e.value.length > 0 ? e.value[0] : null);
54-
};
45+
const applyFilters = useCallback(() => {
46+
const filters: FilterDescriptor[] = [];
5547

56-
const onStatusChange = (e: any) => {
57-
setStatusValue(e.value);
48+
if (categoryValue.length > 0) {
49+
filters.push({
50+
field: "category",
51+
operator: "eq",
52+
value: categoryValue[0],
53+
});
54+
}
5855

59-
const newSorts: SortDescriptor[] = [
60-
{
56+
if (statusValue !== t.statusesData[0]) {
57+
filters.push({
6158
field: "status",
62-
dir: "desc",
63-
},
64-
];
65-
66-
const customCompositeFilters: State = {
67-
filter: undefined,
68-
sort: newSorts,
69-
};
70-
71-
updateUI(customCompositeFilters);
72-
};
73-
74-
const onMaterialChange = (e: any) => {
75-
setMaterialValue(e.value);
59+
operator: "eq",
60+
value: statusValue,
61+
});
62+
}
7663

77-
const newFilter: FilterDescriptor[] = [
78-
{
64+
if (materialValue !== t.materialPlaceholder) {
65+
filters.push({
7966
field: "material",
8067
operator: "eq",
81-
value: e.value,
82-
},
83-
];
68+
value: materialValue,
69+
});
70+
}
8471

8572
const customCompositeFilters: State = {
86-
filter: {
87-
logic: "or",
88-
filters: newFilter,
89-
},
73+
filter: filters.length > 0 ? { logic: "and", filters } : undefined,
9074
sort: undefined,
9175
};
9276

9377
updateUI(customCompositeFilters);
94-
setCategoryValue([]);
95-
};
78+
}, [categoryValue, statusValue, materialValue, t, updateUI]);
79+
80+
useEffect(() => {
81+
applyFilters();
82+
}, [categoryValue, statusValue, materialValue, applyFilters]);
83+
84+
const onCategoryChange = (e: any) => setCategoryValue(e.value);
85+
const onStatusChange = (e: any) => setStatusValue(e.value);
86+
const onMaterialChange = (e: any) => setMaterialValue(e.value);
9687

9788
const clearFilters = () => {
9889
setCategoryValue([]);
99-
setStatusValue("Recommended");
100-
setMaterialValue("Material");
101-
setSelectedCategory(null);
90+
setStatusValue(t.statusesData[0]);
91+
setMaterialValue(t.materialPlaceholder);
10292
updateUI({ filter: undefined, sort: undefined });
10393
};
10494

10595
return (
10696
<section className="k-d-flex k-justify-content-between k-align-items-center">
10797
<span className="k-d-flex k-align-items-center">
10898
<span className="k-d-flex k-align-items-center k-pr-2">
109-
<SvgIcon icon={filterIcon}></SvgIcon> Filter:
99+
<SvgIcon icon={filterIcon}></SvgIcon> {t.filterLabel}
110100
</span>
111101
<span className="k-pr-2">
112102
<MultiSelect
113103
data={chips}
114104
value={categoryValue}
115-
placeholder="Category"
105+
placeholder={t.categoryPlaceholder}
116106
onChange={onCategoryChange}
117107
style={{ minWidth: "119px" }}
118108
/>
@@ -123,13 +113,15 @@ export const FilterComponent: React.FC<FilterComponentProps> = ({ updateUI }) =>
123113
</span>
124114
<span className="k-d-flex k-align-items-center">
125115
<span className="k-d-flex k-align-items-center k-pr-2">
126-
<SvgIcon icon={sortAscIcon}></SvgIcon> Sort by:
116+
<SvgIcon icon={sortAscIcon}></SvgIcon> {t.sortByLabel}
127117
</span>
128118
<span>
129119
<DropDownList data={statuses} value={statusValue} onChange={onStatusChange} />
130120
</span>
131121
</span>
132-
<button className="k-button k-button-flat" onClick={clearFilters}>Clear Filters</button>
122+
<button className="k-button k-button-flat" onClick={clearFilters}>
123+
{t.clearFiltersButton}
124+
</button>
133125
</section>
134126
);
135127
};
Lines changed: 77 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,126 @@
1-
import * as React from "react";
2-
3-
import bracelets from "@/assets/bracelets.png?url";
4-
import necklace from "@/assets/necklace_1.jfif?url";
5-
import ring from "@/assets/ring_1.jfif?url";
6-
import jewel from "@/assets/1111.jfif?url";
1+
import React, { useState, useEffect, useCallback } from "react";
72
import { Layout } from "../components/Layout";
83
import { OrderedImgText } from "../components/OrderedImageCard";
94
import { CustomSection } from "../components/CustomizedSection";
10-
import { listData } from "../data/listData";
115
import { FilterComponent } from "../components/FilterComponent";
126
import { CardsList } from "../components/CardsList";
137
import { CategoryList } from "../components/CategoryList";
14-
import { CardDescriptor } from "../data/types";
15-
import { DataModel } from "../data/types";
16-
178
import { Breadcrumb } from "@progress/kendo-react-layout";
189
import { Button, ButtonGroup } from "@progress/kendo-react-buttons";
1910
import { layout2By2Icon, gridLayoutIcon } from "@progress/kendo-svg-icons";
2011
import { process, State } from "@progress/kendo-data-query";
12+
import getTranslatedListData from "../data/listData";
13+
import { useStore } from "@nanostores/react";
14+
import { selectedLanguage } from "../helpers/languageStore";
15+
16+
import enMessages from "../data/messages/en";
17+
import frMessages from "../data/messages/fr";
18+
import esMessages from "../data/messages/es";
19+
20+
const messages = {
21+
en: enMessages,
22+
fr: frMessages,
23+
es: esMessages,
24+
};
25+
26+
export const AllProductsListView: React.FC = () => {
27+
const language = useStore(selectedLanguage);
28+
const t = messages[language] || messages["en"];
29+
const [translatedData, setTranslatedData] = useState(() => getTranslatedListData());
30+
const [filteredData, setFilteredData] = useState(translatedData);
31+
const [currentLayout, setCurrentLayout] = useState<"grid" | "list">("grid");
2132

22-
export const AllProductsListView = () => {
23-
const title = "Fine Selection";
24-
const subtitle = "Enjoy the real craftsmanship";
25-
const contentText =
26-
"Jewelry is a meaningful form of self-expression that enhances personal style and adds beauty to any occasion.";
27-
const order = "first";
33+
useEffect(() => {
34+
const updatedData = getTranslatedListData();
35+
setTranslatedData(updatedData);
36+
setFilteredData(updatedData);
37+
}, [language]);
2838

29-
const [data, setData] = React.useState(listData);
30-
31-
const updateUI = (newState: State) => {
32-
const newData = process(listData, newState)
33-
setData(newData.data)
34-
};
39+
const updateUI = useCallback(
40+
(newState: State) => {
41+
const updatedData = process(translatedData, newState).data;
42+
setFilteredData(updatedData);
43+
},
44+
[translatedData]
45+
);
3546

36-
const cards: CardDescriptor[] = [
47+
const cards = [
3748
{
38-
img: necklace,
39-
collectionText: 'Collection "SERENE"',
49+
img: "/necklace_1.jfif",
50+
collectionText: t.collectionSerene,
4051
},
4152
{
42-
img: ring,
43-
collectionText: 'Collection "AURELIA"',
53+
img: "/ring_1.jfif",
54+
collectionText: t.collectionAurelia,
4455
},
4556
{
46-
img: jewel,
47-
collectionText: 'Collection "RAVINA"',
57+
img: "/1111.jfif",
58+
collectionText: t.collectionRavina,
4859
},
4960
];
5061

51-
const BreakcrumbData: DataModel[] = [{
52-
text: "Home"
53-
},
54-
{
55-
text: "Jewelry"
56-
}]
62+
const breadcrumbData = [
63+
{ text: t.breadcrumbHome },
64+
{ text: t.breadcrumbJewelry },
65+
];
5766

5867
return (
5968
<>
6069
<Layout>
6170
<section
6271
className="k-d-grid k-grid-cols-12 k-justify-content-center k-align-items-center k-col-span-12"
63-
style={{
64-
paddingTop: "60px",
65-
}}
72+
style={{ paddingTop: "60px" }}
6673
>
6774
<OrderedImgText
68-
title={title}
69-
subtitle={subtitle}
70-
contentText={contentText}
71-
img={bracelets}
72-
order={order}
75+
title={t.allProductsTitle}
76+
subtitle={t.allProductsSubtitle}
77+
contentText={t.allProductsContentText}
78+
img="/bracelets.png"
79+
order="first"
7380
link={null}
7481
/>
7582
</section>
7683
</Layout>
84+
7785
<Layout>
7886
<CustomSection>
79-
<CategoryList title="Our Collections" subtitle="Enjoy an excellent selection of fine jewelry" data={cards}></CategoryList>
87+
<CategoryList
88+
title={t.ourCollectionsTitle}
89+
subtitle={t.ourCollectionsSubtitle}
90+
data={cards}
91+
/>
8092
</CustomSection>
8193
</Layout>
94+
8295
<Layout>
83-
<section className="k-d-flex k-justify-content-between">
84-
<Breadcrumb data={BreakcrumbData}></Breadcrumb>
96+
<section className="k-d-flex k-justify-content-between k-align-items-center k-py-4">
97+
<Breadcrumb data={breadcrumbData} />
8598
<ButtonGroup>
86-
<Button fillMode={"flat"} svgIcon={gridLayoutIcon}></Button>
87-
<Button fillMode={"flat"} svgIcon={layout2By2Icon}></Button>
99+
<Button
100+
fillMode="flat"
101+
svgIcon={gridLayoutIcon}
102+
selected={currentLayout === "grid"}
103+
onClick={() => setCurrentLayout("grid")}
104+
/>
105+
<Button
106+
fillMode="flat"
107+
svgIcon={layout2By2Icon}
108+
selected={currentLayout === "list"}
109+
onClick={() => setCurrentLayout("list")}
110+
/>
88111
</ButtonGroup>
89112
</section>
90113
</Layout>
114+
91115
<Layout>
92-
<FilterComponent updateUI={updateUI}></FilterComponent>
116+
<FilterComponent updateUI={updateUI} />
93117
</Layout>
118+
94119
<Layout>
95-
<CardsList data={data}></CardsList>
120+
<CardsList data={filteredData} layout={currentLayout} />
96121
</Layout>
97122
</>
98123
);
99124
};
125+
126+
export default AllProductsListView;

0 commit comments

Comments
 (0)