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.
Files changed (85) hide show
  1. jac_client/examples/all-in-one/button.jac +4 -3
  2. jac_client/examples/all-in-one/components/CategoryFilter.jac +36 -24
  3. jac_client/examples/all-in-one/components/Header.jac +12 -8
  4. jac_client/examples/all-in-one/components/ProfitOverview.jac +49 -35
  5. jac_client/examples/all-in-one/components/Summary.jac +59 -36
  6. jac_client/examples/all-in-one/components/TransactionForm.jac +142 -112
  7. jac_client/examples/all-in-one/components/TransactionItem.jac +37 -30
  8. jac_client/examples/all-in-one/components/TransactionList.jac +33 -26
  9. jac_client/examples/all-in-one/components/button.jac +4 -3
  10. jac_client/examples/all-in-one/components/navigation.jac +111 -117
  11. jac_client/examples/all-in-one/constants/categories.jac +23 -24
  12. jac_client/examples/all-in-one/constants/clients.jac +7 -8
  13. jac_client/examples/all-in-one/context/BudgetContext.jac +9 -6
  14. jac_client/examples/all-in-one/hooks/useBudget.jac +18 -12
  15. jac_client/examples/all-in-one/hooks/useLocalStorage.jac +14 -13
  16. jac_client/examples/all-in-one/main.jac +340 -371
  17. jac_client/examples/all-in-one/pages/BudgetPlanner.jac +19 -12
  18. jac_client/examples/all-in-one/pages/FeaturesTest.jac +31 -15
  19. jac_client/examples/all-in-one/pages/LandingPage.jac +113 -90
  20. jac_client/examples/all-in-one/pages/budget_planner_ui.cl.jac +34 -39
  21. jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +464 -352
  22. jac_client/examples/all-in-one/pages/loginPage.jac +114 -119
  23. jac_client/examples/all-in-one/pages/nestedDemo.jac +43 -50
  24. jac_client/examples/all-in-one/pages/notFound.jac +14 -15
  25. jac_client/examples/all-in-one/pages/signupPage.jac +113 -119
  26. jac_client/examples/all-in-one/utils/formatters.jac +5 -8
  27. jac_client/examples/asset-serving/css-with-image/main.jac +77 -73
  28. jac_client/examples/asset-serving/image-asset/main.jac +47 -46
  29. jac_client/examples/asset-serving/import-alias/main.jac +93 -95
  30. jac_client/examples/basic/main.jac +17 -15
  31. jac_client/examples/basic-auth/main.jac +246 -254
  32. jac_client/examples/basic-auth-with-router/main.jac +272 -285
  33. jac_client/examples/basic-full-stack/main.jac +245 -242
  34. jac_client/examples/css-styling/js-styling/main.jac +41 -62
  35. jac_client/examples/css-styling/material-ui/main.jac +90 -90
  36. jac_client/examples/css-styling/pure-css/main.jac +35 -44
  37. jac_client/examples/css-styling/sass-example/main.jac +35 -44
  38. jac_client/examples/css-styling/styled-components/main.jac +38 -47
  39. jac_client/examples/css-styling/tailwind-example/main.jac +54 -43
  40. jac_client/examples/full-stack-with-auth/main.jac +407 -433
  41. jac_client/examples/little-x/main.jac +306 -344
  42. jac_client/examples/little-x/src/submit-button.jac +15 -14
  43. jac_client/examples/nested-folders/nested-advance/main.jac +18 -27
  44. jac_client/examples/nested-folders/nested-advance/src/ButtonRoot.jac +4 -6
  45. jac_client/examples/nested-folders/nested-advance/src/level1/ButtonSecondL.jac +9 -13
  46. jac_client/examples/nested-folders/nested-advance/src/level1/Card.jac +29 -32
  47. jac_client/examples/nested-folders/nested-advance/src/level1/level2/ButtonThirdL.jac +12 -18
  48. jac_client/examples/nested-folders/nested-basic/main.jac +7 -5
  49. jac_client/examples/nested-folders/nested-basic/src/button.jac +4 -3
  50. jac_client/examples/nested-folders/nested-basic/src/components/button.jac +4 -3
  51. jac_client/examples/ts-support/main.jac +26 -26
  52. jac_client/examples/with-router/main.jac +186 -223
  53. jac_client/plugin/client_runtime.cl.jac +5 -3
  54. jac_client/plugin/impl/client_runtime.impl.jac +1 -1
  55. jac_client/plugin/plugin_config.jac +53 -99
  56. jac_client/plugin/src/__init__.jac +0 -2
  57. jac_client/plugin/src/compiler.jac +0 -1
  58. jac_client/plugin/src/impl/compiler.impl.jac +49 -17
  59. jac_client/plugin/src/impl/jac_to_js.impl.jac +5 -1
  60. jac_client/plugin/src/impl/package_installer.impl.jac +20 -20
  61. jac_client/plugin/src/impl/vite_bundler.impl.jac +146 -84
  62. jac_client/plugin/src/targets/impl/desktop_target.impl.jac +54 -41
  63. jac_client/plugin/utils/__init__.jac +3 -0
  64. jac_client/plugin/utils/bun_installer.jac +16 -0
  65. jac_client/plugin/utils/client_deps.jac +14 -0
  66. jac_client/plugin/utils/impl/bun_installer.impl.jac +99 -0
  67. jac_client/plugin/utils/impl/client_deps.impl.jac +73 -0
  68. jac_client/templates/client.jacpack +0 -4
  69. jac_client/templates/fullstack.jacpack +1 -5
  70. jac_client/tests/conftest.py +56 -41
  71. jac_client/tests/fixtures/spawn_test/app.jac +49 -52
  72. jac_client/tests/fixtures/with-ts/app.jac +27 -27
  73. jac_client/tests/test_cli.py +71 -6
  74. jac_client/tests/test_helpers.py +11 -18
  75. jac_client/tests/test_it.py +1 -1
  76. {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/METADATA +5 -5
  77. jac_client-0.2.12.dist-info/RECORD +115 -0
  78. {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/WHEEL +1 -1
  79. jac_client/plugin/src/babel_processor.jac +0 -18
  80. jac_client/plugin/src/impl/babel_processor.impl.jac +0 -89
  81. jac_client/plugin/utils/impl/node_installer.impl.jac +0 -249
  82. jac_client/plugin/utils/node_installer.jac +0 -41
  83. jac_client-0.2.10.dist-info/RECORD +0 -115
  84. {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/entry_points.txt +0 -0
  85. {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 <div
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-header"
238
- style={{"fontWeight": "bold", "marginBottom": "80px"}}
239
- >
240
- @{tweet.username}
241
- </div>
242
- <div
243
- class="tweet-content"
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
- <button
253
- onclick={like_tweet_action(tweet.id)}
254
- style={{"padding": "5px 10px", "cursor": "pointer"}}
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
- Comment ({tweet.comments.length})
262
- </button>
263
- </div>
264
- </div>;
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 <div
285
- class="feed-container"
286
- style={{"maxWidth": "600px", "margin": "0 auto", "fontFamily": "sans-serif"}}
287
- >
277
+ return
288
278
  <div
289
- class="feed-header"
290
- style={{"padding": "20px", "borderBottom": "1px solid #e1e8ed"}}
279
+ class="feed-container"
280
+ style={{
281
+ "maxWidth": "600px",
282
+ "margin": "0 auto",
283
+ "fontFamily": "sans-serif"
284
+ }}
291
285
  >
292
- <h1
293
- style={{"margin": "0"}}
286
+ <div
287
+ class="feed-header"
288
+ style={{"padding": "20px", "borderBottom": "1px solid #e1e8ed"}}
294
289
  >
295
- LittleX Feed
296
- </h1>
297
- </div>
298
- <div class="feed-content">
299
- {[TweetCard(tweet) for tweet in tweets]}
300
- </div>
301
- </div>;
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 <Card
310
- title="Login to LittleX"
311
- style={{"maxWidth": "400px", "margin": "50px auto"}}
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
- <div
321
- style={{"marginBottom": "15px"}}
322
- >
323
- <label
324
- style={{"display": "block", "marginBottom": "5px"}}
325
- >
326
- Username:
327
- </label>
328
- <input
329
- type="text"
330
- id="username"
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": "8px",
334
- "boxSizing": "border-box"
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
- Password:
345
- </label>
346
- <input
347
- type="password"
348
- id="password"
349
- style={{
350
- "width": "100%",
351
- "padding": "8px",
352
- "boxSizing": "border-box"
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
- <Button
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 <div
421
- class="signup-container"
422
- style={{
423
- "maxWidth": "400px",
424
- "margin": "50px auto",
425
- "padding": "20px",
426
- "border": "1px solid #e1e8ed",
427
- "borderRadius": "8px",
428
- "fontFamily": "sans-serif"
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
- <div
441
- style={{"marginBottom": "15px"}}
442
- >
443
- <label
444
- style={{"display": "block", "marginBottom": "5px"}}
445
- >
446
- Username:
447
- </label>
448
- <input
449
- type="text"
450
- id="signup-username"
451
- required
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": "8px",
455
- "boxSizing": "border-box"
456
- }}
457
- />
458
- </div>
459
- <div
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
- Confirm Password:
485
- </label>
486
- <input
487
- type="password"
488
- id="signup-password-confirm"
489
- required
490
- style={{
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
- <button
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 -> any{ return LoginForm(); } ,
516
+ "component": lambda -> any { return LoginForm(); },
565
517
  "guard": None
566
518
  };
567
519
  signup_route = {
568
520
  "path": "/signup",
569
- "component": lambda -> any{ return SignupForm(); } ,
521
+ "component": lambda -> any { return SignupForm(); },
570
522
  "guard": None
571
523
  };
572
524
  home_route = {
573
525
  "path": "/home",
574
- "component": lambda -> any{ return HomeView(); } ,
526
+ "component": lambda -> any { return HomeView(); },
575
527
  "guard": jacIsLoggedIn
576
528
  };
577
529
  profile_route = {
578
530
  "path": "/profile",
579
- "component": lambda -> any{ return ProfileView(); } ,
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 <div class="app-container">
590
- {build_nav_bar(currentPath)}
591
- <Rotate>
592
- <span>
593
- 😂
594
- </span>
595
- </Rotate>
596
- {router.render()}
597
- </div>;
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 <nav
606
- style={{
607
- "backgroundColor": "#1da1f2",
608
- "padding": "15px",
609
- "marginBottom": "20px"
610
- }}
611
- >
612
- <div
558
+ return
559
+ <nav
613
560
  style={{
614
- "maxWidth": "600px",
615
- "margin": "0 auto",
616
- "display": "flex",
617
- "gap": "20px",
618
- "alignItems": "center"
561
+ "backgroundColor": "#1da1f2",
562
+ "padding": "15px",
563
+ "marginBottom": "20px"
619
564
  }}
620
565
  >
621
- <Link href="/home">
622
- <span
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
- "color": "white",
625
- "textDecoration": "none",
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
- Home
630
- </span>
631
- </Link>
632
- <Link href="/profile">
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 <div></div>;
620
+ return
621
+ <div></div>;
667
622
  }
668
623
 
669
- return <div
670
- style={{"textAlign": "center", "padding": "50px", "fontFamily": "sans-serif"}}
671
- >
672
- <h1>
673
- Home Feed
674
- </h1>
675
- <p>
676
- Welcome to LittleX! This is the home page.
677
- </p>
678
- <p>
679
- The reactive router is working!
680
- </p>
681
- </div>;
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 <div></div>;
648
+ return
649
+ <div></div>;
689
650
  }
690
- return <div
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
- "padding": "15px",
705
- "border": "1px solid #e1e8ed",
706
- "borderRadius": "8px"
655
+ "maxWidth": "600px",
656
+ "margin": "20px auto",
657
+ "padding": "20px",
658
+ "fontFamily": "sans-serif"
707
659
  }}
708
660
  >
709
- <p>
710
- Profile information will be displayed here.
711
- </p>
712
- </div>
713
- </div>;
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