Settings Component
The Settings component provides a user interface for managing application preferences and clearing stored data. It includes a toggle for playback time saving and multiple clear data buttons with confirmation dialogs.
Location
src/components/Settings/Settings.jsx
Import
import Settings from "../Settings/Settings" ;
Props
This component does not accept any props.
Features
Playback Time Toggle
Allows users to enable/disable automatic playback time saving:
import { Switch } from "@mui/material" ;
import { toggleSavePlaybackTime } from "../../store/slices/audioTimeSlice" ;
const { savePlaybackTime } = useSelector (( state ) => state . audioTime );
< div className = { styles . settingItem } >
< div className = { styles . settingInfo } >
< h3 > Recordar tiempo de reproducción </ h3 >
< p > Guarda el progreso de reproducción de cada episodio </ p >
</ div >
< div className = { styles . toggleSwitch } >
< IOSSwitch
checked = { savePlaybackTime }
onChange = { () => dispatch ( toggleSavePlaybackTime ()) }
/>
</ div >
</ div >
Custom iOS-Style Switch
Uses Material-UI styled switch component:
const IOSSwitch = styled (( props ) => (
< Switch focusVisibleClassName = ".Mui-focusVisible" disableRipple { ... props } />
))(({ theme }) => ({
width: 42 ,
height: 26 ,
padding: 0 ,
"& .MuiSwitch-switchBase" : {
padding: 0 ,
margin: 2 ,
transitionDuration: "300ms" ,
"&.Mui-checked" : {
transform: "translateX(16px)" ,
color: "#15223E" ,
"& + .MuiSwitch-track" : {
backgroundColor: "#16db93" ,
opacity: 1 ,
border: 0
}
}
},
"& .MuiSwitch-thumb" : {
boxSizing: "border-box" ,
width: 22 ,
height: 22
},
"& .MuiSwitch-track" : {
borderRadius: 26 / 2 ,
backgroundColor: "#39393D" ,
opacity: 1
}
}));
Clear Data Actions
Provides six different clear data operations:
Clear Playback Times Removes all saved playback time data dispatch ( clearPlaybackTimes ())
Clear Started Removes all started episode markers
Clear Favorites Removes all favorite episodes dispatch ( clearFavorites ())
Clear Listen Later Removes all listen later episodes dispatch ( clearListenLater ())
Clear Completed Removes all completed episode markers dispatch ( clearCompleted ())
Clear All Removes ALL stored data (favorites, started, completed, listen later, playback times) dispatch ( clearStarted ())
dispatch ( clearFavorites ())
dispatch ( clearListenLater ())
dispatch ( clearCompleted ())
dispatch ( clearPlaybackTimes ())
Confirmation Dialogs
All destructive actions require confirmation:
const showConfirmToast = ( message , onConfirm ) => {
toast . custom (
( t ) => (
< div className = { styles . confirmToast } >
< div className = { styles . confirmHeader } >
< Warning className = { styles . warningIcon } />
< h3 > Confirmar Acción </ h3 >
</ div >
< p className = { styles . confirmMessage } > { message } </ p >
< div className = { styles . confirmButtons } >
< motion.button
whileHover = { { scale: 1.05 } }
whileTap = { { scale: 0.95 } }
className = { styles . confirmButton }
onClick = { () => {
toast . dismiss ( t . id );
onConfirm ();
} }
>
Confirmar
</ motion.button >
< motion.button
whileHover = { { scale: 1.05 } }
whileTap = { { scale: 0.95 } }
className = { styles . cancelButton }
onClick = { () => toast . dismiss ( t . id ) }
>
Cancelar
</ motion.button >
</ div >
</ div >
),
{
duration: Infinity ,
position: "top-center" ,
className: styles . customToast ,
style: {
backgroundColor: "rgba(33, 33, 33, 0.9)" ,
border: "1px solid #16db93" ,
borderRadius: "12px" ,
padding: "20px" ,
boxShadow: "0px 4px 15px rgba(0, 0, 0, 0.2)"
},
closeButton: false ,
closeOnClick: false ,
draggable: false
}
);
};
Success Notifications
Shows toast after successful action:
const showSuccessToast = ( message ) => {
toast . success ( message , {
position: "bottom-left" ,
duration: 5000 ,
style: {
backgroundColor: "rgba(33, 33, 33, 0.9)" ,
color: "#ffffff" ,
borderRadius: "8px" ,
padding: "10px" ,
boxShadow: "0px 4px 15px rgba(0, 0, 0, 0.2)"
}
});
};
Action Handlers
Clear Started
Clear Favorites
Clear All
const handleClearStarted = () => {
showConfirmToast (
"¿Estás seguro de que quieres borrar todos los podcasts empezados?" ,
() => {
dispatch ( clearStarted ());
showSuccessToast ( "Podcasts empezados eliminados" );
}
);
};
Navigation
Includes back button to return to main view:
import { Link } from "react-router-dom" ;
import { ArrowBack } from "@mui/icons-material" ;
const iconVariants = {
hover: {
scale: 1.06 ,
rotate: 45 ,
transition: { type: "spring" , stiffness: 250 , damping: 3 }
}
};
< Link to = "/" style = { { textDecoration: "none" } } >
< motion.div whileHover = "hover" className = { styles . backButton } >
< motion.div variants = { iconVariants } >
< ArrowBack />
</ motion.div >
< span style = { { marginLeft: "2px" } } > Volver </ span >
</ motion.div >
</ Link >
Each clear button has unique styling:
< motion.button
whileHover = { { scale: 1.02 } }
whileTap = { { scale: 0.98 } }
className = { ` ${ styles . clearButton } ${ styles . timeButton } ` }
onClick = { handleClearPlaybackTimes }
>
< Timer className = { styles . buttonIcon } />
Borrar tiempos guardados
</ motion.button >
Button variants:
timeButton - Clear playback times (Timer icon)
startedButton - Clear started episodes (Headphones icon)
favoritesButton - Clear favorites (Favorite icon)
listenLaterButton - Clear listen later (WatchLater icon)
completedButton - Clear completed (CheckCircle icon)
deleteAllButton - Clear all data (DeleteForever icon)
Animations
Page loads with fade-in animation:
< motion.div
className = { styles . settingsContainer }
initial = { { opacity: 0 , y: 20 } }
animate = { { opacity: 1 , y: 0 } }
transition = { { duration: 0.5 } }
>
Redux Actions
Dispatches actions from multiple slices:
audioTimeSlice
podcastSlice
import {
toggleSavePlaybackTime ,
clearPlaybackTimes
} from "../../store/slices/audioTimeSlice" ;
import {
clearFavorites ,
clearStarted ,
clearCompleted ,
clearListenLater
} from "../../store/slices/podcastSlice" ;
Usage Example
import React from "react" ;
import { BrowserRouter , Routes , Route } from "react-router-dom" ;
import Settings from "./components/Settings/Settings" ;
import PodcastList from "./components/PodcastList/PodcastList" ;
function App () {
return (
< BrowserRouter >
< Routes >
< Route path = "/" element = { < PodcastList /> } />
< Route path = "/settings" element = { < Settings /> } />
</ Routes >
</ BrowserRouter >
);
}
Complete Settings Layout
The component structure:
Header : Back button and title
Toggle Setting : Playback time saving preference
Clear Buttons : Six destructive action buttons
return (
< motion.div className = { styles . settingsContainer } >
{ /* Back button */ }
< Link to = "/" > ... </ Link >
{ /* Title */ }
< h2 className = { styles . title } > Ajustes </ h2 >
{ /* Playback time toggle */ }
< div className = { styles . settingItem } > ... </ div >
{ /* Clear data buttons */ }
< div className = { styles . buttonsContainer } >
< button onClick = { handleClearPlaybackTimes } > ... </ button >
< button onClick = { handleClearStarted } > ... </ button >
< button onClick = { handleClearFavorites } > ... </ button >
< button onClick = { handleClearListenLater } > ... </ button >
< button onClick = { handleClearCompleted } > ... </ button >
< button onClick = { handleClearAll } > ... </ button >
</ div >
</ motion.div >
);
The “Clear All” action is irreversible and removes all user data. Users should be clearly warned before confirming.