Skip to content

Commit 8a7fc93

Browse files
Merge pull request #110 from UNLV-CS472-672/frontend_backend_link
Jose 4th PR: Login/Signup Frontend/backend link
2 parents edd1659 + 8b59ecd commit 8a7fc93

40 files changed

+1833
-1303
lines changed

backend/apps/users/views.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from django.contrib.auth import authenticate
55
from django.http import JsonResponse, HttpResponse
66
from django.middleware.csrf import get_token
7+
from .models import Profile
78
from apps.users.models import Profile, TutorProfile
89
from apps.uploads.models import UploadRecord, ProfilePicture
910
from rest_framework import status
@@ -62,7 +63,9 @@ def register_profile(request):
6263
first_name = request.data["firstName"]
6364
last_name = request.data["lastName"]
6465
password = request.data["password"]
65-
role = request.data["role"] # Get the selected role
66+
# TODO: replace "1" with "role" once that is handled by the frontend
67+
# role = request.data["role"] # Get the selected role
68+
role = 3
6669
# Create user
6770
user = User.objects.create_user(
6871
username=username,
@@ -73,6 +76,7 @@ def register_profile(request):
7376
)
7477
# Create associated Profile
7578
profile = Profile.objects.create(user, role)
79+
7680

7781
image=request.data.get("image") #For now, get an optional image
7882

@@ -92,7 +96,6 @@ def register_profile(request):
9296
bio=request.data["bio"]
9397
hourly_rate=request.data["hourly_rate"]
9498
tutor = TutorProfile.objects.create(profile, city, state, bio, hourly_rate)
95-
9699
return Response({"message": "User registered successfully"}, status=status.HTTP_201_CREATED)
97100

98101
@api_view(['POST'])

frontend/package-lock.json

Lines changed: 330 additions & 147 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
},
1212
"dependencies": {
1313
"@tailwindcss/vite": "^4.0.5",
14+
"axios": "^1.8.4",
15+
"bootstrap": "^5.3.3",
16+
"bootstrap-icons": "^1.11.3",
1417
"react": "^19.0.0",
1518
"react-calendar": "^5.1.0",
1619
"react-dom": "^19.0.0",
20+
"react-router-dom": "^7.4.0",
1721
"tailwindcss": "^4.0.5"
1822
},
1923
"devDependencies": {

frontend/src/Components/Login.jsx

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,52 @@
11
import "../Styles/Login.css";
2+
// import {useLocation} from "react-router-dom";
3+
import {useState} from "react";
4+
import axios from "axios";
25

3-
export default function Login() {
4-
const handleSubmit = (e) => {
6+
// export default function Login() {
7+
// const handleSubmit = (e) => {
8+
// e.preventDefault();
9+
// // Add your login logic here
10+
// console.log("Login form submitted");
11+
// };
12+
13+
export default function SignUp() {
14+
// const location = useLocation();
15+
// this will help later for the back end
16+
17+
const [formData, setFormData] = useState({
18+
username: "",
19+
password: "",
20+
});
21+
22+
const handleChanges = (e) => {
23+
const { name, value, type, checked } = e.target;
24+
setFormData({
25+
...formData,
26+
[name]: type === "checkbox" ? checked : value,
27+
});
28+
};
29+
30+
const handleLogin = async (e) => {
531
e.preventDefault();
6-
// Add your login logic here
7-
console.log("Login form submitted");
32+
33+
console.log("Login form submitted", formData);
34+
35+
try {
36+
const response = await axios.post("http://127.0.0.1:8000/users/login/", formData);
37+
38+
39+
// Do this for login
40+
// Store only the access and refresh tokens
41+
localStorage.setItem("accessToken", response.data.accessToken);
42+
localStorage.setItem("refreshToken", response.data.refreshToken);
43+
localStorage.setItem("username", response.data.username);
44+
45+
alert("Login successful!");
46+
47+
} catch (error) {
48+
alert("Login failed! " + (error.response?.data?.message || error.message));
49+
}
850
};
951

1052
return (
@@ -33,13 +75,14 @@ export default function Login() {
3375
<h1>LessonConnect</h1>
3476
<h2>Welcome to LessonConnect</h2>
3577

36-
<form className="login-form" onSubmit={handleSubmit}>
37-
<label htmlFor="email">Username or Email</label>
78+
<form className="login-form" onSubmit={handleLogin}>
79+
<label htmlFor="username">Username</label>
3880
<input
3981
type="text"
40-
id="email"
41-
name="email"
42-
placeholder="e.g., David Brooks"
82+
id="username"
83+
name="username"
84+
onChange={handleChanges}
85+
placeholder="Username"
4386
required
4487
/>
4588

@@ -48,6 +91,7 @@ export default function Login() {
4891
type="password"
4992
id="password"
5093
name="password"
94+
onChange={handleChanges}
5195
placeholder="********"
5296
required
5397
/>

frontend/src/Components/SignUp.jsx

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
// import { useLocation } from "react-router-dom";
1+
import { useLocation } from "react-router-dom";
22
import { useState } from "react";
33
import "../Styles/SignUp.css"; // Import the CSS file
4+
import axios from "axios";
45

56
export default function SignUp() {
6-
// const location = useLocation(); // Uncomment if you are going use it (Ashley helped by Frank)
7+
const location = useLocation(); // Uncomment if you are going use it (Ashley helped by Frank)
78
// this will help later for the back end
8-
// const dob = location.state || {};
9+
const dob = location.state || {};
910

1011
const [formData, setFormData] = useState({
1112
country: "",
@@ -14,6 +15,7 @@ export default function SignUp() {
1415
lastName: "",
1516
displayName: "",
1617
password: "",
18+
dateOfBirth: dob,
1719
termsAccepted: false,
1820
});
1921

@@ -25,16 +27,32 @@ export default function SignUp() {
2527
});
2628
};
2729

28-
const handleSubmit = (e) => {
30+
const handleSubmit = async (e) => {
2931
e.preventDefault();
32+
3033
if (!formData.termsAccepted) {
3134
alert("You must accept the Terms of Service.");
3235
return;
3336
}
3437
console.log("Sign-Up form submitted", formData);
35-
// here is where we add any sign-up logic or API calls
38+
39+
try {
40+
const response = await axios.post("http://127.0.0.1:8000/users/register/", formData);
41+
42+
43+
// Do this for login
44+
// Store only the access and refresh tokens
45+
// localStorage.setItem("accessToken", response.data.accessToken);
46+
// localStorage.setItem("refreshToken", response.data.refreshToken);
47+
48+
49+
alert("Registration successful!\n" + response.data.message);
50+
} catch (error) {
51+
alert("Registration failed! " + (error.response?.data?.message || error.message));
52+
}
3653
};
3754

55+
3856
return (
3957
<div className="signup-page">
4058
{/* Left Panel */}

node_modules/.vite/deps/_metadata.json

Lines changed: 0 additions & 8 deletions
This file was deleted.

node_modules/.vite/deps/package.json

Lines changed: 0 additions & 3 deletions
This file was deleted.

node_modules/@esbuild/win32-x64/README.md

Lines changed: 0 additions & 3 deletions
This file was deleted.
4 KB
Binary file not shown.

node_modules/@esbuild/win32-x64/package.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)