Skip to content

Commit f1504f1

Browse files
committed
Merge branch 'master' of https://github.com/Ben-Sicat/Study_hub into Ben
2 parents 2e7049d + 951ba4b commit f1504f1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+12384
-252
lines changed

backend/app/app.py

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,14 @@ def get_all_users():
128128
except mysql.connector.Error as err:
129129
print(f"Error: {err}")
130130

131+
131132
def get_user_by_id(user_id):
132133
connection = get_db_connection(db_config)
133134
if connection:
134135
try:
135136
cursor = connection.cursor(dictionary=True)
136137
query = """
137-
SELECT UserID, GoogleID, Username, Email, FirstName, LastName, PhoneNumber, UName, Birthday, Gender, Occupation
138+
SELECT UserID, GoogleID, Username, Email, FirstName, LastName, PhoneNumber, UName, Birthday, Gender, Occupation, Level
138139
FROM Users
139140
WHERE UserID = %s
140141
"""
@@ -145,6 +146,9 @@ def get_user_by_id(user_id):
145146
return result
146147
except mysql.connector.Error as err:
147148
print(f"Error fetching user by ID: {err}")
149+
return None
150+
151+
148152

149153
def get_user_by_email_or_username(email_or_username):
150154
connection = get_db_connection(db_config)
@@ -226,32 +230,37 @@ def perform_warehouse_process():
226230
# Initialize the BackgroundScheduler
227231
scheduler = BackgroundScheduler()
228232

229-
# Add the scheduled job to run the ETL process every 1 week
230-
scheduler.add_job(perform_warehouse_process, 'interval', weeks=1)
233+
# Add the scheduled job to run the ETL process every 168 hours or 1 week
234+
scheduler.add_job(perform_warehouse_process, 'interval', hours=168)
231235

232-
@app.route('/api/get-warehouse-data', methods=['GET'])
233-
def get_warehouse_data():
234-
try:
235-
warehouse_connection = get_db_connection(warehouse_db_config)
236-
if not warehouse_connection:
237-
return jsonify(error='Unable to connect to the warehouse database'), 500
238-
239-
with warehouse_connection.cursor(dictionary=True) as warehouse_cursor:
240-
warehouse_cursor.execute("SELECT * FROM UserSummary")
241-
warehouse_data = warehouse_cursor.fetchall()
242-
243-
return jsonify({'message': 'Warehouse data fetched successfully', 'warehouse_data': warehouse_data})
236+
def create_reservation(user_id, reservation_data):
237+
connection = get_db_connection(db_config)
238+
if connection:
239+
try:
240+
cursor = connection.cursor()
241+
query = """
242+
INSERT INTO Reservations (UserID, StartTime, EndTime, Seat)
243+
VALUES (%s, %s, %s, %s)
244+
"""
245+
values = (user_id, reservation_data['starttime'], reservation_data['endtime'], reservation_data.get('seat'))
246+
cursor.execute(query, values)
247+
connection.commit()
248+
cursor.close()
249+
connection.close()
250+
except mysql.connector.Error as err:
251+
print(f"Error creating reservation: {err}")
244252

253+
@app.route('/api/create-reservation', methods=['POST'])
254+
def create_reservation_route():
255+
try:
256+
data = request.get_json()
257+
user_id = data.get('user_id') # Change this to fetch the user_id from your authentication mechanism
258+
create_reservation(user_id, data)
259+
return jsonify({'message': 'Reservation created successfully'}), 200
245260
except Exception as e:
246-
print(f"Error fetching warehouse data: {e}")
247-
return jsonify(error='Error fetching warehouse data'), 500
248-
249-
finally:
250-
if warehouse_connection:
251-
warehouse_connection.close()
252-
print("Warehouse connection closed.")
261+
print(f"Error creating reservation: {e}")
262+
return jsonify(message='Error creating reservation'), 500
253263

254-
255264
@app.route('/api/create-account', methods=['POST'])
256265
def create_account():
257266
try:
@@ -290,6 +299,18 @@ def get_reservations():
290299
print(f"Error fetching reservations: {e}")
291300
return jsonify(error='Error fetching reservations'), 500
292301

