namirasoft-account-react 1.4.19 → 1.4.21
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.
- package/.env.template +10 -10
- package/config-overrides.js +72 -72
- package/dist/IEntityInfo.d.ts +11 -11
- package/dist/Messages.js.map +1 -1
- package/dist/NSARouterMaker.d.ts +0 -1
- package/dist/NSARouterMaker.js.map +1 -1
- package/dist/Router.d.ts +0 -1
- package/dist/components/NSAAccessListDialog.js.map +1 -1
- package/dist/components/NSAAccessListDialog.module.css +87 -0
- package/dist/components/NSABoxOTP.js.map +1 -1
- package/dist/components/NSABoxOTP.module.css +11 -0
- package/dist/components/NSAMessageListDialog.js.map +1 -1
- package/dist/components/NSAMessageListDialog.module.css +98 -0
- package/dist/components/NSAProductListDialog.js.map +1 -1
- package/dist/components/NSAProductListDialog.module.css +45 -0
- package/dist/components/NSAWorkspaceListDialog.js.map +1 -1
- package/dist/components/NSAWorkspaceListDialog.module.css +43 -0
- package/dist/index.js.map +1 -1
- package/dist/layouts/Actions.d.ts +2 -1
- package/dist/layouts/Actions.js +38 -17
- package/dist/layouts/Actions.js.map +1 -1
- package/dist/layouts/NSALayout.d.ts +2 -1
- package/dist/layouts/NSALayout.js +58 -37
- package/dist/layouts/NSALayout.js.map +1 -1
- package/dist/layouts/NSASectionEdit.d.ts +0 -1
- package/dist/layouts/NSASectionEdit.js +12 -8
- package/dist/layouts/NSASectionEdit.js.map +1 -1
- package/dist/layouts/NSASectionList.js +6 -4
- package/dist/layouts/NSASectionList.js.map +1 -1
- package/dist/layouts/NSASectionTabs.d.ts +0 -1
- package/dist/layouts/NSASectionTabs.js +4 -7
- package/dist/layouts/NSASectionTabs.js.map +1 -1
- package/dist/layouts/NSASectionView.js +4 -3
- package/dist/layouts/NSASectionView.js.map +1 -1
- package/dist/pages/NSAHomePage.module.css +23 -0
- package/dist/pages/NSALoginPage.module.css +20 -0
- package/dist/pages/NSAVerificationPage.module.css +23 -0
- package/package.json +70 -70
- package/public/index.html +21 -21
- package/src/App.css +31 -31
- package/src/App.tsx +18 -18
- package/src/IEntityInfo.ts +31 -31
- package/src/INSARouterMaker.ts +7 -7
- package/src/INSARouterProps.ts +17 -17
- package/src/INSARouterState.ts +5 -5
- package/src/Info.ts +20 -20
- package/src/Message.ts +6 -6
- package/src/Messages.ts +33 -33
- package/src/NSARouterMaker.tsx +142 -142
- package/src/Router.tsx +39 -39
- package/src/components/NSAAccessListDialog.module.css +86 -86
- package/src/components/NSAAccessListDialog.tsx +160 -160
- package/src/components/NSABoxOTP.module.css +10 -10
- package/src/components/NSABoxOTP.tsx +63 -63
- package/src/components/NSAMessageListDialog.module.css +97 -97
- package/src/components/NSAMessageListDialog.tsx +116 -116
- package/src/components/NSAProductListDialog.module.css +44 -44
- package/src/components/NSAProductListDialog.tsx +100 -100
- package/src/components/NSAWorkspaceListDialog.module.css +42 -42
- package/src/components/NSAWorkspaceListDialog.tsx +73 -73
- package/src/index.tsx +24 -24
- package/src/layouts/Actions.ts +147 -119
- package/src/layouts/Menus.ts +15 -15
- package/src/layouts/NSALayout.tsx +417 -387
- package/src/layouts/NSASectionEdit.tsx +144 -140
- package/src/layouts/NSASectionList.tsx +161 -158
- package/src/layouts/NSASectionTabs.tsx +152 -156
- package/src/layouts/NSASectionView.tsx +61 -60
- package/src/main.ts +19 -19
- package/src/pages/NSAHomePage.module.css +22 -22
- package/src/pages/NSAHomePage.tsx +27 -27
- package/src/pages/NSALoginPage.module.css +19 -19
- package/src/pages/NSALoginPage.tsx +65 -65
- package/src/pages/NSAVerificationPage.module.css +22 -22
- package/src/pages/NSAVerificationPage.tsx +59 -59
- package/tsconfig.json +43 -43
|
@@ -1,161 +1,161 @@
|
|
|
1
|
-
import React, { Component, createRef } from 'react';
|
|
2
|
-
import { EnvService } from 'namirasoft-core'
|
|
3
|
-
import { NamirasoftAccessServer, PermissionRow } from 'namirasoft-access';
|
|
4
|
-
import { NSLine, NSLoading, NSDialog, NSDialogProps } from 'namirasoft-site-react';
|
|
5
|
-
import { INSARouterProps } from '../INSARouterProps';
|
|
6
|
-
import Styles from './NSAAccessListDialog.module.css';
|
|
7
|
-
|
|
8
|
-
export interface NSAAccessListDialogProps extends INSARouterProps, NSDialogProps
|
|
9
|
-
{
|
|
10
|
-
onClose: () => void;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface NSAAccessListDialogState
|
|
14
|
-
{
|
|
15
|
-
permissions: PermissionRow[] | null;
|
|
16
|
-
copied: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class NSAAccessListDialog extends Component<NSAAccessListDialogProps, NSAAccessListDialogState>
|
|
20
|
-
{
|
|
21
|
-
private toastRef: React.RefObject<HTMLDivElement>;
|
|
22
|
-
|
|
23
|
-
constructor(props: NSAAccessListDialogProps)
|
|
24
|
-
{
|
|
25
|
-
super(props);
|
|
26
|
-
this.state = { permissions: null, copied: false };
|
|
27
|
-
this.toastRef = createRef();
|
|
28
|
-
this.handleClickOutside = this.handleClickOutside.bind(this);
|
|
29
|
-
}
|
|
30
|
-
override componentDidMount(): void
|
|
31
|
-
{
|
|
32
|
-
document.addEventListener('mousedown', this.handleClickOutside);
|
|
33
|
-
let REACT_APP_BASE_URL_ACCESS = new EnvService("REACT_APP_BASE_URL_ACCESS", true).getString();
|
|
34
|
-
let server = new NamirasoftAccessServer(REACT_APP_BASE_URL_ACCESS, this.props.account.token_manager, this.props.notifier.onError);
|
|
35
|
-
server.permission.ListIncoming([], null, null).then(res =>
|
|
36
|
-
{
|
|
37
|
-
this.setState({ permissions: res.rows });
|
|
38
|
-
}).catch(() => { });
|
|
39
|
-
}
|
|
40
|
-
override componentWillUnmount(): void
|
|
41
|
-
{
|
|
42
|
-
document.removeEventListener('mousedown', this.handleClickOutside);
|
|
43
|
-
}
|
|
44
|
-
private copyButton(text: string)
|
|
45
|
-
{
|
|
46
|
-
this.setState({ copied: true });
|
|
47
|
-
setTimeout(() =>
|
|
48
|
-
{
|
|
49
|
-
this.setState({ copied: false });
|
|
50
|
-
}, 3000);
|
|
51
|
-
return navigator.clipboard.writeText(text);
|
|
52
|
-
}
|
|
53
|
-
private handleClickOutside(event: MouseEvent)
|
|
54
|
-
{
|
|
55
|
-
if (this.toastRef.current && !this.toastRef.current.contains(event.target as Node))
|
|
56
|
-
this.props.onClose();
|
|
57
|
-
}
|
|
58
|
-
override render()
|
|
59
|
-
{
|
|
60
|
-
let profile = null;
|
|
61
|
-
let content = null;
|
|
62
|
-
if (this.state.permissions === null)
|
|
63
|
-
content =
|
|
64
|
-
<NSLoading />
|
|
65
|
-
else
|
|
66
|
-
{
|
|
67
|
-
let user_id = this.props.account.token_manager.getUserData(u => u.id, "");
|
|
68
|
-
let first_name = this.props.account.token_manager.getUserData(u => u.first_name, "");
|
|
69
|
-
let last_name = this.props.account.token_manager.getUserData(u => u.last_name, "");
|
|
70
|
-
let email = this.props.account.token_manager.getUserData(u => u.email, "");
|
|
71
|
-
let generate = (permission: PermissionRow) =>
|
|
72
|
-
{
|
|
73
|
-
return <div
|
|
74
|
-
className={Styles.ns_access_account_container}
|
|
75
|
-
onClick={() =>
|
|
76
|
-
{
|
|
77
|
-
let REACT_APP_BASE_URL_ACCESS = new EnvService("REACT_APP_BASE_URL_ACCESS", true).getString();
|
|
78
|
-
let server = new NamirasoftAccessServer(REACT_APP_BASE_URL_ACCESS, this.props.account.token_manager, this.props.notifier.onError);
|
|
79
|
-
if (permission.id)
|
|
80
|
-
server.access.SetOwner({ owner_id: permission.user_id }).then(() =>
|
|
81
|
-
{
|
|
82
|
-
this.props.onClose();
|
|
83
|
-
}).catch(() => { });
|
|
84
|
-
else
|
|
85
|
-
server.access.SetOwner({ owner_id: null }).then(() =>
|
|
86
|
-
{
|
|
87
|
-
this.props.onClose();
|
|
88
|
-
}).catch(() => { });
|
|
89
|
-
}}
|
|
90
|
-
>
|
|
91
|
-
<div className={Styles.ns_access_account_info}>
|
|
92
|
-
<img src={"https://static.namirasoft.com/image/concept/no-profile/grey.svg"} alt='User Profile' width={48} height={48} className='rounded-circle' />
|
|
93
|
-
</div>
|
|
94
|
-
<div className='d-flex flex-column'>
|
|
95
|
-
<h4>{`${permission.firstName} ${permission.lastName}`.trim()}</h4>
|
|
96
|
-
<h5>{permission.user_id}</h5>
|
|
97
|
-
</div>
|
|
98
|
-
</div>
|
|
99
|
-
}
|
|
100
|
-
let me: PermissionRow = {
|
|
101
|
-
id: "",
|
|
102
|
-
user_id,
|
|
103
|
-
to_user_id: user_id,
|
|
104
|
-
firstName: first_name,
|
|
105
|
-
lastName: last_name,
|
|
106
|
-
email: email,
|
|
107
|
-
default: this.state.permissions.filter(x => x.default).length === 0,
|
|
108
|
-
createdAt: new Date(),
|
|
109
|
-
updatedAt: new Date()
|
|
110
|
-
};
|
|
111
|
-
let permissions = [me, ...this.state.permissions];
|
|
112
|
-
let current = permissions.filter(x => x.default)[0];
|
|
113
|
-
content = permissions.filter(x => !x.default).map(generate);
|
|
114
|
-
profile = <>
|
|
115
|
-
<div
|
|
116
|
-
className=
|
|
117
|
-
'text-center d-flex flex-column justify-content-center align-items-center pb-2'
|
|
118
|
-
>
|
|
119
|
-
<img src={"https://static.namirasoft.com/image/namirasoft/access/logo/circle.png"} alt='No Profile' width={103} height={103} className='rounded-circle' style={{ cursor: "default", pointerEvents: "none" }} />
|
|
120
|
-
<h6 className="pb-2">Your current user is:</h6>
|
|
121
|
-
<div className='d-flex flex-row justify-content-center align-items-center'>
|
|
122
|
-
<h2 className='text-center'
|
|
123
|
-
onClick={() => { this.copyButton(current.user_id) }}
|
|
124
|
-
style={{ cursor: "pointer" }}
|
|
125
|
-
>{current.user_id}
|
|
126
|
-
</h2>
|
|
127
|
-
{this.state.copied
|
|
128
|
-
? <img src={"https://static.namirasoft.com/image/concept/check/on/blue.svg"} alt='Copied' width={23} height={23} />
|
|
129
|
-
: <img
|
|
130
|
-
src='https://static.namirasoft.com/image/concept/copy/blue.svg'
|
|
131
|
-
alt='Copy_Button'
|
|
132
|
-
width={16} height={16}
|
|
133
|
-
onClick={() => { this.copyButton(current.user_id) }}
|
|
134
|
-
style={{
|
|
135
|
-
cursor: "pointer",
|
|
136
|
-
marginLeft: "8px"
|
|
137
|
-
}}
|
|
138
|
-
/>
|
|
139
|
-
}
|
|
140
|
-
</div>
|
|
141
|
-
<h6>{`${current.firstName} ${current.lastName}`.trim()}</h6>
|
|
142
|
-
</div >
|
|
143
|
-
</>;
|
|
144
|
-
}
|
|
145
|
-
return (
|
|
146
|
-
<NSDialog {...this.props}>
|
|
147
|
-
<a className='text-left w-100 ps-3' href='https://access.namirasoft.com/' target="_blank" rel="noopener noreferrer">
|
|
148
|
-
<span className='d-flex justify-content-left'>Manage Accesss</span>
|
|
149
|
-
</a>
|
|
150
|
-
<section className={Styles.ns_access_container} >
|
|
151
|
-
{profile}
|
|
152
|
-
<NSLine />
|
|
153
|
-
<h6>Switch user as:</h6>
|
|
154
|
-
{content !== null &&
|
|
155
|
-
<p>There is not any other user</p>
|
|
156
|
-
}
|
|
157
|
-
</section>
|
|
158
|
-
</NSDialog >
|
|
159
|
-
);
|
|
160
|
-
}
|
|
1
|
+
import React, { Component, createRef } from 'react';
|
|
2
|
+
import { EnvService } from 'namirasoft-core'
|
|
3
|
+
import { NamirasoftAccessServer, PermissionRow } from 'namirasoft-access';
|
|
4
|
+
import { NSLine, NSLoading, NSDialog, NSDialogProps } from 'namirasoft-site-react';
|
|
5
|
+
import { INSARouterProps } from '../INSARouterProps';
|
|
6
|
+
import Styles from './NSAAccessListDialog.module.css';
|
|
7
|
+
|
|
8
|
+
export interface NSAAccessListDialogProps extends INSARouterProps, NSDialogProps
|
|
9
|
+
{
|
|
10
|
+
onClose: () => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface NSAAccessListDialogState
|
|
14
|
+
{
|
|
15
|
+
permissions: PermissionRow[] | null;
|
|
16
|
+
copied: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class NSAAccessListDialog extends Component<NSAAccessListDialogProps, NSAAccessListDialogState>
|
|
20
|
+
{
|
|
21
|
+
private toastRef: React.RefObject<HTMLDivElement>;
|
|
22
|
+
|
|
23
|
+
constructor(props: NSAAccessListDialogProps)
|
|
24
|
+
{
|
|
25
|
+
super(props);
|
|
26
|
+
this.state = { permissions: null, copied: false };
|
|
27
|
+
this.toastRef = createRef();
|
|
28
|
+
this.handleClickOutside = this.handleClickOutside.bind(this);
|
|
29
|
+
}
|
|
30
|
+
override componentDidMount(): void
|
|
31
|
+
{
|
|
32
|
+
document.addEventListener('mousedown', this.handleClickOutside);
|
|
33
|
+
let REACT_APP_BASE_URL_ACCESS = new EnvService("REACT_APP_BASE_URL_ACCESS", true).getString();
|
|
34
|
+
let server = new NamirasoftAccessServer(REACT_APP_BASE_URL_ACCESS, this.props.account.token_manager, this.props.notifier.onError);
|
|
35
|
+
server.permission.ListIncoming([], null, null).then(res =>
|
|
36
|
+
{
|
|
37
|
+
this.setState({ permissions: res.rows });
|
|
38
|
+
}).catch(() => { });
|
|
39
|
+
}
|
|
40
|
+
override componentWillUnmount(): void
|
|
41
|
+
{
|
|
42
|
+
document.removeEventListener('mousedown', this.handleClickOutside);
|
|
43
|
+
}
|
|
44
|
+
private copyButton(text: string)
|
|
45
|
+
{
|
|
46
|
+
this.setState({ copied: true });
|
|
47
|
+
setTimeout(() =>
|
|
48
|
+
{
|
|
49
|
+
this.setState({ copied: false });
|
|
50
|
+
}, 3000);
|
|
51
|
+
return navigator.clipboard.writeText(text);
|
|
52
|
+
}
|
|
53
|
+
private handleClickOutside(event: MouseEvent)
|
|
54
|
+
{
|
|
55
|
+
if (this.toastRef.current && !this.toastRef.current.contains(event.target as Node))
|
|
56
|
+
this.props.onClose();
|
|
57
|
+
}
|
|
58
|
+
override render()
|
|
59
|
+
{
|
|
60
|
+
let profile = null;
|
|
61
|
+
let content = null;
|
|
62
|
+
if (this.state.permissions === null)
|
|
63
|
+
content =
|
|
64
|
+
<NSLoading />
|
|
65
|
+
else
|
|
66
|
+
{
|
|
67
|
+
let user_id = this.props.account.token_manager.getUserData(u => u.id, "");
|
|
68
|
+
let first_name = this.props.account.token_manager.getUserData(u => u.first_name, "");
|
|
69
|
+
let last_name = this.props.account.token_manager.getUserData(u => u.last_name, "");
|
|
70
|
+
let email = this.props.account.token_manager.getUserData(u => u.email, "");
|
|
71
|
+
let generate = (permission: PermissionRow) =>
|
|
72
|
+
{
|
|
73
|
+
return <div
|
|
74
|
+
className={Styles.ns_access_account_container}
|
|
75
|
+
onClick={() =>
|
|
76
|
+
{
|
|
77
|
+
let REACT_APP_BASE_URL_ACCESS = new EnvService("REACT_APP_BASE_URL_ACCESS", true).getString();
|
|
78
|
+
let server = new NamirasoftAccessServer(REACT_APP_BASE_URL_ACCESS, this.props.account.token_manager, this.props.notifier.onError);
|
|
79
|
+
if (permission.id)
|
|
80
|
+
server.access.SetOwner({ owner_id: permission.user_id }).then(() =>
|
|
81
|
+
{
|
|
82
|
+
this.props.onClose();
|
|
83
|
+
}).catch(() => { });
|
|
84
|
+
else
|
|
85
|
+
server.access.SetOwner({ owner_id: null }).then(() =>
|
|
86
|
+
{
|
|
87
|
+
this.props.onClose();
|
|
88
|
+
}).catch(() => { });
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
<div className={Styles.ns_access_account_info}>
|
|
92
|
+
<img src={"https://static.namirasoft.com/image/concept/no-profile/grey.svg"} alt='User Profile' width={48} height={48} className='rounded-circle' />
|
|
93
|
+
</div>
|
|
94
|
+
<div className='d-flex flex-column'>
|
|
95
|
+
<h4>{`${permission.firstName} ${permission.lastName}`.trim()}</h4>
|
|
96
|
+
<h5>{permission.user_id}</h5>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
}
|
|
100
|
+
let me: PermissionRow = {
|
|
101
|
+
id: "",
|
|
102
|
+
user_id,
|
|
103
|
+
to_user_id: user_id,
|
|
104
|
+
firstName: first_name,
|
|
105
|
+
lastName: last_name,
|
|
106
|
+
email: email,
|
|
107
|
+
default: this.state.permissions.filter(x => x.default).length === 0,
|
|
108
|
+
createdAt: new Date(),
|
|
109
|
+
updatedAt: new Date()
|
|
110
|
+
};
|
|
111
|
+
let permissions = [me, ...this.state.permissions];
|
|
112
|
+
let current = permissions.filter(x => x.default)[0];
|
|
113
|
+
content = permissions.filter(x => !x.default).map(generate);
|
|
114
|
+
profile = <>
|
|
115
|
+
<div
|
|
116
|
+
className=
|
|
117
|
+
'text-center d-flex flex-column justify-content-center align-items-center pb-2'
|
|
118
|
+
>
|
|
119
|
+
<img src={"https://static.namirasoft.com/image/namirasoft/access/logo/circle.png"} alt='No Profile' width={103} height={103} className='rounded-circle' style={{ cursor: "default", pointerEvents: "none" }} />
|
|
120
|
+
<h6 className="pb-2">Your current user is:</h6>
|
|
121
|
+
<div className='d-flex flex-row justify-content-center align-items-center'>
|
|
122
|
+
<h2 className='text-center'
|
|
123
|
+
onClick={() => { this.copyButton(current.user_id) }}
|
|
124
|
+
style={{ cursor: "pointer" }}
|
|
125
|
+
>{current.user_id}
|
|
126
|
+
</h2>
|
|
127
|
+
{this.state.copied
|
|
128
|
+
? <img src={"https://static.namirasoft.com/image/concept/check/on/blue.svg"} alt='Copied' width={23} height={23} />
|
|
129
|
+
: <img
|
|
130
|
+
src='https://static.namirasoft.com/image/concept/copy/blue.svg'
|
|
131
|
+
alt='Copy_Button'
|
|
132
|
+
width={16} height={16}
|
|
133
|
+
onClick={() => { this.copyButton(current.user_id) }}
|
|
134
|
+
style={{
|
|
135
|
+
cursor: "pointer",
|
|
136
|
+
marginLeft: "8px"
|
|
137
|
+
}}
|
|
138
|
+
/>
|
|
139
|
+
}
|
|
140
|
+
</div>
|
|
141
|
+
<h6>{`${current.firstName} ${current.lastName}`.trim()}</h6>
|
|
142
|
+
</div >
|
|
143
|
+
</>;
|
|
144
|
+
}
|
|
145
|
+
return (
|
|
146
|
+
<NSDialog {...this.props}>
|
|
147
|
+
<a className='text-left w-100 ps-3' href='https://access.namirasoft.com/' target="_blank" rel="noopener noreferrer">
|
|
148
|
+
<span className='d-flex justify-content-left'>Manage Accesss</span>
|
|
149
|
+
</a>
|
|
150
|
+
<section className={Styles.ns_access_container} >
|
|
151
|
+
{profile}
|
|
152
|
+
<NSLine />
|
|
153
|
+
<h6>Switch user as:</h6>
|
|
154
|
+
{content !== null &&
|
|
155
|
+
<p>There is not any other user</p>
|
|
156
|
+
}
|
|
157
|
+
</section>
|
|
158
|
+
</NSDialog >
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
161
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
.nsa_otp_input {
|
|
2
|
-
border: none;
|
|
3
|
-
background-color: transparent;
|
|
4
|
-
border-bottom: 2px solid #141B5C;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.nsa_otp_input:focus {
|
|
8
|
-
border: none;
|
|
9
|
-
outline: none;
|
|
10
|
-
border-bottom: 2px solid #141B5C;
|
|
1
|
+
.nsa_otp_input {
|
|
2
|
+
border: none;
|
|
3
|
+
background-color: transparent;
|
|
4
|
+
border-bottom: 2px solid #141B5C;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.nsa_otp_input:focus {
|
|
8
|
+
border: none;
|
|
9
|
+
outline: none;
|
|
10
|
+
border-bottom: 2px solid #141B5C;
|
|
11
11
|
}
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
import Styles from './NSABoxOTP.module.css';
|
|
2
|
-
import { IBaseComponentProps } from 'namirasoft-site-react';
|
|
3
|
-
import React, { useState, ChangeEvent, useRef } from 'react';
|
|
4
|
-
|
|
5
|
-
export interface INSABoxOTPProps extends IBaseComponentProps
|
|
6
|
-
{
|
|
7
|
-
placeholder?: string;
|
|
8
|
-
defaultValue?: string;
|
|
9
|
-
onChanged?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function NSABoxOTP(props: INSABoxOTPProps)
|
|
13
|
-
{
|
|
14
|
-
let [state, setState] = useState("");
|
|
15
|
-
|
|
16
|
-
const [values, setValues] = useState<string[]>(Array(6).fill(''));
|
|
17
|
-
const inputsRef = useRef<(HTMLInputElement | null)[]>([]);
|
|
18
|
-
|
|
19
|
-
const handleChange = (index: number) => (event: ChangeEvent<HTMLInputElement>) =>
|
|
20
|
-
{
|
|
21
|
-
const newValue = event.target.value;
|
|
22
|
-
setState(state + newValue)
|
|
23
|
-
if (/^\d?$/.test(newValue))
|
|
24
|
-
{
|
|
25
|
-
const updatedValues = [...values];
|
|
26
|
-
updatedValues[index] = newValue;
|
|
27
|
-
setValues(updatedValues);
|
|
28
|
-
if (newValue && index < 5)
|
|
29
|
-
{
|
|
30
|
-
inputsRef.current[index + 1]?.focus();
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (props.onChanged)
|
|
34
|
-
props.onChanged(event);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const handleKeyDown = (index: number) => (event: React.KeyboardEvent<HTMLInputElement>) =>
|
|
38
|
-
{
|
|
39
|
-
if (event.key === 'Backspace' && !values[index] && index > 0)
|
|
40
|
-
{
|
|
41
|
-
inputsRef.current[index - 1]?.focus();
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<div id={props.id} className={`${Styles.nsa_input_parent} ${props.classList?.join(" ")}`} style={{ ...props.style, display: 'flex', gap: '10px' }}>
|
|
47
|
-
{
|
|
48
|
-
values.map((value, index) => (
|
|
49
|
-
<input
|
|
50
|
-
key={index + 10}
|
|
51
|
-
ref={el => inputsRef.current[index] = el}
|
|
52
|
-
type="text"
|
|
53
|
-
value={value}
|
|
54
|
-
onChange={handleChange(index)}
|
|
55
|
-
onKeyDown={handleKeyDown(index)}
|
|
56
|
-
maxLength={1}
|
|
57
|
-
style={{ width: '30px', textAlign: 'center' }}
|
|
58
|
-
className={Styles.nsa_otp_input}
|
|
59
|
-
/>
|
|
60
|
-
))
|
|
61
|
-
}
|
|
62
|
-
</div >
|
|
63
|
-
);
|
|
1
|
+
import Styles from './NSABoxOTP.module.css';
|
|
2
|
+
import { IBaseComponentProps } from 'namirasoft-site-react';
|
|
3
|
+
import React, { useState, ChangeEvent, useRef } from 'react';
|
|
4
|
+
|
|
5
|
+
export interface INSABoxOTPProps extends IBaseComponentProps
|
|
6
|
+
{
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
defaultValue?: string;
|
|
9
|
+
onChanged?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function NSABoxOTP(props: INSABoxOTPProps)
|
|
13
|
+
{
|
|
14
|
+
let [state, setState] = useState("");
|
|
15
|
+
|
|
16
|
+
const [values, setValues] = useState<string[]>(Array(6).fill(''));
|
|
17
|
+
const inputsRef = useRef<(HTMLInputElement | null)[]>([]);
|
|
18
|
+
|
|
19
|
+
const handleChange = (index: number) => (event: ChangeEvent<HTMLInputElement>) =>
|
|
20
|
+
{
|
|
21
|
+
const newValue = event.target.value;
|
|
22
|
+
setState(state + newValue)
|
|
23
|
+
if (/^\d?$/.test(newValue))
|
|
24
|
+
{
|
|
25
|
+
const updatedValues = [...values];
|
|
26
|
+
updatedValues[index] = newValue;
|
|
27
|
+
setValues(updatedValues);
|
|
28
|
+
if (newValue && index < 5)
|
|
29
|
+
{
|
|
30
|
+
inputsRef.current[index + 1]?.focus();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (props.onChanged)
|
|
34
|
+
props.onChanged(event);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const handleKeyDown = (index: number) => (event: React.KeyboardEvent<HTMLInputElement>) =>
|
|
38
|
+
{
|
|
39
|
+
if (event.key === 'Backspace' && !values[index] && index > 0)
|
|
40
|
+
{
|
|
41
|
+
inputsRef.current[index - 1]?.focus();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div id={props.id} className={`${Styles.nsa_input_parent} ${props.classList?.join(" ")}`} style={{ ...props.style, display: 'flex', gap: '10px' }}>
|
|
47
|
+
{
|
|
48
|
+
values.map((value, index) => (
|
|
49
|
+
<input
|
|
50
|
+
key={index + 10}
|
|
51
|
+
ref={el => inputsRef.current[index] = el}
|
|
52
|
+
type="text"
|
|
53
|
+
value={value}
|
|
54
|
+
onChange={handleChange(index)}
|
|
55
|
+
onKeyDown={handleKeyDown(index)}
|
|
56
|
+
maxLength={1}
|
|
57
|
+
style={{ width: '30px', textAlign: 'center' }}
|
|
58
|
+
className={Styles.nsa_otp_input}
|
|
59
|
+
/>
|
|
60
|
+
))
|
|
61
|
+
}
|
|
62
|
+
</div >
|
|
63
|
+
);
|
|
64
64
|
}
|
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
.nsa_message_icon {
|
|
2
|
-
cursor: pointer;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
.nsa_message_title {
|
|
6
|
-
color: hsla(212, 100%, 51%, 1)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.nsa_message_item_title {
|
|
10
|
-
color: hsla(234, 64%, 22%, 1);
|
|
11
|
-
font-size: 16px;
|
|
12
|
-
font-weight: 600;
|
|
13
|
-
text-align: left;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.nsa_message_item_content {
|
|
17
|
-
color: hsla(234, 64%, 22%, 1);
|
|
18
|
-
margin: 0;
|
|
19
|
-
text-align: left;
|
|
20
|
-
overflow: hidden;
|
|
21
|
-
text-overflow: ellipsis;
|
|
22
|
-
white-space: nowrap;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.nsa_message_item_ul {
|
|
26
|
-
padding-left: 16px !important;
|
|
27
|
-
margin-bottom: 8px;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.nsa_message_item_ul li::marker {
|
|
31
|
-
color: hsla(157, 94%, 42%, 1);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.nsa_message_item_dot_green {
|
|
35
|
-
width: 8px;
|
|
36
|
-
height: 8px;
|
|
37
|
-
background: hsla(157, 94%, 42%, 1);
|
|
38
|
-
border-radius: 50%;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.nsa_message_item_dot_gray {
|
|
42
|
-
width: 8px;
|
|
43
|
-
height: 8px;
|
|
44
|
-
background: hsla(228, 9%, 66%, 1);
|
|
45
|
-
border-radius: 50%;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.nsa_body_green {
|
|
49
|
-
background-color: hsla(157, 94%, 42%, 0.1);
|
|
50
|
-
padding: 16px;
|
|
51
|
-
cursor: pointer !important;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.nsa_body_gray {
|
|
55
|
-
background-color: #fff;
|
|
56
|
-
padding: 16px;
|
|
57
|
-
box-shadow: 0px 2px 5px #e6e6e6;
|
|
58
|
-
cursor: pointer !important;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.nsa_count {
|
|
62
|
-
position: absolute;
|
|
63
|
-
background: rgba(3, 119, 255, 1);
|
|
64
|
-
right: -5px;
|
|
65
|
-
top: -5px;
|
|
66
|
-
color: #fff;
|
|
67
|
-
width: 18px;
|
|
68
|
-
height: 18px;
|
|
69
|
-
border-radius: 50%;
|
|
70
|
-
display: flex;
|
|
71
|
-
justify-content: center;
|
|
72
|
-
align-items: center;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.nsa_parent_count {
|
|
76
|
-
position: relative;
|
|
77
|
-
width: max-content;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.nsa_toast_body {
|
|
81
|
-
padding: 0 !important;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.nsa_toast_header {
|
|
85
|
-
padding: 2px !important;
|
|
86
|
-
display: flex;
|
|
87
|
-
justify-content: space-between !important;
|
|
88
|
-
align-items: center;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.nsa_toast div {
|
|
93
|
-
cursor: auto;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.nsa_close_icon {
|
|
97
|
-
cursor: pointer;
|
|
1
|
+
.nsa_message_icon {
|
|
2
|
+
cursor: pointer;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.nsa_message_title {
|
|
6
|
+
color: hsla(212, 100%, 51%, 1)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.nsa_message_item_title {
|
|
10
|
+
color: hsla(234, 64%, 22%, 1);
|
|
11
|
+
font-size: 16px;
|
|
12
|
+
font-weight: 600;
|
|
13
|
+
text-align: left;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.nsa_message_item_content {
|
|
17
|
+
color: hsla(234, 64%, 22%, 1);
|
|
18
|
+
margin: 0;
|
|
19
|
+
text-align: left;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
text-overflow: ellipsis;
|
|
22
|
+
white-space: nowrap;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.nsa_message_item_ul {
|
|
26
|
+
padding-left: 16px !important;
|
|
27
|
+
margin-bottom: 8px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.nsa_message_item_ul li::marker {
|
|
31
|
+
color: hsla(157, 94%, 42%, 1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.nsa_message_item_dot_green {
|
|
35
|
+
width: 8px;
|
|
36
|
+
height: 8px;
|
|
37
|
+
background: hsla(157, 94%, 42%, 1);
|
|
38
|
+
border-radius: 50%;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.nsa_message_item_dot_gray {
|
|
42
|
+
width: 8px;
|
|
43
|
+
height: 8px;
|
|
44
|
+
background: hsla(228, 9%, 66%, 1);
|
|
45
|
+
border-radius: 50%;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.nsa_body_green {
|
|
49
|
+
background-color: hsla(157, 94%, 42%, 0.1);
|
|
50
|
+
padding: 16px;
|
|
51
|
+
cursor: pointer !important;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.nsa_body_gray {
|
|
55
|
+
background-color: #fff;
|
|
56
|
+
padding: 16px;
|
|
57
|
+
box-shadow: 0px 2px 5px #e6e6e6;
|
|
58
|
+
cursor: pointer !important;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.nsa_count {
|
|
62
|
+
position: absolute;
|
|
63
|
+
background: rgba(3, 119, 255, 1);
|
|
64
|
+
right: -5px;
|
|
65
|
+
top: -5px;
|
|
66
|
+
color: #fff;
|
|
67
|
+
width: 18px;
|
|
68
|
+
height: 18px;
|
|
69
|
+
border-radius: 50%;
|
|
70
|
+
display: flex;
|
|
71
|
+
justify-content: center;
|
|
72
|
+
align-items: center;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.nsa_parent_count {
|
|
76
|
+
position: relative;
|
|
77
|
+
width: max-content;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.nsa_toast_body {
|
|
81
|
+
padding: 0 !important;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.nsa_toast_header {
|
|
85
|
+
padding: 2px !important;
|
|
86
|
+
display: flex;
|
|
87
|
+
justify-content: space-between !important;
|
|
88
|
+
align-items: center;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
.nsa_toast div {
|
|
93
|
+
cursor: auto;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.nsa_close_icon {
|
|
97
|
+
cursor: pointer;
|
|
98
98
|
}
|