Skip to content

Commit

Permalink
overrided history api behavior in app
Browse files Browse the repository at this point in the history
  • Loading branch information
edmdz committed Jul 16, 2024
1 parent 27dbf71 commit b81cc2c
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 104 deletions.
8 changes: 4 additions & 4 deletions src/pages/Products/ProductSelectorNav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import Link from '@mui/material/Link';
import Typography from '@mui/material/Typography';
import NavigateNextIcon from '@mui/icons-material/NavigateNext';
import { useProductsContext } from './ProductsContext';
import { ProductTypes, Screens } from './ProductsConstants';
import { ProductTypes } from './ProductsConstants';

const ProductSelectorNav = () => {
const { selectedBrand, selectedCarModel, handleBack, productType } = useProductsContext();
const { selectedBrand, selectedCarModel, productType, navigateBack, } = useProductsContext();

const handleBackToBrands = () => {
handleBack(Screens.BRANDS);
navigateBack();
}

const handleBackToCarModels = () => {
handleBack(Screens.MODELS);
navigateBack();
}

const productVerbiage = productType === ProductTypes.CAP ? 'Tapas' : productType === ProductTypes.FAN ? 'Abanicos' : 'Radiadores';
Expand Down
241 changes: 141 additions & 100 deletions src/pages/Products/ProductsContext.jsx
Original file line number Diff line number Diff line change
@@ -1,111 +1,152 @@
import { createContext, useContext, useState } from 'react';
import { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { ProductTypes, Screens, SearchOptions } from './ProductsConstants';

const ProductsContext = createContext();

export const useProductsContext = () => useContext(ProductsContext);
export const useProductsContext = () => {
const context = useContext(ProductsContext);
if (context === undefined) {
throw new Error('useProductsContext must be used within a ProductsProvider');
}
return context;
};

export const ProductsProvider = ({ children }) => {
const [productType, setProductType] = useState(ProductTypes.RADIATOR);
const [currentScreen, setCurrentScreen] = useState(Screens.BRANDS);
const [openDialog, setOpenDialog] = useState(false);

const [selectedProduct, setSelectedProduct] = useState(null);
const [selectedBrand, setSelectedBrand] = useState(null);
const [selectedCarModel, setSelectedCarModel] = useState(null);

const [searchTerm, setSearchTerm] = useState('');
const [searchOption, setSearchOption] = useState(SearchOptions.BRANDS);

const [loading, setLoading] = useState(false);

const handleItemSelect = (item, type) => {
switch (type) {
case Screens.BRANDS:
setSelectedBrand(item);
setSearchOption(SearchOptions.MODELS);
setCurrentScreen(Screens.MODELS);
setSelectedBrand(item);
break;
case Screens.MODELS:
setSelectedCarModel(item);
setSearchOption(SearchOptions.PRODUCTS);
setCurrentScreen(Screens.PRODUCTS);
break;
case Screens.PRODUCTS:
setSelectedProduct(item);
break;
default:
console.log('Tipo de selección no reconocido:', type);
}
};


const handleChangeProductType = (newValue) => {
setProductType(newValue);
};

const handleOpenDialog = () => {
setOpenDialog(true);
};

const handleCloseDialog = () => {
setOpenDialog(false);
};

const handleBack = (screen) => {
if (screen === Screens.BRANDS) {
setCurrentScreen(Screens.BRANDS);
setSearchOption(SearchOptions.BRANDS);
setSelectedBrand(null);
setSelectedCarModel(null);
} else if (screen === Screens.MODELS) {
setCurrentScreen(Screens.MODELS);
setSearchOption(SearchOptions.MODELS);
setSelectedCarModel(null);
}
};

const handleSearchOptionChange = (value) => {
setSearchTerm('');
setSelectedBrand(null);
const [productType, setProductType] = useState(ProductTypes.RADIATOR);
const [currentScreen, setCurrentScreen] = useState(Screens.BRANDS);
const [openDialog, setOpenDialog] = useState(false);
const [selectedProduct, setSelectedProduct] = useState(null);
const [selectedBrand, setSelectedBrand] = useState(null);
const [selectedCarModel, setSelectedCarModel] = useState(null);
const [searchTerm, setSearchTerm] = useState('');
const [searchOption, setSearchOption] = useState(SearchOptions.BRANDS);
const [loading, setLoading] = useState(false);
const [scrollPosition, setScrollPosition] = useState(0);

const navigateBack = useCallback(() => {
if (openDialog) {
setOpenDialog(false);
return;
}

switch (currentScreen) {
case Screens.PRODUCTS:
setCurrentScreen(Screens.MODELS);
setSelectedCarModel(null);
setSelectedProduct(null);
setSearchOption(value);

if (value === SearchOptions.BRANDS) {
setCurrentScreen(Screens.BRANDS);
} else if (value === SearchOptions.MODELS) {
setCurrentScreen(Screens.MODELS);
} else {
setCurrentScreen(Screens.PRODUCTS);
break;
case Screens.MODELS:
setCurrentScreen(Screens.BRANDS);
setSelectedBrand(null);
break;
case Screens.BRANDS:
// Comportamiento predeterminado: salir de la aplicación
if (window.history.length > 1) {
window.history.back();
}
break;
default:
break;
}
}, [currentScreen, openDialog]);

useEffect(() => {
const handlePopState = (event) => {
event.preventDefault();
navigateBack();
};

window.addEventListener('popstate', handlePopState);

return (
<ProductsContext.Provider value={{
handleBack,
handleChangeProductType,
handleCloseDialog,
handleItemSelect,
handleOpenDialog,
handleSearchOptionChange,
setLoading,
setSearchTerm,
setSelectedProduct,

currentScreen,
loading,
openDialog,
productType,
searchOption,
searchTerm,
selectedBrand,
selectedCarModel,
selectedProduct
}}>
{children}
</ProductsContext.Provider>
);
};
return () => {
window.removeEventListener('popstate', handlePopState);
};
}, [navigateBack]);

const pushState = useCallback(() => {
window.history.pushState(null, '', window.location.pathname);
}, []);

const handleItemSelect = (item, type) => {
pushState();
switch (type) {
case Screens.BRANDS:
setSelectedBrand(item);
setSearchOption(SearchOptions.MODELS);
setCurrentScreen(Screens.MODELS);
break;
case Screens.MODELS:
setSelectedCarModel(item);
setSearchOption(SearchOptions.PRODUCTS);
setCurrentScreen(Screens.PRODUCTS);
break;
case Screens.PRODUCTS:
setSelectedProduct(item);
setScrollPosition(window.pageYOffset);
break;
default:
console.log('Tipo de selección no reconocido:', type);
}
};

const handleOpenDialog = () => {
pushState();
setOpenDialog(true);
};

const handleCloseDialog = () => {
navigateBack();
};

const handleChangeProductType = (newValue) => {
setProductType(newValue);
};

const handleSearchOptionChange = (value) => {
setSearchTerm('');
setSearchOption(value);

if (value === SearchOptions.BRANDS) {
setCurrentScreen(Screens.BRANDS);
} else if (value === SearchOptions.MODELS) {
setCurrentScreen(Screens.MODELS);
} else {
setCurrentScreen(Screens.PRODUCTS);
}
};

const value = {
productType,
currentScreen,
openDialog,
selectedProduct,
selectedBrand,
selectedCarModel,
searchTerm,
searchOption,
loading,
scrollPosition,
setProductType,
setCurrentScreen,
setOpenDialog,
setSelectedProduct,
setSelectedBrand,
setSelectedCarModel,
setSearchTerm,
setSearchOption,
setLoading,
setScrollPosition,
handleItemSelect,
handleOpenDialog,
handleCloseDialog,
handleChangeProductType,
handleSearchOptionChange,
navigateBack,
pushState
};

return (
<ProductsContext.Provider value={value}>
{children}
</ProductsContext.Provider>
);
};

0 comments on commit b81cc2c

Please sign in to comment.