Skip to content

Commit b6a99fe

Browse files
author
k.golikov
committed
Add Date Utils
1 parent 013153d commit b6a99fe

File tree

5 files changed

+106
-11
lines changed

5 files changed

+106
-11
lines changed

src/constants/router/menuItems.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,14 @@ const menuItems: MenuItem[] = [
6868
route: routes.dataUrl
6969
},
7070
{
71-
route: routes.base64,
72-
isHidden: true
71+
route: routes.dateUtils
7372
},
7473
{
75-
route: routes.imageCompressor,
74+
route: routes.base64,
7675
isHidden: true
7776
},
7877
{
79-
route: routes.dateUtils,
78+
route: routes.imageCompressor,
8079
isHidden: true
8180
},
8281
{

src/hooks/useChangeAnyStateHandler.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { ChangeEvent, Dispatch, SetStateAction } from 'react';
2+
import { isObjectLike } from 'lodash';
3+
import call from '../utils/call';
4+
5+
export const isChangeEvent = (value: any): value is ChangeEvent<unknown> => {
6+
return isObjectLike(value) && 'target' in value;
7+
};
8+
9+
const useChangeAnyStateHandler = <S>(setState: Dispatch<SetStateAction<S>>) => {
10+
return (value: ChangeEvent<{ value: S }> | S) => {
11+
const actualValue = call(() => {
12+
if (isChangeEvent(value)) {
13+
const event = value as ChangeEvent<{ value: S }>;
14+
return event.target.value;
15+
}
16+
17+
return value;
18+
});
19+
20+
setState(actualValue);
21+
};
22+
};
23+
24+
export default useChangeAnyStateHandler;

src/hooks/useChangeStateHandler.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import { ChangeEvent, Dispatch, SetStateAction, useCallback } from 'react';
22
import call from '../utils/call';
3-
import { isObjectLike } from 'lodash';
43
import useChangeState from './useChangeState';
5-
6-
const isChangeEvent = (value: any): value is ChangeEvent<unknown> => {
7-
return isObjectLike(value) && 'target' in value;
8-
};
4+
import { isChangeEvent } from './useChangeAnyStateHandler';
95

106
const useChangeStateHandler = <S extends object>(setState: Dispatch<SetStateAction<S>>) => {
117
const changeState = useChangeState(setState);
Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
import React, { FunctionComponent } from 'react';
2-
import PageContainer, { PageTag } from '../../layouts/pages/pageContainer/PageContainer';
2+
import PageContainer from '../../layouts/pages/pageContainer/PageContainer';
3+
import { Tabs } from 'antd';
4+
5+
import DateUtilsDifferenceTab from './components/differenceTab/DateUtilsDifferenceTab';
36

47
const DateUtilsPage: FunctionComponent = () => {
5-
return <PageContainer title="DateUtilsPage" tags={[PageTag.WIP]}></PageContainer>;
8+
return (
9+
<PageContainer title="Date utils">
10+
<Tabs>
11+
<Tabs.TabPane tab="Difference">
12+
<DateUtilsDifferenceTab />
13+
</Tabs.TabPane>
14+
</Tabs>
15+
</PageContainer>
16+
);
617
};
718

819
export default DateUtilsPage;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import React, { FunctionComponent, useMemo, useState } from 'react';
2+
import { Checkbox, Col, DatePicker, Space } from 'antd';
3+
import moment, { duration, Duration, Moment } from 'moment';
4+
import { RangeValue } from 'rc-picker/lib/interface';
5+
import Text from 'antd/lib/typography/Text';
6+
import { CheckboxChangeEvent } from 'antd/lib/checkbox';
7+
8+
const DateUtilsDifferenceTab: FunctionComponent = () => {
9+
const [range, setRange] = useState<RangeValue<Moment>>([moment(), moment()]);
10+
11+
const [isTotalDifference, setIsTotalDifference] = useState<boolean>(false);
12+
const [isTimeShown, setIsTimeShown] = useState<boolean>(false);
13+
14+
const handleIsTotalDifferenceChange = (event: CheckboxChangeEvent) => {
15+
const { checked } = event.target;
16+
setIsTotalDifference(checked);
17+
};
18+
19+
const handleIsTimeShownChange = (event: CheckboxChangeEvent) => {
20+
const { checked } = event.target;
21+
setIsTimeShown(checked);
22+
};
23+
24+
const difference = useMemo<Duration | undefined>(() => {
25+
if (!range) {
26+
return undefined;
27+
}
28+
29+
const [date1, date2] = range;
30+
31+
if (!date1 || !date2) {
32+
return undefined;
33+
}
34+
35+
return duration(date2.diff(date1));
36+
}, [range]);
37+
38+
const differenceMethod = isTotalDifference ? 'as' : 'get';
39+
40+
return (
41+
<Col xs={24} md={18} lg={14} xl={10} xxl={8}>
42+
<DatePicker.RangePicker showTime={isTimeShown} value={range as any} onChange={setRange} />
43+
{difference && (
44+
<Col className="mt-2">
45+
<Space direction="vertical">
46+
<Checkbox checked={isTimeShown} onChange={handleIsTimeShownChange}>
47+
Show time
48+
</Checkbox>
49+
<Checkbox checked={isTotalDifference} onChange={handleIsTotalDifferenceChange}>
50+
Total
51+
</Checkbox>
52+
<Text>Years: {difference[differenceMethod]('years')}</Text>
53+
<Text>Months: {difference[differenceMethod]('months')}</Text>
54+
<Text>Days: {difference[differenceMethod]('days')}</Text>
55+
<Text>Hours: {difference[differenceMethod]('hours')}</Text>
56+
<Text>Minutes: {difference[differenceMethod]('minutes')}</Text>
57+
<Text>Seconds: {difference[differenceMethod]('seconds')}</Text>
58+
</Space>
59+
</Col>
60+
)}
61+
</Col>
62+
);
63+
};
64+
65+
export default DateUtilsDifferenceTab;

0 commit comments

Comments
 (0)