mirror of
https://github.com/vercel/commerce.git
synced 2025-06-28 01:11:24 +00:00
refactor: change layout profile and related products
This commit is contained in:
parent
6775f7363b
commit
23f9f55fab
@ -9,8 +9,8 @@ export async function GET(req: NextRequest) {
|
||||
if (!session?.user?.store_id) {
|
||||
return NextResponse.json({ error: 'User not logged' }, { status: 401 });
|
||||
}
|
||||
const cart = await woocommerce.get('customers', { id: session?.user.store_id });
|
||||
return NextResponse.json(cart, { status: 200 });
|
||||
const customer = await woocommerce.get('customers', { id: session?.user.store_id });
|
||||
return NextResponse.json(customer, { status: 200 });
|
||||
} catch (error) {
|
||||
return NextResponse.json({ error: JSON.stringify(error) }, { status: 500 });
|
||||
}
|
||||
@ -19,9 +19,9 @@ export async function GET(req: NextRequest) {
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const data = await req.json();
|
||||
const cart = await woocommerce.post('customers', data);
|
||||
return NextResponse.json(cart, { status: 200 });
|
||||
const customer = await woocommerce.post('customers', data);
|
||||
return NextResponse.json(customer, { status: 200 });
|
||||
} catch (error) {
|
||||
return NextResponse.json({ error: 'Failed to add item to cart' }, { status: 500 });
|
||||
return NextResponse.json({ error: 'Failed to add item to customer' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import { HIDDEN_PRODUCT_TAG } from 'lib/constants';
|
||||
import { Image } from 'lib/woocomerce/models/base';
|
||||
import { Product, ProductVariations } from 'lib/woocomerce/models/product';
|
||||
import { woocommerce } from 'lib/woocomerce/woocommerce';
|
||||
import Link from 'next/link';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
export async function generateMetadata(props: {
|
||||
@ -51,6 +52,10 @@ export default async function ProductPage(props: { params: Promise<{ name: strin
|
||||
|
||||
if (!product) return notFound();
|
||||
|
||||
const relatedProducts = await Promise.all(
|
||||
product.related_ids?.map(async (id) => woocommerce.get(`products/${id}`)) || []
|
||||
);
|
||||
|
||||
const productJsonLd = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Product',
|
||||
@ -114,6 +119,31 @@ export default async function ProductPage(props: { params: Promise<{ name: strin
|
||||
<AddToCart product={product} variations={variations} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-8 py-4">
|
||||
<h3 className="text-2xl font-bold">Related Products</h3>
|
||||
<div className="mt-4 grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{relatedProducts.map((relatedProduct) => {
|
||||
return (
|
||||
<div
|
||||
key={relatedProduct.id}
|
||||
className="rounded-lg border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-black"
|
||||
>
|
||||
<img
|
||||
src={relatedProduct.images?.[0].src}
|
||||
alt={relatedProduct.name}
|
||||
className="h-48 w-full object-cover"
|
||||
/>
|
||||
<div className="p-4">
|
||||
<Link href={`/product/${relatedProduct.slug}`}>
|
||||
<h2 className="text-xl font-bold">{relatedProduct.name}</h2>
|
||||
</Link>
|
||||
<div dangerouslySetInnerHTML={{ __html: relatedProduct.short_description }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ProductProvider>
|
||||
);
|
||||
|
@ -1,7 +0,0 @@
|
||||
export default async function PersonalArea() {
|
||||
return (
|
||||
<section className="mt-4 grid max-w-screen-2xl gap-4 px-4 pb-4">
|
||||
<h1 className="text-2xl font-bold">Personal Area</h1>
|
||||
</section>
|
||||
);
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { CubeIcon, UserCircleIcon } from '@heroicons/react/24/outline';
|
||||
import { Avatar } from '@nextui-org/react';
|
||||
import LogoutButton from 'components/button/logout';
|
||||
import { Customer } from 'lib/woocomerce/models/customer';
|
||||
@ -39,15 +40,17 @@ export default function ProfileLayout({ children }: { children: React.ReactNode
|
||||
<span className="text-lg font-bold">{customer.last_name}</span>
|
||||
</div>
|
||||
<div className="flex-start mt-3 flex">
|
||||
<Link href={`/profile/area`}>
|
||||
<button type="button" className="w-full rounded-md py-3">
|
||||
<Link href={`/profile`} className="hover:text-indigo-500">
|
||||
<button type="button" className="flex flex-row items-center rounded-md py-3">
|
||||
<UserCircleIcon className="me-2 h-4" />
|
||||
Personal area
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex-start mt-3 flex">
|
||||
<Link href={`/profile/orders`}>
|
||||
<button type="button" className="w-full rounded-md py-3">
|
||||
<Link href={`/profile/orders`} className="hover:text-indigo-500">
|
||||
<button type="button" className="flex flex-row items-center rounded-md py-3">
|
||||
<CubeIcon className="me-2 h-4" />
|
||||
Orders
|
||||
</button>
|
||||
</Link>
|
||||
|
@ -1,7 +1,62 @@
|
||||
export default async function ProfilePage() {
|
||||
'use server';
|
||||
|
||||
import { authOptions } from 'lib/auth/config';
|
||||
import { woocommerce } from 'lib/woocomerce/woocommerce';
|
||||
import { getServerSession } from 'next-auth';
|
||||
|
||||
export default async function PersonalArea() {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.store_id) {
|
||||
return { status: 401, body: { error: 'User not logged' } };
|
||||
}
|
||||
|
||||
const customer = await woocommerce.get('customers', { id: session?.user.store_id });
|
||||
|
||||
return (
|
||||
<section className="mt-4 grid max-w-screen-2xl gap-4 px-4 pb-4">
|
||||
<h1 className="text-2xl font-bold">Personal Area</h1>
|
||||
<div className="flex flex-col">
|
||||
<label
|
||||
htmlFor="name"
|
||||
className="block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
First Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
className="mt-1 block w-full rounded-md border-gray-300 py-3 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-lg"
|
||||
value={customer.first_name}
|
||||
disabled
|
||||
/>
|
||||
<label
|
||||
htmlFor="last_name"
|
||||
className="mt-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
Last Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="last_name"
|
||||
className="mt-1 block w-full rounded-md border-gray-300 py-3 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-lg"
|
||||
value={customer.last_name}
|
||||
disabled
|
||||
/>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="mt-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
className="mt-1 block w-full rounded-md border-gray-300 py-3 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-lg"
|
||||
value={customer.email}
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
import { ArrowRightEndOnRectangleIcon } from '@heroicons/react/24/outline';
|
||||
import { signOut } from 'next-auth/react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
@ -7,11 +8,12 @@ export default function LogoutButton() {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-md py-3"
|
||||
className="flex flex-row items-center rounded-md py-3 hover:text-indigo-500"
|
||||
onClick={() => {
|
||||
signOut({ callbackUrl: '/' });
|
||||
}}
|
||||
>
|
||||
<ArrowRightEndOnRectangleIcon className="me-2 h-4" />
|
||||
Logout
|
||||
</button>
|
||||
);
|
||||
|
@ -4,6 +4,7 @@ import { PlusIcon } from '@heroicons/react/24/outline';
|
||||
import clsx from 'clsx';
|
||||
import { useProduct } from 'components/product/product-context';
|
||||
import { Product, ProductVariations } from 'lib/woocomerce/models/product';
|
||||
import { toast } from 'sonner';
|
||||
import { useCart } from './cart-context';
|
||||
|
||||
function SubmitButton({ disabled = false }: { disabled: boolean }) {
|
||||
@ -50,6 +51,7 @@ export function AddToCart({
|
||||
})
|
||||
).json();
|
||||
setNewCart(cart);
|
||||
toast('Item added to cart');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
@ -89,7 +89,12 @@ export default function CartModal() {
|
||||
key={i}
|
||||
className="flex w-full flex-col border-b border-neutral-300 dark:border-neutral-700"
|
||||
>
|
||||
<CartItemView item={item} editable={true} closeCart={closeCart} />
|
||||
<CartItemView
|
||||
item={item}
|
||||
editable={true}
|
||||
deletable={true}
|
||||
closeCart={closeCart}
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { storeApi } from 'lib/woocomerce/storeApi';
|
||||
import { woocommerce } from 'lib/woocomerce/woocommerce';
|
||||
import { wordpress } from 'lib/wordpress/wordpress';
|
||||
import { NextAuthOptions, Session, User } from 'next-auth';
|
||||
import { JWT } from 'next-auth/jwt';
|
||||
import CredentialsProvider from 'next-auth/providers/credentials';
|
||||
@ -20,11 +20,13 @@ export const authOptions = {
|
||||
if (!credentials?.username || !credentials?.password) {
|
||||
return null;
|
||||
}
|
||||
const user = await woocommerce.login(credentials.username, credentials.password);
|
||||
const user = await wordpress.login(credentials.username, credentials.password);
|
||||
// If no error and we have user data, return it
|
||||
if (user) {
|
||||
return user;
|
||||
}
|
||||
storeApi._seCartToken('');
|
||||
storeApi._setAuthorizationToken('');
|
||||
// Return null if user data could not be retrieved
|
||||
return null;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ export type WooRestApiParams = CouponsParams &
|
||||
type WooCommerceResponse<
|
||||
T extends WooRestApiEndpoint,
|
||||
P extends Partial<WooRestApiParams> = {}
|
||||
> = P['id'] extends number | string // Verifica se `id` è definito e di tipo string
|
||||
> = P['id'] extends number | string
|
||||
? T extends 'products'
|
||||
? Product
|
||||
: T extends 'customers'
|
||||
@ -115,10 +115,6 @@ export default class WooCommerceRestApi<T extends WooRestApiOptions> {
|
||||
this._opt.classVersion = '0.0.2';
|
||||
}
|
||||
|
||||
login(username: string, password: string): Promise<any> {
|
||||
return this._request('POST', 'token', { username, password }, {}, 'jwt-auth/v1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse params to object.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user