Testys commited on
Commit
8f6e099
·
verified ·
1 Parent(s): 857b086

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +318 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,320 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import requests
3
+ import json
4
 
5
+ # Backend URL
6
+ BASE_URL = "https://testys-clearance-sys.hf.space"
7
+
8
+ # Session state for auth
9
+ if 'token' not in st.session_state:
10
+ st.session_state.token = None
11
+ if 'user' not in st.session_state:
12
+ st.session_state.user = None
13
+
14
+ def login(username, password):
15
+ response = requests.post(f"{BASE_URL}/token", data={"username": username, "password": password})
16
+ if response.status_code == 200:
17
+ data = response.json()
18
+ st.session_state.token = data['access_token']
19
+ st.session_state.user = username
20
+ st.success("Logged in successfully!")
21
+ else:
22
+ st.error("Login failed!")
23
+
24
+ def logout():
25
+ st.session_state.token = None
26
+ st.session_state.user = None
27
+ st.success("Logged out!")
28
+
29
+ def api_call(method, endpoint, data=None, headers=None):
30
+ url = f"{BASE_URL}{endpoint}"
31
+ if headers is None:
32
+ headers = {}
33
+ if st.session_state.token:
34
+ headers['Authorization'] = f"Bearer {st.session_state.token}"
35
+ if method == 'GET':
36
+ response = requests.get(url, headers=headers)
37
+ elif method == 'POST':
38
+ response = requests.post(url, json=data, headers=headers)
39
+ elif method == 'PUT':
40
+ response = requests.put(url, json=data, headers=headers)
41
+ elif method == 'DELETE':
42
+ response = requests.delete(url, headers=headers)
43
+ return response
44
+
45
+ st.title("Clearance System Frontend")
46
+
47
+ if st.session_state.token is None:
48
+ st.header("Login")
49
+ username = st.text_input("Username")
50
+ password = st.text_input("Password", type="password")
51
+ if st.button("Login"):
52
+ login(username, password)
53
+ else:
54
+ st.write(f"Logged in as: {st.session_state.user}")
55
+ if st.button("Logout"):
56
+ logout()
57
+
58
+ # Navigation
59
+ page = st.sidebar.selectbox("Select Page", [
60
+ "Students", "Users", "Tags", "Devices", "Clearance", "RFID", "Scanners", "Profile"
61
+ ])
62
+
63
+ if page == "Students":
64
+ st.header("Student Management")
65
+ action = st.selectbox("Action", ["List", "Create", "Lookup", "Read Single", "Update", "Delete"])
66
+ if action == "List":
67
+ skip = st.number_input("Skip", min_value=0, value=0)
68
+ limit = st.number_input("Limit", min_value=1, value=100)
69
+ if st.button("Get Students"):
70
+ response = api_call('GET', f'/admin/students/?skip={skip}&limit={limit}')
71
+ if response.status_code == 200:
72
+ students = response.json()
73
+ st.json(students)
74
+ else:
75
+ st.error("Failed to fetch students")
76
+ elif action == "Create":
77
+ full_name = st.text_input("Full Name")
78
+ matric_no = st.text_input("Matric No")
79
+ email = st.text_input("Email")
80
+ department = st.selectbox("Department", ["Computer Science", "Engineering", "Business Administration", "Law", "Medicine"])
81
+ password = st.text_input("Password", type="password")
82
+ if st.button("Create Student"):
83
+ data = {"full_name": full_name, "matric_no": matric_no, "email": email, "department": department, "password": password}
84
+ response = api_call('POST', '/admin/students/', data)
85
+ if response.status_code == 201:
86
+ st.success("Student created!")
87
+ st.json(response.json())
88
+ else:
89
+ st.error("Failed to create student")
90
+ elif action == "Lookup":
91
+ lookup_type = st.selectbox("Lookup by", ["Matric No", "Tag ID"])
92
+ if lookup_type == "Matric No":
93
+ matric_no = st.text_input("Matric No")
94
+ if st.button("Lookup"):
95
+ response = api_call('GET', f'/admin/students/lookup?matric_no={matric_no}')
96
+ if response.status_code == 200:
97
+ st.json(response.json())
98
+ else:
99
+ st.error("Student not found")
100
+ else:
101
+ tag_id = st.text_input("Tag ID")
102
+ if st.button("Lookup"):
103
+ response = api_call('GET', f'/admin/students/lookup?tag_id={tag_id}')
104
+ if response.status_code == 200:
105
+ st.json(response.json())
106
+ else:
107
+ st.error("Student not found")
108
+ elif action == "Read Single":
109
+ student_id = st.number_input("Student ID", min_value=1)
110
+ if st.button("Read"):
111
+ response = api_call('GET', f'/admin/students/{student_id}')
112
+ if response.status_code == 200:
113
+ st.json(response.json())
114
+ else:
115
+ st.error("Student not found")
116
+ elif action == "Update":
117
+ student_id = st.number_input("Student ID", min_value=1)
118
+ full_name = st.text_input("Full Name")
119
+ department = st.selectbox("Department", ["Computer Science", "Engineering", "Business Administration", "Law", "Medicine"])
120
+ email = st.text_input("Email")
121
+ if st.button("Update"):
122
+ data = {"full_name": full_name, "department": department, "email": email}
123
+ response = api_call('PUT', f'/admin/students/{student_id}', data)
124
+ if response.status_code == 200:
125
+ st.success("Student updated!")
126
+ st.json(response.json())
127
+ else:
128
+ st.error("Failed to update student")
129
+ elif action == "Delete":
130
+ student_id = st.number_input("Student ID", min_value=1)
131
+ if st.button("Delete"):
132
+ response = api_call('DELETE', f'/admin/students/{student_id}')
133
+ if response.status_code == 200:
134
+ st.success("Student deleted!")
135
+ st.json(response.json())
136
+ else:
137
+ st.error("Failed to delete student")
138
+
139
+ elif page == "Users":
140
+ st.header("User Management")
141
+ action = st.selectbox("Action", ["Create", "List", "Lookup", "Update", "Delete"])
142
+ if action == "Create":
143
+ username = st.text_input("Username")
144
+ password = st.text_input("Password", type="password")
145
+ email = st.text_input("Email")
146
+ full_name = st.text_input("Full Name")
147
+ role = st.selectbox("Role", ["admin", "staff"])
148
+ department = st.selectbox("Department", ["Computer Science", "Engineering", "Business Administration", "Law", "Medicine"])
149
+ if st.button("Create User"):
150
+ data = {"username": username, "password": password, "email": email, "full_name": full_name, "role": role, "department": department}
151
+ response = api_call('POST', '/admin/users/', data)
152
+ if response.status_code == 201:
153
+ st.success("User created!")
154
+ st.json(response.json())
155
+ else:
156
+ st.error("Failed to create user")
157
+ elif action == "List":
158
+ if st.button("Get Users"):
159
+ response = api_call('GET', '/admin/users/')
160
+ if response.status_code == 200:
161
+ users = response.json()
162
+ st.json(users)
163
+ else:
164
+ st.error("Failed to fetch users")
165
+ elif action == "Lookup":
166
+ lookup_type = st.selectbox("Lookup by", ["Username", "Tag ID"])
167
+ if lookup_type == "Username":
168
+ username = st.text_input("Username")
169
+ if st.button("Lookup"):
170
+ response = api_call('GET', f'/admin/users/lookup?username={username}')
171
+ if response.status_code == 200:
172
+ st.json(response.json())
173
+ else:
174
+ st.error("User not found")
175
+ else:
176
+ tag_id = st.text_input("Tag ID")
177
+ if st.button("Lookup"):
178
+ response = api_call('GET', f'/admin/users/lookup?tag_id={tag_id}')
179
+ if response.status_code == 200:
180
+ st.json(response.json())
181
+ else:
182
+ st.error("User not found")
183
+ elif action == "Update":
184
+ user_id = st.number_input("User ID", min_value=1)
185
+ username = st.text_input("Username")
186
+ email = st.text_input("Email")
187
+ full_name = st.text_input("Full Name")
188
+ role = st.selectbox("Role", ["admin", "staff"])
189
+ department = st.selectbox("Department", ["Computer Science", "Engineering", "Business Administration", "Law", "Medicine"])
190
+ password = st.text_input("Password", type="password")
191
+ if st.button("Update"):
192
+ data = {"username": username, "email": email, "full_name": full_name, "role": role, "department": department, "password": password}
193
+ response = api_call('PUT', f'/admin/users/{user_id}', data)
194
+ if response.status_code == 200:
195
+ st.success("User updated!")
196
+ st.json(response.json())
197
+ else:
198
+ st.error("Failed to update user")
199
+ elif action == "Delete":
200
+ user_id = st.number_input("User ID", min_value=1)
201
+ if st.button("Delete"):
202
+ response = api_call('DELETE', f'/admin/users/{user_id}')
203
+ if response.status_code == 200:
204
+ st.success("User deleted!")
205
+ st.json(response.json())
206
+ else:
207
+ st.error("Failed to delete user")
208
+
209
+ elif page == "Tags":
210
+ st.header("Tag Management")
211
+ action = st.selectbox("Action", ["Link", "Unlink"])
212
+ if action == "Link":
213
+ tag_id = st.text_input("Tag ID")
214
+ matric_no = st.text_input("Matric No")
215
+ username = st.text_input("Username")
216
+ if st.button("Link Tag"):
217
+ data = {"tag_id": tag_id, "matric_no": matric_no, "username": username}
218
+ response = api_call('POST', '/admin/tags/link', data)
219
+ if response.status_code == 200:
220
+ st.success("Tag linked!")
221
+ st.json(response.json())
222
+ else:
223
+ st.error("Failed to link tag")
224
+ elif action == "Unlink":
225
+ tag_id = st.text_input("Tag ID")
226
+ if st.button("Unlink Tag"):
227
+ response = api_call('DELETE', f'/admin/tags/{tag_id}/unlink')
228
+ if response.status_code == 200:
229
+ st.success("Tag unlinked!")
230
+ st.json(response.json())
231
+ else:
232
+ st.error("Failed to unlink tag")
233
+
234
+ elif page == "Devices":
235
+ st.header("Device Management")
236
+ action = st.selectbox("Action", ["Create", "List", "Delete"])
237
+ if action == "Create":
238
+ device_name = st.text_input("Device Name")
239
+ location = st.text_input("Location")
240
+ department = st.selectbox("Department", ["Computer Science", "Engineering", "Business Administration", "Law", "Medicine"])
241
+ if st.button("Create Device"):
242
+ data = {"device_name": device_name, "location": location, "department": department}
243
+ response = api_call('POST', '/admin/devices/', data)
244
+ if response.status_code == 201:
245
+ st.success("Device created!")
246
+ st.json(response.json())
247
+ else:
248
+ st.error("Failed to create device")
249
+ elif action == "List":
250
+ if st.button("Get Devices"):
251
+ response = api_call('GET', '/admin/devices/')
252
+ if response.status_code == 200:
253
+ devices = response.json()
254
+ st.json(devices)
255
+ else:
256
+ st.error("Failed to fetch devices")
257
+ elif action == "Delete":
258
+ device_id = st.number_input("Device ID", min_value=1)
259
+ if st.button("Delete"):
260
+ response = api_call('DELETE', f'/admin/devices/{device_id}')
261
+ if response.status_code == 200:
262
+ st.success("Device deleted!")
263
+ st.json(response.json())
264
+ else:
265
+ st.error("Failed to delete device")
266
+
267
+ elif page == "Clearance":
268
+ st.header("Clearance Management")
269
+ matric_no = st.text_input("Matric No")
270
+ department = st.selectbox("Department", ["Library", "Student Affairs", "Bursary", "Academic Affairs", "Health Center"])
271
+ status = st.selectbox("Status", ["pending", "approved", "rejected"])
272
+ remarks = st.text_area("Remarks")
273
+ if st.button("Update Clearance"):
274
+ data = {"matric_no": matric_no, "department": department, "status": status, "remarks": remarks}
275
+ response = api_call('PUT', '/clearance/update', data)
276
+ if response.status_code == 200:
277
+ st.success("Clearance updated!")
278
+ st.json(response.json())
279
+ else:
280
+ st.error("Failed to update clearance")
281
+
282
+ elif page == "RFID":
283
+ st.header("RFID Check Status")
284
+ tag_id = st.text_input("Tag ID")
285
+ if st.button("Check Status"):
286
+ data = {"tag_id": tag_id}
287
+ response = api_call('POST', '/rfid/check-status', data)
288
+ if response.status_code == 200:
289
+ st.json(response.json())
290
+ else:
291
+ st.error("Failed to check status")
292
+
293
+ elif page == "Scanners":
294
+ st.header("Scanner Management")
295
+ action = st.selectbox("Action", ["Activate", "Retrieve"])
296
+ if action == "Activate":
297
+ api_key = st.text_input("Device API Key")
298
+ if st.button("Activate Scanner"):
299
+ data = {"api_key": api_key}
300
+ response = api_call('POST', '/rfid/scanners/activate', data)
301
+ if response.status_code == 204:
302
+ st.success("Scanner activated!")
303
+ else:
304
+ st.error("Failed to activate")
305
+ elif action == "Retrieve":
306
+ if st.button("Retrieve Tag"):
307
+ response = api_call('GET', '/rfid/scanners/retrieve')
308
+ if response.status_code == 200:
309
+ st.json(response.json())
310
+ else:
311
+ st.error("No tag scanned yet")
312
+
313
+ elif page == "Profile":
314
+ st.header("My Profile")
315
+ if st.button("Get My Profile"):
316
+ response = api_call('GET', '/users/me')
317
+ if response.status_code == 200:
318
+ st.json(response.json())
319
+ else:
320
+ st.error("Failed to fetch profile")