namirasoft-site-react 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.gitlab-ci.yml +14 -0
  2. package/config-overrides.js +66 -0
  3. package/package.json +45 -0
  4. package/public/favicon.ico +0 -0
  5. package/public/index.html +43 -0
  6. package/public/logo192.png +0 -0
  7. package/public/logo512.png +0 -0
  8. package/public/manifest.json +25 -0
  9. package/public/robots.txt +3 -0
  10. package/src/App.css +2 -0
  11. package/src/App.tsx +71 -0
  12. package/src/assets/images/arrow.svg +3 -0
  13. package/src/assets/images/background.svg +9 -0
  14. package/src/assets/images/danger.svg +3 -0
  15. package/src/assets/images/exit.svg +3 -0
  16. package/src/assets/images/icon-input-date.svg +9 -0
  17. package/src/assets/images/icon-input-duration.svg +9 -0
  18. package/src/assets/images/icon-input-email.svg +9 -0
  19. package/src/assets/images/icon-input-float.svg +9 -0
  20. package/src/assets/images/icon-input-id.svg +9 -0
  21. package/src/assets/images/icon-input-integer.svg +9 -0
  22. package/src/assets/images/icon-input-phone.svg +9 -0
  23. package/src/assets/images/icon-input-price.svg +9 -0
  24. package/src/assets/images/icon-input-search.svg +4 -0
  25. package/src/assets/images/icon-input-string.svg +9 -0
  26. package/src/assets/images/icon-input-text.svg +9 -0
  27. package/src/assets/images/icon-input-time.svg +9 -0
  28. package/src/assets/images/logo.svg +9 -0
  29. package/src/assets/images/menu.svg +3 -0
  30. package/src/assets/images/namira.svg +9 -0
  31. package/src/assets/images/rectangle.svg +3 -0
  32. package/src/components/NSButtonGreen.module.css +12 -0
  33. package/src/components/NSButtonGreen.tsx +18 -0
  34. package/src/components/NSButtonRed.module.css +12 -0
  35. package/src/components/NSButtonRed.tsx +18 -0
  36. package/src/components/NSFooter.module.css +32 -0
  37. package/src/components/NSFooter.tsx +126 -0
  38. package/src/components/NSHeader.module.css +127 -0
  39. package/src/components/NSHeader.tsx +134 -0
  40. package/src/components/NSInputDate.module.css +32 -0
  41. package/src/components/NSInputDate.tsx +54 -0
  42. package/src/components/NSInputDuration.module.css +26 -0
  43. package/src/components/NSInputDuration.tsx +63 -0
  44. package/src/components/NSInputEmail.module.css +38 -0
  45. package/src/components/NSInputEmail.tsx +90 -0
  46. package/src/components/NSInputFloat.module.css +23 -0
  47. package/src/components/NSInputFloat.tsx +63 -0
  48. package/src/components/NSInputIP.module.css +23 -0
  49. package/src/components/NSInputIP.tsx +63 -0
  50. package/src/components/NSInputInteger.module.css +26 -0
  51. package/src/components/NSInputInteger.tsx +63 -0
  52. package/src/components/NSInputPhone.module.css +30 -0
  53. package/src/components/NSInputPhone.tsx +63 -0
  54. package/src/components/NSInputPrice.module.css +24 -0
  55. package/src/components/NSInputPrice.tsx +62 -0
  56. package/src/components/NSInputSearch.module.css +24 -0
  57. package/src/components/NSInputSearch.tsx +76 -0
  58. package/src/components/NSInputString.module.css +24 -0
  59. package/src/components/NSInputString.tsx +62 -0
  60. package/src/components/NSInputText.module.css +25 -0
  61. package/src/components/NSInputText.tsx +63 -0
  62. package/src/components/NSInputTime.module.css +24 -0
  63. package/src/components/NSInputTime.tsx +63 -0
  64. package/src/components/NSSelectBox.module.css +25 -0
  65. package/src/components/NSSelectBox.tsx +60 -0
  66. package/src/index.css +7 -0
  67. package/src/index.tsx +8 -0
  68. package/src/react-app-env.d.ts +1 -0
  69. package/tsconfig.json +38 -0
