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
|
@@ -9,27 +9,27 @@ node Profile {
|
|
|
9
9
|
|
|
10
10
|
can update with update_profile entry {
|
|
11
11
|
self.username = visitor.new_username;
|
|
12
|
-
report self
|
|
12
|
+
report self;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
can get with get_profile entry {
|
|
16
16
|
follwers = [
|
|
17
17
|
{"id": jid(i), "username": i.username} for i in [self-->(`?Profile)]
|
|
18
18
|
];
|
|
19
|
-
report {"user": self, "followers": follwers}
|
|
19
|
+
report {"user": self, "followers": follwers};
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
can follow with follow_request entry {
|
|
23
23
|
current_profile = [root-->(`?Profile)];
|
|
24
24
|
current_profile[0] +>: Follow() :+> self;
|
|
25
|
-
report self
|
|
25
|
+
report self;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
can un_follow with un_follow_request entry {
|
|
29
29
|
current_profile = [root-->(`?Profile)];
|
|
30
30
|
follow_edge = [edge current_profile[0]->:Follow:->self];
|
|
31
|
-
del follow_edge[0]
|
|
32
|
-
report self
|
|
31
|
+
del follow_edge[0];
|
|
32
|
+
report self;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -49,25 +49,25 @@ node Tweet {
|
|
|
49
49
|
|
|
50
50
|
can update with update_tweet exit {
|
|
51
51
|
self.content = visitor.updated_content;
|
|
52
|
-
report self
|
|
52
|
+
report self;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
can delete with remove_tweet exit {
|
|
56
|
-
del self
|
|
56
|
+
del self;
|
|
57
57
|
disengage;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
can like_tweet with like_tweet entry {
|
|
61
61
|
current_profile = [root-->(`?Profile)];
|
|
62
62
|
self +>: Like() :+> current_profile[0];
|
|
63
|
-
report self
|
|
63
|
+
report self;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
can remove_like with remove_like entry {
|
|
67
67
|
current_profile = [root-->(`?Profile)];
|
|
68
68
|
like_edge = [edge self->:Like:->current_profile[0]];
|
|
69
|
-
del like_edge[0]
|
|
70
|
-
report self
|
|
69
|
+
del like_edge[0];
|
|
70
|
+
report self;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
can comment with comment_tweet entry {
|
|
@@ -77,7 +77,7 @@ node Tweet {
|
|
|
77
77
|
);
|
|
78
78
|
grant(comment_node[0], level=ConnectPerm);
|
|
79
79
|
self ++> comment_node[0];
|
|
80
|
-
report comment_node[0]
|
|
80
|
+
report comment_node[0];
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
def get_info -> TweetInfo {
|
|
@@ -108,11 +108,11 @@ node Comment {
|
|
|
108
108
|
|
|
109
109
|
can update with update_comment entry {
|
|
110
110
|
self.content = visitor.updated_content;
|
|
111
|
-
report self
|
|
111
|
+
report self;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
can delete with remove_comment entry {
|
|
115
|
-
del self
|
|
115
|
+
del self;
|
|
116
116
|
disengage;
|
|
117
117
|
}
|
|
118
118
|
}
|
|
@@ -149,7 +149,7 @@ walker load_user_profiles {
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
can report_profiles with exit {
|
|
152
|
-
report self.profiles
|
|
152
|
+
report self.profiles;
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
|
|
@@ -163,7 +163,7 @@ walker create_tweet(visit_profile) {
|
|
|
163
163
|
can tweet with Profile entry {
|
|
164
164
|
tweet_node = here +>: Post() :+> Tweet(content=self.content, embedding=[]);
|
|
165
165
|
grant(tweet_node[0], level=ConnectPerm);
|
|
166
|
-
report tweet_node
|
|
166
|
+
report tweet_node;
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -199,7 +199,7 @@ walker load_feed(visit_profile) {
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
can report_feed with exit {
|
|
202
|
-
report self.results
|
|
202
|
+
report self.results;
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
|
|
@@ -224,44 +224,37 @@ cl obj ClientProfile {
|
|
|
224
224
|
|
|
225
225
|
# UI Components - Render a single tweet card
|
|
226
226
|
cl def TweetCard(tweet: ClientTweet) -> any {
|
|
227
|
-
return
|
|
228
|
-
class="tweet-card"
|
|
229
|
-
style={{
|
|
230
|
-
"border": "1px solid #e1e8ed",
|
|
231
|
-
"padding": "15px",
|
|
232
|
-
"margin": "10px 0",
|
|
233
|
-
"borderRadius": "8px"
|
|
234
|
-
}}
|
|
235
|
-
>
|
|
227
|
+
return
|
|
236
228
|
<div
|
|
237
|
-
class="tweet-
|
|
238
|
-
style={{
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
style={{"marginBottom": "12px"}}
|
|
245
|
-
>
|
|
246
|
-
{tweet.content}
|
|
247
|
-
</div>
|
|
248
|
-
<div
|
|
249
|
-
class="tweet-actions"
|
|
250
|
-
style={{"display": "flex", "gap": "15px"}}
|
|
229
|
+
class="tweet-card"
|
|
230
|
+
style={{
|
|
231
|
+
"border": "1px solid #e1e8ed",
|
|
232
|
+
"padding": "15px",
|
|
233
|
+
"margin": "10px 0",
|
|
234
|
+
"borderRadius": "8px"
|
|
235
|
+
}}
|
|
251
236
|
>
|
|
252
|
-
<
|
|
253
|
-
|
|
254
|
-
style={{"
|
|
255
|
-
>
|
|
256
|
-
Like ({tweet.likes.length})
|
|
257
|
-
</button>
|
|
258
|
-
<button
|
|
259
|
-
style={{"padding": "5px 10px"}}
|
|
237
|
+
<div
|
|
238
|
+
class="tweet-header"
|
|
239
|
+
style={{"fontWeight": "bold", "marginBottom": "80px"}}
|
|
260
240
|
>
|
|
261
|
-
|
|
262
|
-
</
|
|
263
|
-
|
|
264
|
-
|
|
241
|
+
@{tweet.username}
|
|
242
|
+
</div>
|
|
243
|
+
<div class="tweet-content" style={{"marginBottom": "12px"}}>
|
|
244
|
+
{tweet.content}
|
|
245
|
+
</div>
|
|
246
|
+
<div class="tweet-actions" style={{"display": "flex", "gap": "15px"}}>
|
|
247
|
+
<button
|
|
248
|
+
onclick={like_tweet_action(tweet.id)}
|
|
249
|
+
style={{"padding": "5px 10px", "cursor": "pointer"}}
|
|
250
|
+
>
|
|
251
|
+
Like ({tweet.likes.length})
|
|
252
|
+
</button>
|
|
253
|
+
<button style={{"padding": "5px 10px"}}>
|
|
254
|
+
Comment ({tweet.comments.length})
|
|
255
|
+
</button>
|
|
256
|
+
</div>
|
|
257
|
+
</div>;
|
|
265
258
|
}
|
|
266
259
|
|
|
267
260
|
# Handle liking a tweet - calls server walker directly
|
|
@@ -281,24 +274,27 @@ cl async def like_tweet_action(
|
|
|
281
274
|
|
|
282
275
|
# Render the main feed view
|
|
283
276
|
cl def FeedView(tweets: list) -> any {
|
|
284
|
-
return
|
|
285
|
-
class="feed-container"
|
|
286
|
-
style={{"maxWidth": "600px", "margin": "0 auto", "fontFamily": "sans-serif"}}
|
|
287
|
-
>
|
|
277
|
+
return
|
|
288
278
|
<div
|
|
289
|
-
class="feed-
|
|
290
|
-
style={{
|
|
279
|
+
class="feed-container"
|
|
280
|
+
style={{
|
|
281
|
+
"maxWidth": "600px",
|
|
282
|
+
"margin": "0 auto",
|
|
283
|
+
"fontFamily": "sans-serif"
|
|
284
|
+
}}
|
|
291
285
|
>
|
|
292
|
-
<
|
|
293
|
-
|
|
286
|
+
<div
|
|
287
|
+
class="feed-header"
|
|
288
|
+
style={{"padding": "20px", "borderBottom": "1px solid #e1e8ed"}}
|
|
294
289
|
>
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
290
|
+
<h1 style={{"margin": "0"}}>
|
|
291
|
+
LittleX Feed
|
|
292
|
+
</h1>
|
|
293
|
+
</div>
|
|
294
|
+
<div class="feed-content">
|
|
295
|
+
{[TweetCard(tweet) for tweet in tweets]}
|
|
296
|
+
</div>
|
|
297
|
+
</div>;
|
|
302
298
|
}
|
|
303
299
|
|
|
304
300
|
# Render login form
|
|
@@ -306,100 +302,74 @@ cl def LoginForm -> any {
|
|
|
306
302
|
suggestions = ['good luck', 'have fun', 'enjoy the ride'];
|
|
307
303
|
randomSuggestion = _.sample(suggestions);
|
|
308
304
|
result = "Good luck with your journey!";
|
|
309
|
-
return
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
<Card.Meta
|
|
314
|
-
title={randomSuggestion}
|
|
315
|
-
description={result}
|
|
316
|
-
/>
|
|
317
|
-
<form
|
|
318
|
-
onSubmit={handle_login}
|
|
305
|
+
return
|
|
306
|
+
<Card
|
|
307
|
+
title="Login to LittleX"
|
|
308
|
+
style={{"maxWidth": "400px", "margin": "50px auto"}}
|
|
319
309
|
>
|
|
320
|
-
<
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
310
|
+
<Card.Meta title={randomSuggestion} description={result} />
|
|
311
|
+
<form onSubmit={handle_login}>
|
|
312
|
+
<div style={{"marginBottom": "15px"}}>
|
|
313
|
+
<label style={{"display": "block", "marginBottom": "5px"}}>
|
|
314
|
+
Username:
|
|
315
|
+
</label>
|
|
316
|
+
<input
|
|
317
|
+
type="text"
|
|
318
|
+
id="username"
|
|
319
|
+
style={{
|
|
320
|
+
"width": "100%",
|
|
321
|
+
"padding": "8px",
|
|
322
|
+
"boxSizing": "border-box"
|
|
323
|
+
}}
|
|
324
|
+
/>
|
|
325
|
+
</div>
|
|
326
|
+
<div style={{"marginBottom": "15px"}}>
|
|
327
|
+
<label style={{"display": "block", "marginBottom": "5px"}}>
|
|
328
|
+
Password:
|
|
329
|
+
</label>
|
|
330
|
+
<input
|
|
331
|
+
type="password"
|
|
332
|
+
id="password"
|
|
333
|
+
style={{
|
|
334
|
+
"width": "100%",
|
|
335
|
+
"padding": "8px",
|
|
336
|
+
"boxSizing": "border-box"
|
|
337
|
+
}}
|
|
338
|
+
/>
|
|
339
|
+
</div>
|
|
340
|
+
<Button
|
|
341
|
+
htmlType="submit"
|
|
331
342
|
style={{
|
|
332
343
|
"width": "100%",
|
|
333
|
-
"padding": "
|
|
334
|
-
"
|
|
344
|
+
"padding": "10px",
|
|
345
|
+
"backgroundColor": "#1da1f2",
|
|
346
|
+
"color": "white",
|
|
347
|
+
"border": "none",
|
|
348
|
+
"borderRadius": "4px",
|
|
349
|
+
"cursor": "pointer"
|
|
335
350
|
}}
|
|
336
|
-
/>
|
|
337
|
-
</div>
|
|
338
|
-
<div
|
|
339
|
-
style={{"marginBottom": "15px"}}
|
|
340
|
-
>
|
|
341
|
-
<label
|
|
342
|
-
style={{"display": "block", "marginBottom": "5px"}}
|
|
343
351
|
>
|
|
344
|
-
|
|
345
|
-
</
|
|
346
|
-
<
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
352
|
+
Login
|
|
353
|
+
</Button>
|
|
354
|
+
<Button color="default" variant="dashed">
|
|
355
|
+
Dashed
|
|
356
|
+
</Button>
|
|
357
|
+
<Button color="default" variant="filled">
|
|
358
|
+
Filled
|
|
359
|
+
</Button>
|
|
360
|
+
<Button color="default" variant="text">
|
|
361
|
+
Text
|
|
362
|
+
</Button>
|
|
363
|
+
<Button color="default" variant="link">
|
|
364
|
+
Link
|
|
365
|
+
</Button>
|
|
366
|
+
</form>
|
|
367
|
+
<div style={{"marginTop": "15px", "textAlign": "center"}}>
|
|
368
|
+
<Link href="/signup">
|
|
369
|
+
Don't have an account? Sign up
|
|
370
|
+
</Link>
|
|
355
371
|
</div>
|
|
356
|
-
|
|
357
|
-
htmlType="submit"
|
|
358
|
-
style={{
|
|
359
|
-
"width": "100%",
|
|
360
|
-
"padding": "10px",
|
|
361
|
-
"backgroundColor": "#1da1f2",
|
|
362
|
-
"color": "white",
|
|
363
|
-
"border": "none",
|
|
364
|
-
"borderRadius": "4px",
|
|
365
|
-
"cursor": "pointer"
|
|
366
|
-
}}
|
|
367
|
-
>
|
|
368
|
-
Login
|
|
369
|
-
</Button>
|
|
370
|
-
<Button
|
|
371
|
-
color="default"
|
|
372
|
-
variant="dashed"
|
|
373
|
-
>
|
|
374
|
-
Dashed
|
|
375
|
-
</Button>
|
|
376
|
-
<Button
|
|
377
|
-
color="default"
|
|
378
|
-
variant="filled"
|
|
379
|
-
>
|
|
380
|
-
Filled
|
|
381
|
-
</Button>
|
|
382
|
-
<Button
|
|
383
|
-
color="default"
|
|
384
|
-
variant="text"
|
|
385
|
-
>
|
|
386
|
-
Text
|
|
387
|
-
</Button>
|
|
388
|
-
<Button
|
|
389
|
-
color="default"
|
|
390
|
-
variant="link"
|
|
391
|
-
>
|
|
392
|
-
Link
|
|
393
|
-
</Button>
|
|
394
|
-
</form>
|
|
395
|
-
<div
|
|
396
|
-
style={{"marginTop": "15px", "textAlign": "center"}}
|
|
397
|
-
>
|
|
398
|
-
<Link href="/signup">
|
|
399
|
-
Don't have an account? Sign up
|
|
400
|
-
</Link>
|
|
401
|
-
</div>
|
|
402
|
-
</Card>;
|
|
372
|
+
</Card>;
|
|
403
373
|
}
|
|
404
374
|
|
|
405
375
|
# Handle login form submission
|
|
@@ -417,106 +387,88 @@ cl async def handle_login(event: any) -> None {
|
|
|
417
387
|
|
|
418
388
|
# Render signup form
|
|
419
389
|
cl def SignupForm -> any {
|
|
420
|
-
return
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
<Typography.Title
|
|
432
|
-
level={2}
|
|
433
|
-
style={{"marginTop": "0"}}
|
|
434
|
-
>
|
|
435
|
-
Sign Up for LittleX
|
|
436
|
-
</Typography.Title>
|
|
437
|
-
<form
|
|
438
|
-
onSubmit={handle_signup}
|
|
390
|
+
return
|
|
391
|
+
<div
|
|
392
|
+
class="signup-container"
|
|
393
|
+
style={{
|
|
394
|
+
"maxWidth": "400px",
|
|
395
|
+
"margin": "50px auto",
|
|
396
|
+
"padding": "20px",
|
|
397
|
+
"border": "1px solid #e1e8ed",
|
|
398
|
+
"borderRadius": "8px",
|
|
399
|
+
"fontFamily": "sans-serif"
|
|
400
|
+
}}
|
|
439
401
|
>
|
|
440
|
-
<
|
|
441
|
-
|
|
442
|
-
>
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
402
|
+
<Typography.Title level={2} style={{"marginTop": "0"}}>
|
|
403
|
+
Sign Up for LittleX
|
|
404
|
+
</Typography.Title>
|
|
405
|
+
<form onSubmit={handle_signup}>
|
|
406
|
+
<div style={{"marginBottom": "15px"}}>
|
|
407
|
+
<label style={{"display": "block", "marginBottom": "5px"}}>
|
|
408
|
+
Username:
|
|
409
|
+
</label>
|
|
410
|
+
<input
|
|
411
|
+
type="text"
|
|
412
|
+
id="signup-username"
|
|
413
|
+
required
|
|
414
|
+
style={{
|
|
415
|
+
"width": "100%",
|
|
416
|
+
"padding": "8px",
|
|
417
|
+
"boxSizing": "border-box"
|
|
418
|
+
}}
|
|
419
|
+
/>
|
|
420
|
+
</div>
|
|
421
|
+
<div style={{"marginBottom": "15px"}}>
|
|
422
|
+
<label style={{"display": "block", "marginBottom": "5px"}}>
|
|
423
|
+
Password:
|
|
424
|
+
</label>
|
|
425
|
+
<input
|
|
426
|
+
type="password"
|
|
427
|
+
id="signup-password"
|
|
428
|
+
required
|
|
429
|
+
style={{
|
|
430
|
+
"width": "100%",
|
|
431
|
+
"padding": "8px",
|
|
432
|
+
"boxSizing": "border-box"
|
|
433
|
+
}}
|
|
434
|
+
/>
|
|
435
|
+
</div>
|
|
436
|
+
<div style={{"marginBottom": "15px"}}>
|
|
437
|
+
<label style={{"display": "block", "marginBottom": "5px"}}>
|
|
438
|
+
Confirm Password:
|
|
439
|
+
</label>
|
|
440
|
+
<input
|
|
441
|
+
type="password"
|
|
442
|
+
id="signup-password-confirm"
|
|
443
|
+
required
|
|
444
|
+
style={{
|
|
445
|
+
"width": "100%",
|
|
446
|
+
"padding": "8px",
|
|
447
|
+
"boxSizing": "border-box"
|
|
448
|
+
}}
|
|
449
|
+
/>
|
|
450
|
+
</div>
|
|
451
|
+
<button
|
|
452
|
+
type="submit"
|
|
452
453
|
style={{
|
|
453
454
|
"width": "100%",
|
|
454
|
-
"padding": "
|
|
455
|
-
"
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
style={{"marginBottom": "15px"}}
|
|
461
|
-
>
|
|
462
|
-
<label
|
|
463
|
-
style={{"display": "block", "marginBottom": "5px"}}
|
|
464
|
-
>
|
|
465
|
-
Password:
|
|
466
|
-
</label>
|
|
467
|
-
<input
|
|
468
|
-
type="password"
|
|
469
|
-
id="signup-password"
|
|
470
|
-
required
|
|
471
|
-
style={{
|
|
472
|
-
"width": "100%",
|
|
473
|
-
"padding": "8px",
|
|
474
|
-
"boxSizing": "border-box"
|
|
455
|
+
"padding": "10px",
|
|
456
|
+
"backgroundColor": "#1da1f2",
|
|
457
|
+
"color": "white",
|
|
458
|
+
"border": "none",
|
|
459
|
+
"borderRadius": "4px",
|
|
460
|
+
"cursor": "pointer"
|
|
475
461
|
}}
|
|
476
|
-
/>
|
|
477
|
-
</div>
|
|
478
|
-
<div
|
|
479
|
-
style={{"marginBottom": "15px"}}
|
|
480
|
-
>
|
|
481
|
-
<label
|
|
482
|
-
style={{"display": "block", "marginBottom": "5px"}}
|
|
483
462
|
>
|
|
484
|
-
|
|
485
|
-
</
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
"width": "100%",
|
|
492
|
-
"padding": "8px",
|
|
493
|
-
"boxSizing": "border-box"
|
|
494
|
-
}}
|
|
495
|
-
/>
|
|
463
|
+
Sign Up
|
|
464
|
+
</button>
|
|
465
|
+
</form>
|
|
466
|
+
<div style={{"marginTop": "15px", "textAlign": "center"}}>
|
|
467
|
+
<Link href="/login">
|
|
468
|
+
Already have an account? Login
|
|
469
|
+
</Link>
|
|
496
470
|
</div>
|
|
497
|
-
|
|
498
|
-
type="submit"
|
|
499
|
-
style={{
|
|
500
|
-
"width": "100%",
|
|
501
|
-
"padding": "10px",
|
|
502
|
-
"backgroundColor": "#1da1f2",
|
|
503
|
-
"color": "white",
|
|
504
|
-
"border": "none",
|
|
505
|
-
"borderRadius": "4px",
|
|
506
|
-
"cursor": "pointer"
|
|
507
|
-
}}
|
|
508
|
-
>
|
|
509
|
-
Sign Up
|
|
510
|
-
</button>
|
|
511
|
-
</form>
|
|
512
|
-
<div
|
|
513
|
-
style={{"marginTop": "15px", "textAlign": "center"}}
|
|
514
|
-
>
|
|
515
|
-
<Link href="/login">
|
|
516
|
-
Already have an account? Login
|
|
517
|
-
</Link>
|
|
518
|
-
</div>
|
|
519
|
-
</div>;
|
|
471
|
+
</div>;
|
|
520
472
|
}
|
|
521
473
|
|
|
522
474
|
# Navigation helper functions removed - using Link component and navigate() directly
|
|
@@ -561,22 +513,22 @@ cl def:pub App -> any {
|
|
|
561
513
|
# Create routes array manually (workaround for JS compiler bug with named args)
|
|
562
514
|
login_route = {
|
|
563
515
|
"path": "/login",
|
|
564
|
-
"component": lambda
|
|
516
|
+
"component": lambda -> any { return LoginForm(); },
|
|
565
517
|
"guard": None
|
|
566
518
|
};
|
|
567
519
|
signup_route = {
|
|
568
520
|
"path": "/signup",
|
|
569
|
-
"component": lambda
|
|
521
|
+
"component": lambda -> any { return SignupForm(); },
|
|
570
522
|
"guard": None
|
|
571
523
|
};
|
|
572
524
|
home_route = {
|
|
573
525
|
"path": "/home",
|
|
574
|
-
"component": lambda
|
|
526
|
+
"component": lambda -> any { return HomeView(); },
|
|
575
527
|
"guard": jacIsLoggedIn
|
|
576
528
|
};
|
|
577
529
|
profile_route = {
|
|
578
530
|
"path": "/profile",
|
|
579
|
-
"component": lambda
|
|
531
|
+
"component": lambda -> any { return ProfileView(); },
|
|
580
532
|
"guard": jacIsLoggedIn
|
|
581
533
|
};
|
|
582
534
|
|
|
@@ -586,15 +538,16 @@ cl def:pub App -> any {
|
|
|
586
538
|
# Get current path for navbar
|
|
587
539
|
currentPath = router.path();
|
|
588
540
|
|
|
589
|
-
return
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
<
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
541
|
+
return
|
|
542
|
+
<div class="app-container">
|
|
543
|
+
{build_nav_bar(currentPath)}
|
|
544
|
+
<Rotate>
|
|
545
|
+
<span>
|
|
546
|
+
😂
|
|
547
|
+
</span>
|
|
548
|
+
</Rotate>
|
|
549
|
+
{router.render()}
|
|
550
|
+
</div>;
|
|
598
551
|
}
|
|
599
552
|
|
|
600
553
|
# Helper to build navigation bar
|
|
@@ -602,115 +555,124 @@ cl def build_nav_bar(route: str) -> any {
|
|
|
602
555
|
if not jacIsLoggedIn() or route == "/login" or route == "/signup" {
|
|
603
556
|
return None;
|
|
604
557
|
}
|
|
605
|
-
return
|
|
606
|
-
|
|
607
|
-
"backgroundColor": "#1da1f2",
|
|
608
|
-
"padding": "15px",
|
|
609
|
-
"marginBottom": "20px"
|
|
610
|
-
}}
|
|
611
|
-
>
|
|
612
|
-
<div
|
|
558
|
+
return
|
|
559
|
+
<nav
|
|
613
560
|
style={{
|
|
614
|
-
"
|
|
615
|
-
"
|
|
616
|
-
"
|
|
617
|
-
"gap": "20px",
|
|
618
|
-
"alignItems": "center"
|
|
561
|
+
"backgroundColor": "#1da1f2",
|
|
562
|
+
"padding": "15px",
|
|
563
|
+
"marginBottom": "20px"
|
|
619
564
|
}}
|
|
620
565
|
>
|
|
621
|
-
<
|
|
622
|
-
|
|
566
|
+
<div
|
|
567
|
+
style={{
|
|
568
|
+
"maxWidth": "600px",
|
|
569
|
+
"margin": "0 auto",
|
|
570
|
+
"display": "flex",
|
|
571
|
+
"gap": "20px",
|
|
572
|
+
"alignItems": "center"
|
|
573
|
+
}}
|
|
574
|
+
>
|
|
575
|
+
<Link href="/home">
|
|
576
|
+
<span
|
|
577
|
+
style={{
|
|
578
|
+
"color": "white",
|
|
579
|
+
"textDecoration": "none",
|
|
580
|
+
"fontWeight": "bold"
|
|
581
|
+
}}
|
|
582
|
+
>
|
|
583
|
+
Home
|
|
584
|
+
</span>
|
|
585
|
+
</Link>
|
|
586
|
+
<Link href="/profile">
|
|
587
|
+
<span
|
|
588
|
+
style={{
|
|
589
|
+
"color": "white",
|
|
590
|
+
"textDecoration": "none",
|
|
591
|
+
"fontWeight": "bold"
|
|
592
|
+
}}
|
|
593
|
+
>
|
|
594
|
+
Profile
|
|
595
|
+
</span>
|
|
596
|
+
</Link>
|
|
597
|
+
<button
|
|
598
|
+
onClick={logout_action}
|
|
623
599
|
style={{
|
|
624
|
-
"
|
|
625
|
-
"
|
|
600
|
+
"marginLeft": "auto",
|
|
601
|
+
"padding": "5px 15px",
|
|
602
|
+
"backgroundColor": "white",
|
|
603
|
+
"color": "#1da1f2",
|
|
604
|
+
"border": "none",
|
|
605
|
+
"borderRadius": "4px",
|
|
606
|
+
"cursor": "pointer",
|
|
626
607
|
"fontWeight": "bold"
|
|
627
608
|
}}
|
|
628
609
|
>
|
|
629
|
-
|
|
630
|
-
</
|
|
631
|
-
</
|
|
632
|
-
|
|
633
|
-
<span
|
|
634
|
-
style={{
|
|
635
|
-
"color": "white",
|
|
636
|
-
"textDecoration": "none",
|
|
637
|
-
"fontWeight": "bold"
|
|
638
|
-
}}
|
|
639
|
-
>
|
|
640
|
-
Profile
|
|
641
|
-
</span>
|
|
642
|
-
</Link>
|
|
643
|
-
<button
|
|
644
|
-
onClick={logout_action}
|
|
645
|
-
style={{
|
|
646
|
-
"marginLeft": "auto",
|
|
647
|
-
"padding": "5px 15px",
|
|
648
|
-
"backgroundColor": "white",
|
|
649
|
-
"color": "#1da1f2",
|
|
650
|
-
"border": "none",
|
|
651
|
-
"borderRadius": "4px",
|
|
652
|
-
"cursor": "pointer",
|
|
653
|
-
"fontWeight": "bold"
|
|
654
|
-
}}
|
|
655
|
-
>
|
|
656
|
-
Logout
|
|
657
|
-
</button>
|
|
658
|
-
</div>
|
|
659
|
-
</nav>;
|
|
610
|
+
Logout
|
|
611
|
+
</button>
|
|
612
|
+
</div>
|
|
613
|
+
</nav>;
|
|
660
614
|
}
|
|
661
615
|
|
|
662
616
|
# Home view - simplified for testing reactive routing
|
|
663
617
|
cl def HomeView -> any {
|
|
664
618
|
if not jacIsLoggedIn() {
|
|
665
619
|
navigate("/login");
|
|
666
|
-
return
|
|
620
|
+
return
|
|
621
|
+
<div></div>;
|
|
667
622
|
}
|
|
668
623
|
|
|
669
|
-
return
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
624
|
+
return
|
|
625
|
+
<div
|
|
626
|
+
style={{
|
|
627
|
+
"textAlign": "center",
|
|
628
|
+
"padding": "50px",
|
|
629
|
+
"fontFamily": "sans-serif"
|
|
630
|
+
}}
|
|
631
|
+
>
|
|
632
|
+
<h1>
|
|
633
|
+
Home Feed
|
|
634
|
+
</h1>
|
|
635
|
+
<p>
|
|
636
|
+
Welcome to LittleX! This is the home page.
|
|
637
|
+
</p>
|
|
638
|
+
<p>
|
|
639
|
+
The reactive router is working!
|
|
640
|
+
</p>
|
|
641
|
+
</div>;
|
|
682
642
|
}
|
|
683
643
|
|
|
684
644
|
# Profile view
|
|
685
645
|
cl def ProfileView -> any {
|
|
686
646
|
if not jacIsLoggedIn() {
|
|
687
647
|
navigate("/login");
|
|
688
|
-
return
|
|
648
|
+
return
|
|
649
|
+
<div></div>;
|
|
689
650
|
}
|
|
690
|
-
return
|
|
691
|
-
class="profile-container"
|
|
692
|
-
style={{
|
|
693
|
-
"maxWidth": "600px",
|
|
694
|
-
"margin": "20px auto",
|
|
695
|
-
"padding": "20px",
|
|
696
|
-
"fontFamily": "sans-serif"
|
|
697
|
-
}}
|
|
698
|
-
>
|
|
699
|
-
<h1>
|
|
700
|
-
Profile
|
|
701
|
-
</h1>
|
|
651
|
+
return
|
|
702
652
|
<div
|
|
653
|
+
class="profile-container"
|
|
703
654
|
style={{
|
|
704
|
-
"
|
|
705
|
-
"
|
|
706
|
-
"
|
|
655
|
+
"maxWidth": "600px",
|
|
656
|
+
"margin": "20px auto",
|
|
657
|
+
"padding": "20px",
|
|
658
|
+
"fontFamily": "sans-serif"
|
|
707
659
|
}}
|
|
708
660
|
>
|
|
709
|
-
<
|
|
710
|
-
Profile
|
|
711
|
-
</
|
|
712
|
-
|
|
713
|
-
|
|
661
|
+
<h1>
|
|
662
|
+
Profile
|
|
663
|
+
</h1>
|
|
664
|
+
<div
|
|
665
|
+
style={{
|
|
666
|
+
"padding": "15px",
|
|
667
|
+
"border": "1px solid #e1e8ed",
|
|
668
|
+
"borderRadius": "8px"
|
|
669
|
+
}}
|
|
670
|
+
>
|
|
671
|
+
<p>
|
|
672
|
+
Profile information will be displayed here.
|
|
673
|
+
</p>
|
|
674
|
+
</div>
|
|
675
|
+
</div>;
|
|
714
676
|
}
|
|
715
677
|
|
|
716
678
|
# Main SPA entry point - simplified with reactive routing
|