summaryrefslogtreecommitdiff
path: root/src/frontend/providers
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/providers')
-rw-r--r--src/frontend/providers/Ad.provider.tsx58
-rw-r--r--src/frontend/providers/Cart.provider.tsx77
-rw-r--r--src/frontend/providers/Currency.provider.tsx59
3 files changed, 194 insertions, 0 deletions
diff --git a/src/frontend/providers/Ad.provider.tsx b/src/frontend/providers/Ad.provider.tsx
new file mode 100644
index 0000000..0b03f43
--- /dev/null
+++ b/src/frontend/providers/Ad.provider.tsx
@@ -0,0 +1,58 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+import { createContext, useContext, useMemo } from 'react';
+import { useQuery } from '@tanstack/react-query';
+import ApiGateway from '../gateways/Api.gateway';
+import { Ad, Money, Product } from '../protos/demo';
+import { useCurrency } from './Currency.provider';
+
+interface IContext {
+ recommendedProductList: Product[];
+ adList: Ad[];
+}
+
+export const Context = createContext<IContext>({
+ recommendedProductList: [],
+ adList: [],
+});
+
+interface IProps {
+ children: React.ReactNode;
+ productIds: string[];
+ contextKeys: string[];
+}
+
+export const useAd = () => useContext(Context);
+
+const AdProvider = ({ children, productIds, contextKeys }: IProps) => {
+ const { selectedCurrency } = useCurrency();
+ const { data: adList = [] } = useQuery({
+ queryKey: ['ads', contextKeys],
+ queryFn: async () => {
+ if (contextKeys.length === 0) {
+ return [];
+ } else {
+ return ApiGateway.listAds(contextKeys);
+ }
+ },
+ refetchOnWindowFocus: false,
+ });
+ const { data: recommendedProductList = [] } = useQuery({
+ queryKey: ['recommendations', productIds, 'selectedCurrency', selectedCurrency],
+ queryFn: () => ApiGateway.listRecommendations(productIds, selectedCurrency),
+ refetchOnWindowFocus: false,
+ });
+
+ const value = useMemo(
+ () => ({
+ adList,
+ recommendedProductList,
+ }),
+ [adList, recommendedProductList]
+ );
+
+ return <Context.Provider value={value}>{children}</Context.Provider>;
+};
+
+export default AdProvider;
diff --git a/src/frontend/providers/Cart.provider.tsx b/src/frontend/providers/Cart.provider.tsx
new file mode 100644
index 0000000..40cea7f
--- /dev/null
+++ b/src/frontend/providers/Cart.provider.tsx
@@ -0,0 +1,77 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+import { createContext, useCallback, useContext, useMemo } from 'react';
+import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
+import ApiGateway from '../gateways/Api.gateway';
+import { CartItem, OrderResult, PlaceOrderRequest } from '../protos/demo';
+import { IProductCart } from '../types/Cart';
+import { useCurrency } from './Currency.provider';
+
+interface IContext {
+ cart: IProductCart;
+ addItem(item: CartItem): void;
+ emptyCart(): void;
+ placeOrder(order: PlaceOrderRequest): Promise<OrderResult>;
+}
+
+export const Context = createContext<IContext>({
+ cart: { userId: '', items: [] },
+ addItem: () => {},
+ emptyCart: () => {},
+ placeOrder: () => Promise.resolve({} as OrderResult),
+});
+
+interface IProps {
+ children: React.ReactNode;
+}
+
+export const useCart = () => useContext(Context);
+
+const CartProvider = ({ children }: IProps) => {
+ const { selectedCurrency } = useCurrency();
+ const queryClient = useQueryClient();
+ const mutationOptions = useMemo(
+ () => ({
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['cart'] });
+ },
+ }),
+ [queryClient]
+ );
+
+ const { data: cart = { userId: '', items: [] } } = useQuery({
+ queryKey: ['cart', selectedCurrency],
+ queryFn: () => ApiGateway.getCart(selectedCurrency),
+ });
+ const addCartMutation = useMutation({
+ mutationFn: ApiGateway.addCartItem,
+ ...mutationOptions,
+ });
+
+ const emptyCartMutation = useMutation({
+ mutationFn: ApiGateway.emptyCart,
+ ...mutationOptions,
+ });
+
+ const placeOrderMutation = useMutation({
+ mutationFn: ApiGateway.placeOrder,
+ ...mutationOptions,
+ });
+
+ const addItem = useCallback(
+ (item: CartItem) => addCartMutation.mutateAsync({ ...item, currencyCode: selectedCurrency }),
+ [addCartMutation, selectedCurrency]
+ );
+ const emptyCart = useCallback(() => emptyCartMutation.mutateAsync(), [emptyCartMutation]);
+ const placeOrder = useCallback(
+ (order: PlaceOrderRequest) => placeOrderMutation.mutateAsync({ ...order, currencyCode: selectedCurrency }),
+ [placeOrderMutation, selectedCurrency]
+ );
+
+ const value = useMemo(() => ({ cart, addItem, emptyCart, placeOrder }), [cart, addItem, emptyCart, placeOrder]);
+
+ return <Context.Provider value={value}>{children}</Context.Provider>;
+};
+
+export default CartProvider;
diff --git a/src/frontend/providers/Currency.provider.tsx b/src/frontend/providers/Currency.provider.tsx
new file mode 100644
index 0000000..1df16ca
--- /dev/null
+++ b/src/frontend/providers/Currency.provider.tsx
@@ -0,0 +1,59 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+import { createContext, useCallback, useContext, useMemo, useState, useEffect } from 'react';
+import { useQuery } from '@tanstack/react-query';
+import ApiGateway from '../gateways/Api.gateway';
+import SessionGateway from '../gateways/Session.gateway';
+
+const { currencyCode } = SessionGateway.getSession();
+
+interface IContext {
+ currencyCodeList: string[];
+ setSelectedCurrency(currency: string): void;
+ selectedCurrency: string;
+}
+
+export const Context = createContext<IContext>({
+ currencyCodeList: [],
+ selectedCurrency: 'USD',
+ setSelectedCurrency: () => ({}),
+});
+
+interface IProps {
+ children: React.ReactNode;
+}
+
+export const useCurrency = () => useContext(Context);
+
+const CurrencyProvider = ({ children }: IProps) => {
+ const { data: currencyCodeListUnsorted = [] } = useQuery({
+ queryKey: ['currency'],
+ queryFn: ApiGateway.getSupportedCurrencyList
+ });
+ const [selectedCurrency, setSelectedCurrency] = useState<string>('');
+
+ useEffect(() => {
+ setSelectedCurrency(currencyCode);
+ }, []);
+
+ const onSelectCurrency = useCallback((currencyCode: string) => {
+ setSelectedCurrency(currencyCode);
+ SessionGateway.setSessionValue('currencyCode', currencyCode);
+ }, []);
+
+ const currencyCodeList = currencyCodeListUnsorted.sort();
+
+ const value = useMemo(
+ () => ({
+ currencyCodeList,
+ selectedCurrency,
+ setSelectedCurrency: onSelectCurrency,
+ }),
+ [currencyCodeList, selectedCurrency, onSelectCurrency]
+ );
+
+ return <Context.Provider value={value}>{children}</Context.Provider>;
+};
+
+export default CurrencyProvider;