jac-client 0.2.3__py3-none-any.whl → 0.2.4__py3-none-any.whl

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 (176) hide show
  1. jac_client/examples/all-in-one/assets/workers/worker.py +5 -0
  2. jac_client/tests/conftest.py +281 -0
  3. jac_client/tests/test_cli.py +755 -0
  4. jac_client/tests/test_it.py +347 -67
  5. {jac_client-0.2.3.dist-info → jac_client-0.2.4.dist-info}/METADATA +28 -30
  6. jac_client-0.2.4.dist-info/RECORD +10 -0
  7. {jac_client-0.2.3.dist-info → jac_client-0.2.4.dist-info}/WHEEL +2 -1
  8. jac_client-0.2.4.dist-info/entry_points.txt +4 -0
  9. jac_client-0.2.4.dist-info/top_level.txt +1 -0
  10. jac_client/docs/README.md +0 -689
  11. jac_client/docs/advanced-state.md +0 -1265
  12. jac_client/docs/asset-serving/intro.md +0 -209
  13. jac_client/docs/assets/pipe_line-v2.svg +0 -32
  14. jac_client/docs/assets/pipe_line.png +0 -0
  15. jac_client/docs/file-system/app.jac.md +0 -121
  16. jac_client/docs/file-system/backend-frontend.md +0 -217
  17. jac_client/docs/file-system/intro.md +0 -72
  18. jac_client/docs/file-system/nested-imports.md +0 -348
  19. jac_client/docs/guide-example/intro.md +0 -115
  20. jac_client/docs/guide-example/step-01-setup.md +0 -270
  21. jac_client/docs/guide-example/step-02-components.md +0 -416
  22. jac_client/docs/guide-example/step-03-styling.md +0 -478
  23. jac_client/docs/guide-example/step-04-todo-ui.md +0 -477
  24. jac_client/docs/guide-example/step-05-local-state.md +0 -530
  25. jac_client/docs/guide-example/step-06-events.md +0 -749
  26. jac_client/docs/guide-example/step-07-effects.md +0 -468
  27. jac_client/docs/guide-example/step-08-walkers.md +0 -534
  28. jac_client/docs/guide-example/step-09-authentication.md +0 -586
  29. jac_client/docs/guide-example/step-10-routing.md +0 -539
  30. jac_client/docs/guide-example/step-11-final.md +0 -963
  31. jac_client/docs/imports.md +0 -1141
  32. jac_client/docs/lifecycle-hooks.md +0 -773
  33. jac_client/docs/routing.md +0 -659
  34. jac_client/docs/styling/intro.md +0 -249
  35. jac_client/docs/styling/js-styling.md +0 -367
  36. jac_client/docs/styling/material-ui.md +0 -341
  37. jac_client/docs/styling/pure-css.md +0 -299
  38. jac_client/docs/styling/sass.md +0 -403
  39. jac_client/docs/styling/styled-components.md +0 -395
  40. jac_client/docs/styling/tailwind.md +0 -298
  41. jac_client/examples/all-in-one/.babelrc +0 -9
  42. jac_client/examples/all-in-one/README.md +0 -16
  43. jac_client/examples/all-in-one/app.jac +0 -426
  44. jac_client/examples/all-in-one/assets/burger.png +0 -0
  45. jac_client/examples/all-in-one/button.jac +0 -7
  46. jac_client/examples/all-in-one/components/button.jac +0 -7
  47. jac_client/examples/all-in-one/package.json +0 -29
  48. jac_client/examples/all-in-one/styles.css +0 -26
  49. jac_client/examples/all-in-one/vite.config.js +0 -28
  50. jac_client/examples/asset-serving/css-with-image/.babelrc +0 -9
  51. jac_client/examples/asset-serving/css-with-image/README.md +0 -91
  52. jac_client/examples/asset-serving/css-with-image/app.jac +0 -88
  53. jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
  54. jac_client/examples/asset-serving/css-with-image/package.json +0 -28
  55. jac_client/examples/asset-serving/css-with-image/styles.css +0 -26
  56. jac_client/examples/asset-serving/css-with-image/vite.config.js +0 -28
  57. jac_client/examples/asset-serving/image-asset/.babelrc +0 -9
  58. jac_client/examples/asset-serving/image-asset/README.md +0 -119
  59. jac_client/examples/asset-serving/image-asset/app.jac +0 -55
  60. jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
  61. jac_client/examples/asset-serving/image-asset/package.json +0 -28
  62. jac_client/examples/asset-serving/image-asset/styles.css +0 -26
  63. jac_client/examples/asset-serving/image-asset/vite.config.js +0 -28
  64. jac_client/examples/asset-serving/import-alias/.babelrc +0 -9
  65. jac_client/examples/asset-serving/import-alias/README.md +0 -83
  66. jac_client/examples/asset-serving/import-alias/app.jac +0 -111
  67. jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
  68. jac_client/examples/asset-serving/import-alias/package.json +0 -28
  69. jac_client/examples/asset-serving/import-alias/vite.config.js +0 -28
  70. jac_client/examples/basic/.babelrc +0 -9
  71. jac_client/examples/basic/README.md +0 -16
  72. jac_client/examples/basic/app.jac +0 -21
  73. jac_client/examples/basic/package.json +0 -27
  74. jac_client/examples/basic/vite.config.js +0 -27
  75. jac_client/examples/basic-auth/.babelrc +0 -9
  76. jac_client/examples/basic-auth/README.md +0 -16
  77. jac_client/examples/basic-auth/app.jac +0 -308
  78. jac_client/examples/basic-auth/package.json +0 -27
  79. jac_client/examples/basic-auth/vite.config.js +0 -27
  80. jac_client/examples/basic-auth-with-router/.babelrc +0 -9
  81. jac_client/examples/basic-auth-with-router/README.md +0 -60
  82. jac_client/examples/basic-auth-with-router/app.jac +0 -464
  83. jac_client/examples/basic-auth-with-router/package.json +0 -28
  84. jac_client/examples/basic-auth-with-router/vite.config.js +0 -27
  85. jac_client/examples/basic-full-stack/.babelrc +0 -9
  86. jac_client/examples/basic-full-stack/README.md +0 -18
  87. jac_client/examples/basic-full-stack/app.jac +0 -320
  88. jac_client/examples/basic-full-stack/package.json +0 -28
  89. jac_client/examples/basic-full-stack/vite.config.js +0 -27
  90. jac_client/examples/css-styling/js-styling/.babelrc +0 -9
  91. jac_client/examples/css-styling/js-styling/README.md +0 -183
  92. jac_client/examples/css-styling/js-styling/app.jac +0 -84
  93. jac_client/examples/css-styling/js-styling/package.json +0 -28
  94. jac_client/examples/css-styling/js-styling/styles.js +0 -100
  95. jac_client/examples/css-styling/js-styling/vite.config.js +0 -27
  96. jac_client/examples/css-styling/material-ui/.babelrc +0 -9
  97. jac_client/examples/css-styling/material-ui/README.md +0 -16
  98. jac_client/examples/css-styling/material-ui/app.jac +0 -122
  99. jac_client/examples/css-styling/material-ui/package.json +0 -32
  100. jac_client/examples/css-styling/material-ui/vite.config.js +0 -27
  101. jac_client/examples/css-styling/pure-css/.babelrc +0 -9
  102. jac_client/examples/css-styling/pure-css/README.md +0 -16
  103. jac_client/examples/css-styling/pure-css/app.jac +0 -64
  104. jac_client/examples/css-styling/pure-css/package.json +0 -28
  105. jac_client/examples/css-styling/pure-css/styles.css +0 -111
  106. jac_client/examples/css-styling/pure-css/vite.config.js +0 -27
  107. jac_client/examples/css-styling/sass-example/.babelrc +0 -9
  108. jac_client/examples/css-styling/sass-example/README.md +0 -16
  109. jac_client/examples/css-styling/sass-example/app.jac +0 -64
  110. jac_client/examples/css-styling/sass-example/package.json +0 -29
  111. jac_client/examples/css-styling/sass-example/styles.scss +0 -153
  112. jac_client/examples/css-styling/sass-example/vite.config.js +0 -27
  113. jac_client/examples/css-styling/styled-components/.babelrc +0 -9
  114. jac_client/examples/css-styling/styled-components/README.md +0 -16
  115. jac_client/examples/css-styling/styled-components/app.jac +0 -71
  116. jac_client/examples/css-styling/styled-components/package.json +0 -29
  117. jac_client/examples/css-styling/styled-components/styled.js +0 -90
  118. jac_client/examples/css-styling/styled-components/vite.config.js +0 -27
  119. jac_client/examples/css-styling/tailwind-example/.babelrc +0 -9
  120. jac_client/examples/css-styling/tailwind-example/README.md +0 -16
  121. jac_client/examples/css-styling/tailwind-example/app.jac +0 -63
  122. jac_client/examples/css-styling/tailwind-example/global.css +0 -1
  123. jac_client/examples/css-styling/tailwind-example/package.json +0 -30
  124. jac_client/examples/css-styling/tailwind-example/vite.config.js +0 -29
  125. jac_client/examples/full-stack-with-auth/.babelrc +0 -9
  126. jac_client/examples/full-stack-with-auth/README.md +0 -16
  127. jac_client/examples/full-stack-with-auth/app.jac +0 -722
  128. jac_client/examples/full-stack-with-auth/package.json +0 -28
  129. jac_client/examples/full-stack-with-auth/vite.config.js +0 -29
  130. jac_client/examples/little-x/app.jac +0 -724
  131. jac_client/examples/little-x/package.json +0 -23
  132. jac_client/examples/little-x/submit-button.jac +0 -8
  133. jac_client/examples/nested-folders/nested-advance/.babelrc +0 -9
  134. jac_client/examples/nested-folders/nested-advance/ButtonRoot.jac +0 -11
  135. jac_client/examples/nested-folders/nested-advance/README.md +0 -77
  136. jac_client/examples/nested-folders/nested-advance/app.jac +0 -35
  137. jac_client/examples/nested-folders/nested-advance/level1/ButtonSecondL.jac +0 -19
  138. jac_client/examples/nested-folders/nested-advance/level1/Card.jac +0 -43
  139. jac_client/examples/nested-folders/nested-advance/level1/level2/ButtonThirdL.jac +0 -25
  140. jac_client/examples/nested-folders/nested-advance/package.json +0 -29
  141. jac_client/examples/nested-folders/nested-advance/vite.config.js +0 -28
  142. jac_client/examples/nested-folders/nested-basic/.babelrc +0 -9
  143. jac_client/examples/nested-folders/nested-basic/README.md +0 -183
  144. jac_client/examples/nested-folders/nested-basic/app.jac +0 -13
  145. jac_client/examples/nested-folders/nested-basic/app.js +0 -7
  146. jac_client/examples/nested-folders/nested-basic/button.jac +0 -7
  147. jac_client/examples/nested-folders/nested-basic/components/button.jac +0 -7
  148. jac_client/examples/nested-folders/nested-basic/package.json +0 -28
  149. jac_client/examples/nested-folders/nested-basic/vite.config.js +0 -27
  150. jac_client/examples/with-router/.babelrc +0 -9
  151. jac_client/examples/with-router/README.md +0 -17
  152. jac_client/examples/with-router/app.jac +0 -323
  153. jac_client/examples/with-router/package.json +0 -28
  154. jac_client/examples/with-router/vite.config.js +0 -27
  155. jac_client/plugin/cli.py +0 -244
  156. jac_client/plugin/client.py +0 -152
  157. jac_client/plugin/client_runtime.jac +0 -234
  158. jac_client/plugin/vite_client_bundle.py +0 -503
  159. jac_client/tests/fixtures/basic-app/app.jac +0 -23
  160. jac_client/tests/fixtures/cl_file/app.cl.jac +0 -48
  161. jac_client/tests/fixtures/cl_file/app.jac +0 -15
  162. jac_client/tests/fixtures/client_app_with_antd/app.jac +0 -34
  163. jac_client/tests/fixtures/js_import/app.jac +0 -34
  164. jac_client/tests/fixtures/js_import/utils.js +0 -21
  165. jac_client/tests/fixtures/package-lock.json +0 -329
  166. jac_client/tests/fixtures/package.json +0 -11
  167. jac_client/tests/fixtures/relative_import/app.jac +0 -11
  168. jac_client/tests/fixtures/relative_import/button.jac +0 -7
  169. jac_client/tests/fixtures/spawn_test/app.jac +0 -129
  170. jac_client/tests/fixtures/test_fragments_spread/app.jac +0 -67
  171. jac_client/tests/test_asset_examples.py +0 -322
  172. jac_client/tests/test_cl.py +0 -530
  173. jac_client/tests/test_create_jac_app.py +0 -131
  174. jac_client/tests/test_nested_file.py +0 -374
  175. jac_client-0.2.3.dist-info/RECORD +0 -171
  176. jac_client-0.2.3.dist-info/entry_points.txt +0 -4
