Index: frontend/src/Login.tsx
===================================================================
--- frontend/src/Login.tsx	(revision 3727852b5e0f31eb857eab69ab7d5090fa06bcad)
+++ frontend/src/Login.tsx	(revision 484dc3f54a72450588e7ece748ea1b64ad9ffdc3)
@@ -20,10 +20,5 @@
 			}>("/auth/login", { username, password });
 			scheduleTokenRefresh(response.data.tokenExpiresIn);
-			setUser({
-				username: response.data.user.username,
-				fullName: "demo",
-				email: "demo@demo.com",
-				role: response.data.user.role,
-			});
+			setUser(response.data.user);
 			navigate("/");
 		} catch (error) {
Index: frontend/src/Nav.tsx
===================================================================
--- frontend/src/Nav.tsx	(revision 3727852b5e0f31eb857eab69ab7d5090fa06bcad)
+++ frontend/src/Nav.tsx	(revision 484dc3f54a72450588e7ece748ea1b64ad9ffdc3)
@@ -1,4 +1,4 @@
 import { Link } from "react-router-dom";
-import axiosInstance from "./api/axiosInstance";
+import axiosInstance, { baseURL } from "./api/axiosInstance";
 import Logo from "./assets/logo-finkwave.png";
 import { useAuth } from "./context/authContext";
@@ -29,9 +29,18 @@
 							<div className="flex items-center space-x-3">
 								<div className="flex items-center space-x-2 bg-slate-700 rounded-lg px-3 py-2">
-									<div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center">
-										<span className="text-white text-sm font-semibold">
-											{user.username.charAt(0).toUpperCase()}
-										</span>
-									</div>
+									{user.profilePhoto ? (
+										<img
+											src={`${baseURL}/${user.profilePhoto}`}
+											alt={`${user.username}'s profile`}
+											className="w-8 h-8 rounded-full object-cover"
+										/>
+									) : (
+										<div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center">
+											<span className="text-white text-sm font-semibold">
+												{user.username.charAt(0).toUpperCase()}
+											</span>
+										</div>
+									)}
+
 									<div className="text-white">
 										<p className="text-sm font-medium">{user.username}</p>
@@ -42,7 +51,5 @@
 								</div>
 								<button
-									onClick={(e: React.MouseEvent<HTMLButtonElement>) =>
-										handleLogout(e)
-									}
+									onClick={handleLogout}
 									className="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg text-sm 
                                     font-medium transition-colors duration-200 flex items-center space-x-1 cursor-pointer"
Index: frontend/src/Register.tsx
===================================================================
--- frontend/src/Register.tsx	(revision 3727852b5e0f31eb857eab69ab7d5090fa06bcad)
+++ frontend/src/Register.tsx	(revision 484dc3f54a72450588e7ece748ea1b64ad9ffdc3)
@@ -1,3 +1,3 @@
-import { useState } from "react";
+import { useEffect, useState } from "react";
 import { useNavigate } from "react-router";
 import axiosInstance, { scheduleTokenRefresh } from "./api/axiosInstance";
@@ -11,21 +11,43 @@
 	const [fullname, setFullname] = useState("");
 	const [email, setEmail] = useState("");
-	const [profilePhoto, setProfilePhoto] = useState<string | null>(null);
+	const [profilePhotoFile, setProfilePhotoFile] = useState<File | null>(null);
+	const [previewProfilePhoto, setPreviewProfilePhoto] = useState<string | null>(
+		null,
+	);
 
 	const navigate = useNavigate();
 
+	useEffect(() => {
+		return () => {
+			if (previewProfilePhoto) {
+				URL.revokeObjectURL(previewProfilePhoto);
+			}
+		};
+	}, [previewProfilePhoto]);
+
 	const handleRegister = async (e: React.FormEvent) => {
 		e.preventDefault();
+		// todo: add proper error handling
+		if (profilePhotoFile && profilePhotoFile.size > 5 * 1024 * 1024) {
+			alert("Max file size is 5MB");
+			return;
+		}
+
+		if (profilePhotoFile && !profilePhotoFile.type.startsWith("image/")) {
+			alert("Only images allowed");
+			return;
+		}
+		const formData = new FormData();
+		if (profilePhotoFile) formData.append("profilePhoto", profilePhotoFile);
+		formData.append("username", username);
+		formData.append("fullname", fullname);
+		formData.append("email", email);
+		formData.append("password", password);
+
 		try {
 			const response = await axiosInstance.post<{
 				user: User;
 				tokenExpiresIn: number;
-			}>("/auth/register", {
-				username,
-				fullname,
-				email,
-				password,
-				profilePhoto,
-			});
+			}>("/auth/register", formData);
 			scheduleTokenRefresh(response.data.tokenExpiresIn);
 			setUser(response.data.user);
@@ -89,22 +111,43 @@
 				</div>
 				<div className="mb-4">
-					<label className="block text-gray-700 mb-2" htmlFor="profilePhoto">
-						Profile Photo URL
-					</label>
+					<label className="block text-gray-700 mb-2">Profile Photo</label>
+					<div className="flex items-center gap-3">
+						<label
+							htmlFor="profilePhoto"
+							className="px-4 py-2 bg-blue-500 text-white rounded cursor-pointer hover:bg-blue-600 transition-colors text-sm font-medium"
+						>
+							Choose File
+						</label>
+						<span className="text-gray-600 text-sm">
+							{profilePhotoFile ? profilePhotoFile.name : "No file chosen"}
+						</span>
+					</div>
 					<input
-						placeholder="todo"
-						type="text"
+						type="file"
+						accept="image/*"
 						id="profilePhoto"
-						className="w-full p-2 border border-gray-300 rounded"
-						value={profilePhoto || ""}
-						onChange={(e) => setProfilePhoto(e.target.value)}
+						className="hidden"
+						onChange={(e) => {
+							if (e.target.files && e.target.files[0]) {
+								setProfilePhotoFile(e.target.files[0]);
+								setPreviewProfilePhoto(URL.createObjectURL(e.target.files[0]));
+							}
+						}}
 					/>
 				</div>
+				{previewProfilePhoto && (
+					<div className="mb-4">
+						<p className="block text-gray-700 mb-2">Profile Photo Preview:</p>
+						<img
+							src={previewProfilePhoto}
+							alt="Profile Preview"
+							className="w-20 h-20 object-cover rounded-full"
+						/>
+					</div>
+				)}
 				<button
 					type="submit"
 					className="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600 cursor-pointer"
-					onClick={(e: React.MouseEvent<HTMLButtonElement>) =>
-						handleRegister(e)
-					}
+					onClick={handleRegister}
 				>
 					Register
Index: frontend/src/api/axiosInstance.ts
===================================================================
--- frontend/src/api/axiosInstance.ts	(revision 3727852b5e0f31eb857eab69ab7d5090fa06bcad)
+++ frontend/src/api/axiosInstance.ts	(revision 484dc3f54a72450588e7ece748ea1b64ad9ffdc3)
@@ -5,8 +5,13 @@
 export const axiosInstance = axios.create({
 	baseURL,
-	headers: {
-		"Content-Type": "application/json",
-	},
 	withCredentials: true,
+});
+
+// set content-type to application/json unless sending FormData
+axiosInstance.interceptors.request.use((config) => {
+	if (!(config.data instanceof FormData)) {
+		config.headers["Content-Type"] = "application/json";
+	}
+	return config;
 });
 
@@ -23,4 +28,8 @@
 export const scheduleTokenRefresh = (expiryTimeSeconds: number) => {
 	clearRefreshTimeout();
+
+	if (!expiryTimeSeconds || expiryTimeSeconds <= 0) {
+		return;
+	}
 
 	const refreshTime = (expiryTimeSeconds - 60) * 1000;
@@ -44,4 +53,5 @@
 			scheduleTokenRefresh(refreshResponse.data.tokenExpiresIn);
 		} catch (err) {
+			clearRefreshTimeout();
 			console.error(err);
 			throw err;
@@ -53,5 +63,5 @@
 };
 
-axios.interceptors.response.use(
+axiosInstance.interceptors.response.use(
 	(response) => response,
 	async (error) => {