302+
@app.route('/api/get-all-users', methods=['GET'])
303+
def get_all_users_route():
304+
try:
305+
all_users = get_all_users()
306+
if all_users:
307+
return jsonify({'accounts': all_users})
308+
else:
309+
return jsonify(error='No users found'), 404 # Change to 404 status code
310+
except Exception as e:
311+
print(f"Error in route: {e}")
312+
return jsonify(error='Internal server error'), 500
313+
293314
@app.route('/api/sign-in', methods=['POST'])
294315
def sign_in():
295316
data = request.get_json()
@@ -315,7 +336,7 @@ def sign_in():
315336
'PhoneNumber': user_data['PhoneNumber'],
316337
'Gender': user_data['Gender'],
317338
'Occupation': user_data['Occupation'],
318-
339+
'Level': user_data['Level'],
319340
# Add other user data fields as needed
320341
}
321342
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
"use client";
2+
3+
import React, { useState, useEffect } from "react";
4+
import Teste from "@/app/components/account";
5+
import CloseIcon from "@mui/icons-material/Close";
6+
import Image from "@/app/components/account_image";
7+
import CircleIcon from "@mui/icons-material/Circle";
8+
import TextInput from "@/app/components/text_input";
9+
import Drop from "@/app/components/dropdown_button";
10+
import Butt from "@/app/components/button";
11+
12+
import { useRouter } from "next/navigation";
13+
function Page() {
14+
const router = useRouter();
15+
16+
const handleBackButtonClick = () => {
17+
router.back();
18+
};
19+
20+
useEffect(() => {
21+
document.title = "Edit Profile";
22+
}, []);
23+
24+
const options = ["Male", "Female", "Others"];
25+
const options1 = ["Student", "Worker"];
26+
27+
// Fetch user data from local storage
28+
const storedUserData = localStorage.getItem("user");
29+
const initialFormData = storedUserData ? JSON.parse(storedUserData) : null;
30+
31+
const [formData, setFormData] = useState<{
32+
userName: string;
33+
email: string;
34+
phoneNumber: string;
35+
gender: string;
36+
occupation: string;
37+
}>({
38+
userName: initialFormData ? initialFormData.Username : "",
39+
email: initialFormData ? initialFormData.Email : "",
40+
phoneNumber: initialFormData ? initialFormData.PhoneNumber : "",
41+
gender: initialFormData ? initialFormData.Gender : options[0],
42+
occupation: initialFormData ? initialFormData.Occupation : options1[0],
43+
});
44+
const userId = initialFormData ? initialFormData.UserID : null; // Adjust this line based on your actual property name
45+
console.log(userId);
46+
const handleInputChange = (field: string, value: string) => {
47+
setFormData({
48+
...formData,
49+
[field]: value,
50+
});
51+
};
52+
console.log(formData);
53+
const handleUpdateProfile = async () => {
54+
try {
55+
const response = await fetch(
56+
`http://localhost:5000/api/update-account/${userId}`,
57+
{
58+
method: "POST",
59+
headers: {
60+
"Content-Type": "application/json",
61+
},
62+
body: JSON.stringify(formData),
63+
}
64+
);
65+
66+
if (response.ok) {
67+
const updatedUserData = await response.json();
68+
localStorage.setItem("user", JSON.stringify(updatedUserData));
69+
console.log("Profile updated successfully:", updatedUserData);
70+
// Optionally, you can update the local state or perform other actions
71+
} else {
72+
console.error("Error updating profile:", await response.json());
73+
}
74+
} catch (error) {
75+
console.error("Error updating profile:", error);
76+
}
77+
};
78+
79+
return (
80+
<div className="flex min-h-full flex-col bg-backcolor">
81+
<div className="flex items-center space-x-1">
82+
<Teste
83+
backButtonIcon={<CloseIcon style={{ fontSize: 24 }} />}
84+
onBackButtonClick={handleBackButtonClick}
85+
title=""
86+
subTitle1=""
87+
/>
88+
<p className="text-xl text-textcolor font-extrabold">Edit Profile</p>
89+
</div>
90+
91+
<div className="flex justify-center mt-5">
92+
<Image
93+
ImageIcon={<CircleIcon style={{ fontSize: 141, color: "#C7C7C7" }} />}
94+
></Image>
95+
</div>
96+
97+
<div>
98+
<Butt
99+
title="Edit"
100+
Bgcolor="#E5E4E2"
101+
width="100px"
102+
height="28px"
103+
borderRadius="50px"
104+
/>
105+
</div>
106+
107+
<div className="mt-6">
108+
<TextInput
109+
placeholder="Username"
110+
width="335px"
111+
height="35px"
112+
value={formData.userName}
113+
onInputChange={(value) => handleInputChange("userName", value)}
114+
/>
115+
<TextInput
116+
placeholder="Email"
117+
width="335px"
118+
height="35px"
119+
value={formData.email}
120+
onInputChange={(value) => handleInputChange("email", value)}
121+
/>
122+
<TextInput
123+
placeholder="Phone Number"
124+
width="335px"
125+
height="35px"
126+
value={formData.phoneNumber}
127+
onInputChange={(value) => handleInputChange("phoneNumber", value)}
128+
/>
129+
130+
<div className="flex text-redwood text-xs ml-12 space-x-32 mt-2">
131+
<p>Gender</p>
132+
<p>Occupation</p>
133+
</div>
134+
135+
<div className="flex justify-center space-x-3">
136+
<Drop
137+
options={options}
138+
width="161px"
139+
onSelect={(value) => handleInputChange("gender", value)}
140+
/>
141+
<Drop
142+
options={options1}
143+
width="161px"
144+
onSelect={(value) => handleInputChange("occupation", value)}
145+
/>
146+
</div>
147+
{/* <TextInput
148+
placeholder="School/Company"
149+
width="335px"
150+
height="35px"
151+
onInputChange={(value) => handleInputChange("school", value)}
152+
/> */}
153+
</div>
154+
155+
<div className="mt-16"></div>
156+
157+
<Butt
158+
title="Update Profile"
159+
Bgcolor="#FFF1E4"
160+
width="325px"
161+
height="34px"
162+
onClick={handleUpdateProfile}
163+
/>
164+
</div>
165+
);
166+
}
167+
168+
export default Page;

