jac-client 0.2.5__py3-none-any.whl → 0.2.7__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/src/app.jac +473 -741
- jac_client/examples/all-in-one/src/components/CategoryFilter.jac +35 -0
- jac_client/examples/all-in-one/src/components/Header.jac +13 -0
- jac_client/examples/all-in-one/src/components/ProfitOverview.jac +50 -0
- jac_client/examples/all-in-one/src/components/Summary.jac +53 -0
- jac_client/examples/all-in-one/src/components/TransactionForm.jac +158 -0
- jac_client/examples/all-in-one/src/components/TransactionItem.jac +55 -0
- jac_client/examples/all-in-one/src/components/TransactionList.jac +37 -0
- jac_client/examples/all-in-one/src/components/navigation.jac +132 -0
- jac_client/examples/all-in-one/src/constants/categories.jac +37 -0
- jac_client/examples/all-in-one/src/constants/clients.jac +13 -0
- jac_client/examples/all-in-one/src/context/BudgetContext.jac +28 -0
- jac_client/examples/all-in-one/src/hooks/useBudget.jac +116 -0
- jac_client/examples/all-in-one/src/hooks/useLocalStorage.jac +36 -0
- jac_client/examples/all-in-one/src/pages/BudgetPlanner.cl.jac +70 -0
- jac_client/examples/all-in-one/src/pages/BudgetPlanner.jac +126 -0
- jac_client/examples/all-in-one/src/pages/FeaturesTest.cl.jac +552 -0
- jac_client/examples/all-in-one/src/pages/FeaturesTest.jac +126 -0
- jac_client/examples/all-in-one/src/pages/LandingPage.jac +101 -0
- jac_client/examples/all-in-one/src/pages/loginPage.jac +132 -0
- jac_client/examples/all-in-one/src/pages/nestedDemo.jac +61 -0
- jac_client/examples/all-in-one/src/pages/notFound.jac +24 -0
- jac_client/examples/all-in-one/src/pages/signupPage.jac +133 -0
- jac_client/examples/all-in-one/src/utils/formatters.jac +52 -0
- jac_client/examples/asset-serving/css-with-image/src/app.jac +3 -3
- jac_client/examples/asset-serving/image-asset/src/app.jac +3 -3
- jac_client/examples/asset-serving/import-alias/src/app.jac +3 -3
- jac_client/examples/basic/src/app.jac +3 -3
- jac_client/examples/basic-auth/src/app.jac +31 -37
- jac_client/examples/basic-auth-with-router/src/app.jac +16 -16
- jac_client/examples/basic-full-stack/src/app.jac +24 -30
- jac_client/examples/css-styling/js-styling/src/app.jac +5 -5
- jac_client/examples/css-styling/material-ui/src/app.jac +5 -5
- jac_client/examples/css-styling/pure-css/src/app.jac +5 -5
- jac_client/examples/css-styling/sass-example/src/app.jac +5 -5
- jac_client/examples/css-styling/styled-components/src/app.jac +5 -5
- jac_client/examples/css-styling/tailwind-example/src/app.jac +5 -5
- jac_client/examples/full-stack-with-auth/src/app.jac +16 -16
- jac_client/examples/ts-support/src/app.jac +4 -4
- jac_client/examples/with-router/src/app.jac +4 -4
- jac_client/plugin/cli.jac +155 -203
- jac_client/plugin/client_runtime.cl.jac +5 -1
- jac_client/plugin/impl/client.impl.jac +74 -12
- jac_client/plugin/plugin_config.jac +11 -11
- jac_client/plugin/src/compiler.jac +2 -1
- jac_client/plugin/src/impl/babel_processor.impl.jac +22 -17
- jac_client/plugin/src/impl/compiler.impl.jac +57 -18
- jac_client/plugin/src/impl/vite_bundler.impl.jac +66 -102
- jac_client/plugin/src/package_installer.jac +1 -1
- jac_client/plugin/src/vite_bundler.jac +1 -0
- jac_client/tests/conftest.py +10 -8
- jac_client/tests/fixtures/spawn_test/app.jac +15 -18
- jac_client/tests/fixtures/with-ts/app.jac +4 -4
- jac_client/tests/test_cli.py +99 -45
- jac_client/tests/test_it.py +290 -79
- {jac_client-0.2.5.dist-info → jac_client-0.2.7.dist-info}/METADATA +16 -7
- jac_client-0.2.7.dist-info/RECORD +97 -0
- jac_client-0.2.5.dist-info/RECORD +0 -74
- {jac_client-0.2.5.dist-info → jac_client-0.2.7.dist-info}/WHEEL +0 -0
- {jac_client-0.2.5.dist-info → jac_client-0.2.7.dist-info}/entry_points.txt +0 -0
- {jac_client-0.2.5.dist-info → jac_client-0.2.7.dist-info}/top_level.txt +0 -0
|
@@ -7,65 +7,65 @@ cl import from '@jac-client/utils' { jacSignup, jacLogin, jacLogout, jacIsLogged
|
|
|
7
7
|
|
|
8
8
|
cl {
|
|
9
9
|
def:pub app -> any {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
has isLoggedIn: bool = False;
|
|
11
|
+
has isSignup: bool = False;
|
|
12
|
+
has username: str = "";
|
|
13
|
+
has password: str = "";
|
|
14
|
+
has error: str = "";
|
|
15
|
+
has loading: bool = False;
|
|
16
16
|
|
|
17
17
|
# Check login status on mount
|
|
18
|
-
useEffect(lambda -> None{
|
|
18
|
+
useEffect(lambda -> None{ isLoggedIn = jacIsLoggedIn();} , []);
|
|
19
19
|
|
|
20
20
|
# Handle login
|
|
21
21
|
async def handleLogin -> None {
|
|
22
|
-
|
|
22
|
+
error = "";
|
|
23
23
|
if not username.trim() or not password {
|
|
24
|
-
|
|
24
|
+
error = "Please fill in all fields";
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
loading = True;
|
|
28
28
|
success = await jacLogin(username, password);
|
|
29
|
-
|
|
29
|
+
loading = False;
|
|
30
30
|
if success {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
isLoggedIn = True;
|
|
32
|
+
username = "";
|
|
33
|
+
password = "";
|
|
34
34
|
} else {
|
|
35
|
-
|
|
35
|
+
error = "Invalid username or password";
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
# Handle signup
|
|
40
40
|
async def handleSignup -> None {
|
|
41
|
-
|
|
41
|
+
error = "";
|
|
42
42
|
if not username.trim() or not password {
|
|
43
|
-
|
|
43
|
+
error = "Please fill in all fields";
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
if password.length < 6 {
|
|
47
|
-
|
|
47
|
+
error = "Password must be at least 6 characters";
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
loading = True;
|
|
51
51
|
result = await jacSignup(username, password);
|
|
52
|
-
|
|
52
|
+
loading = False;
|
|
53
53
|
if result["success"] {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
isLoggedIn = True;
|
|
55
|
+
username = "";
|
|
56
|
+
password = "";
|
|
57
57
|
} else {
|
|
58
|
-
|
|
58
|
+
error = result["error"] if result["error"] else "Signup failed";
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
# Handle logout
|
|
63
63
|
def handleLogout -> None {
|
|
64
64
|
jacLogout();
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
isLoggedIn = False;
|
|
66
|
+
username = "";
|
|
67
|
+
password = "";
|
|
68
|
+
error = "";
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
# Handle form submit
|
|
@@ -237,9 +237,7 @@ cl {
|
|
|
237
237
|
<input
|
|
238
238
|
type="text"
|
|
239
239
|
value={username}
|
|
240
|
-
onChange={lambda e: any -> None{
|
|
241
|
-
e.target.value
|
|
242
|
-
);} }
|
|
240
|
+
onChange={lambda e: any -> None{ username = e.target.value;} }
|
|
243
241
|
placeholder="Enter your username"
|
|
244
242
|
style={{
|
|
245
243
|
"width": "100%",
|
|
@@ -270,9 +268,7 @@ cl {
|
|
|
270
268
|
<input
|
|
271
269
|
type="password"
|
|
272
270
|
value={password}
|
|
273
|
-
onChange={lambda e: any -> None{
|
|
274
|
-
e.target.value
|
|
275
|
-
);} }
|
|
271
|
+
onChange={lambda e: any -> None{ password = e.target.value;} }
|
|
276
272
|
placeholder="Enter your password"
|
|
277
273
|
style={{
|
|
278
274
|
"width": "100%",
|
|
@@ -355,9 +351,7 @@ cl {
|
|
|
355
351
|
)}
|
|
356
352
|
</p>
|
|
357
353
|
<button
|
|
358
|
-
onClick={lambda -> None{
|
|
359
|
-
""
|
|
360
|
-
);setUsername("");setPassword("");} }
|
|
354
|
+
onClick={lambda -> None{ isSignup = not isSignup; error = ""; username = ""; password = "";} }
|
|
361
355
|
style={{
|
|
362
356
|
"background": "none",
|
|
363
357
|
"border": "none",
|
|
@@ -109,32 +109,32 @@ cl {
|
|
|
109
109
|
|
|
110
110
|
# Login Page
|
|
111
111
|
def LoginPage -> any {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
has username: str = "";
|
|
113
|
+
has password: str = "";
|
|
114
|
+
has error: str = "";
|
|
115
115
|
navigate = useNavigate();
|
|
116
116
|
|
|
117
117
|
async def handleLogin(e: any) -> None {
|
|
118
118
|
e.preventDefault();
|
|
119
|
-
|
|
119
|
+
error = "";
|
|
120
120
|
if not username or not password {
|
|
121
|
-
|
|
121
|
+
error = "Please fill in all fields";
|
|
122
122
|
return;
|
|
123
123
|
}
|
|
124
124
|
success = await jacLogin(username, password);
|
|
125
125
|
if success {
|
|
126
126
|
navigate("/dashboard");
|
|
127
127
|
} else {
|
|
128
|
-
|
|
128
|
+
error = "Invalid credentials";
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
def handleUsernameChange(e: any) -> None {
|
|
133
|
-
|
|
133
|
+
username = e.target.value;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
def handlePasswordChange(e: any) -> None {
|
|
137
|
-
|
|
137
|
+
password = e.target.value;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
errorDisplay = None;
|
|
@@ -235,32 +235,32 @@ cl {
|
|
|
235
235
|
|
|
236
236
|
# Signup Page
|
|
237
237
|
def SignupPage -> any {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
has username: str = "";
|
|
239
|
+
has password: str = "";
|
|
240
|
+
has error: str = "";
|
|
241
241
|
navigate = useNavigate();
|
|
242
242
|
|
|
243
243
|
async def handleSignup(e: any) -> None {
|
|
244
244
|
e.preventDefault();
|
|
245
|
-
|
|
245
|
+
error = "";
|
|
246
246
|
if not username or not password {
|
|
247
|
-
|
|
247
|
+
error = "Please fill in all fields";
|
|
248
248
|
return;
|
|
249
249
|
}
|
|
250
250
|
result = await jacSignup(username, password);
|
|
251
251
|
if result["success"] {
|
|
252
252
|
navigate("/dashboard");
|
|
253
253
|
} else {
|
|
254
|
-
|
|
254
|
+
error = result["error"] if result["error"] else "Signup failed";
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
def handleUsernameChange(e: any) -> None {
|
|
259
|
-
|
|
259
|
+
username = e.target.value;
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
def handlePasswordChange(e: any) -> None {
|
|
263
|
-
|
|
263
|
+
password = e.target.value;
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
errorDisplay = None;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Todo App
|
|
2
|
-
cl import from react {
|
|
2
|
+
cl import from react { useEffect }
|
|
3
3
|
|
|
4
4
|
node Todo {
|
|
5
5
|
has text: str,
|
|
@@ -34,14 +34,14 @@ walker read_todos {
|
|
|
34
34
|
|
|
35
35
|
cl {
|
|
36
36
|
def:pub app -> any {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
has todos: list = [];
|
|
38
|
+
has inputValue: str = "";
|
|
39
|
+
has filter: str = "all";
|
|
40
40
|
|
|
41
41
|
useEffect(
|
|
42
42
|
lambda -> None{ async def loadTodos -> None {
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
result = root spawn read_todos();
|
|
44
|
+
todos = result.reports;
|
|
45
45
|
} loadTodos();} ,
|
|
46
46
|
[]
|
|
47
47
|
);
|
|
@@ -54,41 +54,35 @@ cl {
|
|
|
54
54
|
newTodo = {"id": Date.now(), "text": inputValue.trim(), "done": False};
|
|
55
55
|
response = root spawn create_todo(text=inputValue.trim());
|
|
56
56
|
newTodos = todos.concat([response.reports[0][0]]);
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
todos = newTodos;
|
|
58
|
+
inputValue = "";
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
# Toggle todo completion status
|
|
62
62
|
async def toggleTodo(id: any) -> None {
|
|
63
63
|
console.log("toggleTodo", id);
|
|
64
64
|
id spawn toggle_todo();
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}return todo; }
|
|
76
|
-
)
|
|
65
|
+
todos = todos.map(
|
|
66
|
+
lambda todo: any -> any{ if todo._jac_id == id {
|
|
67
|
+
updatedTodo = {
|
|
68
|
+
"_jac_id": todo._jac_id,
|
|
69
|
+
"text": todo.text,
|
|
70
|
+
"done": not todo.done,
|
|
71
|
+
"id": todo.id
|
|
72
|
+
};
|
|
73
|
+
return updatedTodo;
|
|
74
|
+
}return todo; }
|
|
77
75
|
);
|
|
78
76
|
}
|
|
79
77
|
|
|
80
78
|
# Delete a todo
|
|
81
79
|
def deleteTodo(id: any) -> None {
|
|
82
|
-
|
|
83
|
-
todos.filter(lambda todo: any -> bool{ return todo.id != id; } )
|
|
84
|
-
);
|
|
80
|
+
todos = todos.filter(lambda todo: any -> bool{ return todo.id != id; } );
|
|
85
81
|
}
|
|
86
82
|
|
|
87
83
|
# Clear all completed todos
|
|
88
84
|
def clearCompleted -> None {
|
|
89
|
-
|
|
90
|
-
todos.filter(lambda todo: any -> bool{ return not todo.done; } )
|
|
91
|
-
);
|
|
85
|
+
todos = todos.filter(lambda todo: any -> bool{ return not todo.done; } );
|
|
92
86
|
}
|
|
93
87
|
|
|
94
88
|
# Filter todos based on current filter
|
|
@@ -146,7 +140,7 @@ cl {
|
|
|
146
140
|
<input
|
|
147
141
|
type="text"
|
|
148
142
|
value={inputValue}
|
|
149
|
-
onChange={lambda e: any -> None{
|
|
143
|
+
onChange={lambda e: any -> None{ inputValue = e.target.value;} }
|
|
150
144
|
onKeyPress={lambda e: any -> None{ if e.key == "Enter" {
|
|
151
145
|
addTodo();
|
|
152
146
|
}} }
|
|
@@ -187,7 +181,7 @@ cl {
|
|
|
187
181
|
}}
|
|
188
182
|
>
|
|
189
183
|
<button
|
|
190
|
-
onClick={lambda -> None{
|
|
184
|
+
onClick={lambda -> None{ filter = "all";} }
|
|
191
185
|
style={{
|
|
192
186
|
"padding": "8px 16px",
|
|
193
187
|
"background": ("#3b82f6" if filter == "all" else "#ffffff"),
|
|
@@ -202,7 +196,7 @@ cl {
|
|
|
202
196
|
All
|
|
203
197
|
</button>
|
|
204
198
|
<button
|
|
205
|
-
onClick={lambda -> None{
|
|
199
|
+
onClick={lambda -> None{ filter = "active";} }
|
|
206
200
|
style={{
|
|
207
201
|
"padding": "8px 16px",
|
|
208
202
|
"background": ("#3b82f6" if filter == "active" else "#ffffff"),
|
|
@@ -217,7 +211,7 @@ cl {
|
|
|
217
211
|
Active
|
|
218
212
|
</button>
|
|
219
213
|
<button
|
|
220
|
-
onClick={lambda -> None{
|
|
214
|
+
onClick={lambda -> None{ filter = "completed";} }
|
|
221
215
|
style={{
|
|
222
216
|
"padding": "8px 16px",
|
|
223
217
|
"background": (
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# Pages
|
|
2
|
-
cl import from react {
|
|
2
|
+
cl import from react { useEffect }
|
|
3
3
|
cl import from .styles { default as styles }
|
|
4
4
|
|
|
5
5
|
cl {
|
|
6
6
|
def:pub app -> any {
|
|
7
|
-
|
|
7
|
+
has count: int = 0;
|
|
8
8
|
|
|
9
9
|
useEffect(lambda -> None{ console.log("Count changed: ", count);} , [count]);
|
|
10
10
|
|
|
11
|
-
handleIncrement = lambda e: any -> None{
|
|
11
|
+
handleIncrement = lambda e: any -> None{ count = count + 1;} ;
|
|
12
12
|
|
|
13
|
-
handleDecrement = lambda e: any -> None{
|
|
13
|
+
handleDecrement = lambda e: any -> None{ count = count - 1;} ;
|
|
14
14
|
|
|
15
|
-
handleReset = lambda e: any -> None{
|
|
15
|
+
handleReset = lambda e: any -> None{ count = 0;} ;
|
|
16
16
|
|
|
17
17
|
countStyle = styles.countDisplayZero
|
|
18
18
|
if count == 0
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
cl import from react {
|
|
1
|
+
cl import from react { useEffect }
|
|
2
2
|
cl import from '@mui/material/Button' { default as Button }
|
|
3
3
|
cl import from '@mui/material/Card' { default as Card }
|
|
4
4
|
cl import from '@mui/material/CardContent' { default as CardContent }
|
|
@@ -13,15 +13,15 @@ cl import from '@mui/icons-material/Refresh' { default as RefreshIcon }
|
|
|
13
13
|
|
|
14
14
|
cl {
|
|
15
15
|
def:pub app -> any {
|
|
16
|
-
|
|
16
|
+
has count: int = 0;
|
|
17
17
|
|
|
18
18
|
useEffect(lambda -> None{ console.log("Count changed: ", count);} , [count]);
|
|
19
19
|
|
|
20
|
-
handleIncrement = lambda e: any -> None{
|
|
20
|
+
handleIncrement = lambda e: any -> None{ count = count + 1;} ;
|
|
21
21
|
|
|
22
|
-
handleDecrement = lambda e: any -> None{
|
|
22
|
+
handleDecrement = lambda e: any -> None{ count = count - 1;} ;
|
|
23
23
|
|
|
24
|
-
handleReset = lambda e: any -> None{
|
|
24
|
+
handleReset = lambda e: any -> None{ count = 0;} ;
|
|
25
25
|
|
|
26
26
|
return <Box
|
|
27
27
|
sx={{
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# Pages
|
|
2
|
-
cl import from react {
|
|
2
|
+
cl import from react { useEffect }
|
|
3
3
|
cl import ".styles.css";
|
|
4
4
|
|
|
5
5
|
cl {
|
|
6
6
|
def:pub app -> any {
|
|
7
|
-
|
|
7
|
+
has count: int = 0;
|
|
8
8
|
|
|
9
9
|
useEffect(lambda -> None{ console.log("Count changed: ", count);} , [count]);
|
|
10
10
|
|
|
11
|
-
handleIncrement = lambda e: any -> None{
|
|
11
|
+
handleIncrement = lambda e: any -> None{ count = count + 1;} ;
|
|
12
12
|
|
|
13
|
-
handleDecrement = lambda e: any -> None{
|
|
13
|
+
handleDecrement = lambda e: any -> None{ count = count - 1;} ;
|
|
14
14
|
|
|
15
|
-
handleReset = lambda e: any -> None{
|
|
15
|
+
handleReset = lambda e: any -> None{ count = 0;} ;
|
|
16
16
|
|
|
17
17
|
countClass = "countDisplay " + (
|
|
18
18
|
"positive" if count > 0 else "negative" if count < 0 else "zero"
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# Pages
|
|
2
|
-
cl import from react {
|
|
2
|
+
cl import from react { useEffect }
|
|
3
3
|
cl import ".styles.scss";
|
|
4
4
|
|
|
5
5
|
cl {
|
|
6
6
|
def:pub app -> any {
|
|
7
|
-
|
|
7
|
+
has count: int = 0;
|
|
8
8
|
|
|
9
9
|
useEffect(lambda -> None{ console.log("Count changed: ", count);} , [count]);
|
|
10
10
|
|
|
11
|
-
handleIncrement = lambda e: any -> None{
|
|
11
|
+
handleIncrement = lambda e: any -> None{ count = count + 1;} ;
|
|
12
12
|
|
|
13
|
-
handleDecrement = lambda e: any -> None{
|
|
13
|
+
handleDecrement = lambda e: any -> None{ count = count - 1;} ;
|
|
14
14
|
|
|
15
|
-
handleReset = lambda e: any -> None{
|
|
15
|
+
handleReset = lambda e: any -> None{ count = 0;} ;
|
|
16
16
|
|
|
17
17
|
countClass = "countDisplay " + (
|
|
18
18
|
"positive" if count > 0 else "negative" if count < 0 else "zero"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Pages
|
|
2
|
-
cl import from react {
|
|
2
|
+
cl import from react { useEffect }
|
|
3
3
|
cl import from .styled {
|
|
4
4
|
Container,
|
|
5
5
|
Card,
|
|
@@ -15,15 +15,15 @@ cl import from .styled {
|
|
|
15
15
|
|
|
16
16
|
cl {
|
|
17
17
|
def:pub app -> any {
|
|
18
|
-
|
|
18
|
+
has count: int = 0;
|
|
19
19
|
|
|
20
20
|
useEffect(lambda -> None{ console.log("Count changed: ", count);} , [count]);
|
|
21
21
|
|
|
22
|
-
handleIncrement = lambda e: any -> None{
|
|
22
|
+
handleIncrement = lambda e: any -> None{ count = count + 1;} ;
|
|
23
23
|
|
|
24
|
-
handleDecrement = lambda e: any -> None{
|
|
24
|
+
handleDecrement = lambda e: any -> None{ count = count - 1;} ;
|
|
25
25
|
|
|
26
|
-
handleReset = lambda e: any -> None{
|
|
26
|
+
handleReset = lambda e: any -> None{ count = 0;} ;
|
|
27
27
|
|
|
28
28
|
return <Container>
|
|
29
29
|
<Card>
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# Pages
|
|
2
|
-
cl import from react {
|
|
2
|
+
cl import from react { useEffect }
|
|
3
3
|
cl import ".global.css";
|
|
4
4
|
cl {
|
|
5
5
|
def:pub app -> any {
|
|
6
|
-
|
|
6
|
+
has count: int = 0;
|
|
7
7
|
|
|
8
8
|
useEffect(lambda -> None{ console.log("Count changed: ", count);} , [count]);
|
|
9
9
|
|
|
10
|
-
handleIncrement = lambda e: any -> None{
|
|
10
|
+
handleIncrement = lambda e: any -> None{ count = count + 1;} ;
|
|
11
11
|
|
|
12
|
-
handleDecrement = lambda e: any -> None{
|
|
12
|
+
handleDecrement = lambda e: any -> None{ count = count - 1;} ;
|
|
13
13
|
|
|
14
|
-
handleReset = lambda e: any -> None{
|
|
14
|
+
handleReset = lambda e: any -> None{ count = 0;} ;
|
|
15
15
|
|
|
16
16
|
countColorClass = "text-gray-800"
|
|
17
17
|
if count == 0
|
|
@@ -139,32 +139,32 @@ cl {
|
|
|
139
139
|
|
|
140
140
|
# Login Page
|
|
141
141
|
def LoginPage -> any {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
has username: str = "";
|
|
143
|
+
has password: str = "";
|
|
144
|
+
has error: str = "";
|
|
145
145
|
navigate = useNavigate();
|
|
146
146
|
|
|
147
147
|
async def handleLogin(e: any) -> None {
|
|
148
148
|
e.preventDefault();
|
|
149
|
-
|
|
149
|
+
error = "";
|
|
150
150
|
if not username or not password {
|
|
151
|
-
|
|
151
|
+
error = "Please fill in all fields";
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
154
|
success = await jacLogin(username, password);
|
|
155
155
|
if success {
|
|
156
156
|
navigate("/todos");
|
|
157
157
|
} else {
|
|
158
|
-
|
|
158
|
+
error = "Invalid credentials";
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
def handleUsernameChange(e: any) -> None {
|
|
163
|
-
|
|
163
|
+
username = e.target.value;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
def handlePasswordChange(e: any) -> None {
|
|
167
|
-
|
|
167
|
+
password = e.target.value;
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
errorDisplay = None;
|
|
@@ -265,32 +265,32 @@ cl {
|
|
|
265
265
|
|
|
266
266
|
# Signup Page
|
|
267
267
|
def SignupPage -> any {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
268
|
+
has username: str = "";
|
|
269
|
+
has password: str = "";
|
|
270
|
+
has error: str = "";
|
|
271
271
|
navigate = useNavigate();
|
|
272
272
|
|
|
273
273
|
async def handleSignup(e: any) -> None {
|
|
274
274
|
e.preventDefault();
|
|
275
|
-
|
|
275
|
+
error = "";
|
|
276
276
|
if not username or not password {
|
|
277
|
-
|
|
277
|
+
error = "Please fill in all fields";
|
|
278
278
|
return;
|
|
279
279
|
}
|
|
280
280
|
result = await jacSignup(username, password);
|
|
281
281
|
if result["success"] {
|
|
282
282
|
navigate("/todos");
|
|
283
283
|
} else {
|
|
284
|
-
|
|
284
|
+
error = result["error"] if result["error"] else "Signup failed";
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
def handleUsernameChange(e: any) -> None {
|
|
289
|
-
|
|
289
|
+
username = e.target.value;
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
def handlePasswordChange(e: any) -> None {
|
|
293
|
-
|
|
293
|
+
password = e.target.value;
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
errorDisplay = None;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
|
|
2
2
|
# Pages
|
|
3
|
-
cl import from react {
|
|
3
|
+
cl import from react { useEffect }
|
|
4
4
|
cl import from ".components/Button.tsx" { Button }
|
|
5
5
|
|
|
6
6
|
cl {
|
|
7
7
|
def:pub app -> any {
|
|
8
|
-
|
|
8
|
+
has count: int = 0;
|
|
9
9
|
useEffect(lambda -> None{ console.log("Count: ", count);} , [count]);
|
|
10
10
|
return <div
|
|
11
11
|
style={{padding: "2rem", fontFamily: "Arial, sans-serif"}}
|
|
@@ -21,12 +21,12 @@ cl {
|
|
|
21
21
|
>
|
|
22
22
|
<Button
|
|
23
23
|
label="Increment"
|
|
24
|
-
onClick={lambda -> None{
|
|
24
|
+
onClick={lambda -> None{ count = count + 1;} }
|
|
25
25
|
variant="primary"
|
|
26
26
|
/>
|
|
27
27
|
<Button
|
|
28
28
|
label="Reset"
|
|
29
|
-
onClick={lambda -> None{
|
|
29
|
+
onClick={lambda -> None{ count = 0;} }
|
|
30
30
|
variant="secondary"
|
|
31
31
|
/>
|
|
32
32
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# React Router HashRouter Example
|
|
2
|
-
cl import from react {
|
|
2
|
+
cl import from react { useEffect }
|
|
3
3
|
cl import from "@jac-client/utils" {
|
|
4
4
|
Router,
|
|
5
5
|
Routes,
|
|
@@ -122,15 +122,15 @@ cl {
|
|
|
122
122
|
|
|
123
123
|
# Contact Page Component
|
|
124
124
|
def Contact -> any {
|
|
125
|
-
|
|
125
|
+
has submitted: bool = False;
|
|
126
126
|
|
|
127
127
|
def handleSubmit(e: any) -> None {
|
|
128
128
|
e.preventDefault();
|
|
129
|
-
|
|
129
|
+
submitted = True;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
def resetForm(e: any) -> None {
|
|
133
|
-
|
|
133
|
+
submitted = False;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
if submitted {
|