jac-client 0.2.10__py3-none-any.whl → 0.2.12__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.
- jac_client/examples/all-in-one/button.jac +4 -3
- jac_client/examples/all-in-one/components/CategoryFilter.jac +36 -24
- jac_client/examples/all-in-one/components/Header.jac +12 -8
- jac_client/examples/all-in-one/components/ProfitOverview.jac +49 -35
- jac_client/examples/all-in-one/components/Summary.jac +59 -36
- jac_client/examples/all-in-one/components/TransactionForm.jac +142 -112
- jac_client/examples/all-in-one/components/TransactionItem.jac +37 -30
- jac_client/examples/all-in-one/components/TransactionList.jac +33 -26
- jac_client/examples/all-in-one/components/button.jac +4 -3
- jac_client/examples/all-in-one/components/navigation.jac +111 -117
- jac_client/examples/all-in-one/constants/categories.jac +23 -24
- jac_client/examples/all-in-one/constants/clients.jac +7 -8
- jac_client/examples/all-in-one/context/BudgetContext.jac +9 -6
- jac_client/examples/all-in-one/hooks/useBudget.jac +18 -12
- jac_client/examples/all-in-one/hooks/useLocalStorage.jac +14 -13
- jac_client/examples/all-in-one/main.jac +340 -371
- jac_client/examples/all-in-one/pages/BudgetPlanner.jac +19 -12
- jac_client/examples/all-in-one/pages/FeaturesTest.jac +31 -15
- jac_client/examples/all-in-one/pages/LandingPage.jac +113 -90
- jac_client/examples/all-in-one/pages/budget_planner_ui.cl.jac +34 -39
- jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +464 -352
- jac_client/examples/all-in-one/pages/loginPage.jac +114 -119
- jac_client/examples/all-in-one/pages/nestedDemo.jac +43 -50
- jac_client/examples/all-in-one/pages/notFound.jac +14 -15
- jac_client/examples/all-in-one/pages/signupPage.jac +113 -119
- jac_client/examples/all-in-one/utils/formatters.jac +5 -8
- jac_client/examples/asset-serving/css-with-image/main.jac +77 -73
- jac_client/examples/asset-serving/image-asset/main.jac +47 -46
- jac_client/examples/asset-serving/import-alias/main.jac +93 -95
- jac_client/examples/basic/main.jac +17 -15
- jac_client/examples/basic-auth/main.jac +246 -254
- jac_client/examples/basic-auth-with-router/main.jac +272 -285
- jac_client/examples/basic-full-stack/main.jac +245 -242
- jac_client/examples/css-styling/js-styling/main.jac +41 -62
- jac_client/examples/css-styling/material-ui/main.jac +90 -90
- jac_client/examples/css-styling/pure-css/main.jac +35 -44
- jac_client/examples/css-styling/sass-example/main.jac +35 -44
- jac_client/examples/css-styling/styled-components/main.jac +38 -47
- jac_client/examples/css-styling/tailwind-example/main.jac +54 -43
- jac_client/examples/full-stack-with-auth/main.jac +407 -433
- jac_client/examples/little-x/main.jac +306 -344
- jac_client/examples/little-x/src/submit-button.jac +15 -14
- jac_client/examples/nested-folders/nested-advance/main.jac +18 -27
- jac_client/examples/nested-folders/nested-advance/src/ButtonRoot.jac +4 -6
- jac_client/examples/nested-folders/nested-advance/src/level1/ButtonSecondL.jac +9 -13
- jac_client/examples/nested-folders/nested-advance/src/level1/Card.jac +29 -32
- jac_client/examples/nested-folders/nested-advance/src/level1/level2/ButtonThirdL.jac +12 -18
- jac_client/examples/nested-folders/nested-basic/main.jac +7 -5
- jac_client/examples/nested-folders/nested-basic/src/button.jac +4 -3
- jac_client/examples/nested-folders/nested-basic/src/components/button.jac +4 -3
- jac_client/examples/ts-support/main.jac +26 -26
- jac_client/examples/with-router/main.jac +186 -223
- jac_client/plugin/client_runtime.cl.jac +5 -3
- jac_client/plugin/impl/client_runtime.impl.jac +1 -1
- jac_client/plugin/plugin_config.jac +53 -99
- jac_client/plugin/src/__init__.jac +0 -2
- jac_client/plugin/src/compiler.jac +0 -1
- jac_client/plugin/src/impl/compiler.impl.jac +49 -17
- jac_client/plugin/src/impl/jac_to_js.impl.jac +5 -1
- jac_client/plugin/src/impl/package_installer.impl.jac +20 -20
- jac_client/plugin/src/impl/vite_bundler.impl.jac +146 -84
- jac_client/plugin/src/targets/impl/desktop_target.impl.jac +54 -41
- jac_client/plugin/utils/__init__.jac +3 -0
- jac_client/plugin/utils/bun_installer.jac +16 -0
- jac_client/plugin/utils/client_deps.jac +14 -0
- jac_client/plugin/utils/impl/bun_installer.impl.jac +99 -0
- jac_client/plugin/utils/impl/client_deps.impl.jac +73 -0
- jac_client/templates/client.jacpack +0 -4
- jac_client/templates/fullstack.jacpack +1 -5
- jac_client/tests/conftest.py +56 -41
- jac_client/tests/fixtures/spawn_test/app.jac +49 -52
- jac_client/tests/fixtures/with-ts/app.jac +27 -27
- jac_client/tests/test_cli.py +71 -6
- jac_client/tests/test_helpers.py +11 -18
- jac_client/tests/test_it.py +1 -1
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/METADATA +5 -5
- jac_client-0.2.12.dist-info/RECORD +115 -0
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/WHEEL +1 -1
- jac_client/plugin/src/babel_processor.jac +0 -18
- jac_client/plugin/src/impl/babel_processor.impl.jac +0 -89
- jac_client/plugin/utils/impl/node_installer.impl.jac +0 -249
- jac_client/plugin/utils/node_installer.jac +0 -41
- jac_client-0.2.10.dist-info/RECORD +0 -115
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/entry_points.txt +0 -0
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/top_level.txt +0 -0
|
@@ -3,7 +3,7 @@ cl import from react {
|
|
|
3
3
|
useState,
|
|
4
4
|
useEffect
|
|
5
5
|
}
|
|
6
|
-
cl import from "@jac
|
|
6
|
+
cl import from "@jac/runtime" {
|
|
7
7
|
Router,
|
|
8
8
|
Routes,
|
|
9
9
|
Route,
|
|
@@ -30,7 +30,51 @@ cl {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
if isLoggedIn {
|
|
33
|
-
return
|
|
33
|
+
return
|
|
34
|
+
<nav
|
|
35
|
+
style={{
|
|
36
|
+
"padding": "16px 24px",
|
|
37
|
+
"background": "#667eea",
|
|
38
|
+
"display": "flex",
|
|
39
|
+
"justifyContent": "space-between",
|
|
40
|
+
"alignItems": "center"
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
<div
|
|
44
|
+
style={{
|
|
45
|
+
"fontSize": "1.25rem",
|
|
46
|
+
"fontWeight": "600",
|
|
47
|
+
"color": "#ffffff"
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
MyApp
|
|
51
|
+
</div>
|
|
52
|
+
<div style={{"display": "flex", "gap": "16px"}}>
|
|
53
|
+
<Link
|
|
54
|
+
to="/dashboard"
|
|
55
|
+
style={{"color": "#ffffff", "textDecoration": "none"}}
|
|
56
|
+
>
|
|
57
|
+
Dashboard
|
|
58
|
+
</Link>
|
|
59
|
+
<button
|
|
60
|
+
onClick={handleLogout}
|
|
61
|
+
style={{
|
|
62
|
+
"background": "none",
|
|
63
|
+
"color": "#ffffff",
|
|
64
|
+
"border": "1px solid #ffffff",
|
|
65
|
+
"padding": "4px 12px",
|
|
66
|
+
"borderRadius": "4px",
|
|
67
|
+
"cursor": "pointer"
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
Logout
|
|
71
|
+
</button>
|
|
72
|
+
</div>
|
|
73
|
+
</nav>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return
|
|
77
|
+
<nav
|
|
34
78
|
style={{
|
|
35
79
|
"padding": "16px 24px",
|
|
36
80
|
"background": "#667eea",
|
|
@@ -48,70 +92,29 @@ cl {
|
|
|
48
92
|
>
|
|
49
93
|
MyApp
|
|
50
94
|
</div>
|
|
51
|
-
<div
|
|
52
|
-
style={{"display": "flex", "gap": "16px"}}
|
|
53
|
-
>
|
|
95
|
+
<div style={{"display": "flex", "gap": "16px"}}>
|
|
54
96
|
<Link
|
|
55
|
-
to="/
|
|
97
|
+
to="/login"
|
|
56
98
|
style={{"color": "#ffffff", "textDecoration": "none"}}
|
|
57
99
|
>
|
|
58
|
-
|
|
100
|
+
Login
|
|
59
101
|
</Link>
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
style={{
|
|
63
|
-
"background": "none",
|
|
64
|
-
"color": "#ffffff",
|
|
65
|
-
"border": "1px solid #ffffff",
|
|
66
|
-
"padding": "4px 12px",
|
|
67
|
-
"borderRadius": "4px",
|
|
68
|
-
"cursor": "pointer"
|
|
69
|
-
}}
|
|
102
|
+
<Link
|
|
103
|
+
to="/signup"
|
|
104
|
+
style={{"color": "#ffffff", "textDecoration": "none"}}
|
|
70
105
|
>
|
|
71
|
-
|
|
72
|
-
</
|
|
106
|
+
Sign Up
|
|
107
|
+
</Link>
|
|
73
108
|
</div>
|
|
74
109
|
</nav>;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return <nav
|
|
78
|
-
style={{
|
|
79
|
-
"padding": "16px 24px",
|
|
80
|
-
"background": "#667eea",
|
|
81
|
-
"display": "flex",
|
|
82
|
-
"justifyContent": "space-between",
|
|
83
|
-
"alignItems": "center"
|
|
84
|
-
}}
|
|
85
|
-
>
|
|
86
|
-
<div
|
|
87
|
-
style={{"fontSize": "1.25rem", "fontWeight": "600", "color": "#ffffff"}}
|
|
88
|
-
>
|
|
89
|
-
MyApp
|
|
90
|
-
</div>
|
|
91
|
-
<div
|
|
92
|
-
style={{"display": "flex", "gap": "16px"}}
|
|
93
|
-
>
|
|
94
|
-
<Link
|
|
95
|
-
to="/login"
|
|
96
|
-
style={{"color": "#ffffff", "textDecoration": "none"}}
|
|
97
|
-
>
|
|
98
|
-
Login
|
|
99
|
-
</Link>
|
|
100
|
-
<Link
|
|
101
|
-
to="/signup"
|
|
102
|
-
style={{"color": "#ffffff", "textDecoration": "none"}}
|
|
103
|
-
>
|
|
104
|
-
Sign Up
|
|
105
|
-
</Link>
|
|
106
|
-
</div>
|
|
107
|
-
</nav>;
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
# Login Page
|
|
111
113
|
def LoginPage -> any {
|
|
112
|
-
has username: str = ""
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
has username: str = "",
|
|
115
|
+
password: str = "",
|
|
116
|
+
error: str = "";
|
|
117
|
+
|
|
115
118
|
navigate = useNavigate();
|
|
116
119
|
|
|
117
120
|
async def handleLogin(e: any) -> None {
|
|
@@ -146,98 +149,96 @@ cl {
|
|
|
146
149
|
</div>;
|
|
147
150
|
}
|
|
148
151
|
|
|
149
|
-
return
|
|
150
|
-
style={{
|
|
151
|
-
"minHeight": "calc(100vh - 56px)",
|
|
152
|
-
"display": "flex",
|
|
153
|
-
"alignItems": "center",
|
|
154
|
-
"justifyContent": "center",
|
|
155
|
-
"background": "#f5f5f5"
|
|
156
|
-
}}
|
|
157
|
-
>
|
|
152
|
+
return
|
|
158
153
|
<div
|
|
159
154
|
style={{
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
155
|
+
"minHeight": "calc(100vh - 56px)",
|
|
156
|
+
"display": "flex",
|
|
157
|
+
"alignItems": "center",
|
|
158
|
+
"justifyContent": "center",
|
|
159
|
+
"background": "#f5f5f5"
|
|
165
160
|
}}
|
|
166
161
|
>
|
|
167
|
-
<
|
|
168
|
-
style={{
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
162
|
+
<div
|
|
163
|
+
style={{
|
|
164
|
+
"background": "#ffffff",
|
|
165
|
+
"padding": "32px",
|
|
166
|
+
"borderRadius": "8px",
|
|
167
|
+
"width": "300px",
|
|
168
|
+
"boxShadow": "0 2px 8px rgba(0,0,0,0.1)"
|
|
169
|
+
}}
|
|
174
170
|
>
|
|
175
|
-
<
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
"
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
"
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
171
|
+
<h2 style={{"marginBottom": "24px", "textAlign": "center"}}>
|
|
172
|
+
Login
|
|
173
|
+
</h2>
|
|
174
|
+
<form onSubmit={handleLogin}>
|
|
175
|
+
<input
|
|
176
|
+
type="text"
|
|
177
|
+
value={username}
|
|
178
|
+
onChange={handleUsernameChange}
|
|
179
|
+
placeholder="Username"
|
|
180
|
+
style={{
|
|
181
|
+
"width": "100%",
|
|
182
|
+
"padding": "10px",
|
|
183
|
+
"marginBottom": "12px",
|
|
184
|
+
"border": "1px solid #ddd",
|
|
185
|
+
"borderRadius": "4px",
|
|
186
|
+
"boxSizing": "border-box"
|
|
187
|
+
}}
|
|
188
|
+
/>
|
|
189
|
+
<input
|
|
190
|
+
type="password"
|
|
191
|
+
value={password}
|
|
192
|
+
onChange={handlePasswordChange}
|
|
193
|
+
placeholder="Password"
|
|
194
|
+
style={{
|
|
195
|
+
"width": "100%",
|
|
196
|
+
"padding": "10px",
|
|
197
|
+
"marginBottom": "12px",
|
|
198
|
+
"border": "1px solid #ddd",
|
|
199
|
+
"borderRadius": "4px",
|
|
200
|
+
"boxSizing": "border-box"
|
|
201
|
+
}}
|
|
202
|
+
/>
|
|
203
|
+
{errorDisplay}
|
|
204
|
+
<button
|
|
205
|
+
type="submit"
|
|
206
|
+
style={{
|
|
207
|
+
"width": "100%",
|
|
208
|
+
"padding": "10px",
|
|
209
|
+
"background": "#667eea",
|
|
210
|
+
"color": "#ffffff",
|
|
211
|
+
"border": "none",
|
|
212
|
+
"borderRadius": "4px",
|
|
213
|
+
"cursor": "pointer",
|
|
214
|
+
"fontWeight": "600"
|
|
215
|
+
}}
|
|
216
|
+
>
|
|
217
|
+
Login
|
|
218
|
+
</button>
|
|
219
|
+
</form>
|
|
220
|
+
<p
|
|
206
221
|
style={{
|
|
207
|
-
"
|
|
208
|
-
"
|
|
209
|
-
"
|
|
210
|
-
"color": "#ffffff",
|
|
211
|
-
"border": "none",
|
|
212
|
-
"borderRadius": "4px",
|
|
213
|
-
"cursor": "pointer",
|
|
214
|
-
"fontWeight": "600"
|
|
222
|
+
"textAlign": "center",
|
|
223
|
+
"marginTop": "16px",
|
|
224
|
+
"fontSize": "14px"
|
|
215
225
|
}}
|
|
216
226
|
>
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
"fontSize": "14px"
|
|
225
|
-
}}
|
|
226
|
-
>
|
|
227
|
-
Need an account?
|
|
228
|
-
<Link to="/signup">
|
|
229
|
-
Sign up
|
|
230
|
-
</Link>
|
|
231
|
-
</p>
|
|
232
|
-
</div>
|
|
233
|
-
</div>;
|
|
227
|
+
Need an account?
|
|
228
|
+
<Link to="/signup">
|
|
229
|
+
Sign up
|
|
230
|
+
</Link>
|
|
231
|
+
</p>
|
|
232
|
+
</div>
|
|
233
|
+
</div>;
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
# Signup Page
|
|
237
237
|
def SignupPage -> any {
|
|
238
|
-
has username: str = ""
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
has username: str = "",
|
|
239
|
+
password: str = "",
|
|
240
|
+
error: str = "";
|
|
241
|
+
|
|
241
242
|
navigate = useNavigate();
|
|
242
243
|
|
|
243
244
|
async def handleSignup(e: any) -> None {
|
|
@@ -272,193 +273,179 @@ cl {
|
|
|
272
273
|
</div>;
|
|
273
274
|
}
|
|
274
275
|
|
|
275
|
-
return
|
|
276
|
-
style={{
|
|
277
|
-
"minHeight": "calc(100vh - 56px)",
|
|
278
|
-
"display": "flex",
|
|
279
|
-
"alignItems": "center",
|
|
280
|
-
"justifyContent": "center",
|
|
281
|
-
"background": "#f5f5f5"
|
|
282
|
-
}}
|
|
283
|
-
>
|
|
276
|
+
return
|
|
284
277
|
<div
|
|
285
278
|
style={{
|
|
286
|
-
"
|
|
287
|
-
"
|
|
288
|
-
"
|
|
289
|
-
"
|
|
290
|
-
"
|
|
279
|
+
"minHeight": "calc(100vh - 56px)",
|
|
280
|
+
"display": "flex",
|
|
281
|
+
"alignItems": "center",
|
|
282
|
+
"justifyContent": "center",
|
|
283
|
+
"background": "#f5f5f5"
|
|
291
284
|
}}
|
|
292
285
|
>
|
|
293
|
-
<
|
|
294
|
-
style={{
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
286
|
+
<div
|
|
287
|
+
style={{
|
|
288
|
+
"background": "#ffffff",
|
|
289
|
+
"padding": "32px",
|
|
290
|
+
"borderRadius": "8px",
|
|
291
|
+
"width": "300px",
|
|
292
|
+
"boxShadow": "0 2px 8px rgba(0,0,0,0.1)"
|
|
293
|
+
}}
|
|
300
294
|
>
|
|
301
|
-
<
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
"
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
"
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
295
|
+
<h2 style={{"marginBottom": "24px", "textAlign": "center"}}>
|
|
296
|
+
Sign Up
|
|
297
|
+
</h2>
|
|
298
|
+
<form onSubmit={handleSignup}>
|
|
299
|
+
<input
|
|
300
|
+
type="text"
|
|
301
|
+
value={username}
|
|
302
|
+
onChange={handleUsernameChange}
|
|
303
|
+
placeholder="Username"
|
|
304
|
+
style={{
|
|
305
|
+
"width": "100%",
|
|
306
|
+
"padding": "10px",
|
|
307
|
+
"marginBottom": "12px",
|
|
308
|
+
"border": "1px solid #ddd",
|
|
309
|
+
"borderRadius": "4px",
|
|
310
|
+
"boxSizing": "border-box"
|
|
311
|
+
}}
|
|
312
|
+
/>
|
|
313
|
+
<input
|
|
314
|
+
type="password"
|
|
315
|
+
value={password}
|
|
316
|
+
onChange={handlePasswordChange}
|
|
317
|
+
placeholder="Password"
|
|
318
|
+
style={{
|
|
319
|
+
"width": "100%",
|
|
320
|
+
"padding": "10px",
|
|
321
|
+
"marginBottom": "12px",
|
|
322
|
+
"border": "1px solid #ddd",
|
|
323
|
+
"borderRadius": "4px",
|
|
324
|
+
"boxSizing": "border-box"
|
|
325
|
+
}}
|
|
326
|
+
/>
|
|
327
|
+
{errorDisplay}
|
|
328
|
+
<button
|
|
329
|
+
type="submit"
|
|
330
|
+
style={{
|
|
331
|
+
"width": "100%",
|
|
332
|
+
"padding": "10px",
|
|
333
|
+
"background": "#667eea",
|
|
334
|
+
"color": "#ffffff",
|
|
335
|
+
"border": "none",
|
|
336
|
+
"borderRadius": "4px",
|
|
337
|
+
"cursor": "pointer",
|
|
338
|
+
"fontWeight": "600"
|
|
339
|
+
}}
|
|
340
|
+
>
|
|
341
|
+
Sign Up
|
|
342
|
+
</button>
|
|
343
|
+
</form>
|
|
344
|
+
<p
|
|
332
345
|
style={{
|
|
333
|
-
"
|
|
334
|
-
"
|
|
335
|
-
"
|
|
336
|
-
"color": "#ffffff",
|
|
337
|
-
"border": "none",
|
|
338
|
-
"borderRadius": "4px",
|
|
339
|
-
"cursor": "pointer",
|
|
340
|
-
"fontWeight": "600"
|
|
346
|
+
"textAlign": "center",
|
|
347
|
+
"marginTop": "16px",
|
|
348
|
+
"fontSize": "14px"
|
|
341
349
|
}}
|
|
342
350
|
>
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
"fontSize": "14px"
|
|
351
|
-
}}
|
|
352
|
-
>
|
|
353
|
-
Have an account?
|
|
354
|
-
<Link to="/login">
|
|
355
|
-
Login
|
|
356
|
-
</Link>
|
|
357
|
-
</p>
|
|
358
|
-
</div>
|
|
359
|
-
</div>;
|
|
351
|
+
Have an account?
|
|
352
|
+
<Link to="/login">
|
|
353
|
+
Login
|
|
354
|
+
</Link>
|
|
355
|
+
</p>
|
|
356
|
+
</div>
|
|
357
|
+
</div>;
|
|
360
358
|
}
|
|
361
359
|
|
|
362
360
|
# Dashboard Page (Protected Route)
|
|
363
361
|
def DashboardPage -> any {
|
|
364
362
|
# Check if user is logged in, redirect if not
|
|
365
363
|
if not jacIsLoggedIn() {
|
|
366
|
-
return
|
|
364
|
+
return
|
|
365
|
+
<Navigate to="/login" />;
|
|
367
366
|
}
|
|
368
367
|
|
|
369
|
-
return
|
|
370
|
-
style={{
|
|
371
|
-
"minHeight": "calc(100vh - 56px)",
|
|
372
|
-
"padding": "40px 20px",
|
|
373
|
-
"background": "#f5f5f5"
|
|
374
|
-
}}
|
|
375
|
-
>
|
|
368
|
+
return
|
|
376
369
|
<div
|
|
377
370
|
style={{
|
|
378
|
-
"
|
|
379
|
-
"
|
|
380
|
-
"background": "#
|
|
381
|
-
"padding": "40px",
|
|
382
|
-
"borderRadius": "8px",
|
|
383
|
-
"boxShadow": "0 2px 8px rgba(0,0,0,0.1)"
|
|
371
|
+
"minHeight": "calc(100vh - 56px)",
|
|
372
|
+
"padding": "40px 20px",
|
|
373
|
+
"background": "#f5f5f5"
|
|
384
374
|
}}
|
|
385
375
|
>
|
|
386
|
-
<h1
|
|
387
|
-
style={{"marginBottom": "16px"}}
|
|
388
|
-
>
|
|
389
|
-
🎉 Welcome to Your Dashboard
|
|
390
|
-
</h1>
|
|
391
|
-
<p
|
|
392
|
-
style={{"color": "#666", "lineHeight": "1.6"}}
|
|
393
|
-
>
|
|
394
|
-
You are now logged in and can access protected content.
|
|
395
|
-
</p>
|
|
396
|
-
<p
|
|
397
|
-
style={{"color": "#666", "lineHeight": "1.6", "marginTop": "16px"}}
|
|
398
|
-
>
|
|
399
|
-
This is a simple dashboard page demonstrating authenticationwith React Router in Jac. You can add your own content and functionality here.
|
|
400
|
-
</p>
|
|
401
376
|
<div
|
|
402
377
|
style={{
|
|
403
|
-
"
|
|
404
|
-
"
|
|
405
|
-
"background": "#
|
|
406
|
-
"
|
|
407
|
-
"
|
|
378
|
+
"maxWidth": "800px",
|
|
379
|
+
"margin": "0 auto",
|
|
380
|
+
"background": "#ffffff",
|
|
381
|
+
"padding": "40px",
|
|
382
|
+
"borderRadius": "8px",
|
|
383
|
+
"boxShadow": "0 2px 8px rgba(0,0,0,0.1)"
|
|
408
384
|
}}
|
|
409
385
|
>
|
|
410
|
-
<
|
|
411
|
-
|
|
412
|
-
>
|
|
413
|
-
|
|
414
|
-
|
|
386
|
+
<h1 style={{"marginBottom": "16px"}}>
|
|
387
|
+
🎉 Welcome to Your Dashboard
|
|
388
|
+
</h1>
|
|
389
|
+
<p style={{"color": "#666", "lineHeight": "1.6"}}>
|
|
390
|
+
You are now logged in and can access protected content.
|
|
391
|
+
</p>
|
|
415
392
|
<p
|
|
416
|
-
style={{
|
|
393
|
+
style={{
|
|
394
|
+
"color": "#666",
|
|
395
|
+
"lineHeight": "1.6",
|
|
396
|
+
"marginTop": "16px"
|
|
397
|
+
}}
|
|
417
398
|
>
|
|
418
|
-
This
|
|
399
|
+
This is a simple dashboard page demonstrating authenticationwith React Router in Jac. You can add your own content and functionality here.
|
|
419
400
|
</p>
|
|
401
|
+
<div
|
|
402
|
+
style={{
|
|
403
|
+
"marginTop": "24px",
|
|
404
|
+
"padding": "16px",
|
|
405
|
+
"background": "#f0f9ff",
|
|
406
|
+
"borderRadius": "4px",
|
|
407
|
+
"border": "1px solid #bae6fd"
|
|
408
|
+
}}
|
|
409
|
+
>
|
|
410
|
+
<h3 style={{"marginBottom": "8px", "color": "#0369a1"}}>
|
|
411
|
+
Protected Route Demo
|
|
412
|
+
</h3>
|
|
413
|
+
<p style={{"color": "#0c4a6e", "fontSize": "14px"}}>
|
|
414
|
+
This page is only accessible to authenticated users. Try logging outand accessing this page - you'll be redirected to the login page!
|
|
415
|
+
</p>
|
|
416
|
+
</div>
|
|
420
417
|
</div>
|
|
421
|
-
</div
|
|
422
|
-
</div>;
|
|
418
|
+
</div>;
|
|
423
419
|
}
|
|
424
420
|
|
|
425
421
|
# Home/Landing Page - auto-redirect based on auth status
|
|
426
422
|
def HomePage -> any {
|
|
427
423
|
if jacIsLoggedIn() {
|
|
428
|
-
return
|
|
424
|
+
return
|
|
425
|
+
<Navigate to="/dashboard" />;
|
|
429
426
|
}
|
|
430
|
-
return
|
|
427
|
+
return
|
|
428
|
+
<Navigate to="/login" />;
|
|
431
429
|
}
|
|
432
430
|
|
|
433
431
|
# Main App with React Router
|
|
434
432
|
def:pub app -> any {
|
|
435
|
-
return
|
|
436
|
-
<
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
<
|
|
445
|
-
path="/"
|
|
446
|
-
element={<
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
<Route
|
|
453
|
-
path="/signup"
|
|
454
|
-
element={<SignupPage />}
|
|
455
|
-
/>
|
|
456
|
-
<Route
|
|
457
|
-
path="/dashboard"
|
|
458
|
-
element={<DashboardPage />}
|
|
459
|
-
/>
|
|
460
|
-
</Routes>
|
|
461
|
-
</div>
|
|
462
|
-
</Router>;
|
|
433
|
+
return
|
|
434
|
+
<Router>
|
|
435
|
+
<div
|
|
436
|
+
style={{
|
|
437
|
+
"fontFamily": "system-ui, -apple-system, sans-serif",
|
|
438
|
+
"minHeight": "100vh"
|
|
439
|
+
}}
|
|
440
|
+
>
|
|
441
|
+
<Navigation />
|
|
442
|
+
<Routes>
|
|
443
|
+
<Route path="/" element={<HomePage />} />
|
|
444
|
+
<Route path="/login" element={<LoginPage />} />
|
|
445
|
+
<Route path="/signup" element={<SignupPage />} />
|
|
446
|
+
<Route path="/dashboard" element={<DashboardPage />} />
|
|
447
|
+
</Routes>
|
|
448
|
+
</div>
|
|
449
|
+
</Router>;
|
|
463
450
|
}
|
|
464
451
|
}
|