Create PauseDialog component

This commit is contained in:
Mathias Wagner
2026-01-20 20:45:05 +01:00
parent e0bbd6cf7c
commit b084f28a6b
3 changed files with 164 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
import React, {useState} from "react";
import {Dialog, DialogHeader, DialogBody, DialogFooter} from "@/common/contexts/Dialog";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faInfinity, faClock, faMugHot, faMoon} from "@fortawesome/free-solid-svg-icons";
import {t} from "i18next";
import {postRequest} from "@/common/utils/RequestUtil";
import "./styles.sass";
const PRESETS = [
{id: "manual", hours: null, icon: faInfinity},
{id: "short", hours: 1, icon: faMugHot},
{id: "medium", hours: 6, icon: faClock},
{id: "long", hours: 12, icon: faMoon}
];
export const PauseDialog = ({open, onClose, onPause}) => {
const [selected, setSelected] = useState("manual");
const [customHours, setCustomHours] = useState("");
const handleSave = async (close) => {
const preset = PRESETS.find(p => p.id === selected);
if (selected === "custom") {
if (customHours && parseFloat(customHours) > 0) {
await postRequest("/speedtests/pause", {resumeIn: parseFloat(customHours)});
} else {
return;
}
} else if (preset.hours === null) {
await postRequest("/speedtests/pause", {resumeIn: 0});
} else {
await postRequest("/speedtests/pause", {resumeIn: preset.hours});
}
onPause?.();
close();
};
const isCustomValid = selected !== "custom" || (customHours && parseFloat(customHours) > 0);
return (
<Dialog open={open} onClose={onClose} className="pause-dialog">
{({close}) => (
<>
<DialogHeader onClose={close}>{t("update.pause_title")}</DialogHeader>
<DialogBody>
<div className="pause-content">
<div className="pause-presets">
{PRESETS.map(preset => (
<div key={preset.id}
className={`pause-item${selected === preset.id ? " pause-item-active" : ""}`}
onClick={() => setSelected(preset.id)}>
<FontAwesomeIcon icon={preset.icon}/>
<div className="pause-item-text">
<h3>{t(`pause.${preset.id}`)}</h3>
<p>{t(`pause.${preset.id}_desc`)}</p>
</div>
</div>
))}
</div>
<div className="pause-custom">
<div className="pause-custom-header">
<h3>{t("pause.custom")}</h3>
</div>
<input type="number"
className={`dialog-input pause-input${selected === "custom" && !isCustomValid ? " input-error" : ""}`}
value={customHours}
onChange={(e) => {
setCustomHours(e.target.value);
setSelected("custom");
}}
placeholder={t("update.hours")}
min="0.1"
step="0.5"/>
</div>
</div>
</DialogBody>
<DialogFooter>
<button className="dialog-btn" onClick={() => handleSave(close)} disabled={!isCustomValid}>
{t("update.pause")}
</button>
</DialogFooter>
</>
)}
</Dialog>
);
};

View File

@@ -0,0 +1 @@
export {PauseDialog as default} from './PauseDialog';

View File

@@ -0,0 +1,76 @@
@use "@/common/styles/colors" as *
.pause-dialog
.dialog-main
display: block
.pause-content
margin: 1rem 0.5rem
display: flex
flex-direction: column
gap: 1rem
user-select: none
.pause-presets
display: flex
flex-direction: column
gap: 0.5rem
.pause-item
display: flex
align-items: center
gap: 0.8rem
padding: 0.6rem 1rem
border-radius: 0.5rem
border: 1px solid $light-gray
cursor: pointer
transition: background-color 0.15s
&:hover
background-color: $darker-gray
svg
font-size: 1.2rem
color: $subtext
width: 1.5rem
&-text
flex: 1
h3
margin: 0
font-size: 1rem
color: $subtext
p
margin: 0.2rem 0 0
font-size: 0.85rem
color: $subtext
opacity: 0.7
.pause-item-active
background-color: $light-gray
svg, h3
color: $white
&:hover
background-color: $light-gray
.pause-custom
padding-top: 1rem
border-top: 1px solid $light-gray
&-header
display: flex
align-items: center
gap: 0.5rem
margin-bottom: 0.5rem
h3
margin: 0
font-size: 1rem
color: $subtext
.pause-input
text-align: center