@visns-studio/visns-components 4.4.0 → 4.4.2

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.
@@ -1,4 +1,5 @@
1
1
  // src/components/Profile.jsx
2
+ import '../../styles/global.css';
2
3
 
3
4
  import React, { useState, useEffect, useRef } from 'react';
4
5
  import PasswordStrengthBar from 'react-password-strength-bar';
@@ -129,7 +130,7 @@ const Profile = ({ userProfile, setUserProfile }) => {
129
130
  type="text"
130
131
  name="name"
131
132
  onChange={handleChangeProfile}
132
- className={inputClasses.name}
133
+ className={`${styles.input} ${inputClasses.name}`}
133
134
  value={profile.name}
134
135
  />
135
136
  <span className={styles.fi__span}>
@@ -143,7 +144,7 @@ const Profile = ({ userProfile, setUserProfile }) => {
143
144
  type="text"
144
145
  name="email"
145
146
  readOnly
146
- className={inputClasses.email}
147
+ className={`${styles.input} ${inputClasses.email}`}
147
148
  value={profile.email}
148
149
  />
149
150
  <span className={styles.fi__span}>
@@ -163,7 +164,7 @@ const Profile = ({ userProfile, setUserProfile }) => {
163
164
  name="password"
164
165
  onChange={handleChangeProfile}
165
166
  value={profile.password}
166
- className={inputClasses.password}
167
+ className={`${styles.input} ${inputClasses.password}`}
167
168
  />
168
169
  <PasswordStrengthBar
169
170
  password={profile.password}
@@ -182,9 +183,7 @@ const Profile = ({ userProfile, setUserProfile }) => {
182
183
  name="password_confirmation"
183
184
  onChange={handleChangeProfile}
184
185
  value={profile.password_confirmation}
185
- className={
186
- inputClasses.password_confirmation
187
- }
186
+ className={`${styles.input} ${inputClasses.password_confirmation}`}
188
187
  />
189
188
  </label>
190
189
  </div>
@@ -1,5 +1,16 @@
1
1
  /* Profile.module.css */
2
2
 
3
+ input:not(:placeholder-shown) + .fi__span,
4
+ textarea:not(:placeholder-shown) + .fi__span,
5
+ select:not(:placeholder-shown) + .fi__span {
6
+ transform: translateY(-40%) translateX(10px) scale(0.75);
7
+ opacity: 1;
8
+ padding: 0 4px;
9
+ background: var(--tertiary-color);
10
+ font-weight: 300;
11
+ border-radius: var(--br);
12
+ }
13
+
3
14
  .grid {
4
15
  width: 100%;
5
16
  display: flex;
@@ -136,8 +147,9 @@
136
147
  z-index: 500;
137
148
  }
138
149
 
139
- input[type='text'],
140
- input[type='password'] {
150
+ .input,
151
+ .textarea,
152
+ .select {
141
153
  background: var(--item-color);
142
154
  border-radius: var(--br);
143
155
  border: 1px solid transparent;
@@ -149,28 +161,19 @@ input[type='password'] {
149
161
  transition: box-shadow 0.15s linear;
150
162
  }
151
163
 
152
- input[type='text']:hover,
153
- input[type='password']:hover {
164
+ .input:hover,
165
+ .textarea:hover,
166
+ .select:hover {
154
167
  border: 1px solid rgba(var(--highlight-color-rgb), 0.85);
155
168
  transition: border 0.15s linear;
156
169
  }
157
170
 
158
- input[type='text']:focus,
159
- input[type='password']:focus {
171
+ .input:focus,
172
+ .textarea:focus,
173
+ .select:focus {
160
174
  border: 1px solid rgba(var(--highlight-color-rgb), 0.85);
161
175
  }
162
176
 
163
- input:not(:placeholder-shown) + .fi__span,
164
- textarea:not(:placeholder-shown) + .fi__span,
165
- select:not(:placeholder-shown) + .fi__span {
166
- transform: translateY(-40%) translateX(10px) scale(0.75);
167
- opacity: 1;
168
- padding: 0 4px;
169
- background: var(--tertiary-color);
170
- font-weight: 300;
171
- border-radius: var(--br);
172
- }
173
-
174
177
  .sigcanvas {
175
178
  border: 2px solid #ccc;
176
179
  border-radius: 10px;
@@ -229,6 +229,11 @@ function GenericDetail({ extraUrlParam, setting, urlParam, userProfile }) {
229
229
 
230
230
  const renderBoolean = () => (value ? 'Yes' : 'No');
231
231
 
232
+ const renderCheckbox = (value) => {
233
+ const keys = Object.keys(value).filter((key) => value[key]);
234
+ return keys.join(', ');
235
+ };
236
+
232
237
  const renderDate = () => formatDateValue(value);
233
238
 
234
239
  const renderDateTime = () => formatDateTimeValue(value);
@@ -276,6 +281,8 @@ function GenericDetail({ extraUrlParam, setting, urlParam, userProfile }) {
276
281
  switch (type) {
277
282
  case 'boolean':
278
283
  return renderBoolean();
284
+ case 'checkbox':
285
+ return renderCheckbox();
279
286
  case 'copyToClipboard':
280
287
  return renderCopyToClipboard();
281
288
  case 'date':
@@ -2,12 +2,15 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { Outlet } from 'react-router-dom';
3
3
  import { toast } from 'react-toastify';
4
4
  import { saveAs } from 'file-saver';
5
+ import _ from 'lodash';
6
+
5
7
  import CustomFetch from '../Fetch';
6
8
  import Download from '../Download';
7
9
  import Field from '../Field';
8
10
  import Table from '../DataGrid';
9
11
  import TableFilter from '../TableFilter';
10
- import _ from 'lodash';
12
+
13
+ import styles from './styles/GenericIndex.module.css';
11
14
 
12
15
  function useWindowHeight() {
13
16
  const [windowHeight, setWindowHeight] = useState(window.innerHeight);
@@ -234,11 +237,11 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
234
237
  const renderContent = useCallback(() => {
235
238
  if (subnav?.length > 0) {
236
239
  return (
237
- <div className="grid__subrow">
240
+ <div className={styles.grid__subrow}>
238
241
  {layout === 'simple' ? (
239
- <div className={`grid__full`}>
240
- <div className="tabcontent">
241
- <div className="tabcontent__menu">
242
+ <div className={styles.grid__full}>
243
+ <div className={styles.tabcontent}>
244
+ <div className={styles.tabcontent__menu}>
242
245
  <TableFilter
243
246
  filters={subnav}
244
247
  setFilters={setSubnav}
@@ -246,14 +249,14 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
246
249
  type={layout}
247
250
  />
248
251
  </div>
249
- <div className="tabcontent__main">
252
+ <div className={styles.tabcontent__main}>
250
253
  {renderContentBasedOnType()}
251
254
  </div>
252
255
  </div>
253
256
  </div>
254
257
  ) : (
255
258
  <>
256
- <div className={`grid__subnav`}>
259
+ <div className={styles.grid__subnav}>
257
260
  <TableFilter
258
261
  filters={subnav}
259
262
  setFilters={setSubnav}
@@ -261,7 +264,7 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
261
264
  type={layout}
262
265
  />
263
266
  </div>
264
- <div className="grid__subcontent">
267
+ <div className={styles.grid__subcontent}>
265
268
  {renderContentBasedOnType()}
266
269
  </div>
267
270
  </>
@@ -277,9 +280,9 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
277
280
 
278
281
  return (
279
282
  <>
280
- <div className="grid">
281
- <div className="grid__row">
282
- <div className="grid__full crmtitle">
283
+ <div className={styles.grid}>
284
+ <div className={styles.grid__row}>
285
+ <div className={`${styles.grid__full} ${styles.crmtitle}`}>
283
286
  <h1>{setting.page?.title}</h1>
284
287
  <div className="titleInfo">
285
288
  <span>
@@ -291,11 +294,14 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
291
294
  </div>
292
295
  </div>
293
296
 
294
- <div className="grid">{renderContent()}</div>
297
+ <div className={styles.grid}>{renderContent()}</div>
295
298
  <Outlet />
296
299
  {setting.functions?.checkboxUpdate && (
297
- <div className="polActions">
298
- <button className="btn" onClick={handleCheckboxUpdate}>
300
+ <div className={styles.polActions}>
301
+ <button
302
+ className={styles.btn}
303
+ onClick={handleCheckboxUpdate}
304
+ >
299
305
  {setting.functions.checkboxUpdate.label || 'Update'}
300
306
  </button>
301
307
  </div>
@@ -0,0 +1,232 @@
1
+ .grid {
2
+ &__row {
3
+ width: 100%;
4
+ display: flex;
5
+ align-items: flex-start;
6
+ flex-wrap: nowrap;
7
+ height: auto;
8
+ gap: 1rem;
9
+ }
10
+
11
+ &__three {
12
+ width: 33%;
13
+ background: var(--item-color);
14
+ border-radius: var(--br);
15
+ border: 1px solid rgba(var(--item-color-rgb), 1.15);
16
+ box-sizing: border-box;
17
+ overflow: visible;
18
+ position: relative;
19
+ padding: 20px;
20
+ margin: 8px 0;
21
+ box-shadow: 0 4px 0 rgba(var(--primary-color-rgb), 0.05);
22
+ }
23
+
24
+ &__half {
25
+ width: 50%;
26
+ background: var(--item-color);
27
+ border-radius: 6px;
28
+ border: 1px solid #dadce0;
29
+ box-sizing: border-box;
30
+ overflow: visible;
31
+ position: relative;
32
+ padding: 20px;
33
+ margin: 8px 0;
34
+ box-shadow: 0 4px 0 rgba(var(--primary-color), 0.05);
35
+ }
36
+
37
+ &__full {
38
+ width: 100%;
39
+ background: var(--item-color);
40
+ border-radius: var(--br);
41
+ border: 1px solid rgba(var(--item-color-rgb), 1.15);
42
+ box-sizing: border-box;
43
+ overflow: visible;
44
+ position: relative;
45
+ padding: 2px;
46
+ margin: 8px 0;
47
+ box-shadow: 0 4px 0 rgba(var(--primary-color-rgb), 0.05);
48
+ }
49
+
50
+ &__dashfull {
51
+ width: 100%;
52
+ background: var(--item-color);
53
+ border-radius: 6px;
54
+ border: 1px solid #dadce0;
55
+ box-sizing: border-box;
56
+ overflow: visible;
57
+ position: relative;
58
+ padding: 20px;
59
+ margin: 8px 0;
60
+ box-shadow: 0 4px 0 rgba(var(--primary-color-rgb), 0.05);
61
+ }
62
+
63
+ &__subrow {
64
+ width: 100%;
65
+ display: flex;
66
+ flex-wrap: wrap;
67
+ height: auto;
68
+ gap: 0.5rem;
69
+ }
70
+
71
+ &__subnav {
72
+ flex: 1;
73
+ background: rgba(var(--item-color-rgb), 1.01);
74
+ border-radius: var(--br);
75
+ border: 1px solid rgba(var(--item-color-rgb), 1.15);
76
+ box-sizing: border-box;
77
+ padding: 5px;
78
+ margin: 8px 0;
79
+ height: auto;
80
+ box-shadow: 0 4px 0 rgba(var(--primary-color-rgb), 0.05);
81
+
82
+ > ul {
83
+ width: 100%;
84
+ list-style: none;
85
+ padding: 0;
86
+ margin: 0;
87
+ display: flex;
88
+ flex-wrap: wrap;
89
+
90
+ li {
91
+ width: 100%;
92
+ margin-bottom: 3px;
93
+
94
+ a {
95
+ width: 100%;
96
+ padding: 8px 20px;
97
+ box-sizing: border-box;
98
+ display: block;
99
+ text-decoration: none;
100
+ background: rgba(var(--primary-color-rgb), 0.05);
101
+ color: var(--primary-color);
102
+ border-radius: 5px;
103
+ transition: background 0.25s
104
+ cubic-bezier(0.25, 0.8, 0.25, 1);
105
+ outline: none;
106
+ cursor: pointer;
107
+ }
108
+
109
+ &:hover {
110
+ a {
111
+ background: var(--primary-color);
112
+ color: var(--tertiary-color);
113
+ }
114
+ }
115
+
116
+ .subactive {
117
+ font-weight: 700;
118
+ background: var(--primary-color);
119
+ color: var(--tertiary-color);
120
+ }
121
+ }
122
+ }
123
+ }
124
+
125
+ &__minheight {
126
+ min-height: 300px;
127
+ }
128
+
129
+ .noborder {
130
+ border: none !important;
131
+ }
132
+
133
+ &__subcontent {
134
+ flex: 0 1 80%;
135
+ background: var(--item-color);
136
+ border-radius: var(--br);
137
+ border: 1px solid rgba(var(--item-color-rgb), 1.15);
138
+ box-sizing: border-box;
139
+ padding: 2px;
140
+ margin: 8px 0;
141
+ height: auto;
142
+ position: relative;
143
+ box-shadow: 0 4px 0 rgba(var(--primary-color-rgb), 0.05);
144
+
145
+ h2 {
146
+ color: var(--primary-color);
147
+ font-size: 1.35em;
148
+ padding: 0;
149
+ margin: 0 0 30px 0;
150
+ }
151
+ }
152
+ }
153
+
154
+ .crmtitle {
155
+ border: none;
156
+ min-height: auto;
157
+ padding: 10px 20px;
158
+ margin: 0;
159
+ background: var(--tertiary-color);
160
+ border-radius: var(--br);
161
+ border: 1px solid rgba(var(--item-color-rgb), 1.15);
162
+ position: relative;
163
+
164
+ h1 {
165
+ font-weight: 700;
166
+ font-size: 1.45em;
167
+ margin: 0;
168
+ padding: 0.65rem 0;
169
+
170
+ a {
171
+ text-decoration: none;
172
+ color: rgba(var(--secondary-color-rgb), 1.1);
173
+ font-weight: 300;
174
+ }
175
+
176
+ svg {
177
+ color: rgba(var(--primary-color-rgb), 0.25);
178
+ position: relative;
179
+ top: 2px;
180
+ margin: 0 0.25rem;
181
+ }
182
+ }
183
+ }
184
+
185
+ .titleInfo {
186
+ position: absolute;
187
+ right: 2em;
188
+ top: 24px;
189
+
190
+ span {
191
+ font-size: 0.875em;
192
+ color: rgba(var(--paragraph-color-rgb), 0.65);
193
+ }
194
+ }
195
+
196
+ .btn {
197
+ width: max-content;
198
+ display: inline-block;
199
+ position: relative;
200
+ padding: 0.65rem 1rem;
201
+ cursor: pointer;
202
+ font-size: 1rem;
203
+ color: var(--tertiary-color);
204
+ text-decoration: none;
205
+ overflow: hidden;
206
+ background: var(--primary-color);
207
+ border: 1px solid rgba(var(--primary-color--rgb), 1.1);
208
+ border-radius: var(--br);
209
+ outline: none;
210
+ transition: all 0.2s cubic-bezier(0.85, 0, 0.15, 1) 0s;
211
+ font-size: 1.25em;
212
+
213
+ &:hover {
214
+ color: var(--primary-color);
215
+ background: var(--highlight-color);
216
+ border: 1px solid rgba(var(--highlight-color-rgb), 1.05);
217
+ }
218
+ }
219
+
220
+ .polActions {
221
+ position: fixed;
222
+ bottom: 15px;
223
+ right: 20px;
224
+ width: auto;
225
+
226
+ button {
227
+ display: block;
228
+ float: left;
229
+ padding: 0.35em 1em;
230
+ margin: 0 0.15em;
231
+ }
232
+ }
@@ -0,0 +1,12 @@
1
+ .visns__ms {
2
+ input {
3
+ &:hover {
4
+ box-shadow: none !important;
5
+ transition: box-shadow 0.15s linear !important;
6
+ }
7
+
8
+ &:focus {
9
+ box-shadow: none !important;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,44 @@
1
+ .AutocompletePlace-results {
2
+ z-index: 999;
3
+ }
4
+
5
+ .AutocompletePlace {
6
+ position: relative;
7
+
8
+ > svg {
9
+ position: absolute;
10
+ right: 0.5em;
11
+ top: 0.5em;
12
+ color: var(--primary-color);
13
+ cursor: pointer;
14
+ }
15
+ }
16
+
17
+ .AutocompletePlace.toggleActive {
18
+ color: var(--highlight-color);
19
+ }
20
+
21
+ .AutocompletePlace-input {
22
+ padding: 0.65rem 3rem 0.65rem 0.95rem !important;
23
+ }
24
+
25
+ .AutocompletePlace-results {
26
+ position: absolute;
27
+ background-color: white;
28
+ padding: 0;
29
+ margin: 0;
30
+ border: 1px solid rgba(var(--primary-color-rgb), 0.25);
31
+ border-radius: var(--br);
32
+ overflow: hidden;
33
+ }
34
+
35
+ .AutocompletePlace-items {
36
+ list-style: none;
37
+ border-bottom: 1px solid rgba(var(--primary-color-rgb), 0.1);
38
+ cursor: pointer;
39
+ padding: 10px 10px;
40
+
41
+ &:hover {
42
+ background-color: rgba(var(--primary-color-rgb), 0.065);
43
+ }
44
+ }