create-bdpamke-react-scaffold 1.0.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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/bin/create-bdpamke-react-scaffold.js +101 -0
  4. package/package.json +39 -0
  5. package/template/.env.example +6 -0
  6. package/template/FUNCTIONS_EXAMPLES.md +480 -0
  7. package/template/HOWTOadd a page.md +166 -0
  8. package/template/REACT_PROPS_USEEFFECT.md +210 -0
  9. package/template/REGISTRATION_FLOW.md +268 -0
  10. package/template/USESTATE_EXAMPLES.md +451 -0
  11. package/template/components.json +20 -0
  12. package/template/index.html +13 -0
  13. package/template/jsconfig.json +19 -0
  14. package/template/package-lock.json +5988 -0
  15. package/template/package.json +73 -0
  16. package/template/postcss.config.cjs +6 -0
  17. package/template/public/images/BDPA_edited.png +0 -0
  18. package/template/server/server.js +86 -0
  19. package/template/server/utils/apiClient.js +59 -0
  20. package/template/server/utils/password.js +60 -0
  21. package/template/src/App.jsx +10 -0
  22. package/template/src/components/layout/Container.jsx +7 -0
  23. package/template/src/components/layout/Section.jsx +7 -0
  24. package/template/src/components/ui/accordion.jsx +41 -0
  25. package/template/src/components/ui/alert-dialog.jsx +99 -0
  26. package/template/src/components/ui/alert.jsx +47 -0
  27. package/template/src/components/ui/aspect-ratio.jsx +5 -0
  28. package/template/src/components/ui/avatar.jsx +35 -0
  29. package/template/src/components/ui/badge.jsx +34 -0
  30. package/template/src/components/ui/button.jsx +47 -0
  31. package/template/src/components/ui/calendar.jsx +173 -0
  32. package/template/src/components/ui/card.jsx +50 -0
  33. package/template/src/components/ui/carousel.jsx +194 -0
  34. package/template/src/components/ui/checkbox.jsx +22 -0
  35. package/template/src/components/ui/collapsible.jsx +11 -0
  36. package/template/src/components/ui/command.jsx +116 -0
  37. package/template/src/components/ui/dialog.jsx +94 -0
  38. package/template/src/components/ui/drawer.jsx +92 -0
  39. package/template/src/components/ui/dropdown-menu.jsx +155 -0
  40. package/template/src/components/ui/form.jsx +138 -0
  41. package/template/src/components/ui/hover-card.jsx +25 -0
  42. package/template/src/components/ui/icons.jsx +81 -0
  43. package/template/src/components/ui/input.jsx +19 -0
  44. package/template/src/components/ui/label.jsx +16 -0
  45. package/template/src/components/ui/menubar.jsx +200 -0
  46. package/template/src/components/ui/navigation-menu.jsx +104 -0
  47. package/template/src/components/ui/popover.jsx +25 -0
  48. package/template/src/components/ui/progress.jsx +20 -0
  49. package/template/src/components/ui/radio-group.jsx +29 -0
  50. package/template/src/components/ui/scroll-area.jsx +40 -0
  51. package/template/src/components/ui/select.jsx +120 -0
  52. package/template/src/components/ui/separator.jsx +25 -0
  53. package/template/src/components/ui/sheet.jsx +108 -0
  54. package/template/src/components/ui/skeleton.jsx +10 -0
  55. package/template/src/components/ui/slider.jsx +23 -0
  56. package/template/src/components/ui/sonner.jsx +42 -0
  57. package/template/src/components/ui/switch.jsx +24 -0
  58. package/template/src/components/ui/table.jsx +83 -0
  59. package/template/src/components/ui/tabs.jsx +41 -0
  60. package/template/src/components/ui/textarea.jsx +18 -0
  61. package/template/src/components/ui/toast.jsx +82 -0
  62. package/template/src/components/ui/toaster.jsx +33 -0
  63. package/template/src/components/ui/toggle.jsx +40 -0
  64. package/template/src/components/ui/tooltip.jsx +24 -0
  65. package/template/src/hooks/use-toast.js +155 -0
  66. package/template/src/index.css +61 -0
  67. package/template/src/index.js +6 -0
  68. package/template/src/lib/utils.js +11 -0
  69. package/template/src/main.jsx +15 -0
  70. package/template/src/pages/Home.jsx +26 -0
  71. package/template/tailwind.config.cjs +76 -0
  72. package/template/vite.config.mts +22 -0
