@visns-studio/visns-components 5.6.7 → 5.6.9
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/package.json +1 -1
- package/src/components/crm/TableFilter.jsx +287 -102
- package/src/components/crm/auth/Login.jsx +51 -39
- package/src/components/crm/auth/Reset.jsx +11 -5
- package/src/components/crm/auth/TwoFactorAuth.jsx +7 -9
- package/src/components/crm/auth/Verify.jsx +11 -5
- package/src/components/crm/auth/styles/Login.module.scss +110 -39
- package/src/components/crm/auth/styles/Reset.module.scss +51 -46
- package/src/components/crm/auth/styles/TwoFactorAuth.module.scss +154 -25
- package/src/components/crm/auth/styles/Verify.module.scss +51 -46
- package/src/components/crm/examples/FilterExample.jsx +207 -0
- package/src/components/crm/examples/README.md +113 -0
- package/src/components/crm/generic/GenericIndex.jsx +244 -87
- package/src/components/crm/generic/styles/ReportForm.module.scss +150 -0
- package/src/components/crm/styles/TableFilter.module.scss +121 -23
|
@@ -1,47 +1,176 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
.formItem {
|
|
2
|
+
width: 100%;
|
|
3
|
+
position: relative;
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
margin-bottom: 1rem;
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
.fi__label {
|
|
8
|
+
position: relative;
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.fi__span {
|
|
14
|
+
position: absolute;
|
|
15
|
+
transition: all 200ms;
|
|
16
|
+
opacity: 0.7;
|
|
17
|
+
left: 0;
|
|
18
|
+
transform-origin: top left;
|
|
19
|
+
cursor: text;
|
|
20
|
+
padding: 0 1rem;
|
|
21
|
+
font-size: 0.9rem;
|
|
22
|
+
color: #6b7280;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
input[name='verificationCode'] {
|
|
26
|
+
letter-spacing: 0.25rem;
|
|
27
|
+
font-size: 1.2rem;
|
|
28
|
+
text-align: center;
|
|
29
|
+
}
|
|
11
30
|
}
|
|
12
31
|
|
|
13
|
-
.
|
|
14
|
-
|
|
15
|
-
|
|
32
|
+
.fwItem,
|
|
33
|
+
.fwBuilderItem {
|
|
34
|
+
grid-column: 1 / -1;
|
|
35
|
+
width: 100%;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.lastItem .btn {
|
|
39
|
+
width: 100%;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.loginlogo {
|
|
43
|
+
display: block;
|
|
44
|
+
width: 100%;
|
|
45
|
+
max-width: 150px;
|
|
46
|
+
height: auto;
|
|
47
|
+
margin: 0 auto;
|
|
48
|
+
padding-bottom: 1.5rem;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.logincontainer {
|
|
52
|
+
width: 100%;
|
|
53
|
+
min-height: 100vh;
|
|
54
|
+
display: grid;
|
|
55
|
+
place-items: center;
|
|
16
56
|
padding: 1rem;
|
|
57
|
+
background-color: #f9fafb;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.login {
|
|
61
|
+
width: 28rem;
|
|
62
|
+
padding: 2rem;
|
|
17
63
|
margin: 0;
|
|
18
64
|
display: grid;
|
|
19
65
|
grid-template-columns: 1fr;
|
|
20
|
-
gap:
|
|
66
|
+
gap: 1rem;
|
|
67
|
+
background-color: white;
|
|
68
|
+
border-radius: 0.75rem;
|
|
69
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
|
70
|
+
0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
71
|
+
|
|
72
|
+
> .formItem {
|
|
73
|
+
padding: 0;
|
|
74
|
+
|
|
75
|
+
small {
|
|
76
|
+
position: absolute;
|
|
77
|
+
width: 18px;
|
|
78
|
+
height: 18px;
|
|
79
|
+
right: 14px;
|
|
80
|
+
top: 14px;
|
|
81
|
+
opacity: 0.4;
|
|
82
|
+
color: #6b7280;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
21
85
|
|
|
22
86
|
h2 {
|
|
23
87
|
text-align: center;
|
|
24
|
-
margin: 0;
|
|
25
|
-
color:
|
|
88
|
+
margin-bottom: 0.5rem;
|
|
89
|
+
color: #111827;
|
|
90
|
+
font-weight: 600;
|
|
91
|
+
font-size: 1.5rem;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.instructions {
|
|
96
|
+
text-align: center;
|
|
97
|
+
margin: 0 0 1.5rem;
|
|
98
|
+
color: var(--paragraph-color, #6b7280);
|
|
99
|
+
font-size: 0.95rem;
|
|
100
|
+
line-height: 1.4;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.forgotten span {
|
|
104
|
+
display: block;
|
|
105
|
+
text-align: center;
|
|
106
|
+
color: #6b7280;
|
|
107
|
+
padding: 1rem 0;
|
|
108
|
+
font-size: 0.875rem;
|
|
109
|
+
|
|
110
|
+
a {
|
|
111
|
+
color: var(--primary-color, #4f46e5);
|
|
112
|
+
text-decoration: none;
|
|
26
113
|
font-weight: 500;
|
|
114
|
+
|
|
115
|
+
&:hover {
|
|
116
|
+
text-decoration: underline;
|
|
117
|
+
}
|
|
27
118
|
}
|
|
28
119
|
}
|
|
29
120
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
121
|
+
.lcontainer {
|
|
122
|
+
min-height: 100vh;
|
|
123
|
+
display: flex;
|
|
124
|
+
align-items: center;
|
|
125
|
+
justify-content: center;
|
|
126
|
+
background-color: #f9fafb;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.lwrap {
|
|
130
|
+
display: grid;
|
|
131
|
+
grid-template-columns: 1fr;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.btn {
|
|
135
|
+
width: max-content;
|
|
136
|
+
display: inline-block;
|
|
34
137
|
position: relative;
|
|
35
|
-
|
|
36
|
-
|
|
138
|
+
padding: 0.75rem 1rem;
|
|
139
|
+
cursor: pointer;
|
|
140
|
+
font-size: 0.875rem;
|
|
141
|
+
font-weight: 500;
|
|
142
|
+
color: white;
|
|
143
|
+
text-decoration: none;
|
|
144
|
+
overflow: hidden;
|
|
145
|
+
background: var(--primary-color, #4f46e5);
|
|
146
|
+
border: 1px solid var(--primary-color, #4f46e5);
|
|
147
|
+
border-radius: 0.5rem;
|
|
148
|
+
outline: none;
|
|
149
|
+
transition: all 0.2s ease;
|
|
150
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
37
151
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
152
|
+
&:hover {
|
|
153
|
+
background: #4338ca;
|
|
154
|
+
border-color: #4338ca;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
&:focus {
|
|
158
|
+
box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.25);
|
|
42
159
|
}
|
|
43
160
|
}
|
|
44
161
|
|
|
162
|
+
input:not(:placeholder-shown) + .fi__span,
|
|
163
|
+
textarea:not(:placeholder-shown) + .fi__span,
|
|
164
|
+
select:not(:placeholder-shown) + .fi__span {
|
|
165
|
+
transform: translateY(-135%) translateX(10px) scale(0.85);
|
|
166
|
+
opacity: 1;
|
|
167
|
+
padding: 0;
|
|
168
|
+
background: white;
|
|
169
|
+
font-weight: 500;
|
|
170
|
+
transition: all 0.3s ease;
|
|
171
|
+
color: var(--primary-color, #4f46e5) !important;
|
|
172
|
+
}
|
|
173
|
+
|
|
45
174
|
.rememberMeIndicator {
|
|
46
175
|
display: flex;
|
|
47
176
|
align-items: center;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
.formItem {
|
|
2
|
-
width:
|
|
2
|
+
width: 100%;
|
|
3
3
|
position: relative;
|
|
4
4
|
box-sizing: border-box;
|
|
5
|
+
margin-bottom: 1rem;
|
|
5
6
|
|
|
6
7
|
h1 {
|
|
7
8
|
text-align: center;
|
|
8
|
-
font-size: 1.
|
|
9
|
+
font-size: 1.5rem;
|
|
10
|
+
font-weight: 600;
|
|
11
|
+
color: #111827;
|
|
12
|
+
margin-bottom: 1.5rem;
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
.fi__label {
|
|
@@ -17,11 +21,13 @@
|
|
|
17
21
|
.fi__span {
|
|
18
22
|
position: absolute;
|
|
19
23
|
transition: all 200ms;
|
|
20
|
-
opacity: 0.
|
|
24
|
+
opacity: 0.7;
|
|
21
25
|
left: 0;
|
|
22
26
|
transform-origin: top left;
|
|
23
27
|
cursor: text;
|
|
24
28
|
padding: 0 1rem;
|
|
29
|
+
font-size: 0.9rem;
|
|
30
|
+
color: #6b7280;
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
.fi__div {
|
|
@@ -29,8 +35,8 @@
|
|
|
29
35
|
opacity: 0.8;
|
|
30
36
|
left: 0;
|
|
31
37
|
padding: 19px 13px;
|
|
32
|
-
border-radius:
|
|
33
|
-
border: 1px solid
|
|
38
|
+
border-radius: 0.5rem;
|
|
39
|
+
border: 1px solid #e5e7eb;
|
|
34
40
|
box-shadow: none;
|
|
35
41
|
}
|
|
36
42
|
|
|
@@ -64,29 +70,10 @@
|
|
|
64
70
|
.loginlogo {
|
|
65
71
|
display: block;
|
|
66
72
|
width: 100%;
|
|
67
|
-
max-width:
|
|
73
|
+
max-width: 150px;
|
|
68
74
|
height: auto;
|
|
69
75
|
margin: 0 auto;
|
|
70
|
-
padding-bottom:
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.logincontainer {
|
|
74
|
-
min-height: 100vh;
|
|
75
|
-
flex-grow: 1;
|
|
76
|
-
display: flex;
|
|
77
|
-
align-items: center;
|
|
78
|
-
justify-content: center;
|
|
79
|
-
align-content: center;
|
|
80
|
-
flex-wrap: wrap;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.loginlogo {
|
|
84
|
-
display: block;
|
|
85
|
-
width: 100%;
|
|
86
|
-
max-width: 200px;
|
|
87
|
-
height: auto;
|
|
88
|
-
margin: 0 auto;
|
|
89
|
-
padding-bottom: 1rem;
|
|
76
|
+
padding-bottom: 1.5rem;
|
|
90
77
|
}
|
|
91
78
|
|
|
92
79
|
.logincontainer {
|
|
@@ -95,15 +82,20 @@
|
|
|
95
82
|
display: grid;
|
|
96
83
|
place-items: center;
|
|
97
84
|
padding: 1rem;
|
|
85
|
+
background-color: #f9fafb;
|
|
98
86
|
}
|
|
99
87
|
|
|
100
88
|
.login {
|
|
101
|
-
width:
|
|
102
|
-
padding:
|
|
89
|
+
width: 28rem;
|
|
90
|
+
padding: 2rem;
|
|
103
91
|
margin: 0;
|
|
104
92
|
display: grid;
|
|
105
93
|
grid-template-columns: 1fr;
|
|
106
|
-
gap:
|
|
94
|
+
gap: 1rem;
|
|
95
|
+
background-color: white;
|
|
96
|
+
border-radius: 0.75rem;
|
|
97
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
|
98
|
+
0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
107
99
|
|
|
108
100
|
> .formItem {
|
|
109
101
|
padding: 0;
|
|
@@ -112,9 +104,10 @@
|
|
|
112
104
|
position: absolute;
|
|
113
105
|
width: 18px;
|
|
114
106
|
height: 18px;
|
|
115
|
-
right:
|
|
116
|
-
top:
|
|
117
|
-
opacity: 0.
|
|
107
|
+
right: 14px;
|
|
108
|
+
top: 14px;
|
|
109
|
+
opacity: 0.4;
|
|
110
|
+
color: #6b7280;
|
|
118
111
|
}
|
|
119
112
|
}
|
|
120
113
|
|
|
@@ -149,11 +142,12 @@
|
|
|
149
142
|
display: flex;
|
|
150
143
|
align-items: center;
|
|
151
144
|
justify-content: center;
|
|
145
|
+
background-color: #f9fafb;
|
|
152
146
|
}
|
|
153
147
|
|
|
154
148
|
.lwrap {
|
|
155
149
|
display: grid;
|
|
156
|
-
grid-template-columns:
|
|
150
|
+
grid-template-columns: 1fr;
|
|
157
151
|
}
|
|
158
152
|
|
|
159
153
|
.aside {
|
|
@@ -168,27 +162,38 @@
|
|
|
168
162
|
width: max-content;
|
|
169
163
|
display: inline-block;
|
|
170
164
|
position: relative;
|
|
171
|
-
padding: 0.
|
|
165
|
+
padding: 0.75rem 1rem;
|
|
172
166
|
cursor: pointer;
|
|
173
|
-
font-size:
|
|
174
|
-
|
|
167
|
+
font-size: 0.875rem;
|
|
168
|
+
font-weight: 500;
|
|
169
|
+
color: white;
|
|
175
170
|
text-decoration: none;
|
|
176
171
|
overflow: hidden;
|
|
177
|
-
background: var(--primary-color);
|
|
178
|
-
border: 1px solid
|
|
179
|
-
border-radius:
|
|
172
|
+
background: var(--primary-color, #4f46e5);
|
|
173
|
+
border: 1px solid var(--primary-color, #4f46e5);
|
|
174
|
+
border-radius: 0.5rem;
|
|
180
175
|
outline: none;
|
|
181
|
-
transition: all 0.2s
|
|
182
|
-
|
|
176
|
+
transition: all 0.2s ease;
|
|
177
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
178
|
+
|
|
179
|
+
&:hover {
|
|
180
|
+
background: #4338ca;
|
|
181
|
+
border-color: #4338ca;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
&:focus {
|
|
185
|
+
box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.25);
|
|
186
|
+
}
|
|
183
187
|
}
|
|
184
188
|
|
|
185
189
|
input:not(:placeholder-shown) + .fi__span,
|
|
186
190
|
textarea:not(:placeholder-shown) + .fi__span,
|
|
187
191
|
select:not(:placeholder-shown) + .fi__span {
|
|
188
|
-
transform: translateY(-
|
|
192
|
+
transform: translateY(-135%) translateX(10px) scale(0.85);
|
|
189
193
|
opacity: 1;
|
|
190
194
|
padding: 0;
|
|
191
|
-
background:
|
|
192
|
-
font-weight:
|
|
193
|
-
transition: all 0.
|
|
194
|
-
|
|
195
|
+
background: white;
|
|
196
|
+
font-weight: 500;
|
|
197
|
+
transition: all 0.3s ease;
|
|
198
|
+
color: var(--primary-color, #4f46e5) !important;
|
|
199
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import TableFilter from '../TableFilter';
|
|
3
|
+
|
|
4
|
+
const FilterExample = () => {
|
|
5
|
+
// Initial filter structure with parent-child relationships
|
|
6
|
+
const initialFilters = [
|
|
7
|
+
{
|
|
8
|
+
id: "personnelLicensesAndRecords",
|
|
9
|
+
label: "Personnel Licenses and Records",
|
|
10
|
+
isParent: true,
|
|
11
|
+
show: false,
|
|
12
|
+
class: "",
|
|
13
|
+
children: [
|
|
14
|
+
{
|
|
15
|
+
id: "completedSiteInduction",
|
|
16
|
+
show: false,
|
|
17
|
+
label: "Completed Site Induction",
|
|
18
|
+
class: ""
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "unapprovedWhiteCard",
|
|
22
|
+
show: false,
|
|
23
|
+
label: "Unapproved White Card",
|
|
24
|
+
class: ""
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "unapprovedLicense",
|
|
28
|
+
show: false,
|
|
29
|
+
label: "Unapproved License",
|
|
30
|
+
class: ""
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "outstandingLicense",
|
|
34
|
+
show: false,
|
|
35
|
+
label: "Outstanding License",
|
|
36
|
+
class: ""
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "unapprovedCovid",
|
|
40
|
+
show: false,
|
|
41
|
+
label: "Unapproved COVID",
|
|
42
|
+
class: ""
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "insurance",
|
|
48
|
+
label: "Insurance",
|
|
49
|
+
isParent: true,
|
|
50
|
+
show: false,
|
|
51
|
+
class: "",
|
|
52
|
+
children: [
|
|
53
|
+
{
|
|
54
|
+
id: "allInsurance",
|
|
55
|
+
show: false,
|
|
56
|
+
label: "All Insurance",
|
|
57
|
+
class: ""
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "unapprovedInsurance",
|
|
61
|
+
show: false,
|
|
62
|
+
label: "Unapproved Insurance",
|
|
63
|
+
class: ""
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "expiredInsurance",
|
|
67
|
+
show: false,
|
|
68
|
+
label: "Expired Insurance",
|
|
69
|
+
class: ""
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: "outstandingInsurance",
|
|
73
|
+
show: false,
|
|
74
|
+
label: "Outstanding Insurance",
|
|
75
|
+
class: ""
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: "workingHours",
|
|
81
|
+
label: "Working Hours",
|
|
82
|
+
isParent: true,
|
|
83
|
+
show: false,
|
|
84
|
+
class: "",
|
|
85
|
+
children: [
|
|
86
|
+
{
|
|
87
|
+
id: "projectTotalHours",
|
|
88
|
+
show: false,
|
|
89
|
+
label: "Project Total Hours",
|
|
90
|
+
class: ""
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: "contractorTotalHours",
|
|
94
|
+
show: false,
|
|
95
|
+
label: "Contractor Total Hours",
|
|
96
|
+
class: ""
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: "sitePersonnelWorkHours",
|
|
100
|
+
show: false,
|
|
101
|
+
label: "Site Personnel Work Hours",
|
|
102
|
+
class: ""
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "sitePersonnelRecords",
|
|
106
|
+
show: false,
|
|
107
|
+
label: "Site Personnel Records",
|
|
108
|
+
class: ""
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "prequalifications",
|
|
114
|
+
label: "Prequalifications",
|
|
115
|
+
isParent: true,
|
|
116
|
+
show: false,
|
|
117
|
+
class: "",
|
|
118
|
+
children: [
|
|
119
|
+
{
|
|
120
|
+
id: "prequalificationsUnapproved",
|
|
121
|
+
show: false,
|
|
122
|
+
label: "Unapproved Prequalifications",
|
|
123
|
+
class: ""
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: "prequalificationsExpiring",
|
|
127
|
+
show: false,
|
|
128
|
+
label: "Expiring Prequalifications",
|
|
129
|
+
class: ""
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: "prequalifiedContractors",
|
|
133
|
+
show: false,
|
|
134
|
+
label: "Prequalified Contractors",
|
|
135
|
+
class: ""
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
const [filters, setFilters] = useState(initialFilters);
|
|
142
|
+
const [settings, setSettings] = useState({
|
|
143
|
+
ajaxSetting: {
|
|
144
|
+
where: []
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Find the active filter to display content
|
|
149
|
+
const getActiveFilter = () => {
|
|
150
|
+
let activeFilter = null;
|
|
151
|
+
|
|
152
|
+
// Check each parent filter
|
|
153
|
+
filters.forEach(parent => {
|
|
154
|
+
if (parent.children) {
|
|
155
|
+
// Check if any child is active
|
|
156
|
+
parent.children.forEach(child => {
|
|
157
|
+
if (child.show) {
|
|
158
|
+
activeFilter = {
|
|
159
|
+
parent: parent.label,
|
|
160
|
+
child: child.label,
|
|
161
|
+
id: child.id
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return activeFilter;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const activeFilter = getActiveFilter();
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<div style={{ maxWidth: '800px', margin: '0 auto', padding: '20px' }}>
|
|
175
|
+
<h1 style={{ marginBottom: '20px' }}>Reports</h1>
|
|
176
|
+
|
|
177
|
+
<div style={{ display: 'flex', gap: '20px' }}>
|
|
178
|
+
<div style={{ width: '300px' }}>
|
|
179
|
+
<TableFilter
|
|
180
|
+
filters={filters}
|
|
181
|
+
setFilters={setFilters}
|
|
182
|
+
setSettings={setSettings}
|
|
183
|
+
/>
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<div style={{ flex: 1, padding: '20px', backgroundColor: '#f9f9f9', borderRadius: '8px', minHeight: '300px' }}>
|
|
187
|
+
{activeFilter ? (
|
|
188
|
+
<div>
|
|
189
|
+
<h2>{activeFilter.child}</h2>
|
|
190
|
+
<p>Category: {activeFilter.parent}</p>
|
|
191
|
+
<p>Filter ID: {activeFilter.id}</p>
|
|
192
|
+
<div style={{ marginTop: '20px', padding: '15px', backgroundColor: '#fff', borderRadius: '4px' }}>
|
|
193
|
+
<p>This is the content area that would display data based on the selected filter.</p>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
) : (
|
|
197
|
+
<div style={{ textAlign: 'center', color: '#666' }}>
|
|
198
|
+
<p>Please select a filter option to view content</p>
|
|
199
|
+
</div>
|
|
200
|
+
)}
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
export default FilterExample;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# TableFilter Component with Parent-Child Structure
|
|
2
|
+
|
|
3
|
+
This document explains how to use the updated TableFilter component with parent-child relationships.
|
|
4
|
+
|
|
5
|
+
## Structure of Filter Data
|
|
6
|
+
|
|
7
|
+
The TableFilter component now supports a hierarchical structure with parent categories and child filters. Here's how to structure your filter data:
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
const filters = [
|
|
11
|
+
{
|
|
12
|
+
id: "parentCategoryId",
|
|
13
|
+
label: "Parent Category Name",
|
|
14
|
+
isParent: true, // Important: mark as parent
|
|
15
|
+
show: false,
|
|
16
|
+
class: "",
|
|
17
|
+
children: [
|
|
18
|
+
{
|
|
19
|
+
id: "childFilter1",
|
|
20
|
+
show: false,
|
|
21
|
+
label: "Child Filter 1",
|
|
22
|
+
class: ""
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "childFilter2",
|
|
26
|
+
show: false,
|
|
27
|
+
label: "Child Filter 2",
|
|
28
|
+
class: ""
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
// More parent categories...
|
|
33
|
+
];
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Key Features
|
|
37
|
+
|
|
38
|
+
1. **Collapsible Parent Categories**: Click on a parent category to show/hide its children
|
|
39
|
+
2. **Visual Indicators**: Arrow indicators show whether a parent category is expanded
|
|
40
|
+
3. **Styling**: Distinct styling for parent categories and child filters
|
|
41
|
+
4. **Active States**: Visual indication of active filters
|
|
42
|
+
5. **Mobile Responsive**: Adapts to smaller screens with a toggle menu
|
|
43
|
+
|
|
44
|
+
## Usage Example
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
import React, { useState } from 'react';
|
|
48
|
+
import TableFilter from '../TableFilter';
|
|
49
|
+
|
|
50
|
+
function MyComponent() {
|
|
51
|
+
const [filters, setFilters] = useState([
|
|
52
|
+
// Your filter structure here
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
const [settings, setSettings] = useState({
|
|
56
|
+
ajaxSetting: {
|
|
57
|
+
where: []
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<TableFilter
|
|
63
|
+
filters={filters}
|
|
64
|
+
setFilters={setFilters}
|
|
65
|
+
setSettings={setSettings}
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## How It Works
|
|
72
|
+
|
|
73
|
+
1. **Parent Categories**: When you click on a parent category, it toggles the visibility of its children
|
|
74
|
+
2. **Child Filters**: When you click on a child filter:
|
|
75
|
+
- It becomes active (highlighted)
|
|
76
|
+
- The `show` property is set to `true`
|
|
77
|
+
- The `settings` object is updated with the filter's ID and value
|
|
78
|
+
- The content area should update based on the selected filter
|
|
79
|
+
|
|
80
|
+
## Handling Filter Selection
|
|
81
|
+
|
|
82
|
+
To display content based on the selected filter, check which filter has `show: true`:
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
// Find the active filter
|
|
86
|
+
const getActiveFilter = () => {
|
|
87
|
+
let activeFilter = null;
|
|
88
|
+
|
|
89
|
+
filters.forEach(parent => {
|
|
90
|
+
if (parent.children) {
|
|
91
|
+
parent.children.forEach(child => {
|
|
92
|
+
if (child.show) {
|
|
93
|
+
activeFilter = {
|
|
94
|
+
parent: parent.label,
|
|
95
|
+
child: child.label,
|
|
96
|
+
id: child.id
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return activeFilter;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// Use the active filter to display content
|
|
107
|
+
const activeFilter = getActiveFilter();
|
|
108
|
+
if (activeFilter) {
|
|
109
|
+
// Display content for the active filter
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
See the `FilterExample.jsx` file for a complete working example.
|