Skip to main content

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
dispatch(clearStarted())

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

const handleClearStarted = () => {
  showConfirmToast(
    "¿Estás seguro de que quieres borrar todos los podcasts empezados?",
    () => {
      dispatch(clearStarted());
      showSuccessToast("Podcasts empezados eliminados");
    }
  );
};
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>

Button Styling

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:
import { 
  toggleSavePlaybackTime, 
  clearPlaybackTimes 
} from "../../store/slices/audioTimeSlice";

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:
  1. Header: Back button and title
  2. Toggle Setting: Playback time saving preference
  3. 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.

Build docs developers (and LLMs) love