108 lines
3.3 KiB
TypeScript
108 lines
3.3 KiB
TypeScript
// app/account/profile/page.tsx
|
|
'use client';
|
|
|
|
import Link from 'next/link';
|
|
import React, { useState } from 'react';
|
|
|
|
import { useCustomer } from '@/providers/customer';
|
|
|
|
export default function ProfilePage() {
|
|
// Access customer data (and possibly other methods: register, login, logout)
|
|
const { customer, token } = useCustomer();
|
|
|
|
// For demonstration, we keep track of form states to update first/last name
|
|
const [firstName, setFirstName] = useState(customer?.first_name ?? '');
|
|
const [lastName, setLastName] = useState(customer?.last_name ?? '');
|
|
const [message, setMessage] = useState<string>('');
|
|
|
|
// If the user isn't logged in, `customer` will be undefined
|
|
if (!customer) {
|
|
return <div className='p-4'>Please log in to view your profile.</div>;
|
|
}
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
setMessage('');
|
|
|
|
try {
|
|
// Make a PUT request to update the currently logged-in Medusa customer
|
|
const res = await fetch(`${process.env.NEXT_PUBLIC_STORE_URL}/store/customers/me`, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
Authorization: `Bearer ${token}`, // pass the JWT
|
|
'x-publishable-api-key': process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY as string,
|
|
},
|
|
credentials: 'include',
|
|
body: JSON.stringify({
|
|
first_name: firstName,
|
|
last_name: lastName,
|
|
}),
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const errorData = await res.json();
|
|
throw new Error(errorData?.message || 'Failed to update profile.');
|
|
}
|
|
|
|
setMessage('Profile updated successfully!');
|
|
|
|
// If you'd like to refresh the data in your context,
|
|
// you could call a function from your provider here (e.g., getCustomer()).
|
|
// Or simply do another fetch of /customers/me and update context:
|
|
// await someProviderMethodToRefreshCustomer();
|
|
} catch (error: any) {
|
|
setMessage(`Error: ${error.message}`);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className='p-4'>
|
|
<h1 className='text-xl font-bold mb-4'>Your Profile</h1>
|
|
|
|
<p>
|
|
<strong>Email:</strong> {customer.email}
|
|
</p>
|
|
<p>
|
|
<strong>First Name:</strong> {customer.first_name}
|
|
</p>
|
|
<p>
|
|
<strong>Last Name:</strong> {customer.last_name}
|
|
</p>
|
|
|
|
<hr className='my-4' />
|
|
|
|
<h2 className='font-semibold mb-2'>Update Profile</h2>
|
|
|
|
<form onSubmit={handleSubmit} className='flex flex-col max-w-sm gap-2'>
|
|
{message && <p className='text-red-500'>{message}</p>}
|
|
|
|
<label>
|
|
New First Name:
|
|
<input
|
|
className='block w-full border border-gray-300 p-2 mt-1'
|
|
value={firstName}
|
|
onChange={(e) => setFirstName(e.target.value)}
|
|
/>
|
|
</label>
|
|
|
|
<label>
|
|
New Last Name:
|
|
<input
|
|
className='block w-full border border-gray-300 p-2 mt-1'
|
|
value={lastName}
|
|
onChange={(e) => setLastName(e.target.value)}
|
|
/>
|
|
</label>
|
|
|
|
<button type='submit' className='mt-2 bg-blue-600 text-white px-4 py-2 rounded'>
|
|
Update
|
|
</button>
|
|
<Link className='w-full mt-4 bg-white' href={'./addresses'}>
|
|
Manage addresses
|
|
</Link>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|