frontend/app/admin_accounts/page.tsx

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,55 @@ import DateComponent from "../components/date";
66
import TimeComponent from "../components/time";
77
import SearchBar from "../components/search_bar";
88
import InfoTable from "../components/info_table";
9+
import { useRouter } from "next/navigation";
910

10-
type UserInfo = {
11-
id: number;
12-
name: string;
13-
// Add more properties as needed
14-
};
11+
interface Accounts {
12+
UserID: number;
13+
Username: string;
14+
}
1515

1616
function Page() {
17+
const router = useRouter();
1718
useEffect(() => {
1819
// Set the title directly for the browser tab
1920
document.title = "Admin Modify Accounts";
2021
}, []);
2122

22-
const userData = [
23-
{ id: 1, name: "John Doe" },
24-
{ id: 2, name: "Jane Smith" },
25-
{ id: 101, name: "Gian Limbaga" },
26-
{ id: 102, name: "The Fourth" },
27-
{ id: 103, name: "Melaissa Rioveros" },
28-
{ id: 104, name: "Chen Leonor" },
29-
{ id: 105, name: "Eric Ramos" },
30-
// Add more user data as needed
31-
];
23+
const [accounts, setAccounts] = useState<Accounts[]>([]);
24+
const [filteredData, setFilteredData] = useState<Accounts[]>(accounts);
25+
26+
useEffect(() => {
27+
fetch("http://localhost:5000/api/get-all-users")
28+
.then((response) => response.json())
29+
.then((data: { accounts: Accounts[] }) => {
30+
const simplifiedData = data.accounts.map(({ UserID, Username }) => ({
31+
UserID,
32+
Username,
33+
}));
34+
setAccounts(simplifiedData);
35+
})
36+
.catch((error) => {
37+
console.error("Error fetching data:", error);
38+
});
39+
}, []);
40+
41+
useEffect(() => {
42+
setFilteredData(accounts);
43+
}, [accounts]);
3244

33-
const [data, setData] = useState<UserInfo[]>(userData);
34-
const [filteredData, setFilteredData] = useState<UserInfo[]>(data);
45+
// console.log(accounts);
3546

3647
const handleDataSearch = (searchQuery: string) => {
3748
// Implement your filtering logic here
38-
const filteredResults = data.filter(
49+
const filteredResults = accounts.filter(
3950
(item) =>
40-
item.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
41-
String(item.id).includes(searchQuery) // Convert id to string and check for inclusion
51+
item.Username.toLowerCase().includes(searchQuery.toLowerCase()) ||
52+
String(item.UserID).includes(searchQuery)
4253
);
4354

4455
setFilteredData(filteredResults);
4556
};
57+
console.log(filteredData);
4658

4759
return (
4860
<div className="flex min-h-full flex-col bg-backcolor">
@@ -78,9 +90,8 @@ function Page() {
7890
<Link href="/admin_sales">
7991
<p>Sales Ledger</p>
8092
</Link>
81-
<Link href="/admin_accounts">
82-
<p className="text-amber-500">Edit Accounts</p>
83-
</Link>
93+
94+
<p className="text-amber-500">Edit Account</p>
8495
</div>
8596

8697
<div className="container flex items-center justify-center space-x-8 text-xs text-black font-bold mb-2">

0 commit comments

Comments
 (0)