Add Profile update page

This commit is contained in:
sosokker 2023-11-05 19:01:05 +07:00
parent 0ce32b9613
commit 47d4d97ce7
5 changed files with 151 additions and 8 deletions

View File

@ -31,6 +31,19 @@ class UpdateProfileSerializer(serializers.ModelSerializer):
"""
Serializer for updating user profile.
"""
profile_pic = serializers.ImageField(required=False)
first_name = serializers.CharField(max_length=255, required=False)
about = serializers.CharField(required=False)
class Meta:
model = CustomUser
fields = ('profile_pic', 'first_name', 'about')
def update(self, instance, validated_data):
"""
Update an existing user's profile.
"""
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance

View File

@ -8,7 +8,7 @@ from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser
from users.serializers import CustomUserSerializer, UpdateProfileSerializer
from users.models import CustomUser
class CustomUserCreate(APIView):
"""
@ -49,8 +49,12 @@ class CustomUserProfileUpdate(APIView):
return Response(data)
def post(self, request):
serializer = UpdateProfileSerializer(data=request.data)
if not CustomUser.objects.filter(email=request.user.email).exists():
return Response ({
'error': 'User does not exist'
}, status=status.HTTP_404_NOT_FOUND)
serializer = UpdateProfileSerializer(request.user, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=400)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

View File

@ -2,11 +2,11 @@ import './App.css';
import { BrowserRouter, Route, Routes, Link } from 'react-router-dom';
import TestAuth from './components/testAuth';
import IconSideNav from './components/IconSideNav';
import LoginPage from './components/authentication/LoginPage';
import SignUpPage from './components/authentication/SignUpPage';
import NavBar from './components/Nav/Navbar';
import Home from './components/Home';
import ProfileUpdate from './components/ProfileUpdatePage'
const App = () => {
return (
@ -18,11 +18,9 @@ const App = () => {
<Route path="/login" element={<LoginPage/>}/>
<Route path="/signup" element={<SignUpPage/>}/>
<Route path="/testAuth" element={<TestAuth/>}/>
<Route path="/update_profile" element={<ProfileUpdate/>}/>
</Routes>
</div>
{/* <div>
<IconSideNav />
</div> */}
</BrowserRouter>
);
}

View File

@ -0,0 +1,21 @@
import axios from 'axios';
const ApiUpdateUserProfile = async (formData) => {
try {
const response = await axios.post('http://127.0.1:8000/api/user/update/', formData, {
headers: {
'Authorization': "Bearer " + localStorage.getItem('access_token'),
'Content-Type': 'multipart/form-data',
},
});
console.log(response.data);
return response.data;
} catch (error) {
console.error('Error updating user profile:', error);
throw error;
}
};
export { ApiUpdateUserProfile };

View File

@ -0,0 +1,107 @@
import React, { useState, useRef } from 'react';
import { ApiUpdateUserProfile } from '../api/UserProfileApi';
function ProfileUpdate() {
const [file, setFile] = useState(null);
const [username, setUsername] = useState('');
const [fullName, setFullName] = useState('');
const [about, setAbout] = useState('');
const defaultImage = 'https://i1.sndcdn.com/artworks-cTz48e4f1lxn5Ozp-L3hopw-t500x500.jpg';
const fileInputRef = useRef(null);
const handleImageUpload = () => {
if (fileInputRef.current) {
fileInputRef.current.click();
}
};
const handleFileChange = (e) => {
const selectedFile = e.target.files[0];
if (selectedFile) {
setFile(selectedFile);
}
};
const handleSave = () => {
const formData = new FormData();
formData.append('profile_pic', file);
formData.append('first_name', username);
formData.append('about', about);
ApiUpdateUserProfile(formData);
};
return (
<div className="flex flex-col items-center mt-12 space-y-4">
{/* Profile Image */}
<div className="w-32 h-32 relative">
<label htmlFor="profileImage" className="absolute inset-0">
<input
type="file"
id="profileImage"
accept="image/*"
className="hidden"
onChange={handleFileChange}
ref={fileInputRef}
/>
</label>
<div
className="avatar w-32 h-32 cursor-pointer hover:blur"
onClick={handleImageUpload}
>
{file ? (
<img src={URL.createObjectURL(file)} alt="Profile" className="rounded-full" />
) : (
<>
<img src={defaultImage} alt="Default" className="rounded-full" />
<i className="fas fa-camera text-white text-2xl absolute bottom-0 right-0 mr-2 mb-2"></i>
<i className="fas fa-arrow-up text-white text-2xl absolute top-0 right-0 mr-2 mt-2"></i>
</>
)}
</div>
</div>
{/* Username Field */}
<div className="w-96">
<label className="block mb-2 text-gray-600">Username</label>
<input
type="text"
placeholder="Enter your username"
className="input w-full"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</div>
{/* Full Name Field */}
<div className="w-96">
<label className="block mb-2 text-gray-600">Full Name</label>
<input
type="text"
placeholder="Enter your full name"
className="input w-full"
value={fullName}
onChange={(e) => setFullName(e.target.value)}
/>
</div>
{/* About Field */}
<div className="w-96">
<label className="block mb-2 text-gray-600">About Me</label>
<textarea
placeholder="Tell us about yourself"
className="textarea w-full h-32"
value={about}
onChange={(e) => setAbout(e.target.value)}
/>
</div>
{/* Save Button */}
<button className="btn btn-primary w-96" onClick={handleSave}>
Save
</button>
</div>
);
}
export default ProfileUpdate;