jac-client 0.2.6__py3-none-any.whl → 0.2.11__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 (119) hide show
  1. jac_client/examples/all-in-one/{src/button.jac → button.jac} +4 -3
  2. jac_client/examples/all-in-one/components/CategoryFilter.jac +47 -0
  3. jac_client/examples/all-in-one/components/Header.jac +17 -0
  4. jac_client/examples/all-in-one/components/ProfitOverview.jac +64 -0
  5. jac_client/examples/all-in-one/components/Summary.jac +76 -0
  6. jac_client/examples/all-in-one/components/TransactionForm.jac +188 -0
  7. jac_client/examples/all-in-one/components/TransactionItem.jac +62 -0
  8. jac_client/examples/all-in-one/components/TransactionList.jac +44 -0
  9. jac_client/examples/all-in-one/components/button.jac +8 -0
  10. jac_client/examples/all-in-one/components/navigation.jac +126 -0
  11. jac_client/examples/all-in-one/constants/categories.jac +36 -0
  12. jac_client/examples/all-in-one/constants/clients.jac +12 -0
  13. jac_client/examples/all-in-one/context/BudgetContext.jac +31 -0
  14. jac_client/examples/all-in-one/hooks/useBudget.jac +122 -0
  15. jac_client/examples/all-in-one/hooks/useLocalStorage.jac +37 -0
  16. jac_client/examples/all-in-one/main.jac +542 -0
  17. jac_client/examples/all-in-one/pages/BudgetPlanner.jac +140 -0
  18. jac_client/examples/all-in-one/pages/FeaturesTest.jac +157 -0
  19. jac_client/examples/all-in-one/pages/LandingPage.jac +124 -0
  20. jac_client/examples/all-in-one/pages/budget_planner_ui.cl.jac +65 -0
  21. jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +675 -0
  22. jac_client/examples/all-in-one/pages/loginPage.jac +127 -0
  23. jac_client/examples/all-in-one/pages/nestedDemo.jac +54 -0
  24. jac_client/examples/all-in-one/pages/notFound.jac +18 -0
  25. jac_client/examples/all-in-one/pages/signupPage.jac +127 -0
  26. jac_client/examples/all-in-one/utils/formatters.jac +49 -0
  27. jac_client/examples/asset-serving/css-with-image/main.jac +92 -0
  28. jac_client/examples/asset-serving/image-asset/main.jac +56 -0
  29. jac_client/examples/asset-serving/import-alias/main.jac +109 -0
  30. jac_client/examples/basic/main.jac +23 -0
  31. jac_client/examples/basic-auth/main.jac +363 -0
  32. jac_client/examples/basic-auth-with-router/main.jac +451 -0
  33. jac_client/examples/basic-full-stack/main.jac +362 -0
  34. jac_client/examples/css-styling/js-styling/main.jac +63 -0
  35. jac_client/examples/css-styling/material-ui/main.jac +122 -0
  36. jac_client/examples/css-styling/pure-css/main.jac +55 -0
  37. jac_client/examples/css-styling/sass-example/main.jac +55 -0
  38. jac_client/examples/css-styling/styled-components/main.jac +62 -0
  39. jac_client/examples/css-styling/tailwind-example/main.jac +74 -0
  40. jac_client/examples/full-stack-with-auth/main.jac +696 -0
  41. jac_client/examples/little-x/main.jac +681 -0
  42. jac_client/examples/little-x/src/submit-button.jac +15 -14
  43. jac_client/examples/nested-folders/nested-advance/main.jac +26 -0
  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/{src/app.jac → 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 +35 -0
  52. jac_client/examples/with-router/main.jac +286 -0
  53. jac_client/plugin/cli.jac +507 -470
  54. jac_client/plugin/client.jac +30 -12
  55. jac_client/plugin/client_runtime.cl.jac +25 -15
  56. jac_client/plugin/impl/client.impl.jac +126 -26
  57. jac_client/plugin/impl/client_runtime.impl.jac +182 -10
  58. jac_client/plugin/plugin_config.jac +216 -34
  59. jac_client/plugin/src/__init__.jac +0 -2
  60. jac_client/plugin/src/compiler.jac +2 -2
  61. jac_client/plugin/src/config_loader.jac +1 -0
  62. jac_client/plugin/src/desktop_config.jac +31 -0
  63. jac_client/plugin/src/impl/compiler.impl.jac +99 -30
  64. jac_client/plugin/src/impl/config_loader.impl.jac +8 -0
  65. jac_client/plugin/src/impl/desktop_config.impl.jac +191 -0
  66. jac_client/plugin/src/impl/jac_to_js.impl.jac +5 -1
  67. jac_client/plugin/src/impl/package_installer.impl.jac +20 -20
  68. jac_client/plugin/src/impl/vite_bundler.impl.jac +384 -144
  69. jac_client/plugin/src/package_installer.jac +1 -1
  70. jac_client/plugin/src/targets/desktop/sidecar/main.py +144 -0
  71. jac_client/plugin/src/targets/desktop_target.jac +37 -0
  72. jac_client/plugin/src/targets/impl/desktop_target.impl.jac +2347 -0
  73. jac_client/plugin/src/targets/impl/registry.impl.jac +64 -0
  74. jac_client/plugin/src/targets/impl/web_target.impl.jac +157 -0
  75. jac_client/plugin/src/targets/register.jac +21 -0
  76. jac_client/plugin/src/targets/registry.jac +87 -0
  77. jac_client/plugin/src/targets/web_target.jac +35 -0
  78. jac_client/plugin/src/vite_bundler.jac +15 -1
  79. jac_client/plugin/utils/__init__.jac +3 -0
  80. jac_client/plugin/utils/bun_installer.jac +16 -0
  81. jac_client/plugin/utils/impl/bun_installer.impl.jac +99 -0
  82. jac_client/templates/client.jacpack +72 -0
  83. jac_client/templates/fullstack.jacpack +61 -0
  84. jac_client/tests/conftest.py +110 -52
  85. jac_client/tests/fixtures/spawn_test/app.jac +64 -70
  86. jac_client/tests/fixtures/with-ts/app.jac +28 -28
  87. jac_client/tests/test_cli.py +280 -113
  88. jac_client/tests/test_e2e.py +232 -0
  89. jac_client/tests/test_helpers.py +58 -0
  90. jac_client/tests/test_it.py +325 -154
  91. jac_client/tests/test_it_desktop.py +891 -0
  92. {jac_client-0.2.6.dist-info → jac_client-0.2.11.dist-info}/METADATA +20 -11
  93. jac_client-0.2.11.dist-info/RECORD +113 -0
  94. {jac_client-0.2.6.dist-info → jac_client-0.2.11.dist-info}/WHEEL +1 -1
  95. jac_client/examples/all-in-one/src/app.jac +0 -841
  96. jac_client/examples/all-in-one/src/components/button.jac +0 -7
  97. jac_client/examples/asset-serving/css-with-image/src/app.jac +0 -88
  98. jac_client/examples/asset-serving/image-asset/src/app.jac +0 -55
  99. jac_client/examples/asset-serving/import-alias/src/app.jac +0 -111
  100. jac_client/examples/basic/src/app.jac +0 -21
  101. jac_client/examples/basic-auth/src/app.jac +0 -377
  102. jac_client/examples/basic-auth-with-router/src/app.jac +0 -464
  103. jac_client/examples/basic-full-stack/src/app.jac +0 -365
  104. jac_client/examples/css-styling/js-styling/src/app.jac +0 -84
  105. jac_client/examples/css-styling/material-ui/src/app.jac +0 -122
  106. jac_client/examples/css-styling/pure-css/src/app.jac +0 -64
  107. jac_client/examples/css-styling/sass-example/src/app.jac +0 -64
  108. jac_client/examples/css-styling/styled-components/src/app.jac +0 -71
  109. jac_client/examples/css-styling/tailwind-example/src/app.jac +0 -63
  110. jac_client/examples/full-stack-with-auth/src/app.jac +0 -722
  111. jac_client/examples/little-x/src/app.jac +0 -719
  112. jac_client/examples/nested-folders/nested-advance/src/app.jac +0 -35
  113. jac_client/examples/ts-support/src/app.jac +0 -35
  114. jac_client/examples/with-router/src/app.jac +0 -323
  115. jac_client/plugin/src/babel_processor.jac +0 -18
  116. jac_client/plugin/src/impl/babel_processor.impl.jac +0 -84
  117. jac_client-0.2.6.dist-info/RECORD +0 -74
  118. {jac_client-0.2.6.dist-info → jac_client-0.2.11.dist-info}/entry_points.txt +0 -0
  119. {jac_client-0.2.6.dist-info → jac_client-0.2.11.dist-info}/top_level.txt +0 -0
@@ -1,7 +0,0 @@
1
- cl import from antd { Button }
2
-
3
- cl def:pub CustomButton -> any {
4
- return <Button>
5
- Nested Button
6
- </Button>;
7
- }
@@ -1,88 +0,0 @@
1
- # Pages
2
- cl import from react { useState, useEffect }
3
- cl import ".styles.css";
4
-
5
- cl {
6
- def:pub app -> any {
7
- [count, setCount] = useState(0);
8
- useEffect(lambda -> None{ console.log("Count: ", count);} , [count]);
9
- return <div
10
- style={{
11
- padding: "20px",
12
- textAlign: "center",
13
- fontFamily: "Arial, sans-serif"
14
- }}
15
- >
16
- <h1>
17
- 🍔 Burger Counter App
18
- </h1>
19
- <img
20
- src="/static/assets/burger.png"
21
- alt="Delicious Burger"
22
- style={{
23
- width: "200px",
24
- height: "auto",
25
- margin: "20px 0",
26
- borderRadius: "10px",
27
- boxShadow: "0 4px 8px rgba(0,0,0,0.2)"
28
- }}
29
- />
30
- <p
31
- style={{fontSize: "18px", margin: "20px 0"}}
32
- >
33
- You've clicked the burger
34
- <strong>
35
- {count}
36
- </strong>
37
- times!
38
- </p>
39
- <button
40
- onClick={lambda e: any -> None{ setCount(count + 1);} }
41
- style={{
42
- padding: "10px 20px",
43
- fontSize: "16px",
44
- backgroundColor: "#ff6b35",
45
- color: "white",
46
- border: "none",
47
- borderRadius: "5px",
48
- cursor: "pointer",
49
- boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
50
- }}
51
- >
52
- Click the Burger! 🍔
53
- </button>
54
- <h2
55
- style={{marginTop: "40px", marginBottom: "20px"}}
56
- >
57
- CSS Asset Examples
58
- </h2>
59
- <div className="container">
60
- <h3
61
- style={{color: "white", textShadow: "2px 2px 4px rgba(0,0,0,0.5)"}}
62
- >
63
- Background Image Example
64
- </h3>
65
- <p
66
- style={{color: "white", textShadow: "2px 2px 4px rgba(0,0,0,0.5)"}}
67
- >
68
- This container uses the burger image as a background via CSS
69
- </p>
70
- </div>
71
- <div className="card">
72
- <h3>
73
- Image in Card
74
- </h3>
75
- <img
76
- src="/static/assets/burger.png"
77
- alt="Burger in Card"
78
- className="burgerImage"
79
- />
80
- <p
81
- style={{marginTop: "15px", color: "#666"}}
82
- >
83
- This image is displayed within a styled card using CSS classes
84
- </p>
85
- </div>
86
- </div>;
87
- }
88
- }
@@ -1,55 +0,0 @@
1
- # Pages
2
- cl import from react { useState, useEffect }
3
-
4
- cl {
5
- def:pub app -> any {
6
- [count, setCount] = useState(0);
7
- useEffect(lambda -> None{ console.log("Count: ", count);} , [count]);
8
- return <div
9
- style={{
10
- padding: "20px",
11
- textAlign: "center",
12
- fontFamily: "Arial, sans-serif"
13
- }}
14
- >
15
- <h1>
16
- 🍔 Burger Counter App
17
- </h1>
18
- <img
19
- src="/static/assets/burger.png"
20
- alt="Delicious Burger"
21
- style={{
22
- width: "200px",
23
- height: "auto",
24
- margin: "20px 0",
25
- borderRadius: "10px",
26
- boxShadow: "0 4px 8px rgba(0,0,0,0.2)"
27
- }}
28
- />
29
- <p
30
- style={{fontSize: "18px", margin: "20px 0"}}
31
- >
32
- You've clicked the burger
33
- <strong>
34
- {count}
35
- </strong>
36
- times!
37
- </p>
38
- <button
39
- onClick={lambda e: any -> None{ setCount(count + 1);} }
40
- style={{
41
- padding: "10px 20px",
42
- fontSize: "16px",
43
- backgroundColor: "#ff6b35",
44
- color: "white",
45
- border: "none",
46
- borderRadius: "5px",
47
- cursor: "pointer",
48
- boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
49
- }}
50
- >
51
- Click the Burger! 🍔
52
- </button>
53
- </div>;
54
- }
55
- }
@@ -1,111 +0,0 @@
1
- # Pages
2
- cl import from react { useState, useEffect }
3
- # Import image using the @jac-client/assets alias
4
- cl import from "@jac-client/assets/burger.png" {
5
- default as burgerImage
6
- }
7
-
8
- cl {
9
- def:pub app -> any {
10
- [count, setCount] = useState(0);
11
- useEffect(lambda -> None{ console.log("Count: ", count);} , [count]);
12
- return <div
13
- style={{
14
- padding: "20px",
15
- textAlign: "center",
16
- fontFamily: "Arial, sans-serif"
17
- }}
18
- >
19
- <h1>
20
- 🍔 Import Alias Example
21
- </h1>
22
- <p
23
- style={{color: "#666", marginBottom: "20px"}}
24
- >
25
- Using
26
- <code>
27
- @jac-client/assets
28
- </code>
29
- alias to import assets
30
- </p>
31
- <img
32
- src={burgerImage}
33
- alt="Delicious Burger"
34
- style={{
35
- width: "200px",
36
- height: "auto",
37
- margin: "20px 0",
38
- borderRadius: "10px",
39
- boxShadow: "0 4px 8px rgba(0,0,0,0.2)"
40
- }}
41
- />
42
- <p
43
- style={{fontSize: "18px", margin: "20px 0"}}
44
- >
45
- You've clicked the burger
46
- <strong>
47
- {count}
48
- </strong>
49
- times!
50
- </p>
51
- <button
52
- onClick={lambda e: any -> None{ setCount(count + 1);} }
53
- style={{
54
- padding: "10px 20px",
55
- fontSize: "16px",
56
- backgroundColor: "#ff6b35",
57
- color: "white",
58
- border: "none",
59
- borderRadius: "5px",
60
- cursor: "pointer",
61
- boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
62
- }}
63
- >
64
- Click the Burger! 🍔
65
- </button>
66
- <div
67
- style={{
68
- marginTop: "30px",
69
- padding: "15px",
70
- backgroundColor: "#f5f5f5",
71
- borderRadius: "5px",
72
- fontSize: "12px",
73
- textAlign: "left",
74
- maxWidth: "600px",
75
- margin: "30px auto"
76
- }}
77
- >
78
- <strong>
79
- How it works:
80
- </strong>
81
- <ul
82
- style={{marginTop: "10px", paddingLeft: "20px"}}
83
- >
84
- <li>
85
- Import using:
86
- <code>
87
- cl import from '@jac-client/assets/burger.png'
88
- </code>
89
- </li>
90
- <li>
91
- Vite processes the import and generates optimized URLs
92
- </li>
93
- <li>
94
- Assets are automatically copied from
95
- <code>
96
- assets/
97
- </code>
98
- to
99
- <code>
100
- compiled/assets/
101
- </code>
102
- during build
103
- </li>
104
- <li>
105
- Automatic hash generation for cache busting
106
- </li>
107
- </ul>
108
- </div>
109
- </div>;
110
- }
111
- }
@@ -1,21 +0,0 @@
1
- # Pages
2
- cl import from react { useState, useEffect }
3
- cl {
4
- def:pub app -> any {
5
- [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,377 +0,0 @@
1
- # Simple Authentication App with Jac Client Utils
2
- cl import from react {
3
- useState,
4
- useEffect
5
- }
6
- cl import from '@jac-client/utils' { jacSignup, jacLogin, jacLogout, jacIsLoggedIn }
7
-
8
- cl {
9
- def:pub app -> any {
10
- [isLoggedIn, setIsLoggedIn] = useState(False);
11
- [isSignup, setIsSignup] = useState(False);
12
- [username, setUsername] = useState("");
13
- [password, setPassword] = useState("");
14
- [error, setError] = useState("");
15
- [loading, setLoading] = useState(False);
16
-
17
- # Check login status on mount
18
- useEffect(lambda -> None{ setIsLoggedIn(jacIsLoggedIn());} , []);
19
-
20
- # Handle login
21
- async def handleLogin -> None {
22
- setError("");
23
- if not username.trim() or not password {
24
- setError("Please fill in all fields");
25
- return;
26
- }
27
- setLoading(True);
28
- success = await jacLogin(username, password);
29
- setLoading(False);
30
- if success {
31
- setIsLoggedIn(True);
32
- setUsername("");
33
- setPassword("");
34
- } else {
35
- setError("Invalid username or password");
36
- }
37
- }
38
-
39
- # Handle signup
40
- async def handleSignup -> None {
41
- setError("");
42
- if not username.trim() or not password {
43
- setError("Please fill in all fields");
44
- return;
45
- }
46
- if password.length < 6 {
47
- setError("Password must be at least 6 characters");
48
- return;
49
- }
50
- setLoading(True);
51
- result = await jacSignup(username, password);
52
- setLoading(False);
53
- if result["success"] {
54
- setIsLoggedIn(True);
55
- setUsername("");
56
- setPassword("");
57
- } else {
58
- setError(result["error"] if result["error"] else "Signup failed");
59
- }
60
- }
61
-
62
- # Handle logout
63
- def handleLogout -> None {
64
- jacLogout();
65
- setIsLoggedIn(False);
66
- setUsername("");
67
- setPassword("");
68
- setError("");
69
- }
70
-
71
- # Handle form submit
72
- async def handleSubmit(e: any) -> None {
73
- e.preventDefault();
74
- if isSignup {
75
- await handleSignup();
76
- } else {
77
- await handleLogin();
78
- }
79
- }
80
-
81
- # Logged in view - Dashboard
82
- if isLoggedIn {
83
- return <div
84
- style={{
85
- "minHeight": "100vh",
86
- "background": "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
87
- "display": "flex",
88
- "alignItems": "center",
89
- "justifyContent": "center",
90
- "fontFamily": "system-ui, -apple-system, sans-serif"
91
- }}
92
- >
93
- <div
94
- style={{
95
- "background": "#ffffff",
96
- "borderRadius": "16px",
97
- "padding": "48px",
98
- "boxShadow": "0 20px 60px rgba(0,0,0,0.3)",
99
- "maxWidth": "500px",
100
- "width": "90%",
101
- "textAlign": "center"
102
- }}
103
- >
104
- <h1
105
- style={{
106
- "fontSize": "2.5rem",
107
- "marginBottom": "16px",
108
- "color": "#1f2937",
109
- "fontWeight": "700"
110
- }}
111
- >
112
- ✅ Welcome!
113
- </h1>
114
- <p
115
- style={{
116
- "fontSize": "1.1rem",
117
- "color": "#6b7280",
118
- "marginBottom": "32px"
119
- }}
120
- >
121
- You are successfully logged in
122
- </p>
123
- <div
124
- style={{
125
- "background": "#f3f4f6",
126
- "padding": "24px",
127
- "borderRadius": "12px",
128
- "marginBottom": "32px"
129
- }}
130
- >
131
- <p
132
- style={{
133
- "fontSize": "0.9rem",
134
- "color": "#6b7280",
135
- "marginBottom": "8px"
136
- }}
137
- >
138
- Logged in as:
139
- </p>
140
- <p
141
- style={{
142
- "fontSize": "1.2rem",
143
- "fontWeight": "600",
144
- "color": "#667eea"
145
- }}
146
- >
147
- User
148
- </p>
149
- </div>
150
- <button
151
- onClick={handleLogout}
152
- style={{
153
- "width": "100%",
154
- "padding": "14px 24px",
155
- "background": "#ef4444",
156
- "color": "#ffffff",
157
- "border": "none",
158
- "borderRadius": "10px",
159
- "fontSize": "16px",
160
- "fontWeight": "600",
161
- "cursor": "pointer",
162
- "transition": "all 0.3s",
163
- "boxShadow": "0 4px 12px rgba(239,68,68,0.3)"
164
- }}
165
- >
166
- Logout
167
- </button>
168
- </div>
169
- </div>;
170
- }
171
-
172
- # Login/Signup view
173
- return <div
174
- style={{
175
- "minHeight": "100vh",
176
- "background": "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
177
- "display": "flex",
178
- "alignItems": "center",
179
- "justifyContent": "center",
180
- "fontFamily": "system-ui, -apple-system, sans-serif",
181
- "padding": "20px"
182
- }}
183
- >
184
- <div
185
- style={{
186
- "background": "#ffffff",
187
- "borderRadius": "16px",
188
- "padding": "48px",
189
- "boxShadow": "0 20px 60px rgba(0,0,0,0.3)",
190
- "maxWidth": "400px",
191
- "width": "100%"
192
- }}
193
- >
194
- # Header
195
- <div
196
- style={{"textAlign": "center", "marginBottom": "32px"}}
197
- >
198
- <h1
199
- style={{
200
- "fontSize": "2rem",
201
- "fontWeight": "700",
202
- "color": "#1f2937",
203
- "marginBottom": "8px"
204
- }}
205
- >
206
- {("Create Account" if isSignup else "Welcome Back")}
207
- </h1>
208
- <p
209
- style={{"color": "#6b7280", "fontSize": "0.95rem"}}
210
- >
211
- {(
212
- "Sign up to get started"
213
- if isSignup
214
- else "Sign in to continue"
215
- )}
216
- </p>
217
- </div>
218
- # Form
219
- <form
220
- onSubmit={handleSubmit}
221
- style={{"marginBottom": "24px"}}
222
- >
223
- <div
224
- style={{"marginBottom": "20px"}}
225
- >
226
- <label
227
- style={{
228
- "display": "block",
229
- "marginBottom": "8px",
230
- "color": "#374151",
231
- "fontSize": "14px",
232
- "fontWeight": "600"
233
- }}
234
- >
235
- Username
236
- </label>
237
- <input
238
- type="text"
239
- value={username}
240
- onChange={lambda e: any -> None{ setUsername(
241
- e.target.value
242
- );} }
243
- placeholder="Enter your username"
244
- style={{
245
- "width": "100%",
246
- "padding": "12px 16px",
247
- "border": "2px solid #e5e7eb",
248
- "borderRadius": "10px",
249
- "fontSize": "16px",
250
- "outline": "none",
251
- "transition": "border 0.2s",
252
- "boxSizing": "border-box"
253
- }}
254
- />
255
- </div>
256
- <div
257
- style={{"marginBottom": "24px"}}
258
- >
259
- <label
260
- style={{
261
- "display": "block",
262
- "marginBottom": "8px",
263
- "color": "#374151",
264
- "fontSize": "14px",
265
- "fontWeight": "600"
266
- }}
267
- >
268
- Password
269
- </label>
270
- <input
271
- type="password"
272
- value={password}
273
- onChange={lambda e: any -> None{ setPassword(
274
- e.target.value
275
- );} }
276
- placeholder="Enter your password"
277
- style={{
278
- "width": "100%",
279
- "padding": "12px 16px",
280
- "border": "2px solid #e5e7eb",
281
- "borderRadius": "10px",
282
- "fontSize": "16px",
283
- "outline": "none",
284
- "transition": "border 0.2s",
285
- "boxSizing": "border-box"
286
- }}
287
- />
288
- </div>
289
- {(
290
- <div
291
- style={{
292
- "padding": "12px",
293
- "background": "#fee2e2",
294
- "border": "1px solid #fecaca",
295
- "borderRadius": "8px",
296
- "marginBottom": "20px"
297
- }}
298
- >
299
- <p
300
- style={{
301
- "color": "#dc2626",
302
- "fontSize": "14px",
303
- "margin": "0"
304
- }}
305
- >
306
- {error}
307
- </p>
308
- </div>
309
- )
310
- if error
311
- else None}
312
- <button
313
- type="submit"
314
- disabled={loading}
315
- style={{
316
- "width": "100%",
317
- "padding": "14px 24px",
318
- "background": (("#9ca3af" if loading else "#667eea")),
319
- "color": "#ffffff",
320
- "border": "none",
321
- "borderRadius": "10px",
322
- "fontSize": "16px",
323
- "fontWeight": "600",
324
- "cursor": (("not-allowed" if loading else "pointer")),
325
- "transition": "all 0.3s",
326
- "boxShadow": "0 4px 12px rgba(102,126,234,0.4)"
327
- }}
328
- >
329
- {(
330
- (
331
- "Processing..."
332
- if loading
333
- else ("Sign Up" if isSignup else "Sign In")
334
- )
335
- )}
336
- </button>
337
- </form>
338
- # Toggle between login/signup
339
- <div
340
- style={{"textAlign": "center"}}
341
- >
342
- <p
343
- style={{
344
- "color": "#6b7280",
345
- "fontSize": "14px",
346
- "marginBottom": "8px"
347
- }}
348
- >
349
- {(
350
- (
351
- "Already have an account?"
352
- if isSignup
353
- else "Don't have an account?"
354
- )
355
- )}
356
- </p>
357
- <button
358
- onClick={lambda -> None{ setIsSignup(not isSignup);setError(
359
- ""
360
- );setUsername("");setPassword("");} }
361
- style={{
362
- "background": "none",
363
- "border": "none",
364
- "color": "#667eea",
365
- "fontSize": "14px",
366
- "fontWeight": "600",
367
- "cursor": "pointer",
368
- "textDecoration": "underline"
369
- }}
370
- >
371
- {(("Sign In" if isSignup else "Create Account"))}
372
- </button>
373
- </div>
374
- </div>
375
- </div>;
376
- }
377
- }