mirror of
https://github.com/gnmyt/myspeed.git
synced 2026-02-11 08:08:49 -06:00
Create PauseDialog component
This commit is contained in:
87
client/src/common/components/PauseDialog/PauseDialog.jsx
Normal file
87
client/src/common/components/PauseDialog/PauseDialog.jsx
Normal 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>
|
||||
);
|
||||
};
|
||||
1
client/src/common/components/PauseDialog/index.js
Normal file
1
client/src/common/components/PauseDialog/index.js
Normal file
@@ -0,0 +1 @@
|
||||
export {PauseDialog as default} from './PauseDialog';
|
||||
76
client/src/common/components/PauseDialog/styles.sass
Normal file
76
client/src/common/components/PauseDialog/styles.sass
Normal 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
|
||||
Reference in New Issue
Block a user