@@ -0,0 +1,3 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect x="1" y="1" width="18" height="18" rx="3" fill="white" stroke="#848484" stroke-width="2"/>
3
+ </svg>
@@ -0,0 +1,12 @@
1
+ .ns_button_green {
2
+ width: 358px;
3
+ max-width: 100%;
4
+ height: 48px;
5
+ border-radius: 8px;
6
+ background-color: #06D182;
7
+ color: #fff;
8
+ border: 0;
9
+ box-shadow: inset 0 -4px 4px 0px rgb(0 0 0 / 25%);
10
+ font-size: 16px;
11
+ font-weight: 400;
12
+ }
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import Style from "./NSButtonGreen.module.css";
3
+
4
+ interface IProps
5
+ {
6
+ title: string;
7
+ onClick: () => void;
8
+ }
9
+
10
+ interface IState { }
11
+
12
+ export default class NSButtonGreen extends React.Component<IProps, IState>
13
+ {
14
+ override render()
15
+ {
16
+ return <button onClick={this.props.onClick} className={Style.ns_button_green}>{this.props.title}</button>;
17
+ }
18
+ }
@@ -0,0 +1,12 @@
1
+ .ns_button_red {
2
+ width: 358px;
3
+ max-width: 100%;
4
+ height: 48px;
5
+ border-radius: 8px;
6
+ background-color: #FF3F3F;
7
+ color: #fff;
8
+ border: 0;
9
+ box-shadow: inset 0 -4px 4px 0px rgb(0 0 0 / 25%);
10
+ font-size: 16px;
11
+ font-weight: 400;
12
+ }
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import Style from "./NSButtonRed.module.css";
3
+
4
+ interface IProps
5
+ {
6
+ title: string;
7
+ onClick: () => void;
8
+ }
9
+
10
+ interface IState { }
11
+
12
+ export default class NSButtonRed extends React.Component<IProps, IState>
13
+ {
14
+ override render()
15
+ {
16
+ return <button onClick={this.props.onClick} className={Style.ns_button_red}>{this.props.title}</button>;
17
+ }
18
+ }
@@ -0,0 +1,32 @@
1
+ .ns_footer {
2
+ width: 100%;
3
+ background: rgba(0, 0, 0, 0.3);
4
+ padding: 16px 0 8px 0;
5
+ }
6
+
7
+ .footns_footer li {
8
+ color: #fff;
9
+ }
10
+
11
+ .ns_footer ul {
12
+ list-style: none;
13
+ color: #fff;
14
+ padding: 0;
15
+ }
16
+ .ns_footer_copyright{
17
+ color: #fff !important;
18
+ text-align: center;
19
+ justify-content: center;
20
+ width: 100%;
21
+ }
22
+ .ns_footer_parent_items{
23
+ gap: 64px;
24
+ }
25
+ .ns_footer li{
26
+ font-size: 12px !important;
27
+ font-weight: 300 !important;
28
+ }
29
+ .ns_footer h5{
30
+ font-size: 16px !important;
31
+ font-weight: 600 !important;
32
+ }
@@ -0,0 +1,126 @@
1
+ import React from "react";
2
+ // import Namira from '../assets/images/namira.svg';
3
+ import Styles from "./NSFooter.module.css";
4
+ import { NamirasoftAPILinkServer, FilterLinkRow } from 'namirasoft-api-link';
5
+
6
+ interface IProps
7
+ {
8
+ scope: string;
9
+ name: string;
10
+ }
11
+
12
+ interface IState
13
+ {
14
+ filters: FilterLinkRow[];
15
+ selected: FilterLinkRow | null;
16
+ }
17
+
18
+ export default class NSFooter extends React.Component<IProps, IState> {
19
+ constructor(props: IProps)
20
+ {
21
+ super(props);
22
+ this.state = {
23
+ filters: [],
24
+ selected: null
25
+ };
26
+ this.hasChild = this.hasChild.bind(this);
27
+ this.render_menu = this.render_menu.bind(this);
28
+ this.render_menuItem = this.render_menuItem.bind(this);
29
+ }
30
+ override componentDidMount(): void
31
+ {
32
+ let server = new NamirasoftAPILinkServer(console.error);
33
+ server.filter.GetFilters(this.props.scope, this.props.name).then(filters =>
34
+ {
35
+ this.setState({ filters });
36
+ });
37
+ }
38
+ private hasChild(id: number): boolean
39
+ {
40
+ return this.state.filters.filter(f => f.parent_id === id).length > 0;
41
+ }
42
+ override render()
43
+ {
44
+ return (
45
+ <div className={Styles.ns_footer}>
46
+ <div className="container">
47
+ <div className={`d-flex justify-content-between ${Styles.ns_footer_parent_items}`}>
48
+ <div className="d-none d-md-block">
49
+ <div>
50
+ <a href="/">
51
+ <img src="https://static.namirasoft.com/logo/account/base.png" alt='footer' width={48} height={48} />
52
+ </a>
53
+ </div>
54
+ </div>
55
+ <div className="d-flex flex-wrap w-100 gap-5">
56
+ {this.render_menu(0, null)}
57
+ </div>
58
+ <div className="justify-content-end d-none d-md-flex">
59
+ <div>
60
+ <a href="/">
61
+ <img src="https://static.namirasoft.com/logo/namirasoft/name.png" alt='footer' width={48} height={48} />
62
+ </a>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ <div className="d-flex justify-content-center gap-4 mb-3 d-block d-md-none">
67
+ <div>
68
+ <a href="/">
69
+ <img src="https://static.namirasoft.com/logo/account/base.png" alt='footer' width={48} height={48} />
70
+ </a>
71
+ </div>
72
+ <div>
73
+ <a href="/">
74
+ <img src="https://static.namirasoft.com/logo/namirasoft/name.png" alt='footer' width={48} height={48} />
75
+ </a>
76
+ </div>
77
+ </div>
78
+ <div className={`row ${Styles.ns_footer_copyright}`}>©Copyright 2010 - 2023 Namira Software Corporation. All rights reserved.</div>
79
+ </div>
80
+ </div>
81
+ );
82
+ }
83
+ private render_menu(level: number, parent_id: number | null)
84
+ {
85
+ let fs: FilterLinkRow[] = this.state.filters?.filter(f => f.parent_id === parent_id);
86
+ return (
87
+ <>
88
+ {(fs?.map(f => this.render_menuItem(level, f)))}
89
+ </>
90
+ );
91
+ }
92
+ private render_menuItem(level: number, filter: FilterLinkRow)
93
+ {
94
+ if (this.hasChild(filter.id))
95
+ {
96
+ return (<>
97
+ <ul
98
+ id={`dropdown_parent${filter.id}`}>
99
+ {filter.name}
100
+ {this.render_menu(1, filter.id)}
101
+ </ul>
102
+ </>
103
+ );
104
+ }
105
+ else if (level == 0)
106
+ {
107
+ return (<>
108
+ <ul
109
+ id={`dropdown_parent${filter.id}`}>
110
+ {filter.name}
111
+ </ul>
112
+ </>
113
+ );
114
+ }
115
+ else
116
+ {
117
+ return (
118
+ <li className="mb-2">{filter.name}</li>
119
+ );
120
+ }
121
+ }
122
+
123
+
124
+ }
125
+
126
+
@@ -0,0 +1,127 @@
1
+ .ns_navbar_usersname {
2
+ color: #fff !important;
3
+ font-size: 16px;
4
+ font-weight: 400;
5
+ }
6
+
7
+ .ns_navbar {
8
+ min-height: 60px;
9
+ background-color: rgba(0, 0, 0, 0.3) !important;
10
+ position: relative;
11
+ z-index: 10;
12
+ display: flex;
13
+ align-items: center;
14
+ }
15
+
16
+ .ns_navbar_menu_icon {
17
+ display: none;
18
+ }
19
+
20
+ .ns_navbar_elements ul {
21
+ display: flex;
22
+ justify-content: space-between;
23
+ list-style-type: none;
24
+ }
25
+
26
+ .ns_navbar_elements ul li:not(:last-child) {
27
+ margin-right: 60px;
28
+ }
29
+
30
+ .ns_navbar_elements ul a {
31
+ font-size: 16px;
32
+ font-weight: 400;
33
+ color: #2f234f;
34
+ text-decoration: none;
35
+ }
36
+
37
+ .ns_navbar_elements ul a.ns_navbar_active {
38
+ color: #574c4c;
39
+ font-weight: 500;
40
+ position: relative;
41
+ }
42
+
43
+ .ns_navbar_elements ul a.ns_navbar_active::after {
44
+ content: "";
45
+ position: absolute;
46
+ bottom: -4px;
47
+ left: 0;
48
+ width: 100%;
49
+ height: 2px;
50
+ background-color: #574c4c;
51
+ }
52
+
53
+ @media (max-width: 768px) {
54
+ .ns_navbar_elements ul li:not(:last-child) {
55
+ margin-right: 30px;
56
+ }
57
+ }
58
+
59
+ @media (max-width: 600px) {
60
+ .ns_navbar_menu_icon {
61
+ display: block;
62
+ cursor: pointer;
63
+ }
64
+
65
+ .ns_navbar_elements {
66
+ position: absolute;
67
+ right: 0;
68
+ top: 60px;
69
+ width: 0px;
70
+ height: calc(100vh - 60px);
71
+ transition: all 0.3s ease-in;
72
+ overflow: hidden;
73
+ background-color: rgb(0 15 53 / 98%) !important;
74
+ }
75
+
76
+ .ns_navbar_elements.ns_navbar_active {
77
+ width: 270px;
78
+ }
79
+
80
+ .ns_navbar_elements ul {
81
+ display: flex;
82
+ flex-direction: column;
83
+ }
84
+
85
+ .ns_navbar_elements ul li {
86
+ margin-right: unset;
87
+ margin-top: 22px;
88
+ }
89
+
90
+ .ns_navbar_elements div {
91
+ flex-direction: column;
92
+ align-content: center;
93
+ }
94
+ }
95
+
96
+ .ns_navbar_parent_content {
97
+ display: flex;
98
+ align-items: center;
99
+ justify-content: space-between;
100
+ }
101
+
102
+ @media only screen and (min-width: 991px) {
103
+ .ns_nav_second_item .dropdown-menu {
104
+ margin-top: -20% !important;
105
+ margin-left: 100%;
106
+ }
107
+
108
+ .ns_navbar_content {
109
+ width: 100%;
110
+ }
111
+ }
112
+
113
+ .ns_navbar_first_level_item a {
114
+ color: #fff;
115
+ }
116
+
117
+ .ns_navbar_second_level_item a {
118
+ color: #000 !important;
119
+ }
120
+
121
+ .ns_navbar_first_level_item {
122
+ color: #fff;
123
+ }
124
+
125
+ .ns_navbar_second_level_item {
126
+ color: #000 !important;
127
+ }
@@ -0,0 +1,134 @@
1
+ import React from "react";
2
+ import Styles from "./NSHeader.module.css";
3
+ import Nav from 'react-bootstrap/Nav';
4
+ import Menu from '../assets/images/menu.svg';
5
+ import Exit from '../assets/images/exit.svg';
6
+ import NavDropdown from 'react-bootstrap/NavDropdown';
7
+ import { NamirasoftAPILinkServer, FilterLinkRow } from 'namirasoft-api-link';
8
+
9
+ interface IProps
10
+ {
11
+ scope: string;
12
+ name: string;
13
+ }
14
+
15
+ interface IState
16
+ {
17
+ filters: FilterLinkRow[];
18
+ selected: FilterLinkRow | null;
19
+ showNavbar: boolean;
20
+ }
21
+
22
+ export default class NSHeader extends React.Component<IProps, IState> {
23
+ constructor(props: IProps)
24
+ {
25
+ super(props);
26
+ this.state = {
27
+ filters: [],
28
+ selected: null,
29
+ showNavbar: false
30
+ };
31
+ this.hasChild = this.hasChild.bind(this);
32
+ this.onMenuItemToggled = this.onMenuItemToggled.bind(this);
33
+ this.render_menu = this.render_menu.bind(this);
34
+ this.render_menuItem = this.render_menuItem.bind(this);
35
+ this.handleShowNavbar = this.handleShowNavbar.bind(this);
36
+ }
37
+ override componentDidMount(): void
38
+ {
39
+ let server = new NamirasoftAPILinkServer(console.error);
40
+ server.filter.GetFilters(this.props.scope, this.props.name).then(filters =>
41
+ {
42
+ this.setState({ filters });
43
+ });
44
+ }
45
+ private onMenuItemToggled(checked: boolean, selected: FilterLinkRow)
46
+ {
47
+ if (checked)
48
+ this.setState({ selected });
49
+ }
50
+ private hasChild(id: number): boolean
51
+ {
52
+ return this.state.filters.filter(f => f.parent_id === id).length > 0;
53
+ }
54
+ handleShowNavbar(): void
55
+ {
56
+ this.setState({ showNavbar: !this.state.showNavbar });
57
+ }
58
+ override render()
59
+ {
60
+ return (
61
+ <nav className={Styles.ns_navbar}>
62
+ <div className={`${Styles.ns_navbar_parent_content} container`}>
63
+ <img
64
+ src="https://static.namirasoft.com/logo/account/base.png"
65
+ alt="logo"
66
+ width={48}
67
+ height={48}
68
+ />
69
+ <div className={`${Styles.ns_navbar_content} gap-2 d-flex justify-content-between`} >
70
+ <div className={`${Styles.ns_navbar_elements} ${this.state.showNavbar && Styles.ns_navbar_active}`}>
71
+ {this.render_menu(0, null)}
72
+ </div>
73
+ <div className="d-flex justify-content-center align-items-center">
74
+ <span className={`me-2 ${Styles.ns_navbar_usersname}`}>name</span>
75
+ <img src={Exit}
76
+ alt="exit"
77
+ width={20}
78
+ height={20}
79
+ />
80
+ </div>
81
+ <div className={Styles.ns_navbar_menu_icon} onClick={this.handleShowNavbar}>
82
+ <img
83
+ src={Menu}
84
+ alt="menu"
85
+ width={19}
86
+ height={17}
87
+ />
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </nav>
92
+ );
93
+ }
94
+ private render_menu(level: number, parent_id: number | null)
95
+ {
96
+ let fs: FilterLinkRow[] = this.state.filters?.filter(f => f.parent_id === parent_id);
97
+ return (
98
+ <Nav className="me-auto" >
99
+ {(fs?.map(f => this.render_menuItem(level, f)))}
100
+ </Nav>
101
+ );
102
+ }
103
+ private render_menuItem(level: number, filter: FilterLinkRow)
104
+ {
105
+ if (this.hasChild(filter.id))
106
+ {
107
+ let sub_menus = <></>;
108
+ if (level === 0)
109
+ if (this.state.selected)
110
+ {
111
+ sub_menus =
112
+ <div
113
+ id={`dropdown_items${filter.id}`}>
114
+ {this.render_menu(1, this.state.selected.id)}
115
+ </div >
116
+ }
117
+ return (<>
118
+ <NavDropdown
119
+ onToggle={(checked) => this.onMenuItemToggled(checked, filter)}
120
+ className={level === 0 ? Styles.ns_navbar_first_level_item : Styles.ns_navbar_second_level_item}
121
+ title={filter.name}
122
+ id={`dropdown_parent${filter.id}`}>
123
+ {sub_menus}
124
+ </NavDropdown >
125
+ </>
126
+ );
127
+ } else
128
+ {
129
+ return (
130
+ <Nav.Link className={level === 0 ? Styles.ns_navbar_first_level_item : Styles.ns_navbar_second_level_item} href={filter.link?.url}>{filter.name}li</Nav.Link>
131
+ );
132
+ }
133
+ }
134
+ }
@@ -0,0 +1,32 @@
1
+ .ns_parent_input{
2
+ display: flex;
3
+ flex-direction: column;
4
+ width: 326px;
5
+ color: #fff;
6
+ position: relative;
7
+ max-width: 100%;
8
+ }
9
+ .ns_input{
10
+ border-radius: 8px;
11
+ padding: 10px 12px;
12
+ font-size: 16px;
13
+ font-weight: 400;
14
+ }
15
+ .ns_input_icon{
16
+ position: absolute;
17
+ right: 20px;
18
+ top: 51%;
19
+ }
20
+ .ns_input_title {
21
+ font-size: 16px;
22
+ font-weight: 400;
23
+ }
24
+ input[type="date"]::-webkit-calendar-picker-indicator {
25
+ display: block;
26
+ background: url(../assets/images/icon-input-date.svg) no-repeat;
27
+ width: 24px;
28
+ height: 24px;
29
+ position: relative;
30
+ top: 3px;
31
+ left: 4px;
32
+ }
@@ -0,0 +1,54 @@
1
+ import React from "react";
2
+ import Styles from "./NSInputDate.module.css";
3
+
4
+ interface IProps
5
+ {
6
+ title: string;
7
+ }
8
+
9
+ interface IState
10
+ {
11
+ value: string;
12
+ }
13
+
14
+ export default class NSInputDate extends React.Component<IProps, IState> {
15
+ constructor(props: IProps)
16
+ {
17
+ super(props);
18
+ this.state = {
19
+ value: "",
20
+ };
21
+ this.setValue = this.setValue.bind(this);
22
+ this.getValue = this.getValue.bind(this);
23
+ this.setDefaultValue = this.setDefaultValue.bind(this);
24
+ }
25
+ setValue(e: React.ChangeEvent<HTMLInputElement>): void
26
+ {
27
+ this.setState({ value: e.target.value });
28
+ }
29
+ setDefaultValue(value: string): void
30
+ {
31
+ this.setState({ value });
32
+ }
33
+ getValue(): string
34
+ {
35
+ return this.state.value;
36
+ }
37
+ override render()
38
+ {
39
+ return (
40
+ <div className={`${Styles.ns_parent_input} p-2`}>
41
+ <span className={Styles.ns_input_title}>{this.props.title}</span>
42
+ <input
43
+ value={this.state.value}
44
+ onChange={this.setValue}
45
+ type="date"
46
+ className={Styles.ns_input}
47
+ placeholder="YYYY/MM/DD"
48
+ />
49
+ </div>
50
+ );
51
+ }
52
+ }
53
+
54
+
@@ -0,0 +1,26 @@
1
+ .ns_input_parent {
2
+ display: flex;
3
+ flex-direction: column;
4
+ width: 326px;
5
+ color: #fff;
6
+ position: relative;
7
+ max-width: 100%;
8
+ }
9
+
10
+ .ns_input {
11
+ border-radius: 8px;
12
+ padding: 10px 12px;
13
+ font-size: 16px;
14
+ font-weight: 400;
15
+ }
16
+
17
+ .ns_input_icon {
18
+ position: absolute;
19
+ right: 20px;
20
+ top: 51%;
21
+ }
22
+
23
+ .ns_input_title {
24
+ font-size: 16px;
25
+ font-weight: 400;
26
+ }
@@ -0,0 +1,63 @@
1
+ import React from "react";
2
+ import Styles from "./NSInputDuration.module.css";
3
+ import IconInputDuration from '../assets/images/icon-input-duration.svg';
4
+
5
+ interface IProps
6
+ {
7
+ title: string;
8
+ }
9
+
10
+ interface IState
11
+ {
12
+ value: string;
13
+ }
14
+
15
+ export default class NSInputDuration extends React.Component<IProps, IState> {
16
+ constructor(props: IProps)
17
+ {
18
+ super(props);
19
+ this.state = {
20
+ value: "",
21
+ };
22
+ this.setValue = this.setValue.bind(this);
23
+ this.getValue = this.getValue.bind(this);
24
+ this.setDefaultValue = this.setDefaultValue.bind(this);
25
+ }
26
+ setValue(e: React.ChangeEvent<HTMLInputElement>): void
27
+ {
28
+ this.setState({ value: e.target.value });
29
+ }
30
+ setDefaultValue(value: string): void
31
+ {
32
+ this.setState({ value });
33
+ }
34
+ getValue(): string
35
+ {
36
+ return this.state.value;
37
+ }
38
+ override render()
39
+ {
40
+ return (
41
+ <div className={`${Styles.ns_input_parent} p-2`}>
42
+ <span className={Styles.ns_input_title}>{this.props.title}</span>
43
+ <img
44
+ className={Styles.ns_input_icon}
45
+ src={IconInputDuration}
46
+ alt="icon"
47
+ width={24}
48
+ height={24}
49
+ />
50
+ <input
51
+ value={this.state.value}
52
+ onChange={this.setValue}
53
+ type="time"
54
+ className={Styles.ns_input}
55
+ placeholder="21:44:06"
56
+ step="2"
57
+ />
58
+ </div>
59
+ );
60
+ }
61
+ }
62
+
63
+