Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some improvements #16

Merged
merged 1 commit into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions src/components/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,6 @@ const Chat: React.FC<ChatProps> = ({ socket }) => {
const ChatHeader: React.FC<ChatHeaderProps> = ({ setShowProfile, selectedUser, handleShowUser, setSelectedUser }) => {
const { setUser } = useContext(UserContext) as UserContextType;
const navigate = useNavigate();
const toggleSidebar = () => {
const sidebar = document.querySelector('.chatSidebar');
if (sidebar) {
sidebar.classList.toggle('sidebar-open');
}
};
// Function to handle leaving the chat (logging out)
const handleLeaveChat = async (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
Expand Down Expand Up @@ -95,9 +89,6 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({ setShowProfile, selectedUser, h
return (
<>
<header className="chatMainHeader">
<button style={{float:"right", marginRight:"10px"}} className="menu-button" onClick={toggleSidebar} aria-label="View Menu">
Menu
</button>
{selectedUser && (<p>{selectedUser?.username} ({selectedUser?.firstName} {selectedUser?.lastName})</p>) }
<button style={{float:"right", marginRight:"10px"}} className="leaveChatButton" onClick={() => {setShowProfile(true); handleShowUser(null); setSelectedUser(null);}} aria-label="View Profile">
Profile
Expand Down
107 changes: 62 additions & 45 deletions src/components/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import '../index.css'
import { useState, useContext } from "react";
import '../index.css';
import { useState, useContext } from 'react';
import React from 'react';
import { UserContext } from "./UserProvider";
import { UserContextType } from "../types";
import { getCookie, togglePassword } from "../utils";
import { UserContext } from './UserProvider';
import { UserContextType } from '../types';
import { getCookie, togglePassword } from '../utils';
import axios, { AxiosResponse } from 'axios';

const Login: React.FC = () => {
// Context to access user data and set user
const { setUser } = useContext(UserContext) as UserContextType;

// State variables for form inputs and error message
const [username, setUsername] = useState<string>("");
const [password, setPassword] = useState<string>("");
const [errorMessage, setErrorMessage] = useState<string>("");
const [username, setUsername] = useState<string>('');
const [password, setPassword] = useState<string>('');
const [errorMessage, setErrorMessage] = useState<string>('');

// Event handler for username input change
const usernameChangeHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -26,38 +26,47 @@ const Login: React.FC = () => {
};

// Event handler for form submission
const submitHandler = async (event: React.MouseEvent<HTMLButtonElement>) => {
const submitHandler = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
setErrorMessage("");
setErrorMessage('');

// Check if username and password are provided
if (username && password) {
const body = {
"username": username,
"password": password,
username: username,
password: password,
};
axios.defaults.withCredentials = true;
// Make POST request to login endpoint
try {
const response: AxiosResponse = await axios.post('http://localhost:8080/auth/login', body, {
withCredentials: true,
headers: { crossDomain: true, 'Content-Type': 'application/json', 'Accept': '*/*', 'credentials': 'include' },
});
const response: AxiosResponse = await axios.post(
'http://localhost:8080/auth/login',
body,
{
withCredentials: true,
headers: {
crossDomain: true,
'Content-Type': 'application/json',
Accept: '*/*',
credentials: 'include',
},
}
);
// Save user data and JWT token to local storage
setUser(response.data);
localStorage.setItem("user", JSON.stringify(response.data));
localStorage.setItem('user', JSON.stringify(response.data));
const cookie = getCookie('ChatApp');
if (cookie) {
localStorage.setItem("jwt", cookie);
localStorage.setItem('jwt', cookie);
}
// Redirect to chat page
window.location.href = "/chat";
window.location.href = '/chat';
} catch (error: any) {
console.error('Error:', error);
setErrorMessage("Failed to login");
setErrorMessage('Failed to login');
}
}
}
};
return (
<>
<div className="flex min-h-full flex-1 flex-col justify-center px-6 py-12 lg:px-8">
Expand All @@ -73,14 +82,19 @@ const Login: React.FC = () => {
</div>

<div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
{/* Show error message if it exists */}
{errorMessage !== "" && (
<span id="message" style={{ color: "#AA0000", fontSize: "14px", display: "block", textAlign: "center" }} aria-live="assertive">
{errorMessage}
</span>
)}
{/* Show error message if it exists */}
{errorMessage !== '' && (
<span
id="message"
style={{ color: '#AA0000', fontSize: '14px', display: 'block', textAlign: 'center' }}
aria-live="assertive"
role="alert"
>
{errorMessage}
</span>
)}

<form className="space-y-6" action="#" method="POST">
<form className="space-y-6" onSubmit={submitHandler}>
<div>
<label htmlFor="username" className="block text-sm font-medium leading-6 text-gray-900">
Username
Expand All @@ -102,11 +116,9 @@ const Login: React.FC = () => {
</div>

<div>
<div className="flex items-center justify-between">
<label htmlFor="password" className="block text-sm font-medium leading-6 text-gray-900">
Password
</label>
</div>
<label htmlFor="password" className="block text-sm font-medium leading-6 text-gray-900">
Password
</label>
<div className="mt-2">
<input
aria-label="Password"
Expand All @@ -120,22 +132,27 @@ const Login: React.FC = () => {
placeholder="Enter password"
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
/>
{/* if checked, show/hide password */}
<div className="flex mt-4">
<input data-hs-toggle-password='{
"target": "#password"
}' onChange={togglePassword} id="hs-toggle-password-checkbox" type="checkbox" className="shrink-0 mt-0.5 border-gray-200 rounded"/>
<label htmlFor="hs-toggle-password-checkbox" className="text-sm text-gray-500 ms-3 dark:text-gray-400" aria-label="Show Password">Show password</label>
</div>

</div>
</div>

{/* if checked, show/hide password */}
<div className="flex items-center">
<input
data-hs-toggle-password='{"target": "#password"}'
onChange={togglePassword}
id="hs-toggle-password-checkbox"
type="checkbox"
className="mt-0.5 border-gray-200 rounded"
/>
<label htmlFor="hs-toggle-password-checkbox" className="text-sm text-gray-500 ms-3 dark:text-gray-400">
Show password
</label>
</div>

{/* if pressed, submit form */}
<div>
<button
type="submit"
onClick={submitHandler}
className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
Sign in
Expand All @@ -152,7 +169,7 @@ const Login: React.FC = () => {
</div>
</div>
</>
)
}
);
};

export default Login;
export default Login;
42 changes: 32 additions & 10 deletions src/components/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@ import {
togglePasswordConfirm
} from "../utils";

const DeleteModal: React.FC<{ onClose: () => void, onDelete: (event: React.MouseEvent<HTMLButtonElement>) => Promise<void> }> = ({ onClose, onDelete }) => {
return (
<div className="modal">
<div className="modal-content">
<span className="close" onClick={onClose}>&times;</span>
<p>Are you sure you want to delete your account?</p>
<div>
<button style={{marginRight:"10px"}} className="leaveChatButton" onClick={onDelete} aria-label="Confirm deletion">
Yes
</button>
<button className="leaveChatButton" onClick={onClose} aria-label="Cancel deletion">
Cancel
</button>
</div>
</div>
</div>
);
};

const Profile: React.FC<ProfileProps> = ({ showUser }) => {
// Context to access user data and set user
const { setUser } = useContext(UserContext) as UserContextType;
Expand All @@ -33,6 +52,7 @@ const Profile: React.FC<ProfileProps> = ({ showUser }) => {
const [confirm, setConfirm] = useState<string>("");
const [errorMessage, setErrorMessage] = useState<string>("");
const [successMessage, setSuccessMessage] = useState<string>("");
const [showDeleteModal, setShowDeleteModal] = useState<boolean>(false);

// Event handlers for input changes
const firstnameChangeHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -321,23 +341,25 @@ const Profile: React.FC<ProfileProps> = ({ showUser }) => {
<button
type="submit"
onClick={submitHandler}
aria-label="Update Profile"
className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
Update
</button>
</div>

{/* if pressed, delete account */}
<button
style={{ color: "#4F46E5", background: "white", borderColor: "#4F46E5" }}
type="submit"
onClick={deleteAccount}
className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
Delete account
</button>
</form>

<button
style={{ color: "#4F46E5", background: "white", borderColor: "#4F46E5", marginTop: "7px" }}
onClick={() => setShowDeleteModal(true)}
aria-label="Delete Account"
className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
Delete account
</button>

{/* Delete Account Modal */}
{showDeleteModal && <DeleteModal onClose={() => setShowDeleteModal(false)} onDelete={deleteAccount} />}
</div>
</div>
</div>
Expand Down
7 changes: 3 additions & 4 deletions src/components/Register.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import '../index.css'
import React, { useState } from 'react';
import {
validateEmail,
Expand All @@ -8,6 +7,7 @@ import {
validateName,
togglePasswordConfirm
} from "../utils";
import '../index.css';

const Register: React.FC = () => {

Expand Down Expand Up @@ -41,7 +41,7 @@ const Register: React.FC = () => {
};

// Event handler for form submission
const submitHandler = async (event: React.MouseEvent<HTMLButtonElement>) => {
const submitHandler = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
try {
// Validate form inputs
Expand Down Expand Up @@ -113,7 +113,7 @@ const Register: React.FC = () => {
{errorMessage}
</span>
)}
<form className="space-y-6" action="#" method="POST">
<form className="space-y-6" action="#" method="POST" onSubmit={submitHandler}>
<div>
<label htmlFor="username" className="block text-sm font-medium leading-6 text-gray-900">
Username
Expand Down Expand Up @@ -258,7 +258,6 @@ const Register: React.FC = () => {
<div>
<button
type="submit"
onClick={submitHandler}
className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
Sign up
Expand Down
58 changes: 46 additions & 12 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ button:focus-visible {
.chat {
height: 100vh;
width: 100%;
/* max-height: 90vh; */
display: flex;
align-items: flex-start;
}
Expand Down Expand Up @@ -118,16 +117,6 @@ button:focus-visible {
display: flex;
}

.menu-button {
display: block; /* By default, show the button */
}

/* CSS for large screens */
@media (min-width: 768px) {
.menu-button {
display: none; /* Hide the button for large screens */
}
}
.chatUsers {
max-height: 70vh;
overflow-y: auto;
Expand Down Expand Up @@ -170,7 +159,7 @@ button:focus-visible {
}
.messageContainer {
width: 100%;
height: 80vh;
height: 77vh;
background-color: #fff;
padding: 20px;
overflow-y: scroll;
Expand Down Expand Up @@ -236,3 +225,48 @@ button:focus-visible {
.container {
display: flex;
}


/* Modal styles */
.modal {
display: block;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
}

.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 18%;
height: 15%;
border-radius: 8px;
position: relative; /* Ensure the modal content is positioned relatively */
}

.modal-content > div {
position: absolute;
bottom: 20px; /* Adjust the distance from the bottom as needed */
left: 50%;
transform: translateX(-50%);
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}

.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
Loading