From 82e03978b89938219958032efb1448cc76baa181 Mon Sep 17 00:00:00 2001
From: Saumit <justsaumit@protonmail.com>
Date: Sat, 27 Sep 2025 02:14:26 +0530
Subject: Initial snapshot - OpenTelemetry demo 2.1.3 -f

---
 .../components/ProductCard/ProductCard.tsx         | 102 +++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 src/react-native-app/components/ProductCard/ProductCard.tsx

(limited to 'src/react-native-app/components/ProductCard/ProductCard.tsx')

diff --git a/src/react-native-app/components/ProductCard/ProductCard.tsx b/src/react-native-app/components/ProductCard/ProductCard.tsx
new file mode 100644
index 0000000..d5bd301
--- /dev/null
+++ b/src/react-native-app/components/ProductCard/ProductCard.tsx
@@ -0,0 +1,102 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+/**
+ * Copied with modification from src/frontend/components/ProductCard/ProductCard.tsx
+ */
+import { Product } from "@/protos/demo";
+import { ThemedView } from "@/components/ThemedView";
+import { useState, useEffect, useMemo } from "react";
+import { Image, Pressable, StyleSheet } from "react-native";
+import { ThemedText } from "@/components/ThemedText";
+import { useThemeColor } from "@/hooks/useThemeColor";
+import getFrontendProxyURL from "@/utils/Settings";
+
+interface IProps {
+  product: Product;
+  onClickAdd: () => void;
+}
+
+async function getImageURL(picture: string) {
+  const proxyURL = await getFrontendProxyURL();
+  return `${proxyURL}/images/products/${picture}`;
+}
+
+const ProductCard = ({
+  product: {
+    picture,
+    name,
+    priceUsd = {
+      currencyCode: "USD",
+      units: 0,
+      nanos: 0,
+    },
+  },
+  onClickAdd,
+}: IProps) => {
+  const tint = useThemeColor({}, "tint");
+  const styles = useMemo(() => getStyles(tint), [tint]);
+  const [imageSrc, setImageSrc] = useState<string>("");
+
+  useEffect(() => {
+    getImageURL(picture)
+      .then(setImageSrc)
+      .catch((reason) => {
+        console.warn("Failed to get image URL: ", reason);
+      });
+  }, [picture]);
+
+  // TODO simplify react native demo for now by hard-coding the selected currency
+  const price = (priceUsd?.units + priceUsd?.nanos / 100000000).toFixed(2);
+
+  return (
+    <ThemedView style={styles.container}>
+      <ThemedView>
+        {imageSrc && <Image style={styles.image} source={{ uri: imageSrc }} />}
+      </ThemedView>
+      <ThemedView style={styles.productInfo}>
+        <ThemedText style={styles.name}>{name}</ThemedText>
+        <ThemedText style={styles.price}>$ {price}</ThemedText>
+        <Pressable style={styles.add} onPress={onClickAdd}>
+          <ThemedText style={styles.addText}>Add to Cart</ThemedText>
+        </Pressable>
+      </ThemedView>
+    </ThemedView>
+  );
+};
+
+const getStyles = (tint: string) =>
+  StyleSheet.create({
+    container: {
+      display: "flex",
+      flexDirection: "row",
+      padding: 20,
+      marginLeft: 10,
+      marginRight: 10,
+      borderStyle: "solid",
+      borderBottomWidth: 1,
+      borderColor: tint,
+      gap: 30,
+    },
+    image: {
+      width: 100,
+      height: 100,
+    },
+    productInfo: {
+      flexShrink: 1,
+    },
+    name: {},
+    price: {
+      fontWeight: "bold",
+    },
+    add: {
+      borderRadius: 4,
+      backgroundColor: "green",
+      alignItems: "center",
+      width: 100,
+    },
+    addText: {
+      color: "white",
+    },
+  });
+
+export default ProductCard;
-- 
cgit v1.2.3

