Skip to content

Commit 59f6bea

Browse files
authored
Merge pull request #29 from igh9410/dev
Implemented custom sign up including frontend
2 parents 4a9671b + e0d63db commit 59f6bea

File tree

7 files changed

+98
-37
lines changed

7 files changed

+98
-37
lines changed

backend/internal/common/validation.go

-31
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,6 @@ import (
99
"github.com/google/uuid"
1010
)
1111

12-
/*
13-
func EmailValidator(c *gin.Context) (string, error) {
14-
// Extract the email parameter from the request context
15-
email, exists := c.Get("email")
16-
if !exists {
17-
c.JSON(http.StatusBadRequest, gin.H{"error": "Email does not exist in the context"})
18-
return "", nil
19-
}
20-
log.Println("Email: ", email)
21-
return email.(string), nil
22-
}*/
23-
2412
func ChatRoomIDValidator(c *gin.Context) (uuid.UUID, error) {
2513
// Extract the id parameter from the request context
2614
chatRoomIDStr := c.Param("id")
@@ -35,25 +23,6 @@ func ChatRoomIDValidator(c *gin.Context) (uuid.UUID, error) {
3523
return chatRoomID, nil
3624
}
3725

38-
/*
39-
func UserIDValidator(c *gin.Context) (uuid.UUID, error) {
40-
41-
userIDStr, exists := c.Get("user_id")
42-
if !exists {
43-
c.JSON(http.StatusBadRequest, gin.H{"error": "User ID does not exist in the context"})
44-
return uuid.Nil, nil
45-
}
46-
47-
// Validate the UUID format
48-
userID, err := uuid.Parse(userIDStr.(string))
49-
if err != nil {
50-
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid UUID format"})
51-
return uuid.Nil, err
52-
}
53-
log.Println("User ID: ", userID)
54-
return userID, nil
55-
} */
56-
5726
func EmailValidator(email interface{}) (string, error) {
5827
emailStr, ok := email.(string)
5928
if !ok {

backend/internal/user/handler.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,14 @@ func (h *Handler) CreateUser(c *gin.Context) {
4545
return
4646
}
4747

48-
userID, err := common.UserIDValidator(c)
48+
userID, err := common.UserIDValidator(c.MustGet("user_id"))
49+
log.Println("User ID: ", userID)
4950
if err != nil {
5051
log.Printf("Error occured with user ID %v: %v", userID, err.Error())
5152
return
5253
}
5354

54-
userEmail, err := common.EmailValidator(c)
55+
userEmail, err := common.EmailValidator(c.MustGet("email"))
5556
if err != nil {
5657
log.Printf("Error occured with user email %v: %v", userEmail, err.Error())
5758
return

frontend/src/features/user/api/userApi.ts

+31
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { User } from '../types';
44
import { getAccessToken } from '@utils';
55

66
const userCheckURL = '/api/users/check';
7+
const signUpURL = '/api/users/register';
78

89
export async function fetchUserFn(): Promise<User | null> {
910
let accessToken = '';
@@ -38,3 +39,33 @@ export async function fetchUserFn(): Promise<User | null> {
3839
throw error;
3940
}
4041
}
42+
43+
export async function signUpFn({ username }: { username: string }) {
44+
try {
45+
// Retrieve the access token
46+
const accessToken = await getAccessToken();
47+
console.log('Access token:', accessToken);
48+
49+
const userData: { username: string } = {
50+
username,
51+
};
52+
53+
const headers = {
54+
'Content-Type': 'application/json',
55+
Authorization: `Bearer ${accessToken}`, // Include the access token in the Authorization header
56+
};
57+
58+
const response = await axiosInstance.post(
59+
signUpURL,
60+
JSON.stringify(userData),
61+
{ headers }
62+
);
63+
64+
console.log('User created');
65+
66+
return response.data;
67+
} catch (error) {
68+
console.error('Error:', error);
69+
// Handle any errors that occur during the token retrieval or the POST request
70+
}
71+
}

frontend/src/features/user/components/SignUpForm.module.scss

+6
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,9 @@
5353
#signupForm button:hover {
5454
background-color: #4752c4;
5555
}
56+
57+
.error {
58+
color: #dc3545;
59+
font-size: 1rem;
60+
margin-top: 0.25rem; /* 4px */
61+
}

frontend/src/features/user/components/SignUpForm.tsx

+29-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,29 @@
1-
import React, { ChangeEvent, useState } from 'react';
1+
import React, { ChangeEvent, useRef, useState } from 'react';
22
import styles from './SignUpForm.module.scss';
3+
import { Form } from 'react-router-dom';
4+
import { useSignUp } from '@hooks';
35

46
export function SignUpForm() {
7+
const { signUp } = useSignUp();
58
const [imagePreviewUrl, setImagePreviewUrl] = useState('');
9+
const [usernameError, setUsernameError] = useState(''); // State for username error message
10+
const usernameRef = useRef<HTMLInputElement | null>(null);
11+
12+
const handleFormSubmit = (e: React.FormEvent) => {
13+
e.preventDefault();
14+
// You can now use the username state directly
15+
// Accessing the username value
16+
const username = usernameRef.current?.value;
17+
18+
if (!username) {
19+
setUsernameError('Username is required'); // Set error message
20+
return;
21+
}
22+
23+
// Reset error message if username is provided
24+
setUsernameError('');
25+
signUp({ username });
26+
};
627

728
const handleImageChange = (e: ChangeEvent<HTMLInputElement>) => {
829
if (e.target.files && e.target.files[0]) {
@@ -15,11 +36,15 @@ export function SignUpForm() {
1536
};
1637
return (
1738
<div className={styles.signupFormContainer}>
18-
<form id={styles.signupForm}>
39+
<Form method="POST" id={styles.signupForm} onSubmit={handleFormSubmit}>
1940
<h2>Sign Up</h2>
2041
<div className={styles.formGroup}>
2142
<label htmlFor="username">Username (required)</label>
22-
<input type="text" id="username" name="username" />
43+
<input type="text" id="username" name="username" ref={usernameRef} />
44+
{usernameError && (
45+
<div className={styles.error}>{usernameError}</div>
46+
)}{' '}
47+
{/* Display error message */}
2348
</div>
2449
<div className={styles.formGroup}>
2550
<label htmlFor="profileImage">Profile Image (optional)</label>
@@ -42,7 +67,7 @@ export function SignUpForm() {
4267
)}
4368
</div>
4469
<button type="submit">Sign Up</button>
45-
</form>
70+
</Form>
4671
</div>
4772
);
4873
}

frontend/src/hooks/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './useWebSocketConnection';
22
export * from './useChatMessages';
33
export * from './useUsers';
4+
export * from './useSignUp';

frontend/src/hooks/useSignUp.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { signUpFn } from '@features/user';
2+
import { useMutation } from '@tanstack/react-query';
3+
import { useNavigate } from 'react-router-dom';
4+
5+
export const useSignUp = () => {
6+
const navigate = useNavigate();
7+
const {
8+
mutate: signUp,
9+
isLoading,
10+
error,
11+
} = useMutation(signUpFn, {
12+
onSuccess: () => {
13+
// Success actions
14+
navigate('/');
15+
},
16+
onError: (error) => {
17+
// Error actions
18+
console.log('Sign Up Failed');
19+
console.error('Error: ', error);
20+
},
21+
});
22+
23+
return {
24+
signUp,
25+
isLoading,
26+
error,
27+
};
28+
};

0 commit comments

Comments
 (0)