diff --git a/frontend/src/hooks/useSameUser.ts b/frontend/src/hooks/useSameUser.ts new file mode 100644 index 0000000..6bf874a --- /dev/null +++ b/frontend/src/hooks/useSameUser.ts @@ -0,0 +1,24 @@ +import { useEffect, useState } from "react" + +export function useSameUser({ username }: { username: string | undefined }) { + const [isSame, setIsSame] = useState(false); + + useEffect(() => { + const fetchStatus = async () => { + try { + const response = await fetch(`/api/user/same/${username}`); + if (!response.ok) { + throw new Error("Failed to validate user"); + } + const data = await response.json(); + setIsSame(data.same); + } catch (error) { + console.error("Error:", error); + } + }; + + fetchStatus(); + }, []); + + return isSame; +} \ No newline at end of file diff --git a/frontend/src/pages/UserPage.tsx b/frontend/src/pages/UserPage.tsx index 1d03b9e..92f5977 100644 --- a/frontend/src/pages/UserPage.tsx +++ b/frontend/src/pages/UserPage.tsx @@ -11,6 +11,7 @@ import LoadingScreen from "../components/Layout/LoadingScreen"; import { StreamListItem } from "../components/Layout/ListItem"; import { CameraIcon } from "lucide-react"; import { getCategoryThumbnail } from "../utils/thumbnailUtils"; +import { useSameUser } from "../hooks/useSameUser"; interface UserProfileData { id: number; @@ -36,16 +37,29 @@ const UserPage: React.FC = () => { const { showAuthModal, setShowAuthModal } = useAuthModal(); const { username: loggedInUsername } = useAuth(); const { username } = useParams(); - const [isUser, setIsUser] = useState(true); + const isUser = useSameUser({username}); const navigate = useNavigate(); - const bgColors = { - personal: "", - streamer: - "bg-gradient-radial from-[rgba(255, 0, 241, 0.5)] via-[rgba(4, 0, 255, 0.5)] to-[rgba(255, 0, 0, 0.5)]", // offline streamer - user: "bg-gradient-radial from-[rgba(255, 0, 241, 0.5)] via-[rgba(4, 0, 255, 0.5)] to-[rgba(255, 0, 241, 0.5)]", - admin: - "bg-gradient-to-r from-[rgba(255,100,100,0.5)] via-transparent to-[rgba(100,100,255,0.5)]", + // Saves uploaded image as profile picture for the user + const saveUploadedImage = async (event) => { + const img = event.target.files[0]; + if (img) { + const formData = new FormData(); + formData.append('image', img); + + try { + const response = await fetch('/api/user/profile_picture/upload', { + method: 'POST', + body: formData, + }); + + if (response.ok) { + console.log("Success"); + } + } catch (error) { + console.log("Failure"); + } + } }; useEffect(() => { @@ -108,11 +122,7 @@ const UserPage: React.FC = () => { return (
@@ -138,18 +148,25 @@ const UserPage: React.FC = () => { {/* Profile Picture */}
- + )} diff --git a/web_server/blueprints/user.py b/web_server/blueprints/user.py index 89f3950..0c6ee79 100644 --- a/web_server/blueprints/user.py +++ b/web_server/blueprints/user.py @@ -1,4 +1,4 @@ -from flask import Blueprint, jsonify, session +from flask import Blueprint, jsonify, session, request from utils.user_utils import * from utils.auth import * from utils.utils import get_category_id @@ -6,6 +6,9 @@ from blueprints.middleware import login_required from utils.email import send_email, forgot_password_body, newsletter_conf import redis +from io import BytesIO +from PIL import Image + redis_url = "redis://redis:6379/1" r = redis.from_url(redis_url, decode_responses=True) @@ -33,6 +36,31 @@ def user_stream_key(username: str): data = db.fetchone("SELECT stream_key FROM users WHERE user_id = ?", (user_id,)) return jsonify({"stream_key": data["stream_key"]}) +@login_required +@user_bp.route('/user/profile_picture/upload', methods=['POST']) +def user_profile_picture_save(): + """ + Saves user profile picture + """ + user_id = session.get("user_id") + image = request.files['image'] + ext = image.filename.split('.')[-1] + + image.save(f"/web_server/stream_data/{user_id}.{ext}") + + return "Success", 200 + +@login_required +@user_bp.route('/user/same/') +def user_is_same(username): + """ + Returns if given user is current user + """ + current_username = session.get("username") + if username == current_username: + return jsonify({"same": True}) + return jsonify({"same": False}) + ## Subscription Routes @login_required @user_bp.route('/user/subscription/') @@ -146,7 +174,7 @@ def user_login_status(): 'username': username, 'user_id': user_id}) -@user_bp.route('/user/forgot_password/', methods=['GET','POST']) +@user_bp.route('/user/forgot_password/', methods=['POST']) def user_forgot_password(email): """ Initializes the function to handle password reset diff --git a/web_server/requirements.txt b/web_server/requirements.txt index 1cca4ad..f679b51 100644 --- a/web_server/requirements.txt +++ b/web_server/requirements.txt @@ -28,4 +28,5 @@ flask-oauthlib==0.9.6 celery==5.2.3 redis==5.2.1 python-dateutil -Authlib==1.4.1 \ No newline at end of file +Authlib==1.4.1 +Pillow==11.1.0 \ No newline at end of file