Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ the release.
([#2614](https://github.com/open-telemetry/opentelemetry-demo/pull/2614))
* [grafana] Update grafana version to 12.2.0
([#2615](https://github.com/open-telemetry/opentelemetry-demo/pull/2615))
* [frontend] Fix navigation and cart math
([#2660](https://github.com/open-telemetry/opentelemetry-demo/pull/2660))
* [chore] Upgrade OpenFeature and add fix deprecation warnings for dependency
injection
([#2644](https://github.com/open-telemetry/opentelemetry-demo/pull/2644))
Expand Down
31 changes: 26 additions & 5 deletions src/frontend/components/CartDropdown/CartDropdown.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ export const CartDropdown = styled.div`
width: 100%;
height: 100%;
max-height: 100%;
padding: 25px;
padding: 5px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: 24px;
background: ${({ theme }) => theme.colors.white};
z-index: 1000;
Expand All @@ -27,7 +27,7 @@ export const CartDropdown = styled.div`
width: 400px;
top: 95px;
right: 17px;
max-height: 650px;
max-height: 600px;
}
`;

Expand All @@ -43,7 +43,7 @@ export const Title = styled.h5`
export const ItemList = styled.div`
${({ theme }) => theme.breakpoints.desktop} {
max-height: 450px;
overflow-y: scroll;
overflow-y: auto;
}
`;

Expand All @@ -60,6 +60,7 @@ export const ItemImage = styled(Image).attrs({
height: '80',
})`
border-radius: 5px;
object-fit: contain;
`;

export const ItemName = styled.p`
Expand All @@ -80,10 +81,29 @@ export const ItemQuantity = styled(ItemName)`

export const CartButton = styled(Button)``;

export const ContentWrapper = styled.div`
width: 100%;
overflow-y: auto;
flex: 1;
min-height: 0;

${({ theme }) => theme.breakpoints.desktop} {
overflow-y: visible;
flex: 0 1 auto;
min-height: auto;
}
`;

export const Header = styled.div`
display: flex;
justify-content: space-between;
justify-content: center;
align-items: center;
width: 100%;

span {
position: absolute;
right: 25px;
}

${({ theme }) => theme.breakpoints.desktop} {
span {
Expand All @@ -97,4 +117,5 @@ export const EmptyCart = styled.h3`
margin-top: 25px;
font-size: ${({ theme }) => theme.sizes.mLarge};
color: ${({ theme }) => theme.colors.textLightGray};
text-align: center;
`;
4 changes: 2 additions & 2 deletions src/frontend/components/CartDropdown/CartDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const CartDropdown = ({ productList, isOpen, onClose }: IProps) => {

return isOpen ? (
<S.CartDropdown ref={ref} data-cy={CypressFields.CartDropdown}>
<div>
<S.ContentWrapper>
<S.Header>
<S.Title>Shopping Cart</S.Title>
<span onClick={onClose}>Close</span>
Expand All @@ -54,7 +54,7 @@ const CartDropdown = ({ productList, isOpen, onClose }: IProps) => {
)
)}
</S.ItemList>
</div>
</S.ContentWrapper>
<Link href="/cart">
<S.CartButton data-cy={CypressFields.CartGoToShopping}>Go to Shopping Cart</S.CartButton>
</Link>
Expand Down
1 change: 1 addition & 0 deletions src/frontend/components/CartItems/CartItems.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const CartItemImage = styled.img`
width: 100%;
height: auto;
border-radius: 5px;
object-fit: contain;

${({ theme }) => theme.breakpoints.desktop} {
width: 120px;
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/components/CartItems/CartItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ const CartItems = ({ productList, shouldShowPrice = true }: IProps) => {

const total = useMemo<Money>(() => {
const nanoSum =
productList.reduce((acc, { product: { priceUsd: { nanos = 0 } = {} } }) => acc + Number(nanos), 0) +
productList.reduce((acc, { product: { priceUsd: { nanos = 0 } = {} }, quantity }) => acc + Number(nanos) * quantity, 0) +
shippingConst?.nanos || 0;
const nanoExceed = Math.floor(nanoSum / 1000000000);

const unitSum =
productList.reduce((acc, { product: { priceUsd: { units = 0 } = {} } }) => acc + Number(units), 0) +
productList.reduce((acc, { product: { priceUsd: { units = 0 } = {} }, quantity }) => acc + Number(units) * quantity, 0) +
(shippingConst?.units || 0) + nanoExceed;

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export const ItemImage = styled(Image).attrs({
height: '80',
})`
border-radius: 5px;
object-fit: contain;
`;

export const SeeMore = styled.a`
Expand Down
2 changes: 2 additions & 0 deletions src/frontend/components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import Header from '../Header';
import Footer from '../Footer';

interface IProps {
children: React.ReactNode;
Expand All @@ -12,6 +13,7 @@ const Layout = ({ children }: IProps) => {
<>
<Header />
<main>{children}</main>
<Footer />
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const Image = styled.div<{ $src: string }>`
width: 100%;
height: 150px;
background: url(${({ $src }) => $src}) no-repeat center;
background-size: 100% auto;
background-size: contain;

${({ theme }) => theme.breakpoints.desktop} {
height: 300px;
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/components/Recommendations/Recommendations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import * as S from './Recommendations.styled';
const Recommendations = () => {
const { recommendedProductList } = useAd();

if (!recommendedProductList || recommendedProductList.length === 0) {
return null;
}

return (
<S.Recommendations data-cy={CypressFields.RecommendationList}>
<S.TitleContainer>
Expand Down
97 changes: 81 additions & 16 deletions src/frontend/pages/cart/checkout/[orderId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,39 @@ import { NextPage } from 'next';
import Head from 'next/head';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useMemo } from 'react';
import Ad from '../../../../components/Ad';
import Button from '../../../../components/Button';
import CheckoutItem from '../../../../components/CheckoutItem';
import Footer from '../../../../components/Footer';
import Layout from '../../../../components/Layout';
import ProductPrice from '../../../../components/ProductPrice';
import Recommendations from '../../../../components/Recommendations';
import AdProvider from '../../../../providers/Ad.provider';
import { Money } from '../../../../protos/demo';
import * as S from '../../../../styles/Checkout.styled';
import { IProductCheckout } from '../../../../types/Cart';

const Checkout: NextPage = () => {
const { query } = useRouter();
const { items = [], shippingAddress } = JSON.parse((query.order || '{}') as string) as IProductCheckout;
const { orderId, items = [], shippingAddress, shippingCost = { units: 0, currencyCode: 'USD', nanos: 0 } } = JSON.parse((query.order || '{}') as string) as IProductCheckout;

const orderTotal = useMemo<Money>(() => {
const itemsTotal = items.reduce((acc, { cost = { units: 0, nanos: 0, currencyCode: 'USD' } }) => {
return {
units: acc.units + (cost.units || 0),
nanos: acc.nanos + (cost.nanos || 0),
currencyCode: cost.currencyCode || 'USD',
};
}, { units: 0, nanos: 0, currencyCode: 'USD' });

const totalNanos = itemsTotal.nanos + (shippingCost.nanos || 0);
const nanoExceed = Math.floor(totalNanos / 1000000000);

return {
units: itemsTotal.units + (shippingCost.units || 0) + nanoExceed,
nanos: totalNanos % 1000000000,
currencyCode: shippingCost.currencyCode || 'USD',
};
}, [items, shippingCost]);

return (
<AdProvider
Expand All @@ -30,18 +50,64 @@ const Checkout: NextPage = () => {
<Layout>
<S.Checkout>
<S.Container>
<S.Title>Your order is complete!</S.Title>
<S.Subtitle>We&apos;ve sent you a confirmation email.</S.Subtitle>

<S.ItemList>
{items.map(checkoutItem => (
<CheckoutItem
key={checkoutItem.item.productId}
checkoutItem={checkoutItem}
address={shippingAddress}
/>
))}
</S.ItemList>
<S.LeftColumn>
<S.Title>Your order is complete!</S.Title>
<S.Subtitle>We&apos;ve sent you a confirmation email.</S.Subtitle>
<S.OrderInfo>
<S.InfoLabel>Order ID:</S.InfoLabel>
<S.InfoValue>{orderId}</S.InfoValue>
</S.OrderInfo>
</S.LeftColumn>

<S.RightColumn>
<S.SectionTitle>Shipping Address</S.SectionTitle>
<S.AddressText>{shippingAddress.streetAddress}</S.AddressText>
<S.AddressText>{shippingAddress.city}, {shippingAddress.state} {shippingAddress.zipCode}</S.AddressText>
<S.AddressText>{shippingAddress.country}</S.AddressText>
</S.RightColumn>

<S.ItemsSection>
<S.SectionTitle>Order Items</S.SectionTitle>
<S.ItemList>
{items.map(({ item, cost = { units: 0, currencyCode: 'USD', nanos: 0 } }) => {
const itemTotal: Money = {
units: (cost.units || 0) * item.quantity,
nanos: (cost.nanos || 0) * item.quantity,
currencyCode: cost.currencyCode || 'USD',
};
// Handle nanos overflow
const nanoExceed = Math.floor(itemTotal.nanos / 1000000000);
itemTotal.units += nanoExceed;
itemTotal.nanos = itemTotal.nanos % 1000000000;

return (
<S.OrderItem key={item.productId}>
<S.ItemImage src={"/images/products/" + item.product.picture} alt={item.product.name}/>
<S.ItemDetails>
<S.ItemName>{item.product.name}</S.ItemName>
<S.ItemQuantity>Quantity: {item.quantity}</S.ItemQuantity>
</S.ItemDetails>
<S.ItemPrice>
<ProductPrice price={itemTotal} />
</S.ItemPrice>
</S.OrderItem>
);
})}
</S.ItemList>

<S.OrderSummary>
<S.SummaryRow>
<span>Shipping:</span>
<ProductPrice price={shippingCost} />
</S.SummaryRow>
<S.TotalRow>
<S.TotalLabel>Total:</S.TotalLabel>
<S.TotalAmount>
<ProductPrice price={orderTotal} />
</S.TotalAmount>
</S.TotalRow>
</S.OrderSummary>
</S.ItemsSection>

<S.ButtonContainer>
<Link href="/">
Expand All @@ -52,7 +118,6 @@ const Checkout: NextPage = () => {
<Recommendations />
</S.Checkout>
<Ad />
<Footer />
</Layout>
</AdProvider>
);
Expand Down
2 changes: 0 additions & 2 deletions src/frontend/pages/cart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import { NextPage } from 'next';
import Head from 'next/head';
import Footer from '../../components/Footer';
import Layout from '../../components/Layout';
import Recommendations from '../../components/Recommendations';
import * as S from '../../styles/Cart.styled';
Expand All @@ -30,7 +29,6 @@ const Cart: NextPage = () => {
{(!!items.length && <CartDetail />) || <EmptyCart />}
<Recommendations />
</S.Cart>
<Footer />
</Layout>
</AdProvider>
);
Expand Down
2 changes: 0 additions & 2 deletions src/frontend/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import { NextPage } from 'next';
import Head from 'next/head';
import Footer from '../components/Footer';
import Layout from '../components/Layout';
import ProductList from '../components/ProductList';
import * as S from '../styles/Home.styled';
Expand Down Expand Up @@ -39,7 +38,6 @@ const Home: NextPage = () => {
</S.Content>
</S.Row>
</S.Container>
<Footer />
</S.Home>
</Layout>
);
Expand Down
2 changes: 0 additions & 2 deletions src/frontend/pages/product/[productId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { useRouter } from 'next/router';
import { useCallback, useState, useEffect } from 'react';
import { useQuery } from '@tanstack/react-query';
import Ad from '../../../components/Ad';
import Footer from '../../../components/Footer';
import Layout from '../../../components/Layout';
import ProductPrice from '../../../components/ProductPrice';
import Recommendations from '../../../components/Recommendations';
Expand Down Expand Up @@ -98,7 +97,6 @@ const ProductDetail: NextPage = () => {
<Recommendations />
</S.ProductDetail>
<Ad />
<Footer />
</Layout>
</AdProvider>
);
Expand Down
Loading
Loading