Skip to content

Commit

Permalink
add skeleton pages/endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
spencerlepine committed Sep 21, 2024
1 parent 5e20a21 commit c4a6044
Show file tree
Hide file tree
Showing 21 changed files with 242 additions and 57 deletions.
3 changes: 2 additions & 1 deletion src/app/api/auth/[auth0]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
// source: https://auth0.com/docs/quickstart/webapp/nextjs/interactive
import { handleAuth } from '@auth0/nextjs-auth0';

export const GET = handleAuth();
export const GET = handleAuth();
export const POST = handleAuth(); // work-around for AddToCart
10 changes: 0 additions & 10 deletions src/app/api/ping-protected/route.ts

This file was deleted.

7 changes: 0 additions & 7 deletions src/app/api/ping/route.ts

This file was deleted.

12 changes: 12 additions & 0 deletions src/app/api/v1/cart/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { NextResponse } from 'next/server';
import { getSession, withApiAuthRequired } from '@auth0/nextjs-auth0'

export const POST = withApiAuthRequired(async () => {
const session = await getSession();
const userId = session.user.sid; // Auth0 userId

// TODO

const res = new NextResponse();
return NextResponse.json({ message: `Added to cart - TODO` }, res);
});
31 changes: 31 additions & 0 deletions src/app/cart/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { DUMMY_CART, DUMMY_PRODUCTS } from '@/demoData';
import { CartPageItem } from '@/types';

const CartItemCard: React.FC<CartPageItem> = ({ productSlug, size, quantity, title }) => (
<li key={productSlug}>
<h4>{title}</h4>
<p>{size}</p>
<p>{quantity}</p>
</li>
);

export default async function CartPage() {
const cartItems: CartPageItem[] = DUMMY_CART.map(cartItem => ({
...cartItem,
...DUMMY_PRODUCTS.find(product => product.slug === cartItem.productSlug),
}));

return (
<div>
<h2>Cart</h2>
<button>Checkout</button>
{cartItems && cartItems.length > 0 && (
<ul>
{cartItems.map(cartItem => (
<CartItemCard key={cartItem.productSlug} {...cartItem} />
))}
</ul>
)}
</div>
);
}
7 changes: 7 additions & 0 deletions src/app/contact/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default async function ContactPage() {
return (
<div>
<h2>TODO</h2>
</div>
);
}
7 changes: 7 additions & 0 deletions src/app/faq/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default async function FAQPage() {
return (
<div>
<h2>TODO</h2>
</div>
);
}
4 changes: 3 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Metadata } from 'next';
import { UserProvider } from '@auth0/nextjs-auth0/client';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
import localFont from 'next/font/local';
import './globals.css';

