Skip to content

Commit

Permalink
fix avatar, translate app
Browse files Browse the repository at this point in the history
add files

add two other files

split messages, adjust switch widht

translate remaining parts of the app

fix home and footer

fix ts errors
  • Loading branch information
filipKovachev committed Dec 3, 2024
1 parent 217494b commit a4975ef
Show file tree
Hide file tree
Showing 31 changed files with 3,507 additions and 1,314 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>
);
};
106 changes: 106 additions & 0 deletions examples/ecommerce-jewellery-store/src/data/mesagges.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
export const messages = {
en: {
title: "Vilora Jewelry",
subtitle: "We offer exquisite jewelry, each showcasing timeless elegance",
buttonText: "See Collections",
bestsellersTitle: "Our Bestsellers",
bestsellersSubtitle: "Enjoy an excellent selection of fine jewelry",
timelessTitle: "Timeless Classics",
timelessSubtitle: "Get our unique handmade collections",
timelessContent: "Jewelry enhances style and adds elegance, with each piece telling a unique story.",
fineJewelryTitle: "Fine Jewelry",
fineJewelrySubtitle: "Get our unique handmade collections",
fineJewelryContent: "Jewelry elevates one's style and brings sophistication, with every piece narrating a distinct tale.",
ringsTitle: "Our Rings",
ringsSubtitle: "Enjoy an excellent selection of fine rings",
watchesTitle: "Our Watches",
watchesSubtitle: "Enjoy an excellent selection of watches",
servicesTitle: "Services",
servicesSubtitle: "Explore expert repairs to elevate your experience",
servicesContent: "Vilora provides services like custom designs, repairs, and appraisals to enhance the customer experience.",
filterLabel: "Filter:",
sortByLabel: "Sort by:",
clearFiltersButton: "Clear Filters",
categoryPlaceholder: "Category",
materialPlaceholder: "Material",
categoriesData: ["Bracelets", "Rings", "Earrings", "Watches", "Necklaces"],
statusesData: ["Sale", "Recommended", "Must Have"],
materialsData: ["Gold", "Silver"],
addToCartButtonText: "Add to Cart",
shoppingCartTitle: "Shopping Cart",
backButtonText: "Back",
removeButtonText: "Remove",
emptyCartMessage: "Your shopping cart is empty.",
proceedToCheckoutButtonText: "Proceed to Checkout"
},
es: {
title: "Joyería Vilora",
subtitle: "Ofrecemos joyería exquisita, cada una mostrando elegancia atemporal",
buttonText: "Ver Colecciones",
bestsellersTitle: "Nuestros Más Vendidos",
bestsellersSubtitle: "Disfruta de una excelente selección de joyas finas",
timelessTitle: "Clásicos Atemporales",
timelessSubtitle: "Obtén nuestras colecciones únicas hechas a mano",
timelessContent: "Las joyas mejoran el estilo y agregan elegancia, cada pieza cuenta una historia única.",
fineJewelryTitle: "Joyería Fina",
fineJewelrySubtitle: "Obtén nuestras colecciones únicas hechas a mano",
fineJewelryContent: "Las joyas elevan el estilo y aportan sofisticación, cada pieza narra una historia distinta.",
ringsTitle: "Nuestros Anillos",
ringsSubtitle: "Disfruta de una excelente selección de anillos finos",
watchesTitle: "Nuestros Relojes",
watchesSubtitle: "Disfruta de una excelente selección de relojes",
servicesTitle: "Servicios",
servicesSubtitle: "Explora reparaciones expertas para mejorar tu experiencia",
servicesContent: "Vilora ofrece servicios como diseños personalizados, reparaciones y tasaciones para mejorar la experiencia del cliente.",
filterLabel: "Filtrar:",
sortByLabel: "Ordenar por:",
clearFiltersButton: "Borrar filtros",
categoryPlaceholder: "Categoría",
materialPlaceholder: "Material",
categoriesData: ["Pulseras", "Anillos", "Pendientes", "Relojes", "Collares"],
statusesData: ["Oferta", "Recomendado", "Imprescindible"],
materialsData: ["Oro", "Plata"],
addToCartButtonText: "Agregar al Carrito",
shoppingCartTitle: "Carrito de Compras",
backButtonText: "Volver",
removeButtonText: "Eliminar",
emptyCartMessage: "Tu carrito está vacío.",
proceedToCheckoutButtonText: "Proceder al Pago"
},
fr: {
title: "Bijoux Vilora",
subtitle: "Nous proposons des bijoux exquis, chacun illustrant une élégance intemporelle",
buttonText: "Voir les Collections",
bestsellersTitle: "Nos Meilleures Ventes",
bestsellersSubtitle: "Profitez d'une excellente sélection de bijoux fins",
timelessTitle: "Classiques Intemporels",
timelessSubtitle: "Découvrez nos collections artisanales uniques",
timelessContent: "Les bijoux subliment le style et ajoutent de l'élégance, chaque pièce raconte une histoire unique.",
fineJewelryTitle: "Bijoux Fins",
fineJewelrySubtitle: "Découvrez nos collections artisanales uniques",
fineJewelryContent: "Les bijoux rehaussent le style et apportent de la sophistication, chaque pièce raconte une histoire distincte.",
ringsTitle: "Nos Bagues",
ringsSubtitle: "Profitez d'une excellente sélection de bagues fines",
watchesTitle: "Nos Montres",
watchesSubtitle: "Profitez d'une excellente sélection de montres",
servicesTitle: "Services",
servicesSubtitle: "Explorez des réparations expertes pour enrichir votre expérience",
servicesContent: "Vilora propose des services tels que des designs personnalisés, des réparations et des expertises pour enrichir l'expérience client.",
filterLabel: "Filtrer :",
sortByLabel: "Trier par :",
clearFiltersButton: "Effacer les filtres",
categoryPlaceholder: "Catégorie",
materialPlaceholder: "Matériau",
categoriesData: ["Bracelets", "Bagues", "Boucles d'oreilles", "Montres", "Colliers"],
statusesData: ["Vente", "Recommandé", "Indispensable"],
materialsData: ["Or", "Argent"],
addToCartButtonText: "Ajouter au Panier",
shoppingCartTitle: "Panier",
backButtonText: "Retour",
removeButtonText: "Supprimer",
emptyCartMessage: "Votre panier est vide.",
proceedToCheckoutButtonText: "Passer à la caisse",
},
};

export default messages;
Loading

0 comments on commit a4975ef

Please sign in to comment.