update profile route and updated user page functionality

This commit is contained in:
Juthatip McDevitt 2024-05-21 11:34:32 -05:00
parent 6af6da358b
commit 589c9e59c4
7 changed files with 128 additions and 81 deletions

View file

@ -7,27 +7,42 @@ import { UserInfo } from "../models/UserInfo"
export async function PUT(req){
mongoose.connect(process.env.MONGO_URL)
const data = await req.json();
const session = await getServerSession(authOptions)
const email = session.user.email
const {name, image, ...otherUserInfo} = data
await User.updateOne({email}, {name, image});
//update userInfo
await UserInfo.findOneAndUpdate({email}, otherUserInfo, {upsert:true});
const {_id, name, image, ...otherUserInfo} = data;
let filter = {};
if(_id) {
filter = {_id}
} else {
const session = await getServerSession(authOptions);
const email = session.user.email;
filter = {email};
}
const user = await User.findOne(filter);
await User.updateOne(filter, {name, image});
await UserInfo.findOneAndUpdate({email:user.email}, otherUserInfo, {upsert:true});
return Response.json(true)
}
export async function GET(){
export async function GET(req){
mongoose.connect(process.env.MONGO_URL)
const url = new URL(req.url);
const _id = url.searchParams.get('_id');
let filterUser = {}
if(_id) {
filterUser={_id}
} else {
const session = await getServerSession(authOptions)
const email = session?.user?.email
if(!email){
return Response.json({})
}
const user = await User.findOne({email}).lean()
const userInfo = await UserInfo.findOne({email}).lean()
filterUser = {email}
}
const user = await User.findOne(filterUser).lean()
const userInfo = await UserInfo.findOne({email:user.email}).lean()
return Response.json({...user, ...userInfo})
}

View file

@ -21,7 +21,7 @@ const LoginPage = () => {
}
return (
<div className='px-5 mt-10'>
<div className='px-5 mt-10 mb-10'>
<p className='text-center text-2xl font-semibold uppercase mb-5 text-[#FF5580]'>Login</p>
<form className='block max-w-xs mx-auto' onSubmit={handleFormSubmit}>
<input type='email' name="email" placeholder='Enter your email' value={email} onChange={ev => setEmail(ev.target.value)} disabled={loginInProgress} className=' disabled:bg-gray-300 disabled:cursor-not-allowed'/>

View file

@ -6,36 +6,22 @@ import React, { useEffect, useState } from 'react'
import toast from 'react-hot-toast';
import UserTabs from "../../components/layout/UserTab"
import EditImage from "../../components/layout/EditImage"
import UserForm from "../../components/layout/UserForm"
const ProfilePage = () => {
//use session
const session = useSession();
const {status} = session;
//profile update
const [userName, setUserName] = useState('');
const [image, setImage] = useState('');
const [phoneNumber, setPhoneNumber] = useState('');
const [streetAddress, setStreetAddress] = useState('');
const [city, setCity] = useState('');
const [stateProvince, setStateProvince] = useState('');
const [zipCode, setZipCode] = useState('');
const [country, setCountry] = useState('');
const [user, setUser] = useState(null);
const [isAdmin, setIsAdmin] = useState(false);
const [profileFetchd, setProfileFetched] = useState(false);
useEffect(() => {
if(status === 'authenticated'){
setUserName(session.data.user.name)
setImage(session.data.user.image)
fetch('/api/profile').then(response => {
response.json().then(data => {
setPhoneNumber(data.phoneNumber);
setStreetAddress(data.streetAddress);
setCity(data.city);
setStateProvince(data.stateProvince);
setZipCode(data.zipCode);
setCountry(data.country);
setUser(data)
setIsAdmin(data.admin);
setProfileFetched(true);
})
@ -44,14 +30,14 @@ const ProfilePage = () => {
},[session, status])
async function handleInfoUpdate(ev){
async function handleInfoUpdate(ev, data){
ev.preventDefault()
const savingPromise = new Promise(async (resolve, reject) => {
const response = await fetch('/api/profile', {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({name:userName, image, phoneNumber, streetAddress, city, stateProvince, zipCode, country}),
body: JSON.stringify({data}),
});
if(response.ok)
resolve()
@ -78,48 +64,7 @@ const ProfilePage = () => {
return (
<div className='px-5 mb-10'>
<UserTabs isAdmin={isAdmin}/>
<div className='max-w-md mx-auto mt-10'>
<div className='flex flex-col gap-2 justify-center items-center max-w-[100px] mx-auto'>
<EditImage link={image} setLink={setImage}/>
</div>
<form className='mt-5 text-sm sm:text-base flex flex-col gap-0 sm:gap-1' onSubmit={handleInfoUpdate}>
<div>
<label className='text-gray-700 text-sm font-semibold'>Name</label>
<input type='text' placeholder='Name' value={userName} onChange={ev => setUserName(ev.target.value)}/>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>Email</label>
<input type='text' value={session.data.user.email} disabled={true} className='disabled:bg-gray-200 disabled:text-gray-400'/>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>Phone number</label>
<input type='tel' placeholder='Phone number' value={phoneNumber} onChange={ev => setPhoneNumber(ev.target.value)}/>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>Street Address</label>
<input type='text' placeholder='Address' value={streetAddress} onChange={ev => setStreetAddress(ev.target.value)}/>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>City</label>
<input type='text' placeholder='City' value={city} onChange={ev => setCity(ev.target.value)}/>
</div>
<div className='flex flex-col sm:flex-row gap-0 sm:gap-2'>
<div>
<label className='text-gray-700 text-sm font-semibold'>State/Province</label>
<input type='text' placeholder='State/Province' value={stateProvince} onChange={ev => setStateProvince(ev.target.value)}/>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>Zip/Postal code</label>
<input type='text' placeholder='Zip/Postal code' value={zipCode} onChange={ev => setZipCode(ev.target.value)}/>
</div>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>Country</label>
<input type='text' placeholder='Country' value={country} onChange={ev => setCountry(ev.target.value)}/>
</div>
<button className='w-full bg-pink-500 text-white p-2 rounded-md hover:opacity-80 duration-300 disabled:cursor-not-allowed'>Save</button>
</form>
</div>
<UserForm user={user} onSave={handleInfoUpdate}/>
</div>
)
}

View file

@ -31,7 +31,7 @@ const RegisterPage = () => {
}
return (
<div className='px-5 mt-10'>
<div className='px-5 mt-10 mb-10'>
<p className='text-center text-2xl font-semibold uppercase mb-5 text-[#FF5580]'>Register</p>
{userCreated && (
<div className='my-4 text-center text-green-600 font-bold'>

View file

@ -1,10 +1,32 @@
"use client"
import React from 'react'
import React, { use, useEffect, useState } from 'react'
import UserTab from '../../../components/layout/UserTab'
import useProfile from '../../../components/UseProfile';
import UserForm from '../../../components/layout/UserForm';
import { useParams } from 'next/navigation';
const EditUsersPage = () => {
const {data, loading} = useProfile();
const {id} = useParams();
const [user, setUser] = useState(null);
useEffect(() => {
fetch('/api/profile?_id='+id).then(res => {
res.json().then(user => {
setUser(user)
})
})
}, [])
function handleSaveButton(ev, data){
ev.preventDefault();
fetch('/api/profile', {
method: 'PUT',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({...data, _id:id}),
})
}
@ -16,8 +38,11 @@ const EditUsersPage = () => {
}
return (
<div className='px-5'>
<div className='px-5 mb-10'>
<UserTab isAdmin={true}/>
<div className='max-w-md mx-auto mt-10'>
<UserForm user={user} onSave={handleSaveButton}/>
</div>
</div>
)
}

View file

@ -28,7 +28,7 @@ const Userspage = () => {
return (
<div className='px-5'>
<div className='px-5 mb-10'>
<UserTab isAdmin={true}/>
<div className='max-w-md mx-auto mt-10'>
{users?.length > 0 && users.map(user => (

View file

@ -0,0 +1,62 @@
"use client"
import React, { useState } from 'react'
import EditImage from '../../components/layout/EditImage'
const UserForm = ({user, onSave}) => {
const [userName, setUserName] = useState(user?.name || '');
const [image, setImage] = useState(user?.image || '');
const [phoneNumber, setPhoneNumber] = useState(user?.phoneNumber || '');
const [streetAddress, setStreetAddress] = useState(user?.streetAddress || '');
const [city, setCity] = useState(user?.city || '');
const [stateProvince, setStateProvince] = useState(user?.stateProvince || '');
const [zipCode, setZipCode] = useState(user?.zipCode || '');
const [country, setCountry] = useState(user?.country || '');
return (
<div className='max-w-md mx-auto mt-10'>
<div className='flex flex-col gap-2 justify-center items-center max-w-[100px] mx-auto'>
<EditImage link={image} setLink={setImage}/>
</div>
<form className='mt-5 text-sm sm:text-base flex flex-col gap-0 sm:gap-1' onSubmit={ev => onSave(ev, {name:userName, image, phoneNumber, streetAddress, city, stateProvince, zipCode, country,})}>
<div>
<label className='text-gray-700 text-sm font-semibold'>Name</label>
<input type='text' placeholder='Name' value={userName} onChange={ev => setUserName(ev.target.value)}/>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>Email</label>
<input type='text' value={user.email} disabled={true} className='disabled:bg-gray-200 disabled:text-gray-400'/>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>Phone number</label>
<input type='tel' placeholder='Phone number' value={phoneNumber} onChange={ev => setPhoneNumber(ev.target.value)}/>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>Street Address</label>
<input type='text' placeholder='Address' value={streetAddress} onChange={ev => setStreetAddress(ev.target.value)}/>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>City</label>
<input type='text' placeholder='City' value={city} onChange={ev => setCity(ev.target.value)}/>
</div>
<div className='flex flex-col sm:flex-row gap-0 sm:gap-2'>
<div>
<label className='text-gray-700 text-sm font-semibold'>State/Province</label>
<input type='text' placeholder='State/Province' value={stateProvince} onChange={ev => setStateProvince(ev.target.value)}/>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>Zip/Postal code</label>
<input type='text' placeholder='Zip/Postal code' value={zipCode} onChange={ev => setZipCode(ev.target.value)}/>
</div>
</div>
<div>
<label className='text-gray-700 text-sm font-semibold'>Country</label>
<input type='text' placeholder='Country' value={country} onChange={ev => setCountry(ev.target.value)}/>
</div>
<button className='w-full bg-pink-500 text-white p-2 rounded-md hover:opacity-80 duration-300 disabled:cursor-not-allowed'>Save</button>
</form>
</div>
)
}
export default UserForm