Bin
2025-12-16 9e0b2ba2c317b1a86212f24cbae3195ad1f3dbfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import React, { type FC, useCallback, useEffect, useState } from "react";
import { cn } from "../../utils/bem";
import { MaskUtil } from "../../utils/InputMask";
import Label from "../../common/Label/Label";
 
import "./TimeBox.scss";
 
export interface TimerProps {
  sidepanel: boolean;
  value: number;
  readonly?: boolean;
  onChange: (value: number) => void;
  label?: string;
}
 
export const TimeBox: FC<TimerProps> = ({ sidepanel = false, value, readonly = false, onChange, label, ...props }) => {
  const inputRef = React.createRef<HTMLInputElement>();
  const [currentInputTime, setCurrentInputTime] = useState<string | number | undefined>(value);
 
  useEffect(() => {
    if (inputRef.current)
      new MaskUtil(inputRef.current, "11:11:11:111", (data: string) => {
        setCurrentInputTime(data);
      });
  }, []);
 
  useEffect(() => {
    setCurrentInputTime(formatTime(value || 0, true));
  }, [value]);
 
  const formatTime = useCallback((time: number, input = false): any => {
    const timeDate = new Date(time * 1000).toISOString();
    let formatted = time > 3600 ? timeDate.substr(11, 8) : `00:${timeDate.substr(14, 5)}`;
 
    if (input) {
      const isHour = timeDate.substr(11, 2) !== "00";
 
      formatted = timeDate.substr(isHour ? 11 : 14, isHour ? 12 : 9).replace(".", ":");
 
      formatted = !isHour ? `00:${formatted}` : formatted;
    }
 
    return formatted;
  }, []);
 
  const convertTextToTime = (value: string) => {
    const splittedValue = value.split(":").reverse();
    let totalTime = 0;
 
    if (value.indexOf("_") >= 0) return;
 
    const calcs = [(x: number) => x / 1000, (x: number) => x, (x: number) => x * 60, (x: number) => x * 60 * 60];
 
    splittedValue.forEach((value, index) => {
      totalTime += calcs[index](Number.parseFloat(value));
    });
 
    onChange(totalTime);
  };
 
  const handleBlurInput = (e: React.FormEvent<HTMLInputElement>) => {
    const splittedValue = e.currentTarget.value.split(":");
 
    splittedValue[0] =
      splittedValue[0].toString().length === 1 ? `0${splittedValue[0].toString()}` : `${splittedValue[0]}`;
 
    convertTextToTime(splittedValue.join(":"));
    setCurrentInputTime(formatTime(value || 0, true));
  };
 
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Enter") {
      e.currentTarget?.blur?.();
    }
  };
 
  const renderInputTime = () => {
    return (
      <input
        className={cn("time-box").elem("input-time").toClassName()}
        maxLength={12}
        ref={inputRef}
        type="text"
        readOnly={readonly}
        value={currentInputTime}
        onKeyDown={handleKeyDown}
        onChange={() => {}}
        onBlur={handleBlurInput}
      />
    );
  };
 
  const timeBoxContent = (
    <div className={cn("time-box").mod({ sidepanel }).toClassName()} {...props}>
      {renderInputTime()}
    </div>
  );
 
  return label ? (
    <Label size="small" flat text={label}>
      {timeBoxContent}
    </Label>
  ) : (
    timeBoxContent
  );
};