mirror of
https://git.sr.ht/~ashkeel/strimertul
synced 2024-09-20 02:00:49 +00:00
Add Interval component
This commit is contained in:
parent
f4a30dddb5
commit
e45544171d
2 changed files with 86 additions and 5 deletions
|
@ -1,15 +1,14 @@
|
||||||
import { ActionCreatorWithOptionalPayload, AsyncThunk } from '@reduxjs/toolkit';
|
import { ActionCreatorWithOptionalPayload, AsyncThunk } from '@reduxjs/toolkit';
|
||||||
import { useEffect } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
KilovoltMessage,
|
KilovoltMessage,
|
||||||
SubscriptionHandler,
|
SubscriptionHandler,
|
||||||
} from '@strimertul/kilovolt-client';
|
} from '@strimertul/kilovolt-client';
|
||||||
import { RootState } from '../store';
|
import { RootState } from '../store';
|
||||||
import apiReducer, {
|
import apiReducer, { getUserPoints } from '../store/api/reducer';
|
||||||
getUserPoints,
|
import { APIState, LoyaltyStorage } from '../store/api/types';
|
||||||
} from '../store/api/reducer';
|
import { getInterval } from './time-utils';
|
||||||
import {APIState, LoyaltyStorage} from "../store/api/types";
|
|
||||||
|
|
||||||
export function useModule<T>({
|
export function useModule<T>({
|
||||||
key,
|
key,
|
||||||
|
@ -63,7 +62,30 @@ export function useUserPoints(): LoyaltyStorage {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useInterval(
|
||||||
|
initialValue: number,
|
||||||
|
): [
|
||||||
|
number,
|
||||||
|
number,
|
||||||
|
number,
|
||||||
|
(newNum: number) => void,
|
||||||
|
(newMult: number) => void,
|
||||||
|
] {
|
||||||
|
const [value, setValue] = useState(initialValue);
|
||||||
|
|
||||||
|
const [numInitialValue, multInitialValue] = getInterval(value);
|
||||||
|
const [num, setNum] = useState(numInitialValue);
|
||||||
|
const [mult, setMult] = useState(multInitialValue);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setValue(num * mult);
|
||||||
|
}, [num, mult]);
|
||||||
|
|
||||||
|
return [value, num, mult, setNum, setMult];
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
useModule,
|
useModule,
|
||||||
useUserPoints,
|
useUserPoints,
|
||||||
|
useInterval,
|
||||||
};
|
};
|
||||||
|
|
59
frontend/src/ui/components/Interval.tsx
Normal file
59
frontend/src/ui/components/Interval.tsx
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useInterval } from '../../lib/react-utils';
|
||||||
|
|
||||||
|
export interface IntervalProps {
|
||||||
|
active: boolean;
|
||||||
|
value: number;
|
||||||
|
onChange?: (value: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Field({ active, value, onChange }: IntervalProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [valueNum, num, mult, setNum, setMult] = useInterval(value);
|
||||||
|
useEffect(() => {
|
||||||
|
onChange(valueNum);
|
||||||
|
}, [valueNum]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p className="control">
|
||||||
|
<input
|
||||||
|
disabled={!active}
|
||||||
|
className="input"
|
||||||
|
type="number"
|
||||||
|
placeholder="#"
|
||||||
|
value={num ?? ''}
|
||||||
|
onChange={(ev) => {
|
||||||
|
const intNum = parseInt(ev.target.value, 10);
|
||||||
|
if (Number.isNaN(intNum)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setNum(intNum);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p className="control">
|
||||||
|
<span className="select">
|
||||||
|
<select
|
||||||
|
value={mult.toString() ?? ''}
|
||||||
|
disabled={!active}
|
||||||
|
onChange={(ev) => {
|
||||||
|
const intMult = parseInt(ev.target.value, 10);
|
||||||
|
if (Number.isNaN(intMult)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setMult(intMult);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value="1">{t('form-common.time.seconds')}</option>
|
||||||
|
<option value="60">{t('form-common.time.minutes')}</option>
|
||||||
|
<option value="3600">{t('form-common.time.hours')}</option>
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(Field);
|
Loading…
Reference in a new issue