summaryrefslogtreecommitdiff
path: root/src/frontend/components/ProductCard
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/components/ProductCard')
-rw-r--r--src/frontend/components/ProductCard/ProductCard.styled.ts36
-rw-r--r--src/frontend/components/ProductCard/ProductCard.tsx65
-rw-r--r--src/frontend/components/ProductCard/index.ts4
3 files changed, 105 insertions, 0 deletions
diff --git a/src/frontend/components/ProductCard/ProductCard.styled.ts b/src/frontend/components/ProductCard/ProductCard.styled.ts
new file mode 100644
index 0000000..50d2f7a
--- /dev/null
+++ b/src/frontend/components/ProductCard/ProductCard.styled.ts
@@ -0,0 +1,36 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+import styled from 'styled-components';
+import RouterLink from 'next/link';
+
+export const Link = styled(RouterLink)`
+ text-decoration: none;
+`;
+
+export const Image = styled.div<{ $src: string }>`
+ width: 100%;
+ height: 150px;
+ background: url(${({ $src }) => $src}) no-repeat center;
+ background-size: 100% auto;
+
+ ${({ theme }) => theme.breakpoints.desktop} {
+ height: 300px;
+ }
+`;
+
+export const ProductCard = styled.div`
+ cursor: pointer;
+`;
+
+export const ProductName = styled.p`
+ margin: 0;
+ margin-top: 10px;
+ font-size: ${({ theme }) => theme.sizes.dSmall};
+`;
+
+export const ProductPrice = styled.p`
+ margin: 0;
+ font-size: ${({ theme }) => theme.sizes.dMedium};
+ font-weight: ${({ theme }) => theme.fonts.bold};
+`;
diff --git a/src/frontend/components/ProductCard/ProductCard.tsx b/src/frontend/components/ProductCard/ProductCard.tsx
new file mode 100644
index 0000000..0744e21
--- /dev/null
+++ b/src/frontend/components/ProductCard/ProductCard.tsx
@@ -0,0 +1,65 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+import { CypressFields } from '../../utils/enums/CypressFields';
+import { Product } from '../../protos/demo';
+import ProductPrice from '../ProductPrice';
+import * as S from './ProductCard.styled';
+import { useState, useEffect } from 'react';
+import { useNumberFlagValue } from '@openfeature/react-sdk';
+
+interface IProps {
+ product: Product;
+}
+
+async function getImageWithHeaders(requestInfo: Request) {
+ const res = await fetch(requestInfo);
+ return await res.blob();
+}
+
+const ProductCard = ({
+ product: {
+ id,
+ picture,
+ name,
+ priceUsd = {
+ currencyCode: 'USD',
+ units: 0,
+ nanos: 0,
+ },
+ },
+}: IProps) => {
+ const imageSlowLoad = useNumberFlagValue('imageSlowLoad', 0);
+ const [imageSrc, setImageSrc] = useState<string>('');
+
+ useEffect(() => {
+ const headers = new Headers();
+ headers.append('x-envoy-fault-delay-request', imageSlowLoad.toString());
+ headers.append('Cache-Control', 'no-cache')
+ const requestInit = {
+ method: "GET",
+ headers: headers
+ };
+ const image_url ='/images/products/' + picture
+ const requestInfo = new Request(image_url, requestInit);
+ getImageWithHeaders(requestInfo).then(blob => {
+ setImageSrc(URL.createObjectURL(blob));
+ });
+ }, [imageSlowLoad, picture]);
+
+ return (
+ <S.Link href={`/product/${id}`}>
+ <S.ProductCard data-cy={CypressFields.ProductCard}>
+ <S.Image $src={imageSrc} />
+ <div>
+ <S.ProductName>{name}</S.ProductName>
+ <S.ProductPrice>
+ <ProductPrice price={priceUsd} />
+ </S.ProductPrice>
+ </div>
+ </S.ProductCard>
+ </S.Link>
+ );
+};
+
+export default ProductCard;
diff --git a/src/frontend/components/ProductCard/index.ts b/src/frontend/components/ProductCard/index.ts
new file mode 100644
index 0000000..ba9de7a
--- /dev/null
+++ b/src/frontend/components/ProductCard/index.ts
@@ -0,0 +1,4 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+export { default } from './ProductCard';