Expand Down Expand Up @@ -30,7 +31,8 @@ export default function RootLayout({
<UserProvider>
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
<Header />
{children}
<main className="font-[family-name:var(--font-geist-sans)]">{children}</main>
<Footer />
</body>
</UserProvider>
</html>
Expand Down
28 changes: 18 additions & 10 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import Image from 'next/image';
import PingBtn from '@/components/PingBtn';
import React from 'react';
import CatalogFilters from '@/components/CatalogFilters';
import ProductCard from '@/components/ProductCard';
import { DUMMY_PRODUCTS } from '@/demoData';
import { Product } from '@/types';

export default function LandingPage() {
const ITEMS_PER_PAGE_LIMIT = 25;
const catalogProducts: Product[] = DUMMY_PRODUCTS.slice(0, ITEMS_PER_PAGE_LIMIT);

return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
<Image className="dark:invert" src="https://nextjs.org/icons/next.svg" alt="Next.js logo" width={180} height={38} priority />
<>
<CatalogFilters />

<PingBtn endpoint="/api/ping" title="Ping" />
<PingBtn endpoint="/api/ping-protected" title="Ping [protected]" />
<p>secret: {process.env.MY_SECRET_VALUE}</p>
</main>
</div>
{catalogProducts && catalogProducts.length > 0 && (
<div className="">
{catalogProducts.map(product => (
<ProductCard key={product.slug} {...product} />
))}
</div>
)}
</>
);
}
7 changes: 7 additions & 0 deletions src/app/privacy/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default async function PrivacyPage() {
return (
<div>
<h2>TODO</h2>
</div>
);
}
7 changes: 7 additions & 0 deletions src/app/product/[productSlug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default async function ProductPage() {
return (
<div>
<h2>TODO</h2>
</div>
);
}
36 changes: 36 additions & 0 deletions src/components/AddToCartBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use client';

import React from 'react';
// import { useRouter } from 'next/navigation';

const AddToCartBtn: React.FC<{ productSlug: string; size: string }> = ({ productSlug, size }) => {
// const router = useRouter();

const handleAddtoCart = async () => {
alert('Added to cart!');

// TODO
// try {
// const data = await fetch('/api/v1/cart', {
// method: 'POST',
// body: {
// productSlug: productSlug,
// size: size,
// },
// });
// const response = await data.json();
// if (response.status !== 200) {
// return router.push('/api/auth/login');
// }
// const { message } = response;
// console.log('POST /cart', response);
// alert(message);
// } catch (err: unknown) {
// alert('Requested failed, check the console.');
// console.error(err);
// }
};
return <button onClick={handleAddtoCart}>Add to Cart</button>;
};

export default AddToCartBtn;
11 changes: 11 additions & 0 deletions src/components/CatalogFilters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

const CatalogFilters: React.FC = () => {
return (
<main>
<p>TODO</p>
</main>
);
};

export default CatalogFilters;
15 changes: 15 additions & 0 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

const Footer: React.FC = () => {
return (
<footer>
<p>English (US) | $ (USD)</p>
<p>© 2024 SwagSticker</p>
<a href="/contact">Contact</a>
<a href="/faq">FAQ</a>
<a href="/privacy">Privacy</a>
</footer>
);
};

export default Footer;
6 changes: 5 additions & 1 deletion src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ const Header: React.FC = () => {
return (
<header>
<a href="/">SwagSticker</a>
{user ? <a href="/account">Account</a> : <a href="/api/auth/login">Login</a>}
<div>
<p>Searchbar</p>
</div>
{user ? <a href="/account">Account</a> : <a href="/api/auth/login">Sign in</a>}
<a href="/cart">Cart</a>
</header>
);
};
Expand Down
11 changes: 11 additions & 0 deletions src/components/PaymentInfoForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

const PaymentInfoForm: React.FC = () => {
return (
<main>
<p>TODO</p>
</main>
);
};

export default PaymentInfoForm;
27 changes: 0 additions & 27 deletions src/components/PingBtn.tsx

This file was deleted.

20 changes: 20 additions & 0 deletions src/components/ProductCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import Product from '@/types/Product';
import AddToCartBtn from './AddToCartBtn';
import Image from 'next/image';

const ProductCard: React.FC<Product> = props => {
const { slug, title, thumbnailUrl, price, sizes } = props;
return (
<div>
<a href={`/product/${slug}`}>
<p>{title}</p>
<Image alt={title} src={thumbnailUrl} width={100} height={100} />
<p>${price}</p>
</a>
<AddToCartBtn productSlug={slug} size={sizes[0]} />
</div>
);
};

export default ProductCard;
11 changes: 11 additions & 0 deletions src/components/ShippingInfoForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

const ShippingInfoForm: React.FC = () => {
return (
<main>
<p>TODO</p>
</main>
);
};

export default ShippingInfoForm;
23 changes: 23 additions & 0 deletions src/demoData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { CartItem, Product } from "./types";

export const DUMMY_PRODUCTS: Product[] = [
{
slug: 'amazon-web-services',
title: 'Amazon Web Services Sticker',
description: 'Amazon Web Services logo sticker for laptops.',
thumbnailUrl: 'next.svg', // public/next.svg
price: 2.3,
sizes: ['2x2 in', '3x3 in', '4x4 in'],
},
{
slug: 'github-octocat',
title: 'GitHub Octocat Sticker',
description: 'GitHub Octocat logo sticker for laptops.',
thumbnailUrl: 'next.svg', // public/next.svg
price: 2.4,
sizes: ['2x2 in', '3x3 in', '4x4 in'],
},
];

// Queried from CartItems DB
export const DUMMY_CART: CartItem[] = [{ productSlug: 'github-octocat', size: '2x2 in', quantity: 1 }];
16 changes: 16 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export type Product = {
slug: string;
title: string;
description: string;
thumbnailUrl: string;
price: number;
sizes: string[];
};

export type CartItem = {
productSlug: string;
size: string;
quantity: number;
};

export type CartPageItem = CartItem & Product;

0 comments on commit c4a6044

Please sign in to comment.