@@ -0,0 +1,451 @@
1
+ # useState Examples
2
+
3
+ This guide explains how `useState` works in React with simple examples.
4
+
5
+ ## 1. What `useState` does
6
+
7
+ `useState` lets a React component remember values between renders.
8
+
9
+ You usually use it for things like:
10
+
11
+ - text input values
12
+ - counters
13
+ - toggles
14
+ - form data
15
+ - API loading state
16
+ - error messages
17
+
18
+ Basic syntax:
19
+
20
+ ```jsx
21
+ import { useState } from "react";
22
+
23
+ export default function Example() {
24
+ const [count, setCount] = useState(0);
25
+
26
+ return <p>{count}</p>;
27
+ }
28
+ ```
29
+
30
+ In this example:
31
+
32
+ - `count` is the current state value
33
+ - `setCount` updates the state
34
+ - `0` is the initial value
35
+
36
+ ## 2. Example: counter
37
+
38
+ ```jsx
39
+ import { useState } from "react";
40
+
41
+ export default function CounterExample() {
42
+ const [count, setCount] = useState(0);
43
+
44
+ return (
45
+ <div>
46
+ <p>Count: {count}</p>
47
+ <button onClick={() => setCount(count + 1)}>Increase</button>
48
+ <button onClick={() => setCount(count - 1)}>Decrease</button>
49
+ <button onClick={() => setCount(0)}>Reset</button>
50
+ </div>
51
+ );
52
+ }
53
+ ```
54
+
55
+ What happens here:
56
+
57
+ - clicking `Increase` adds `1`
58
+ - clicking `Decrease` subtracts `1`
59
+ - clicking `Reset` sets the value back to `0`
60
+
61
+ ## 3. Example: text input
62
+
63
+ ```jsx
64
+ import { useState } from "react";
65
+
66
+ export default function NameExample() {
67
+ const [name, setName] = useState("");
68
+
69
+ return (
70
+ <div>
71
+ <input
72
+ type="text"
73
+ value={name}
74
+ onChange={(event) => setName(event.target.value)}
75
+ placeholder="Enter your name"
76
+ />
77
+ <p>Hello, {name || "friend"}.</p>
78
+ </div>
79
+ );
80
+ }
81
+ ```
82
+
83
+ What happens here:
84
+
85
+ - the input shows the current `name`
86
+ - typing calls `setName(...)`
87
+ - the paragraph updates immediately
88
+
89
+ ## 4. Example: boolean toggle
90
+
91
+ ```jsx
92
+ import { useState } from "react";
93
+
94
+ export default function ToggleExample() {
95
+ const [isOpen, setIsOpen] = useState(false);
96
+
97
+ return (
98
+ <div>
99
+ <button onClick={() => setIsOpen(!isOpen)}>
100
+ {isOpen ? "Hide" : "Show"}
101
+ </button>
102
+
103
+ {isOpen ? <p>The panel is open.</p> : null}
104
+ </div>
105
+ );
106
+ }
107
+ ```
108
+
109
+ This is useful for:
110
+
111
+ - modals
112
+ - dropdowns
113
+ - accordions
114
+ - mobile menus
115
+ - show/hide sections
116
+
117
+ ## 5. Example: multiple fields in one object
118
+
119
+ When a form has several related values, you can store them in one object.
120
+
121
+ ```jsx
122
+ import { useState } from "react";
123
+
124
+ export default function FormExample() {
125
+ const [formData, setFormData] = useState({
126
+ email: "",
127
+ password: "",
128
+ });
129
+
130
+ const handleChange = (event) => {
131
+ const { name, value } = event.target;
132
+
133
+ setFormData((current) => ({
134
+ ...current,
135
+ [name]: value,
136
+ }));
137
+ };
138
+
139
+ return (
140
+ <form>
141
+ <input
142
+ name="email"
143
+ type="email"
144
+ value={formData.email}
145
+ onChange={handleChange}
146
+ placeholder="Email"
147
+ />
148
+
149
+ <input
150
+ name="password"
151
+ type="password"
152
+ value={formData.password}
153
+ onChange={handleChange}
154
+ placeholder="Password"
155
+ />
156
+
157
+ <pre>{JSON.stringify(formData, null, 2)}</pre>
158
+ </form>
159
+ );
160
+ }
161
+ ```
162
+
163
+ Why use this pattern:
164
+
165
+ - it keeps related form values together
166
+ - it scales better than many separate state variables
167
+ - it works well for registration and login forms
168
+
169
+ ## 6. Example: array state
170
+
171
+ You can also store arrays in state.
172
+
173
+ ```jsx
174
+ import { useState } from "react";
175
+
176
+ export default function TodoExample() {
177
+ const [items, setItems] = useState(["Learn React"]);
178
+ const [newItem, setNewItem] = useState("");
179
+
180
+ const addItem = () => {
181
+ if (!newItem.trim()) return;
182
+
183
+ setItems((current) => [...current, newItem]);
184
+ setNewItem("");
185
+ };
186
+
187
+ return (
188
+ <div>
189
+ <input
190
+ value={newItem}
191
+ onChange={(event) => setNewItem(event.target.value)}
192
+ placeholder="Add item"
193
+ />
194
+ <button onClick={addItem}>Add</button>
195
+
196
+ <ul>
197
+ {items.map((item, index) => (
198
+ <li key={index}>{item}</li>
199
+ ))}
200
+ </ul>
201
+ </div>
202
+ );
203
+ }
204
+ ```
205
+
206
+ Common array operations with state:
207
+
208
+ - add item with `[...current, newItem]`
209
+ - remove item with `.filter(...)`
210
+ - update item with `.map(...)`
211
+
212
+ ## 7. Example: loading and error state for API calls
213
+
214
+ This pattern is common when talking to a server.
215
+
216
+ ```jsx
217
+ import { useState } from "react";
218
+
219
+ export default function ApiExample() {
220
+ const [loading, setLoading] = useState(false);
221
+ const [data, setData] = useState(null);
222
+ const [error, setError] = useState("");
223
+
224
+ const fetchHealth = async () => {
225
+ setLoading(true);
226
+ setError("");
227
+
228
+ try {
229
+ const response = await fetch("/api/health");
230
+ const result = await response.json();
231
+ setData(result);
232
+ } catch (err) {
233
+ setError("Failed to load API response.");
234
+ } finally {
235
+ setLoading(false);
236
+ }
237
+ };
238
+
239
+ return (
240
+ <div>
241
+ <button onClick={fetchHealth} disabled={loading}>
242
+ {loading ? "Loading..." : "Check API"}
243
+ </button>
244
+
245
+ {error ? <p>{error}</p> : null}
246
+ {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : null}
247
+ </div>
248
+ );
249
+ }
250
+ ```
251
+
252
+ This pattern is useful because it separates:
253
+
254
+ - the request state
255
+ - the successful response
256
+ - the failure message
257
+
258
+ ## 8. Example: functional state updates
259
+
260
+ When the next state depends on the previous state, use the callback form.
261
+
262
+ ```jsx
263
+ import { useState } from "react";
264
+
265
+ export default function FunctionalUpdateExample() {
266
+ const [count, setCount] = useState(0);
267
+
268
+ const addThree = () => {
269
+ setCount((current) => current + 1);
270
+ setCount((current) => current + 1);
271
+ setCount((current) => current + 1);
272
+ };
273
+
274
+ return (
275
+ <div>
276
+ <p>{count}</p>
277
+ <button onClick={addThree}>Add 3</button>
278
+ </div>
279
+ );
280
+ }
281
+ ```
282
+
283
+ Why this matters:
284
+
285
+ - `setCount(count + 1)` can use an older value
286
+ - `setCount((current) => current + 1)` always uses the latest state
287
+
288
+ Use the functional form when:
289
+
290
+ - incrementing counters
291
+ - toggling based on previous value
292
+ - updating arrays or objects from current state
293
+
294
+ ## 9. Example: registration form using `useState`
295
+
296
+ This example matches a real app pattern.
297
+
298
+ ```jsx
299
+ import { useState } from "react";
300
+
301
+ export default function RegisterExample() {
302
+ const [email, setEmail] = useState("");
303
+ const [password, setPassword] = useState("");
304
+ const [message, setMessage] = useState("");
305
+
306
+ const handleSubmit = async (event) => {
307
+ event.preventDefault();
308
+ setMessage("");
309
+
310
+ try {
311
+ const response = await fetch("/api/register", {
312
+ method: "POST",
313
+ headers: {
314
+ "Content-Type": "application/json",
315
+ },
316
+ body: JSON.stringify({ email, password }),
317
+ });
318
+
319
+ const result = await response.json();
320
+
321
+ if (!response.ok) {
322
+ throw new Error(result.error || "Registration failed.");
323
+ }
324
+
325
+ setMessage("Registration submitted successfully.");
326
+ } catch (error) {
327
+ setMessage(error.message);
328
+ }
329
+ };
330
+
331
+ return (
332
+ <form onSubmit={handleSubmit}>
333
+ <input
334
+ type="email"
335
+ value={email}
336
+ onChange={(event) => setEmail(event.target.value)}
337
+ placeholder="Email"
338
+ />
339
+
340
+ <input
341
+ type="password"
342
+ value={password}
343
+ onChange={(event) => setPassword(event.target.value)}
344
+ placeholder="Password"
345
+ />
346
+
347
+ <button type="submit">Register</button>
348
+ <p>{message}</p>
349
+ </form>
350
+ );
351
+ }
352
+ ```
353
+
354
+ Here `useState` is used for:
355
+
356
+ - `email`
357
+ - `password`
358
+ - `message`
359
+
360
+ That is a common and clean pattern for simple forms.
361
+
362
+ ## 10. Common mistakes
363
+
364
+ ### Mistake: updating objects without copying existing values
365
+
366
+ Wrong:
367
+
368
+ ```jsx
369
+ setFormData({ email: "new@example.com" });
370
+ ```
371
+
372
+ This replaces the whole object.
373
+
374
+ Better:
375
+
376
+ ```jsx
377
+ setFormData((current) => ({
378
+ ...current,
379
+ email: "new@example.com",
380
+ }));
381
+ ```
382
+
383
+ ### Mistake: mutating arrays directly
384
+
385
+ Wrong:
386
+
387
+ ```jsx
388
+ items.push("New item");
389
+ setItems(items);
390
+ ```
391
+
392
+ Better:
393
+
394
+ ```jsx
395
+ setItems((current) => [...current, "New item"]);
396
+ ```
397
+
398
+ ### Mistake: expecting state to update immediately
399
+
400
+ Wrong expectation:
401
+
402
+ ```jsx
403
+ setCount(count + 1);
404
+ console.log(count);
405
+ ```
406
+
407
+ The `console.log` may still print the old value during that render cycle.
408
+
409
+ ## 11. Quick rule of thumb
410
+
411
+ Use `useState` when:
412
+
413
+ - the value changes over time
414
+ - the UI should re-render when the value changes
415
+ - the value belongs to that component
416
+
417
+ Examples:
418
+
419
+ - form inputs
420
+ - open/closed UI state
421
+ - fetched API data
422
+ - loading indicators
423
+ - local validation messages
424
+
425
+ ## 12. Summary
426
+
427
+ `useState` is one of the main React hooks.
428
+
429
+ It gives you:
430
+
431
+ - a current value
432
+ - a function to update that value
433
+ - automatic re-rendering when the value changes
434
+
435
+ Pattern:
436
+
437
+ ```jsx
438
+ const [value, setValue] = useState(initialValue);
439
+ ```
440
+
441
+ Examples in this guide covered:
442
+
443
+ - numbers
444
+ - strings
445
+ - booleans
446
+ - objects
447
+ - arrays
448
+ - forms
449
+ - API state
450
+
451
+ Once `useState` feels comfortable, the next hook to learn is usually `useEffect`.
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "default",
4
+ "rsc": false,
5
+ "tsx": false,
6
+ "tailwind": {
7
+ "config": "tailwind.config.cjs",
8
+ "css": "src/index.css",
9
+ "baseColor": "slate",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "aliases": {
14
+ "components": "@/components",
15
+ "utils": "@/lib/utils",
16
+ "ui": "@/components/ui",
17
+ "lib": "@/lib",
18
+ "hooks": "@/hooks"
19
+ }
20
+ }
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/png" href="/BDPA_edited.png" />
6
+ <title>BDPA React Scaffold and Demo</title>
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ </head>
9
+ <body class="bg-gray-100">
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.jsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "jsx": "react-jsx",
7
+ "checkJs": true,
8
+ "strict": false,
9
+ "allowSyntheticDefaultImports": true,
10
+ "esModuleInterop": true,
11
+ "resolveJsonModule": true,
12
+ "baseUrl": ".",
13
+ "paths": {
14
+ "@/*": ["src/*"]
15
+ }
16
+ },
17
+ "include": ["src", "index.html"],
18
+ "exclude": ["node_modules", "dist"]
19
+ }