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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # create-bdpamke-react-scaffold
2
+
3
+ Scaffold generator for a BDPA React full-stack starter built with Vite, Express, Tailwind CSS, and shadcn/ui.
4
+
5
+ Use this package to create a new project from the BDPA scaffold template without cloning the repository manually.
6
+
7
+ ## Usage
8
+
9
+ ```bash
10
+ npx create-bdpamke-react-scaffold my-app
11
+ ```
12
+
13
+ To generate into the current empty directory:
14
+
15
+ ```bash
16
+ npx create-bdpamke-react-scaffold .
17
+ ```
18
+
19
+ or:
20
+
21
+ ```bash
22
+ npx create-bdpamke-react-scaffold --use-current-dir
23
+ ```
24
+
25
+ This creates a new project directory containing the scaffold template.
26
+
27
+ ## What You Get
28
+
29
+ The generated project includes:
30
+
31
+ - Vite + React frontend
32
+ - Express backend in `server/`
33
+ - Tailwind CSS configuration
34
+ - shadcn/ui component scaffold
35
+ - starter docs and example guides
36
+ - image assets and app structure ready to customize
37
+
38
+ ## Quick Start
39
+
40
+ If you generated into a new directory:
41
+
42
+ ```bash
43
+ cd my-app
44
+ npm install
45
+ npm run dev:all
46
+ ```
47
+
48
+ If you generated into the current directory, skip the `cd` step.
49
+
50
+ ## Optional Git Setup
51
+
52
+ ```bash
53
+ git init
54
+ git add .
55
+ git commit -m "Initial commit"
56
+ ```
57
+
58
+ ## Notes
59
+
60
+ - The generated app is a starter scaffold, not a published component library.
61
+ - The template is intended to be customized after generation.
62
+ - Run `npm run dev:all` in the generated project to start both the frontend and backend together.
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ function printUsage() {
7
+ console.log("Usage: create-bdpamke-react-scaffold <project-directory>");
8
+ console.log(" create-bdpamke-react-scaffold .");
9
+ console.log(" create-bdpamke-react-scaffold --use-current-dir");
10
+ }
11
+
12
+ function normalizePackageName(value) {
13
+ return value
14
+ .trim()
15
+ .toLowerCase()
16
+ .replace(/[^a-z0-9-_]+/g, "-")
17
+ .replace(/^-+|-+$/g, "")
18
+ .replace(/-{2,}/g, "-") || "bdpa-react-scaffold-app";
19
+ }
20
+
21
+ function updateJsonFile(filePath, updater) {
22
+ const raw = fs.readFileSync(filePath, "utf8");
23
+ const parsed = JSON.parse(raw);
24
+ const updated = updater(parsed);
25
+ fs.writeFileSync(filePath, `${JSON.stringify(updated, null, 2)}\n`, "utf8");
26
+ }
27
+
28
+ const args = process.argv.slice(2);
29
+ const targetArg = args[0];
30
+ const useCurrentDir = targetArg === "." || targetArg === "--use-current-dir";
31
+
32
+ if (!targetArg || targetArg === "-h" || targetArg === "--help") {
33
+ printUsage();
34
+ process.exit(targetArg ? 0 : 1);
35
+ }
36
+
37
+ if (args.length > 1) {
38
+ console.error("Too many arguments provided.");
39
+ printUsage();
40
+ process.exit(1);
41
+ }
42
+
43
+ const cwd = process.cwd();
44
+ const templateDir = path.resolve(__dirname, "..", "template");
45
+ const targetDir = useCurrentDir ? cwd : path.resolve(cwd, targetArg);
46
+ const projectName = path.basename(targetDir);
47
+ const normalizedPackageName = normalizePackageName(projectName);
48
+
49
+ if (fs.existsSync(targetDir)) {
50
+ const existing = fs.readdirSync(targetDir);
51
+ if (existing.length > 0) {
52
+ console.error(`Target directory is not empty: ${targetDir}`);
53
+ process.exit(1);
54
+ }
55
+ } else {
56
+ fs.mkdirSync(targetDir, { recursive: true });
57
+ }
58
+
59
+ fs.cpSync(templateDir, targetDir, { recursive: true });
60
+
61
+ updateJsonFile(path.join(targetDir, "package.json"), (pkg) => ({
62
+ ...pkg,
63
+ name: normalizedPackageName,
64
+ version: "0.1.0"
65
+ }));
66
+
67
+ const packageLockPath = path.join(targetDir, "package-lock.json");
68
+
69
+ if (fs.existsSync(packageLockPath)) {
70
+ updateJsonFile(packageLockPath, (lockfile) => {
71
+ const updated = {
72
+ ...lockfile,
73
+ name: normalizedPackageName,
74
+ version: "0.1.0"
75
+ };
76
+
77
+ if (updated.packages && updated.packages[""]) {
78
+ updated.packages[""] = {
79
+ ...updated.packages[""],
80
+ name: normalizedPackageName,
81
+ version: "0.1.0"
82
+ };
83
+ }
84
+
85
+ return updated;
86
+ });
87
+ }
88
+
89
+ console.log(`Created project in ${targetDir}`);
90
+ console.log("");
91
+ console.log("Next steps:");
92
+ if (!useCurrentDir) {
93
+ console.log(` cd ${path.relative(cwd, targetDir) || "."}`);
94
+ }
95
+ console.log(" npm install");
96
+ console.log(" npm run dev:all");
97
+ console.log("");
98
+ console.log("Optional git setup:");
99
+ console.log(" git init");
100
+ console.log(" git add .");
101
+ console.log(' git commit -m "Initial commit"');
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "create-bdpamke-react-scaffold",
3
+ "version": "1.0.0",
4
+ "description": "Scaffold generator for a BDPA React full-stack starter with Vite, Express, Tailwind CSS, and shadcn/ui.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/lxdavis9lxd/create-bdpamke-react-scaffoldfullstack-basic.git"
8
+ },
9
+ "bugs": {
10
+ "url": "https://github.com/lxdavis9lxd/create-bdpamke-react-scaffoldfullstack-basic/issues"
11
+ },
12
+ "homepage": "https://github.com/lxdavis9lxd/create-bdpamke-react-scaffoldfullstack-basic#readme",
13
+ "bin": {
14
+ "create-bdpamke-react-scaffold": "bin/create-bdpamke-react-scaffold.js"
15
+ },
16
+ "files": [
17
+ "bin",
18
+ "template"
19
+ ],
20
+ "keywords": [
21
+ "bdpa",
22
+ "react",
23
+ "vite",
24
+ "express",
25
+ "scaffold",
26
+ "generator",
27
+ "create-app",
28
+ "starter",
29
+ "template",
30
+ "boilerplate",
31
+ "full-stack",
32
+ "tailwindcss",
33
+ "shadcn-ui"
34
+ ],
35
+ "license": "MIT",
36
+ "publishConfig": {
37
+ "access": "public"
38
+ }
39
+ }
@@ -0,0 +1,6 @@
1
+ # React / Vite client
2
+ VITE_API_BASE_URL=http://localhost:5000
3
+
4
+ # Express server
5
+ PORT=5000
6
+ CLIENT_ORIGIN=http://localhost:3000
@@ -0,0 +1,480 @@
1
+ # Functions Examples
2
+
3
+ This guide explains what functions are in JavaScript and shows common patterns you will use in general JavaScript, Node.js, and server code.
4
+
5
+ ## See also
6
+
7
+ For React-specific examples with `props` and `useEffect`, see `REACT_PROPS_USEEFFECT.md`.
8
+
9
+ ## 1. What a function is
10
+
11
+ A function is a reusable block of code.
12
+
13
+ You define it once, then call it whenever you need that logic.
14
+
15
+ Functions help you:
16
+
17
+ - avoid repeating code
18
+ - organize logic
19
+ - make code easier to read
20
+ - pass behavior into other code
21
+
22
+ ## 2. Basic function declaration
23
+
24
+ ```js
25
+ function sayHello() {
26
+ console.log("Hello");
27
+ }
28
+
29
+ sayHello();
30
+ ```
31
+
32
+ What happens:
33
+
34
+ - `sayHello` is the function name
35
+ - the code inside `{}` runs when you call it
36
+ - `sayHello()` calls the function
37
+
38
+ ## 3. Function with parameters
39
+
40
+ Parameters let you pass values into a function.
41
+
42
+ ```js
43
+ function greet(name) {
44
+ console.log("Hello, " + name);
45
+ }
46
+
47
+ greet("Ada");
48
+ greet("Grace");
49
+ ```
50
+
51
+ Here:
52
+
53
+ - `name` is the parameter
54
+ - `"Ada"` and `"Grace"` are arguments
55
+
56
+ ## 4. Function that returns a value
57
+
58
+ A function can give a value back using `return`.
59
+
60
+ ```js
61
+ function add(a, b) {
62
+ return a + b;
63
+ }
64
+
65
+ const total = add(2, 3);
66
+ console.log(total);
67
+ ```
68
+
69
+ What happens:
70
+
71
+ - `add(2, 3)` returns `5`
72
+ - that returned value is stored in `total`
73
+
74
+ ## 5. Function expression
75
+
76
+ You can store a function in a variable.
77
+
78
+ ```js
79
+ const multiply = function (a, b) {
80
+ return a * b;
81
+ };
82
+
83
+ console.log(multiply(4, 5));
84
+ ```
85
+
86
+ This is called a function expression.
87
+
88
+ ## 6. Arrow function
89
+
90
+ Arrow functions are a shorter syntax.
91
+
92
+ ```js
93
+ const subtract = (a, b) => {
94
+ return a - b;
95
+ };
96
+
97
+ console.log(subtract(10, 4));
98
+ ```
99
+
100
+ Shorter version when there is only one expression:
101
+
102
+ ```js
103
+ const square = (number) => number * number;
104
+
105
+ console.log(square(6));
106
+ ```
107
+
108
+ ## 7. Function with no parameters
109
+
110
+ ```js
111
+ const showMessage = () => {
112
+ console.log("This function takes no arguments.");
113
+ };
114
+
115
+ showMessage();
116
+ ```
117
+
118
+ ## 8. Function with one parameter
119
+
120
+ ```js
121
+ const double = (value) => value * 2;
122
+
123
+ console.log(double(8));
124
+ ```
125
+
126
+ ## 9. Function with default values
127
+
128
+ Default values are used when no argument is passed.
129
+
130
+ ```js
131
+ function greetUser(name = "friend") {
132
+ return "Hello, " + name;
133
+ }
134
+
135
+ console.log(greetUser());
136
+ console.log(greetUser("Jordan"));
137
+ ```
138
+
139
+ ## 10. Function passed as a callback
140
+
141
+ A callback is a function passed into another function.
142
+
143
+ ```js
144
+ function processUserInput(callback) {
145
+ const name = "Taylor";
146
+ callback(name);
147
+ }
148
+
149
+ processUserInput(function (value) {
150
+ console.log("Received:", value);
151
+ });
152
+ ```
153
+
154
+ Arrow function version:
155
+
156
+ ```js
157
+ processUserInput((value) => {
158
+ console.log("Received:", value);
159
+ });
160
+ ```
161
+
162
+ ## 11. Functions in array methods
163
+
164
+ Functions are often passed into `.map()`, `.filter()`, and `.forEach()`.
165
+
166
+ ### `map`
167
+
168
+ ```js
169
+ const numbers = [1, 2, 3];
170
+ const doubled = numbers.map((number) => number * 2);
171
+
172
+ console.log(doubled);
173
+ ```
174
+
175
+ ### `filter`
176
+
177
+ ```js
178
+ const numbers = [1, 2, 3, 4, 5];
179
+ const evenNumbers = numbers.filter((number) => number % 2 === 0);
180
+
181
+ console.log(evenNumbers);
182
+ ```
183
+
184
+ ### `forEach`
185
+
186
+ ```js
187
+ const names = ["Ada", "Grace", "Linus"];
188
+
189
+ names.forEach((name) => {
190
+ console.log(name);
191
+ });
192
+ ```
193
+
194
+ ## 12. Function that returns an object
195
+
196
+ ```js
197
+ function createUser(email, role) {
198
+ return {
199
+ email,
200
+ role,
201
+ };
202
+ }
203
+
204
+ const user = createUser("user@example.com", "admin");
205
+ console.log(user);
206
+ ```
207
+
208
+ This is useful when building structured data.
209
+
210
+ ## 13. Async functions
211
+
212
+ An `async` function lets you use `await`.
213
+
214
+ ```js
215
+ async function getHealth() {
216
+ const response = await fetch("/api/health");
217
+ const data = await response.json();
218
+ return data;
219
+ }
220
+ ```
221
+
222
+ Using it:
223
+
224
+ ```js
225
+ getHealth().then((result) => {
226
+ console.log(result);
227
+ });
228
+ ```
229
+
230
+ Or inside another async function:
231
+
232
+ ```js
233
+ async function run() {
234
+ const result = await getHealth();
235
+ console.log(result);
236
+ }
237
+
238
+ run();
239
+ ```
240
+
241
+ ## 14. Server-side function example
242
+
243
+ This matches the kind of code used in Express routes.
244
+
245
+ ```js
246
+ function validateEmail(email) {
247
+ if (!email || typeof email !== "string") {
248
+ throw new Error("Email is required.");
249
+ }
250
+
251
+ return email.includes("@");
252
+ }
253
+
254
+ console.log(validateEmail("user@example.com"));
255
+ ```
256
+
257
+ This function:
258
+
259
+ - checks input
260
+ - throws an error if the input is invalid
261
+ - returns `true` or `false`
262
+
263
+ ## 15. Function that calls another function
264
+
265
+ Functions are often combined.
266
+
267
+ ```js
268
+ function formatName(name) {
269
+ return name.trim().toUpperCase();
270
+ }
271
+
272
+ function greetFormattedName(name) {
273
+ const cleanName = formatName(name);
274
+ return "Hello, " + cleanName;
275
+ }
276
+
277
+ console.log(greetFormattedName(" ada "));
278
+ ```
279
+
280
+ This helps break large tasks into smaller pieces.
281
+
282
+ ## 16. Pure functions
283
+
284
+ A pure function:
285
+
286
+ - gives the same output for the same input
287
+ - does not change values outside itself
288
+
289
+ ```js
290
+ function toCelsius(fahrenheit) {
291
+ return (fahrenheit - 32) * (5 / 9);
292
+ }
293
+ ```
294
+
295
+ Pure functions are easier to test and reuse.
296
+
297
+ ## 17. Impure function example
298
+
299
+ ```js
300
+ let total = 0;
301
+
302
+ function addToTotal(value) {
303
+ total += value;
304
+ }
305
+ ```
306
+
307
+ This changes outside state, so it is not pure.
308
+
309
+ Impure functions are not always wrong, but they require more care.
310
+
311
+ ## 18. Common mistakes
312
+
313
+ ### Mistake: forgetting to call the function
314
+
315
+ Wrong:
316
+
317
+ ```js
318
+ console.log(add);
319
+ ```
320
+
321
+ Correct:
322
+
323
+ ```js
324
+ console.log(add(2, 3));
325
+ ```
326
+
327
+ ### Mistake: forgetting `return`
328
+
329
+ Wrong:
330
+
331
+ ```js
332
+ function add(a, b) {
333
+ a + b;
334
+ }
335
+ ```
336
+
337
+ Correct:
338
+
339
+ ```js
340
+ function add(a, b) {
341
+ return a + b;
342
+ }
343
+ ```
344
+
345
+ ### Mistake: calling the function immediately
346
+
347
+ Wrong:
348
+
349
+ ```js
350
+ runTask();
351
+ ```
352
+
353
+ when you meant to pass the function itself somewhere.
354
+
355
+ Correct:
356
+
357
+ ```js
358
+ runTask;
359
+ ```
360
+
361
+ or pass it as a callback where needed.
362
+
363
+ ## 19. When to use each style
364
+
365
+ ### Function declaration
366
+
367
+ Use when:
368
+
369
+ - you want a named reusable function
370
+ - you want clear readability
371
+ - you define general-purpose logic
372
+
373
+ ```js
374
+ function calculateTotal(price, tax) {
375
+ return price + tax;
376
+ }
377
+ ```
378
+
379
+ ### Function expression
380
+
381
+ Use when:
382
+
383
+ - you want to store a function in a variable
384
+ - you want to pass it around
385
+
386
+ ```js
387
+ const calculateTotal = function (price, tax) {
388
+ return price + tax;
389
+ };
390
+ ```
391
+
392
+ ### Arrow function
393
+
394
+ Use when:
395
+
396
+ - you want shorter syntax
397
+ - you are writing callbacks
398
+ - you want consistency in modern JavaScript code
399
+
400
+ ```js
401
+ const calculateTotal = (price, tax) => price + tax;
402
+ ```
403
+
404
+ ## 20. Summary
405
+
406
+ Functions are one of the most important parts of JavaScript.
407
+
408
+ They let you:
409
+
410
+ - group logic
411
+ - reuse code
412
+ - respond to events
413
+ - process data
414
+ - call APIs
415
+ - structure backend and utility code
416
+
417
+ Examples in this guide covered:
418
+
419
+ - function declarations
420
+ - parameters and return values
421
+ - function expressions
422
+ - arrow functions
423
+ - callbacks
424
+ - async functions
425
+ - array method callbacks
426
+ - server-side validation functions
427
+ - pure and impure functions
428
+
429
+ A simple rule:
430
+
431
+ - if you want reusable logic, put it in a function
432
+ - if the code should run later, pass a function
433
+ - if you need a result back, `return` a value
434
+
435
+ - you want to store a function in a variable
436
+ - you want to pass it around
437
+
438
+ ```js
439
+ const calculateTotal = function (price, tax) {
440
+ return price + tax;
441
+ };
442
+ ```
443
+
444
+ ### Arrow function
445
+
446
+ Use when:
447
+
448
+ - you want shorter syntax
449
+ - you are writing callbacks
450
+ - you want consistency in modern React code
451
+
452
+ ```js
453
+ const calculateTotal = (price, tax) => price + tax;
454
+ ```
455
+
456
+ ## 22. Summary
457
+
458
+ Functions are one of the most important parts of JavaScript.
459
+
460
+ They let you:
461
+
462
+ - group logic
463
+ - reuse code
464
+ - respond to events
465
+ - process data
466
+ - call APIs
467
+ - structure React components and server code
468
+
469
+ Common patterns you will use often:
470
+
471
+ - `function name() {}`
472
+ - `const name = function () {}`
473
+ - `const name = () => {}`
474
+ - `async function name() {}`
475
+
476
+ A simple rule:
477
+
478
+ - if you want reusable logic, put it in a function
479
+ - if the code should run later, pass a function
480
+ - if you need a result back, `return` a value