add: added pfps and user profile modification

This commit is contained in:
Lukian 2025-04-18 15:42:55 +02:00
parent 56d171439e
commit 7781e6b8a1
20 changed files with 404 additions and 36 deletions

View file

@ -0,0 +1,134 @@
import { useState, useEffect } from "react"
import { User } from "../types"
import { Link } from "react-router-dom"
import axios from "axios"
import TopBar from "../components/TopBar"
import "../styles/EditProfile.css"
export default function EditProfile() {
const [token, setToken] = useState<string>("");
const [user, setUser] = useState<User>();
useEffect(() => {
const localToken = localStorage.getItem("token");
if (localToken) {
setToken(localToken)
axios
.post("/api/auth/me", { token: localToken })
.then((res) => {
setUser(res.data);
});
}
}, []);
function uploadPfp(e: React.FormEvent) {
e.preventDefault();
const formData = new FormData();
const fileInput = document.getElementById("pfp") as HTMLInputElement;
if (fileInput.files) {
formData.append("pfp", fileInput.files[0]);
}
formData.append("token", token);
axios
.post("/api/auth/me/uploadpfp", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
})
.then(() => {
window.location.reload();
})
.catch((err) => {
console.error(err.response.data);
});
}
function deletePfp(e: React.FormEvent) {
e.preventDefault();
axios
.post("/api/auth/me/deletepfp", { token: token })
.then(() => {
window.location.reload();
})
.catch((err) => {
console.error(err.response.data);
});
}
function editUsername(e: React.FormEvent) {
e.preventDefault();
const newUsername = (document.getElementById("username") as HTMLInputElement).value;
axios
.post("/api/auth/me/setusername", { token: token, username: newUsername })
.then(() => {
window.location.reload();
})
.catch((err) => {
console.error(err.response.data);
});
}
function editPassword(e: React.FormEvent) {
e.preventDefault();
const oldPassword = (document.getElementById("old-password") as HTMLInputElement).value;
const newPassword = (document.getElementById("password") as HTMLInputElement).value;
const confirmPassword = (document.getElementById("confirm-password") as HTMLInputElement).value;
if (newPassword !== confirmPassword) {
alert("Passwords do not match");
return;
}
axios
.post("/api/auth/me/setpassword", { token: token, oldPassword: oldPassword, password: newPassword })
.then(() => {
window.location.reload();
})
.catch((err) => {
console.error(err.response.data);
});
}
if (!user) {
return (
<div className="edit-profile-page">
<TopBar user={user}/>
<div className="edit-login">
<p>Please log in to edit your profile</p>
<Link to="/login">Login</Link>
</div>
</div>
)
}
return (
<div className="edit-profile-page">
<TopBar user={user}/>
<div className="edit-pfp">
<h2>Edit Profile Picture</h2>
<form>
<input type="file" name="pfp" id="pfp" />
<button onClick={uploadPfp}>Save</button>
<button onClick={deletePfp}>Delete</button>
</form>
</div>
<div className="edit-username">
<h2>Edit Username</h2>
<form>
<input type="text" name="username" id="username" placeholder={user?.username} />
<button onClick={editUsername}>Save</button>
</form>
</div>
<div className="edit-password">
<h2>Edit Password</h2>
<form>
<input type="password" name="old-password" id="old-password" placeholder="Old password" />
<input type="password" name="password" id="password" placeholder="New password" />
<input type="password" name="confirm-password" id="confirm-password" placeholder="Confirm new password" />
<button onClick={editPassword}>Save</button>
</form>
</div>
</div>
)
}

View file

@ -1,4 +1,4 @@
import { useParams } from "react-router-dom";
import { Link, useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import { User, Messages } from "../types";
import TopBar from "../components/TopBar";
@ -75,8 +75,14 @@ export default function UserPage({socket}: {socket: WebSocket}) {
<div className="user-page">
<TopBar user={user} />
<div className="user">
<h2>{pageUser.username}</h2>
<div className="user-top">
<img src={`/api/users/${pageUser.username}/pfp`} alt="pfp" className="user-page-pfp" />
<h2>{pageUser.username}</h2>
</div>
{pageUser.admin ? <p>Admin</p> : <p>User</p>}
{pageUser.id === user?.id && (
<Link to="/edit-profile">Edit profile</Link>
)}
</div>
<div className="user-messages">
<h2>Last messages</h2>

View file

@ -74,7 +74,7 @@ export default function UsersPage({socket}: {socket: WebSocket}) {
return (
<div className="users-page">
<TopBar user={thisUser} />
<div className="users-page-channels">
<div className="users-page-users">
<h2>Users</h2>
<input
type="text"