@ramesesinc/app-forms 0.1.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.
- package/dist/components/AppContactForm.d.ts +2 -0
- package/dist/components/AppContactForm.js +13 -0
- package/dist/components/AppContactForm.tsx +80 -0
- package/dist/components/AppInitForm.d.ts +0 -0
- package/dist/components/AppInitForm.js +74 -0
- package/dist/components/AppInitForm.tsx +80 -0
- package/dist/components/AppOtpForm.d.ts +2 -0
- package/dist/components/AppOtpForm.js +25 -0
- package/dist/components/AppOtpForm.tsx +71 -0
- package/dist/components/AppSaveForm.d.ts +2 -0
- package/dist/components/AppSaveForm.js +8 -0
- package/dist/components/AppSaveForm.tsx +29 -0
- package/dist/components/ApplicantInfo.d.ts +2 -0
- package/dist/components/ApplicantInfo.js +29 -0
- package/dist/components/ApplicantInfo.tsx +125 -0
- package/dist/components/HtmlTemplate.d.ts +8 -0
- package/dist/components/HtmlTemplate.js +28 -0
- package/dist/components/HtmlTemplate.tsx +46 -0
- package/dist/components/NewPermitAppCodeForm.d.ts +2 -0
- package/dist/components/NewPermitAppCodeForm.js +6 -0
- package/dist/components/NewPermitAppCodeForm.tsx +22 -0
- package/dist/components/NewPermitAppForm.d.ts +2 -0
- package/dist/components/NewPermitAppForm.js +8 -0
- package/dist/components/NewPermitAppForm.tsx +26 -0
- package/dist/components/NewPermitAppTermForm.d.ts +2 -0
- package/dist/components/NewPermitAppTermForm.js +8 -0
- package/dist/components/NewPermitAppTermForm.tsx +33 -0
- package/dist/components/NewPermitAppTypeForm.d.ts +2 -0
- package/dist/components/NewPermitAppTypeForm.js +8 -0
- package/dist/components/NewPermitAppTypeForm.tsx +28 -0
- package/dist/components/PrivacyStatementForm.d.ts +0 -0
- package/dist/components/PrivacyStatementForm.js +49 -0
- package/dist/components/PrivacyStatementForm.tsx +55 -0
- package/dist/components/common/InputValidator.d.ts +13 -0
- package/dist/components/common/InputValidator.js +118 -0
- package/dist/components/common/InputValidator.tsx +252 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.js +12 -0
- package/dist/components/index.ts +14 -0
- package/dist/components/test.d.ts +2 -0
- package/dist/components/test.js +5 -0
- package/dist/components/test.tsx +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/styles/index.css +47 -0
- package/package.json +51 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
type InputValidatorProps = {
|
|
4
|
+
datatype: "number" | "decimal" | "string" | "boolean" | "list" | "complexlist" | any;
|
|
5
|
+
value?: any;
|
|
6
|
+
onChange?: (value: any) => void;
|
|
7
|
+
options?: string[];
|
|
8
|
+
className?: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
activeFirst?: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const InputValidator: React.FC<InputValidatorProps> = ({ datatype, value, onChange, options = [], className = "", label = "", placeholder = "", activeFirst = true }) => {
|
|
15
|
+
const [inputValue, setInputValue] = useState<any>(value ?? "");
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setInputValue(value ?? "");
|
|
19
|
+
}, [value]);
|
|
20
|
+
|
|
21
|
+
const handleChange = (val: any) => {
|
|
22
|
+
setInputValue(val);
|
|
23
|
+
onChange?.(val);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
switch (datatype) {
|
|
27
|
+
case "number":
|
|
28
|
+
return (
|
|
29
|
+
<input
|
|
30
|
+
type="text"
|
|
31
|
+
value={inputValue}
|
|
32
|
+
placeholder={placeholder}
|
|
33
|
+
className={`outline-none ${className}`}
|
|
34
|
+
onChange={(e) => {
|
|
35
|
+
const val = e.target.value;
|
|
36
|
+
if (/^-?\d*$/.test(val)) {
|
|
37
|
+
handleChange(val);
|
|
38
|
+
}
|
|
39
|
+
}}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
case "decimal":
|
|
44
|
+
return (
|
|
45
|
+
<input
|
|
46
|
+
type="text"
|
|
47
|
+
value={inputValue}
|
|
48
|
+
placeholder={placeholder}
|
|
49
|
+
className={`outline-none ${className}`}
|
|
50
|
+
onChange={(e) => {
|
|
51
|
+
const val = e.target.value;
|
|
52
|
+
if (/^-?\d*\.?\d*$/.test(val)) {
|
|
53
|
+
handleChange(val);
|
|
54
|
+
}
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
case "string":
|
|
60
|
+
return (
|
|
61
|
+
<input
|
|
62
|
+
type="text"
|
|
63
|
+
value={inputValue}
|
|
64
|
+
placeholder={placeholder}
|
|
65
|
+
className={`
|
|
66
|
+
focus:ring-0
|
|
67
|
+
focus:border-transparent
|
|
68
|
+
bg-transparent
|
|
69
|
+
focus:bg-transparent
|
|
70
|
+
shadow-none
|
|
71
|
+
focus:shadow-none
|
|
72
|
+
appearance-none ${className}`}
|
|
73
|
+
onChange={(e) => {
|
|
74
|
+
const val = e.target.value;
|
|
75
|
+
|
|
76
|
+
// allow empty value
|
|
77
|
+
if (val === "") {
|
|
78
|
+
handleChange(val);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// allow alphanumeric + space
|
|
83
|
+
if (/^[a-zA-Z0-9 ]+$/.test(val)) {
|
|
84
|
+
handleChange(val);
|
|
85
|
+
}
|
|
86
|
+
}}
|
|
87
|
+
/>
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
case "mobilenumber":
|
|
91
|
+
return (
|
|
92
|
+
<input
|
|
93
|
+
type="text"
|
|
94
|
+
value={inputValue}
|
|
95
|
+
placeholder={placeholder}
|
|
96
|
+
className={`focus:ring-0
|
|
97
|
+
focus:border-transparent
|
|
98
|
+
bg-transparent
|
|
99
|
+
focus:bg-transparent
|
|
100
|
+
shadow-none
|
|
101
|
+
focus:shadow-none
|
|
102
|
+
appearance-none ${className}`}
|
|
103
|
+
onChange={(e) => {
|
|
104
|
+
const val = e.target.value;
|
|
105
|
+
|
|
106
|
+
// allow empty, digits, or + at start
|
|
107
|
+
if (/^\+?\d*$/.test(val)) {
|
|
108
|
+
handleChange(val);
|
|
109
|
+
}
|
|
110
|
+
}}
|
|
111
|
+
/>
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
case "email":
|
|
115
|
+
return (
|
|
116
|
+
<input
|
|
117
|
+
type="text"
|
|
118
|
+
value={inputValue}
|
|
119
|
+
placeholder={placeholder}
|
|
120
|
+
className={`focus:ring-0
|
|
121
|
+
focus:border-transparent
|
|
122
|
+
bg-transparent
|
|
123
|
+
focus:bg-transparent
|
|
124
|
+
shadow-none
|
|
125
|
+
focus:shadow-none
|
|
126
|
+
appearance-none ${className}`}
|
|
127
|
+
onChange={(e) => {
|
|
128
|
+
const val = e.target.value;
|
|
129
|
+
|
|
130
|
+
// allow empty value
|
|
131
|
+
if (val === "") {
|
|
132
|
+
handleChange(val);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// allow email-safe characters while typing
|
|
137
|
+
if (/^[a-zA-Z0-9@._-]*$/.test(val)) {
|
|
138
|
+
handleChange(val);
|
|
139
|
+
}
|
|
140
|
+
}}
|
|
141
|
+
/>
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
case "boolean":
|
|
146
|
+
if (options.length > 0) {
|
|
147
|
+
// Multiple checkboxes
|
|
148
|
+
return (
|
|
149
|
+
<div className={`flex flex-col space-y-1 ${className}`}>
|
|
150
|
+
{options.map((opt, i) => (
|
|
151
|
+
<label key={i} className="inline-flex items-center space-x-2 cursor-pointer">
|
|
152
|
+
<input
|
|
153
|
+
type="checkbox"
|
|
154
|
+
value={opt}
|
|
155
|
+
checked={Array.isArray(inputValue) ? inputValue.includes(opt) : false}
|
|
156
|
+
className="w-4 h-4 accent-blue-500"
|
|
157
|
+
onChange={(e) => {
|
|
158
|
+
let newValue = Array.isArray(inputValue) ? [...inputValue] : [];
|
|
159
|
+
if (e.target.checked) {
|
|
160
|
+
newValue.push(opt);
|
|
161
|
+
} else {
|
|
162
|
+
newValue = newValue.filter((v) => v !== opt);
|
|
163
|
+
}
|
|
164
|
+
handleChange(newValue);
|
|
165
|
+
}}
|
|
166
|
+
/>
|
|
167
|
+
<span>{opt}</span>
|
|
168
|
+
</label>
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Single checkbox (default)
|
|
175
|
+
return (
|
|
176
|
+
<label className={`inline-flex items-center space-x-2 cursor-pointer ${className}`}>
|
|
177
|
+
<input
|
|
178
|
+
type="checkbox"
|
|
179
|
+
checked={!!inputValue}
|
|
180
|
+
className="w-4 h-4 accent-blue-500"
|
|
181
|
+
onChange={(e) => handleChange(e.target.checked)}
|
|
182
|
+
/>
|
|
183
|
+
{label && <span>{label}</span>}
|
|
184
|
+
</label>
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
case "radio":
|
|
188
|
+
if (options.length === 0) {
|
|
189
|
+
return <span className={className}>No options provided</span>;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Initialize first option as active if inputValue is empty and activeFirst is true
|
|
193
|
+
useEffect(() => {
|
|
194
|
+
if ((inputValue === "" || inputValue === undefined) && activeFirst) {
|
|
195
|
+
handleChange(options[0]);
|
|
196
|
+
}
|
|
197
|
+
}, [options, activeFirst]);
|
|
198
|
+
|
|
199
|
+
return (
|
|
200
|
+
<div className={`flex flex-col space-y-1 ${className}`}>
|
|
201
|
+
{options.map((opt, i) => (
|
|
202
|
+
<label key={i} className="inline-flex items-center space-x-2 cursor-pointer">
|
|
203
|
+
<input
|
|
204
|
+
type="radio"
|
|
205
|
+
name={`radio-${label || Math.random()}`} // dynamic name to avoid conflicts
|
|
206
|
+
value={opt}
|
|
207
|
+
checked={inputValue === opt}
|
|
208
|
+
className="w-4 h-4 accent-blue-500"
|
|
209
|
+
onChange={() => handleChange(opt)}
|
|
210
|
+
/>
|
|
211
|
+
<span>{opt}</span>
|
|
212
|
+
</label>
|
|
213
|
+
))}
|
|
214
|
+
</div>
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
case "list":
|
|
218
|
+
return (
|
|
219
|
+
<select value={inputValue}
|
|
220
|
+
className={`bg-transparent ${className}`}
|
|
221
|
+
onChange={(e) => handleChange(e.target.value)}
|
|
222
|
+
>
|
|
223
|
+
<option value="">Select an option</option>
|
|
224
|
+
{options.map((opt, i) => (
|
|
225
|
+
<option key={i} value={opt}>
|
|
226
|
+
{opt}
|
|
227
|
+
</option>
|
|
228
|
+
))}
|
|
229
|
+
</select>
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
case "complexlist":
|
|
233
|
+
return (
|
|
234
|
+
<select multiple value={inputValue || []}
|
|
235
|
+
className={`${className}`}
|
|
236
|
+
onChange={(e) => {
|
|
237
|
+
const selected = Array.from(e.target.selectedOptions).map((opt) => opt.value);
|
|
238
|
+
handleChange(selected);
|
|
239
|
+
}}
|
|
240
|
+
>
|
|
241
|
+
{options.map((opt, i) => (
|
|
242
|
+
<option key={i} value={opt}> {opt} </option>
|
|
243
|
+
))}
|
|
244
|
+
</select>
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
default:
|
|
248
|
+
return <span className={className}>Unsupported datatype</span>;
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
export default InputValidator;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { default as AppContactForm } from "./AppContactForm";
|
|
2
|
+
export { default as AppOtpForm } from "./AppOtpForm";
|
|
3
|
+
export { default as AppSaveForm } from "./AppSaveForm";
|
|
4
|
+
export { default as HtmlTemplate } from "./HtmlTemplate";
|
|
5
|
+
export { default as ApplicantInfo } from "./ApplicantInfo";
|
|
6
|
+
export { default as NewPermitAppCodeForm } from "./NewPermitAppCodeForm";
|
|
7
|
+
export { default as NewPermitAppForm } from "./NewPermitAppForm";
|
|
8
|
+
export { default as NewPermitAppTermForm } from "./NewPermitAppTermForm";
|
|
9
|
+
export { default as NewPermitAppTypeForm } from "./NewPermitAppTypeForm";
|
|
10
|
+
export { default as test } from "./test";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { default as AppContactForm } from "./AppContactForm";
|
|
2
|
+
// export { default as AppInitForm } from "./AppInitForm";
|
|
3
|
+
export { default as AppOtpForm } from "./AppOtpForm";
|
|
4
|
+
export { default as AppSaveForm } from "./AppSaveForm";
|
|
5
|
+
export { default as HtmlTemplate } from "./HtmlTemplate";
|
|
6
|
+
// export { default as PrivacyStatementForm } from "./PrivacyStatementForm";
|
|
7
|
+
export { default as ApplicantInfo } from "./ApplicantInfo";
|
|
8
|
+
export { default as NewPermitAppCodeForm } from "./NewPermitAppCodeForm";
|
|
9
|
+
export { default as NewPermitAppForm } from "./NewPermitAppForm";
|
|
10
|
+
export { default as NewPermitAppTermForm } from "./NewPermitAppTermForm";
|
|
11
|
+
export { default as NewPermitAppTypeForm } from "./NewPermitAppTypeForm";
|
|
12
|
+
export { default as test } from "./test";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { default as AppContactForm } from "./AppContactForm";
|
|
2
|
+
// export { default as AppInitForm } from "./AppInitForm";
|
|
3
|
+
export { default as AppOtpForm } from "./AppOtpForm";
|
|
4
|
+
export { default as AppSaveForm } from "./AppSaveForm";
|
|
5
|
+
export { default as HtmlTemplate } from "./HtmlTemplate";
|
|
6
|
+
// export { default as PrivacyStatementForm } from "./PrivacyStatementForm";
|
|
7
|
+
|
|
8
|
+
export { default as ApplicantInfo } from "./ApplicantInfo";
|
|
9
|
+
export { default as NewPermitAppCodeForm } from "./NewPermitAppCodeForm";
|
|
10
|
+
export { default as NewPermitAppForm } from "./NewPermitAppForm";
|
|
11
|
+
export { default as NewPermitAppTermForm } from "./NewPermitAppTermForm";
|
|
12
|
+
export { default as NewPermitAppTypeForm } from "./NewPermitAppTypeForm";
|
|
13
|
+
export { default as test } from "./test";
|
|
14
|
+
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./components";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./components";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
@layer base {
|
|
6
|
+
* {
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
body {
|
|
11
|
+
@apply bg-white text-gray-900;
|
|
12
|
+
|
|
13
|
+
font-family: var(--font-inter), -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
|
|
14
|
+
"Droid Sans", "Helvetica Neue", sans-serif;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
input:focus,
|
|
18
|
+
textarea:focus,
|
|
19
|
+
select:focus {
|
|
20
|
+
@apply outline-none placeholder-gray-400 ring-2 ring-primary-400 border-transparent;
|
|
21
|
+
@apply transition-all duration-200;
|
|
22
|
+
@apply bg-yellow-50;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* --- Base Styles for Headings --- */
|
|
26
|
+
h1 {
|
|
27
|
+
@apply text-4xl font-bold mb-4;
|
|
28
|
+
}
|
|
29
|
+
h2 {
|
|
30
|
+
@apply text-3xl font-semibold mb-3;
|
|
31
|
+
}
|
|
32
|
+
h3 {
|
|
33
|
+
@apply text-2xl font-semibold mb-2;
|
|
34
|
+
}
|
|
35
|
+
h4 {
|
|
36
|
+
@apply text-xl font-medium mb-1;
|
|
37
|
+
}
|
|
38
|
+
h5 {
|
|
39
|
+
@apply text-lg font-semibold mb-1;
|
|
40
|
+
}
|
|
41
|
+
h6 {
|
|
42
|
+
@apply text-base font-semibold mb-1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@layer utilities {
|
|
47
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ramesesinc/app-forms",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Platform Core Library",
|
|
5
|
+
"author": "Rameses Systems Inc.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"style": "dist/index.css",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "rm -rf dist && tsc && postcss src/styles/index.css -o dist/styles/index.css && cp src/styles/* dist/styles/ && cp -r src/components dist/",
|
|
16
|
+
"build2": "rm -rf dist && tsc",
|
|
17
|
+
"clean": "rm -rf dist",
|
|
18
|
+
"dev": "tsc --watch",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"next": ">=13.5.6 <15.0.0",
|
|
23
|
+
"react": ">=18.2.0",
|
|
24
|
+
"react-dom": ">=18.2.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@ramesesinc/client": "1.0.14",
|
|
28
|
+
"@ramesesinc/lib": "1.0.12",
|
|
29
|
+
"@types/crypto-js": "^4.2.2",
|
|
30
|
+
"@types/js-cookie": "^3.0.6",
|
|
31
|
+
"@types/node": "^20",
|
|
32
|
+
"@types/pako": "^2.0.3",
|
|
33
|
+
"@types/react": "^18",
|
|
34
|
+
"@types/react-dom": "^18",
|
|
35
|
+
"autoprefixer": "^10.4.21",
|
|
36
|
+
"clsx": "^2.1.1",
|
|
37
|
+
"eslint": "^8",
|
|
38
|
+
"eslint-config-next": "14.2.9",
|
|
39
|
+
"postcss": "^8",
|
|
40
|
+
"@ramesesinc/loader": "*",
|
|
41
|
+
"supports-color": "^10.2.2",
|
|
42
|
+
"tailwindcss": "^3.4.1",
|
|
43
|
+
"typescript": "^5"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"ramesesinc-platform-core"
|
|
47
|
+
],
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"seti-ramesesv1": "^1.0.154"
|
|
50
|
+
}
|
|
51
|
+
}
|