@@ -1,28 +0,0 @@
1
-
2
- import { defineConfig } from "vite";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
5
-
6
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
-
8
- export default defineConfig({
9
- root: ".", // base folder
10
- build: {
11
- rollupOptions: {
12
- input: "build/main.js", // your compiled entry file
13
- output: {
14
- entryFileNames: "client.[hash].js", // name of the final js file
15
- assetFileNames: "[name].[ext]",
16
- },
17
- },
18
- outDir: "dist", // final bundled output
19
- emptyOutDir: true,
20
- },
21
- publicDir: false,
22
- resolve: {
23
- alias: {
24
- "@jac-client/utils": path.resolve(__dirname, "src/client_runtime.js"),
25
- "@jac-client/assets": path.resolve(__dirname, "src/assets"),
26
- },
27
- },
28
- });
@@ -1,9 +0,0 @@
1
-
2
- {
3
- "presets": [[
4
- "@babel/preset-env",
5
- {
6
- "modules": false
7
- }
8
- ], "@babel/preset-react"]
9
- }
@@ -1,16 +0,0 @@
1
- # my-app
2
- make sure node modules are installed:
3
- ```bash
4
- npm install
5
- ```
6
-
7
-
8
- ## Running Jac Code
9
-
10
- To run your Jac code, use the Jac CLI:
11
-
12
- ```bash
13
- jac serve app.jac
14
- ```
15
-
16
- Happy coding with Jac!
@@ -1,21 +0,0 @@
1
- # Pages
2
- cl import from react { useState, useEffect }
3
- cl {
4
- def app() -> any {
5
- let [count, setCount] = useState(0);
6
- useEffect(lambda -> None{ console.log("Count: ", count);} , [count]);
7
- return <div>
8
- <h1>
9
- Hello, World!
10
- </h1>
11
- <p>
12
- Count: {count}
13
- </p>
14
- <button
15
- onClick={lambda e: any -> None{ setCount(count + 1);} }
16
- >
17
- Increment
18
- </button>
19
- </div>;
20
- }
21
- }
@@ -1,27 +0,0 @@
1
- {
2
- "name": "my-app",
3
- "version": "1.0.0",
4
- "main": "index.js",
5
- "scripts": {
6
- "build": "npm run compile && vite build",
7
- "dev": "vite dev",
8
- "preview": "vite preview",
9
- "compile": "babel src --out-dir build --extensions \".jsx,.js\" --out-file-extension .js"
10
- },
11
- "keywords": [],
12
- "author": "",
13
- "license": "ISC",
14
- "description": "Jac application: my-app",
15
- "type": "module",
16
- "devDependencies": {
17
- "vite": "^6.4.1",
18
- "@babel/cli": "^7.28.3",
19
- "@babel/core": "^7.28.5",
20
- "@babel/preset-env": "^7.28.5",
21
- "@babel/preset-react": "^7.28.5"
22
- },
23
- "dependencies": {
24
- "react": "^19.2.0",
25
- "react-dom": "^19.2.0"
26
- }
27
- }
@@ -1,27 +0,0 @@
1
-
2
- import { defineConfig } from "vite";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
5
-
6
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
-
8
- export default defineConfig({
9
- root: ".", // base folder
10
- build: {
11
- rollupOptions: {
12
- input: "build/main.js", // your compiled entry file
13
- output: {
14
- entryFileNames: "client.[hash].js", // name of the final js file
15
- assetFileNames: "[name].[ext]",
16
- },
17
- },
18
- outDir: "dist", // final bundled output
19
- emptyOutDir: true,
20
- },
21
- publicDir: false,
22
- resolve: {
23
- alias: {
24
- "@jac-client/utils": path.resolve(__dirname, "src/client_runtime.js"),
25
- },
26
- },
27
- });
@@ -1,9 +0,0 @@
1
-
2
- {
3
- "presets": [[
4
- "@babel/preset-env",
5
- {
6
- "modules": false
7
- }
8
- ], "@babel/preset-react"]
9
- }
@@ -1,16 +0,0 @@
1
- # basic-auth
2
-
3
- ## Running Jac Code
4
-
5
- make sure node modules are installed:
6
- ```bash
7
- npm install
8
- ```
9
-
10
- To run your Jac code, use the Jac CLI:
11
-
12
- ```bash
13
- jac serve app.jac
14
- ```
15
-
16
- Happy coding with Jac!
@@ -1,308 +0,0 @@
1
- # Simple Authentication App with Jac Client Utils
2
- cl import from react {useState, useEffect}
3
- cl import from '@jac-client/utils' {jacSignup, jacLogin, jacLogout, jacIsLoggedIn}
4
-
5
- cl {
6
- def app() -> any {
7
- let [isLoggedIn, setIsLoggedIn] = useState(False);
8
- let [isSignup, setIsSignup] = useState(False);
9
- let [username, setUsername] = useState("");
10
- let [password, setPassword] = useState("");
11
- let [error, setError] = useState("");
12
- let [loading, setLoading] = useState(False);
13
-
14
- # Check login status on mount
15
- useEffect(lambda -> None {
16
- setIsLoggedIn(jacIsLoggedIn());
17
- }, []);
18
-
19
- # Handle login
20
- async def handleLogin() -> None {
21
- setError("");
22
- if not username.trim() or not password {
23
- setError("Please fill in all fields");
24
- return;
25
- }
26
- setLoading(True);
27
- success = await jacLogin(username, password);
28
- setLoading(False);
29
- if success {
30
- setIsLoggedIn(True);
31
- setUsername("");
32
- setPassword("");
33
- } else {
34
- setError("Invalid username or password");
35
- }
36
- }
37
-
38
- # Handle signup
39
- async def handleSignup() -> None {
40
- setError("");
41
- if not username.trim() or not password {
42
- setError("Please fill in all fields");
43
- return;
44
- }
45
- if password.length < 6 {
46
- setError("Password must be at least 6 characters");
47
- return;
48
- }
49
- setLoading(True);
50
- result = await jacSignup(username, password);
51
- setLoading(False);
52
- if result["success"] {
53
- setIsLoggedIn(True);
54
- setUsername("");
55
- setPassword("");
56
- } else {
57
- setError(result["error"] if result["error"] else "Signup failed");
58
- }
59
- }
60
-
61
- # Handle logout
62
- def handleLogout() -> None {
63
- jacLogout();
64
- setIsLoggedIn(False);
65
- setUsername("");
66
- setPassword("");
67
- setError("");
68
- }
69
-
70
- # Handle form submit
71
- async def handleSubmit(e: any) -> None {
72
- e.preventDefault();
73
- if isSignup {
74
- await handleSignup();
75
- } else {
76
- await handleLogin();
77
- }
78
- }
79
-
80
- # Logged in view - Dashboard
81
- if isLoggedIn {
82
- return <div style={{
83
- "minHeight": "100vh",
84
- "background": "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
85
- "display": "flex",
86
- "alignItems": "center",
87
- "justifyContent": "center",
88
- "fontFamily": "system-ui, -apple-system, sans-serif"
89
- }}>
90
- <div style={{
91
- "background": "#ffffff",
92
- "borderRadius": "16px",
93
- "padding": "48px",
94
- "boxShadow": "0 20px 60px rgba(0,0,0,0.3)",
95
- "maxWidth": "500px",
96
- "width": "90%",
97
- "textAlign": "center"
98
- }}>
99
- <h1 style={{
100
- "fontSize": "2.5rem",
101
- "marginBottom": "16px",
102
- "color": "#1f2937",
103
- "fontWeight": "700"
104
- }}>✅ Welcome!</h1>
105
- <p style={{
106
- "fontSize": "1.1rem",
107
- "color": "#6b7280",
108
- "marginBottom": "32px"
109
- }}>You are successfully logged in</p>
110
-
111
- <div style={{
112
- "background": "#f3f4f6",
113
- "padding": "24px",
114
- "borderRadius": "12px",
115
- "marginBottom": "32px"
116
- }}>
117
- <p style={{
118
- "fontSize": "0.9rem",
119
- "color": "#6b7280",
120
- "marginBottom": "8px"
121
- }}>Logged in as:</p>
122
- <p style={{
123
- "fontSize": "1.2rem",
124
- "fontWeight": "600",
125
- "color": "#667eea"
126
- }}>User</p>
127
- </div>
128
-
129
- <button
130
- onClick={handleLogout}
131
- style={{
132
- "width": "100%",
133
- "padding": "14px 24px",
134
- "background": "#ef4444",
135
- "color": "#ffffff",
136
- "border": "none",
137
- "borderRadius": "10px",
138
- "fontSize": "16px",
139
- "fontWeight": "600",
140
- "cursor": "pointer",
141
- "transition": "all 0.3s",
142
- "boxShadow": "0 4px 12px rgba(239,68,68,0.3)"
143
- }}
144
- >
145
- Logout
146
- </button>
147
- </div>
148
- </div>;
149
- }
150
-
151
- # Login/Signup view
152
- return <div style={{
153
- "minHeight": "100vh",
154
- "background": "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
155
- "display": "flex",
156
- "alignItems": "center",
157
- "justifyContent": "center",
158
- "fontFamily": "system-ui, -apple-system, sans-serif",
159
- "padding": "20px"
160
- }}>
161
- <div style={{
162
- "background": "#ffffff",
163
- "borderRadius": "16px",
164
- "padding": "48px",
165
- "boxShadow": "0 20px 60px rgba(0,0,0,0.3)",
166
- "maxWidth": "400px",
167
- "width": "100%"
168
- }}>
169
- # Header
170
- <div style={{"textAlign": "center", "marginBottom": "32px"}}>
171
- <h1 style={{
172
- "fontSize": "2rem",
173
- "fontWeight": "700",
174
- "color": "#1f2937",
175
- "marginBottom": "8px"
176
- }}>
177
- {("Create Account" if isSignup else "Welcome Back")}
178
- </h1>
179
- <p style={{
180
- "color": "#6b7280",
181
- "fontSize": "0.95rem"
182
- }}>
183
- {("Sign up to get started" if isSignup else "Sign in to continue")}
184
- </p>
185
- </div>
186
-
187
- # Form
188
- <form onSubmit={handleSubmit} style={{"marginBottom": "24px"}}>
189
- <div style={{"marginBottom": "20px"}}>
190
- <label style={{
191
- "display": "block",
192
- "marginBottom": "8px",
193
- "color": "#374151",
194
- "fontSize": "14px",
195
- "fontWeight": "600"
196
- }}>Username</label>
197
- <input
198
- type="text"
199
- value={username}
200
- onChange={lambda e: any -> None { setUsername(e.target.value); }}
201
- placeholder="Enter your username"
202
- style={{
203
- "width": "100%",
204
- "padding": "12px 16px",
205
- "border": "2px solid #e5e7eb",
206
- "borderRadius": "10px",
207
- "fontSize": "16px",
208
- "outline": "none",
209
- "transition": "border 0.2s",
210
- "boxSizing": "border-box"
211
- }}
212
- />
213
- </div>
214
-
215
- <div style={{"marginBottom": "24px"}}>
216
- <label style={{
217
- "display": "block",
218
- "marginBottom": "8px",
219
- "color": "#374151",
220
- "fontSize": "14px",
221
- "fontWeight": "600"
222
- }}>Password</label>
223
- <input
224
- type="password"
225
- value={password}
226
- onChange={lambda e: any -> None { setPassword(e.target.value); }}
227
- placeholder="Enter your password"
228
- style={{
229
- "width": "100%",
230
- "padding": "12px 16px",
231
- "border": "2px solid #e5e7eb",
232
- "borderRadius": "10px",
233
- "fontSize": "16px",
234
- "outline": "none",
235
- "transition": "border 0.2s",
236
- "boxSizing": "border-box"
237
- }}
238
- />
239
- </div>
240
-
241
- {(<div style={{
242
- "padding": "12px",
243
- "background": "#fee2e2",
244
- "border": "1px solid #fecaca",
245
- "borderRadius": "8px",
246
- "marginBottom": "20px"
247
- }}>
248
- <p style={{
249
- "color": "#dc2626",
250
- "fontSize": "14px",
251
- "margin": "0"
252
- }}>{error}</p>
253
- </div>) if error else None}
254
-
255
- <button
256
- type="submit"
257
- disabled={loading}
258
- style={{
259
- "width": "100%",
260
- "padding": "14px 24px",
261
- "background": (("#9ca3af" if loading else "#667eea")),
262
- "color": "#ffffff",
263
- "border": "none",
264
- "borderRadius": "10px",
265
- "fontSize": "16px",
266
- "fontWeight": "600",
267
- "cursor": (("not-allowed" if loading else "pointer")),
268
- "transition": "all 0.3s",
269
- "boxShadow": "0 4px 12px rgba(102,126,234,0.4)"
270
- }}
271
- >
272
- {(("Processing..." if loading else ("Sign Up" if isSignup else "Sign In")))}
273
- </button>
274
- </form>
275
-
276
- # Toggle between login/signup
277
- <div style={{"textAlign": "center"}}>
278
- <p style={{
279
- "color": "#6b7280",
280
- "fontSize": "14px",
281
- "marginBottom": "8px"
282
- }}>
283
- {(("Already have an account?" if isSignup else "Don't have an account?"))}
284
- </p>
285
- <button
286
- onClick={lambda -> None {
287
- setIsSignup(not isSignup);
288
- setError("");
289
- setUsername("");
290
- setPassword("");
291
- }}
292
- style={{
293
- "background": "none",
294
- "border": "none",
295
- "color": "#667eea",
296
- "fontSize": "14px",
297
- "fontWeight": "600",
298
- "cursor": "pointer",
299
- "textDecoration": "underline"
300
- }}
301
- >
302
- {(("Sign In" if isSignup else "Create Account"))}
303
- </button>
304
- </div>
305
- </div>
306
- </div>;
307
- }
308
- }
@@ -1,27 +0,0 @@
1
- {
2
- "name": "basic-auth",
3
- "version": "1.0.0",
4
- "main": "index.js",
5
- "scripts": {
6
- "build": "npm run compile && vite build",
7
- "dev": "vite dev",
8
- "preview": "vite preview",
9
- "compile": "babel src --out-dir build --extensions \".jsx,.js\" --out-file-extension .js"
10
- },
11
- "keywords": [],
12
- "author": "",
13
- "license": "ISC",
14
- "description": "Jac application: basic-auth",
15
- "type": "module",
16
- "devDependencies": {
17
- "vite": "^6.4.1",
18
- "@babel/cli": "^7.28.3",
19
- "@babel/core": "^7.28.5",
20
- "@babel/preset-env": "^7.28.5",
21
- "@babel/preset-react": "^7.28.5"
22
- },
23
- "dependencies": {
24
- "react": "^19.2.0",
25
- "react-dom": "^19.2.0"
26
- }
27
- }
@@ -1,27 +0,0 @@
1
-
2
- import { defineConfig } from "vite";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
5
-
6
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
-
8
- export default defineConfig({
9
- root: ".", // base folder
10
- build: {
11
- rollupOptions: {
12
- input: "build/main.js", // your compiled entry file
13
- output: {
14
- entryFileNames: "client.[hash].js", // name of the final js file
15
- assetFileNames: "[name].[ext]",
16
- },
17
- },
18
- outDir: "dist", // final bundled output
19
- emptyOutDir: true,
20
- },
21
- publicDir: false,
22
- resolve: {
23
- alias: {
24
- "@jac-client/utils": path.resolve(__dirname, "src/client_runtime.js"),
25
- },
26
- },
27
- });
@@ -1,9 +0,0 @@
1
-
2
- {
3
- "presets": [[
4
- "@babel/preset-env",
5
- {
6
- "modules": false
7
- }
8
- ], "@babel/preset-react"]
9
- }
@@ -1,60 +0,0 @@
1
- # Basic Authentication with React Router
2
-
3
- A complete authentication example using Jac with React Router for client-side routing.
4
-
5
- ## Features
6
-
7
- - ✨ **React Router Integration** - Hash-based routing using `react-router-dom` v6
8
- - 🔐 **User Authentication** - Login and signup functionality
9
- - 🛡️ **Protected Routes** - Dashboard page accessible only to authenticated users
10
- - 🎨 **Modern UI** - Clean, responsive design
11
- - 🔄 **Navigation Guards** - Automatic redirects for unauthenticated users
12
- - 💾 **LocalStorage Session** - Persistent authentication state
13
-
14
- ## React Router Features Demonstrated
15
-
16
- - `HashRouter` for hash-based routing (`#/login`, `#/dashboard`)
17
- - `useNavigate()` hook for programmatic navigation
18
- - `useLocation()` hook for accessing current location
19
- - `<Navigate />` component for conditional redirects
20
- - `<Link />` component for declarative navigation
21
- - `<Routes />` and `<Route />` for route definitions
22
-
23
- ## Setup
24
-
25
- Install dependencies:
26
- ```bash
27
- npm install
28
- ```
29
-
30
- ## Running the App
31
-
32
- Start the development server:
33
- ```bash
34
- jac serve app.jac
35
- ```
36
-
37
- Then open your browser to `http://localhost:8000`
38
-
39
- ## Usage
40
-
41
- 1. **Sign Up**: Create a new account at `#/signup`
42
- 2. **Login**: Access your account at `#/login`
43
- 3. **Dashboard**: View protected content at `#/dashboard` (requires login)
44
- 4. **Logout**: Click the logout button in the navigation
45
-
46
- ## Project Structure
47
-
48
- - `app.jac` - Main application with routing and authentication logic
49
- - `package.json` - Dependencies including `react-router-dom` v6.30.1
50
- - Session files - User data and tokens stored locally
51
-
52
- ## Authentication Flow
53
-
54
- 1. User signs up or logs in
55
- 2. Token stored in localStorage
56
- 3. Navigation redirects to dashboard
57
- 4. Protected routes check authentication status
58
- 5. Unauthenticated access redirects to login
59
-
60
- Happy coding with Jac! 🚀