update profile route and updated user page functionality
This commit is contained in:
parent
6af6da358b
commit
589c9e59c4
7 changed files with 128 additions and 81 deletions
|
@ -7,27 +7,42 @@ import { UserInfo } from "../models/UserInfo"
|
||||||
export async function PUT(req){
|
export async function PUT(req){
|
||||||
mongoose.connect(process.env.MONGO_URL)
|
mongoose.connect(process.env.MONGO_URL)
|
||||||
const data = await req.json();
|
const data = await req.json();
|
||||||
const session = await getServerSession(authOptions)
|
const {_id, name, image, ...otherUserInfo} = data;
|
||||||
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});
|
|
||||||
|
|
||||||
|
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)
|
return Response.json(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function GET(){
|
export async function GET(req){
|
||||||
mongoose.connect(process.env.MONGO_URL)
|
mongoose.connect(process.env.MONGO_URL)
|
||||||
const session = await getServerSession(authOptions)
|
const url = new URL(req.url);
|
||||||
const email = session?.user?.email
|
const _id = url.searchParams.get('_id');
|
||||||
if(!email){
|
|
||||||
return Response.json({})
|
let filterUser = {}
|
||||||
|
if(_id) {
|
||||||
|
filterUser={_id}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const session = await getServerSession(authOptions)
|
||||||
|
const email = session?.user?.email
|
||||||
|
if(!email){
|
||||||
|
return Response.json({})
|
||||||
|
}
|
||||||
|
filterUser = {email}
|
||||||
}
|
}
|
||||||
const user = await User.findOne({email}).lean()
|
const user = await User.findOne(filterUser).lean()
|
||||||
const userInfo = await UserInfo.findOne({email}).lean()
|
const userInfo = await UserInfo.findOne({email:user.email}).lean()
|
||||||
|
|
||||||
return Response.json({...user, ...userInfo})
|
return Response.json({...user, ...userInfo})
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@ const LoginPage = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
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>
|
<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}>
|
<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'/>
|
<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'/>
|
||||||
|
|
|
@ -6,36 +6,22 @@ import React, { useEffect, useState } from 'react'
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import UserTabs from "../../components/layout/UserTab"
|
import UserTabs from "../../components/layout/UserTab"
|
||||||
import EditImage from "../../components/layout/EditImage"
|
import EditImage from "../../components/layout/EditImage"
|
||||||
|
import UserForm from "../../components/layout/UserForm"
|
||||||
|
|
||||||
const ProfilePage = () => {
|
const ProfilePage = () => {
|
||||||
//use session
|
//use session
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const {status} = session;
|
const {status} = session;
|
||||||
//profile update
|
const [user, setUser] = useState(null);
|
||||||
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 [isAdmin, setIsAdmin] = useState(false);
|
const [isAdmin, setIsAdmin] = useState(false);
|
||||||
const [profileFetchd, setProfileFetched] = useState(false);
|
const [profileFetchd, setProfileFetched] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if(status === 'authenticated'){
|
if(status === 'authenticated'){
|
||||||
setUserName(session.data.user.name)
|
|
||||||
setImage(session.data.user.image)
|
|
||||||
fetch('/api/profile').then(response => {
|
fetch('/api/profile').then(response => {
|
||||||
response.json().then(data => {
|
response.json().then(data => {
|
||||||
setPhoneNumber(data.phoneNumber);
|
setUser(data)
|
||||||
setStreetAddress(data.streetAddress);
|
|
||||||
setCity(data.city);
|
|
||||||
setStateProvince(data.stateProvince);
|
|
||||||
setZipCode(data.zipCode);
|
|
||||||
setCountry(data.country);
|
|
||||||
setIsAdmin(data.admin);
|
setIsAdmin(data.admin);
|
||||||
setProfileFetched(true);
|
setProfileFetched(true);
|
||||||
})
|
})
|
||||||
|
@ -44,14 +30,14 @@ const ProfilePage = () => {
|
||||||
},[session, status])
|
},[session, status])
|
||||||
|
|
||||||
|
|
||||||
async function handleInfoUpdate(ev){
|
async function handleInfoUpdate(ev, data){
|
||||||
ev.preventDefault()
|
ev.preventDefault()
|
||||||
|
|
||||||
const savingPromise = new Promise(async (resolve, reject) => {
|
const savingPromise = new Promise(async (resolve, reject) => {
|
||||||
const response = await fetch('/api/profile', {
|
const response = await fetch('/api/profile', {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: {'Content-Type': 'application/json'},
|
||||||
body: JSON.stringify({name:userName, image, phoneNumber, streetAddress, city, stateProvince, zipCode, country}),
|
body: JSON.stringify({data}),
|
||||||
});
|
});
|
||||||
if(response.ok)
|
if(response.ok)
|
||||||
resolve()
|
resolve()
|
||||||
|
@ -78,48 +64,7 @@ const ProfilePage = () => {
|
||||||
return (
|
return (
|
||||||
<div className='px-5 mb-10'>
|
<div className='px-5 mb-10'>
|
||||||
<UserTabs isAdmin={isAdmin}/>
|
<UserTabs isAdmin={isAdmin}/>
|
||||||
<div className='max-w-md mx-auto mt-10'>
|
<UserForm user={user} onSave={handleInfoUpdate}/>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ const RegisterPage = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
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>
|
<p className='text-center text-2xl font-semibold uppercase mb-5 text-[#FF5580]'>Register</p>
|
||||||
{userCreated && (
|
{userCreated && (
|
||||||
<div className='my-4 text-center text-green-600 font-bold'>
|
<div className='my-4 text-center text-green-600 font-bold'>
|
||||||
|
|
|
@ -1,10 +1,32 @@
|
||||||
"use client"
|
"use client"
|
||||||
import React from 'react'
|
import React, { use, useEffect, useState } from 'react'
|
||||||
import UserTab from '../../../components/layout/UserTab'
|
import UserTab from '../../../components/layout/UserTab'
|
||||||
import useProfile from '../../../components/UseProfile';
|
import useProfile from '../../../components/UseProfile';
|
||||||
|
import UserForm from '../../../components/layout/UserForm';
|
||||||
|
import { useParams } from 'next/navigation';
|
||||||
|
|
||||||
const EditUsersPage = () => {
|
const EditUsersPage = () => {
|
||||||
const {data, loading} = useProfile();
|
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 (
|
return (
|
||||||
<div className='px-5'>
|
<div className='px-5 mb-10'>
|
||||||
<UserTab isAdmin={true}/>
|
<UserTab isAdmin={true}/>
|
||||||
|
<div className='max-w-md mx-auto mt-10'>
|
||||||
|
<UserForm user={user} onSave={handleSaveButton}/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ const Userspage = () => {
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='px-5'>
|
<div className='px-5 mb-10'>
|
||||||
<UserTab isAdmin={true}/>
|
<UserTab isAdmin={true}/>
|
||||||
<div className='max-w-md mx-auto mt-10'>
|
<div className='max-w-md mx-auto mt-10'>
|
||||||
{users?.length > 0 && users.map(user => (
|
{users?.length > 0 && users.map(user => (
|
||||||
|
|
62
donutshop_ecommerce/src/components/layout/UserForm.js
Normal file
62
donutshop_ecommerce/src/components/layout/UserForm.js
Normal 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
|
Loading…
Add table
Reference in a new issue