setActiveStep(ActiveStep.OFFER_VIEW)}
+ onClickDone={() => hideModal?.()}
+ onExchangePolicyClick={() =>
+ setActiveStep(ActiveStep.EXCHANGE_POLICY)
+ }
+ exchangeId={exchange?.id || ""}
+ />
+ ) : (
+ Wrong step...something went wrong
+ )}
+ >
+ );
+}
diff --git a/packages/react-kit/src/components/modal/components/Commit/CommitSuccess.tsx b/packages/react-kit/src/components/modal/components/Commit/CommitSuccess.tsx
new file mode 100644
index 000000000..bdcb74b62
--- /dev/null
+++ b/packages/react-kit/src/components/modal/components/Commit/CommitSuccess.tsx
@@ -0,0 +1,162 @@
+import { CheckCircle, Fire, House } from "phosphor-react";
+import React, { useEffect } from "react";
+import styled from "styled-components";
+import { getOfferDetails } from "../../../../lib/offer/getOfferDetails";
+import Grid from "../../../ui/Grid";
+import IpfsImage from "../../../ui/IpfsImage";
+import Loading from "../../../ui/loading/Loading";
+import Typography from "../../../ui/Typography";
+import { theme } from "../../../../theme";
+import Video from "../../../ui/Video";
+import { Button } from "../../../buttons/Button";
+import GridContainer from "../../../ui/GridContainer";
+import { useNonModalContext } from "../../nonModal/NonModal";
+import { useExchanges } from "../../../../hooks/useExchanges";
+import DetailOpenSea from "../common/DetailOpenSea";
+
+const colors = theme.colors.light;
+
+const ImageWrapper = styled.div`
+ position: relative;
+ max-width: 35rem !important;
+ min-width: 50%;
+ width: -webkit-fill-available;
+`;
+
+type Props = {
+ onClickDone: () => void;
+ onHouseClick: () => void;
+ onExchangePolicyClick: () => void;
+ exchangeId: string;
+};
+
+export function CommitSuccess({
+ onClickDone,
+ onHouseClick,
+ exchangeId
+}: Props) {
+ const {
+ data: exchanges,
+ isError,
+ isFetching
+ } = useExchanges(
+ {
+ id: exchangeId
+ },
+ {
+ enabled: !!exchangeId
+ }
+ );
+ const exchange = exchanges?.[0];
+ const offer = exchange?.offer;
+
+ const offerDetails = offer ? getOfferDetails(offer) : undefined;
+ const dispatch = useNonModalContext();
+ useEffect(() => {
+ dispatch({
+ payload: {
+ headerComponent: (
+
+
+
+ Sucess!
+
+
+ ),
+ contentStyle: {
+ background: colors.lightGrey
+ }
+ }
+ });
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [dispatch]);
+ return (
+ <>
+ {isFetching ? (
+
+ ) : !offer ? (
+ This exchange does not exist
+ ) : isError || !exchangeId || !offerDetails ? (
+
+ There has been an error, please try again later...
+
+ ) : (
+
+
+ {offerDetails.animationUrl ? (
+
+
+
+
+
+
+ Congratulations!
+
+
+
+
+
+
+ What's next?
+ Redeem it!
+
+
+
+
+ You got an rNFT
+
+
+
+
+
+
+
+
+ )}
+ >
+ );
+}
diff --git a/packages/react-kit/src/components/modal/components/Commit/ContractualAgreementView/ContractualAgreementView.tsx b/packages/react-kit/src/components/modal/components/Commit/ContractualAgreementView/ContractualAgreementView.tsx
new file mode 100644
index 000000000..1c4a179c9
--- /dev/null
+++ b/packages/react-kit/src/components/modal/components/Commit/ContractualAgreementView/ContractualAgreementView.tsx
@@ -0,0 +1,48 @@
+import React, { useEffect } from "react";
+import Grid from "../../../../ui/Grid";
+import Typography from "../../../../ui/Typography";
+import { ArrowLeft } from "phosphor-react";
+import ContractualAgreement from "../../../../contractualAgreement/ContractualAgreement";
+import { useNonModalContext } from "../../../nonModal/NonModal";
+import { theme } from "../../../../../theme";
+import { Offer } from "../../../../../types/offer";
+
+const colors = theme.colors.light;
+interface Props {
+ onBackClick: () => void;
+ offer: Offer | null;
+}
+
+export function ContractualAgreementView({ onBackClick, offer }: Props) {
+ const offerId = offer?.id;
+ const dispatch = useNonModalContext();
+ useEffect(() => {
+ dispatch({
+ payload: {
+ headerComponent: (
+
+
+ Contractual Agreement
+
+ ),
+ contentStyle: {
+ background: colors.white
+ }
+ }
+ });
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [dispatch]);
+ return (
+ <>
+ {offer ? (
+
+ ) : (
+ Offer could not be retrieved
+ )}
+ >
+ );
+}
diff --git a/packages/react-kit/src/components/modal/components/Commit/LicenseAgreementView/LicenseAgreementView.tsx b/packages/react-kit/src/components/modal/components/Commit/LicenseAgreementView/LicenseAgreementView.tsx
new file mode 100644
index 000000000..1a6110515
--- /dev/null
+++ b/packages/react-kit/src/components/modal/components/Commit/LicenseAgreementView/LicenseAgreementView.tsx
@@ -0,0 +1,47 @@
+import React, { useEffect } from "react";
+import Grid from "../../../../ui/Grid";
+import Typography from "../../../../ui/Typography";
+import { ArrowLeft } from "phosphor-react";
+import { Exchange } from "../../../../../types/exchange";
+import License from "../../../../license/License";
+import { useNonModalContext } from "../../../nonModal/NonModal";
+import { theme } from "../../../../../theme";
+
+const colors = theme.colors.light;
+interface Props {
+ onBackClick: () => void;
+ offer: Exchange["offer"] | null;
+}
+
+export function LicenseAgreementView({ onBackClick, offer }: Props) {
+ const dispatch = useNonModalContext();
+ useEffect(() => {
+ dispatch({
+ payload: {
+ headerComponent: (
+
+
+ License Agreement
+
+ ),
+ contentStyle: {
+ background: colors.white
+ }
+ }
+ });
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [dispatch]);
+ return (
+ <>
+ {offer ? (
+
+ ) : (
+ Offer could not be retrieved
+ )}
+ >
+ );
+}
diff --git a/packages/react-kit/src/components/modal/components/Commit/OfferFullDescriptionView/OfferFullDescriptionView.tsx b/packages/react-kit/src/components/modal/components/Commit/OfferFullDescriptionView/OfferFullDescriptionView.tsx
new file mode 100644
index 000000000..65bd71ca3
--- /dev/null
+++ b/packages/react-kit/src/components/modal/components/Commit/OfferFullDescriptionView/OfferFullDescriptionView.tsx
@@ -0,0 +1,39 @@
+import React, { useEffect } from "react";
+import { theme } from "../../../../../theme";
+import { Offer } from "../../../../../types/offer";
+import { useNonModalContext } from "../../../nonModal/NonModal";
+import { OfferFullDescription } from "../../common/OfferFullDescription";
+import Grid from "../../../../ui/Grid";
+import { ArrowLeft } from "phosphor-react";
+import Typography from "../../../../ui/Typography";
+
+const colors = theme.colors.light;
+interface Props {
+ onBackClick: () => void;
+ offer: Offer;
+}
+
+export function OfferFullDescriptionView({ onBackClick, offer }: Props) {
+ const dispatch = useNonModalContext();
+ useEffect(() => {
+ dispatch({
+ payload: {
+ headerComponent: (
+
+
+ {offer.metadata.name || ""}
+
+ ),
+ contentStyle: {
+ background: colors.white
+ }
+ }
+ });
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [dispatch, offer.metadata.name]);
+ return ;
+}
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangePolicy/ExchangePolicy.tsx b/packages/react-kit/src/components/modal/components/Commit/OfferPolicyView/CommitOfferPolicyView.tsx
similarity index 70%
rename from packages/react-kit/src/components/modal/components/Redeem/ExchangePolicy/ExchangePolicy.tsx
rename to packages/react-kit/src/components/modal/components/Commit/OfferPolicyView/CommitOfferPolicyView.tsx
index 0d7b698b1..ef8fc8a01 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangePolicy/ExchangePolicy.tsx
+++ b/packages/react-kit/src/components/modal/components/Commit/OfferPolicyView/CommitOfferPolicyView.tsx
@@ -4,29 +4,29 @@ import Typography from "../../../../ui/Typography";
import { ArrowLeft } from "phosphor-react";
import { Exchange } from "../../../../../types/exchange";
import { offers } from "@bosonprotocol/core-sdk";
-import ExchangePolicyDetails, {
- ExchangePolicyDetailsProps
-} from "../../../../exchangePolicy/ExchangePolicyDetails";
+import OfferPolicyDetails, {
+ OfferPolicyDetailsProps
+} from "../../../../offerPolicy/OfferPolicyDetails";
import { useNonModalContext } from "../../../nonModal/NonModal";
import { theme } from "../../../../../theme";
const colors = theme.colors.light;
interface Props {
onBackClick: () => void;
- exchange: Exchange | null;
- onContractualAgreementClick: ExchangePolicyDetailsProps["onContractualAgreementClick"];
- onLicenseAgreementClick: ExchangePolicyDetailsProps["onLicenseAgreementClick"];
+ offer: Exchange["offer"] | null | undefined;
+ onContractualAgreementClick: OfferPolicyDetailsProps["onContractualAgreementClick"];
+ onLicenseAgreementClick: OfferPolicyDetailsProps["onLicenseAgreementClick"];
exchangePolicyCheckResult?: offers.CheckExchangePolicyResult;
}
-export function ExchangePolicy({
+export function CommitOfferPolicyView({
onBackClick,
- exchange,
+ offer,
onContractualAgreementClick,
onLicenseAgreementClick,
exchangePolicyCheckResult
}: Props) {
- const exchangeName = exchange?.offer.metadata.name || "";
+ const offerName = offer?.metadata.name || "";
const dispatch = useNonModalContext();
useEffect(() => {
dispatch({
@@ -39,7 +39,7 @@ export function ExchangePolicy({
style={{ cursor: "pointer", flexShrink: 0 }}
/>
- {exchangeName}
+ {offerName}
),
@@ -49,18 +49,18 @@ export function ExchangePolicy({
}
});
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [dispatch, exchangeName]);
+ }, [dispatch, offerName]);
return (
<>
- {exchange ? (
-
) : (
- Exchange could not be retrieved
+ Offer could not be retrieved
)}
>
);
diff --git a/packages/react-kit/src/components/modal/components/Commit/OfferVariantView.tsx b/packages/react-kit/src/components/modal/components/Commit/OfferVariantView.tsx
new file mode 100644
index 000000000..d75cf29c3
--- /dev/null
+++ b/packages/react-kit/src/components/modal/components/Commit/OfferVariantView.tsx
@@ -0,0 +1,182 @@
+import React, { useEffect, useMemo } from "react";
+import styled from "styled-components";
+import { VariantV1 } from "../../../../types/variants";
+import { theme } from "../../../../theme";
+import { useSellers } from "../../../../hooks/useSellers";
+import { getOfferDetails } from "../../../../lib/offer/getOfferDetails";
+import { isTruthy } from "../../../../types/helpers";
+import { useConvertionRate } from "../../../widgets/finance/convertion-rate/useConvertionRate";
+import useCheckExchangePolicy from "../../../../hooks/useCheckExchangePolicy";
+import { useNonModalContext } from "../../nonModal/NonModal";
+import Grid from "../../../ui/Grid";
+import Typography from "../../../ui/Typography";
+import { Loading } from "../../../Loading";
+import DetailSlider from "../common/detail/DetailSlider";
+import GridContainer from "../../../ui/GridContainer";
+import { SellerAndDescription } from "../common/detail/SellerAndDescription";
+import VariationSelects from "../Redeem/ExchangeView/VariationSelects";
+import DetailView from "../Redeem/ExchangeView/DetailView/DetailView";
+
+const colors = theme.colors.light;
+
+const ImageWrapper = styled.div`
+ position: relative;
+ max-width: 35rem !important;
+ min-width: 50%;
+ width: -webkit-fill-available;
+`;
+
+export type OfferVariantViewProps = {
+ onNextClick: () => void;
+ onExchangePolicyClick: () => void;
+ onPurchaseOverview: () => void;
+ onViewFullDescription: () => void;
+ variant: VariantV1;
+ fairExchangePolicyRules: string;
+ defaultDisputeResolverId: string;
+};
+
+const SLIDER_OPTIONS = {
+ type: "carousel" as const,
+ startAt: 0,
+ gap: 20,
+ perView: 1
+};
+
+export function OfferVariantView({
+ variant,
+ onNextClick,
+ onExchangePolicyClick,
+ onPurchaseOverview,
+ onViewFullDescription,
+ fairExchangePolicyRules,
+ defaultDisputeResolverId
+}: OfferVariantViewProps) {
+ const hasVariations = !!variant.variations?.length;
+ const { offer } = variant;
+
+ const {
+ data: sellers,
+ isLoading,
+ isError
+ } = useSellers(
+ {
+ id: offer?.seller.id,
+ includeFunds: true
+ },
+ {
+ enabled: !!offer?.seller.id
+ }
+ );
+
+ const sellerAvailableDeposit = sellers?.[0]?.funds?.find(
+ (fund) => fund.token.address === offer?.exchangeToken.address
+ )?.availableAmount;
+ const offerRequiredDeposit = Number(offer?.sellerDeposit || 0);
+ const hasSellerEnoughFunds =
+ offerRequiredDeposit > 0
+ ? Number(sellerAvailableDeposit) >= offerRequiredDeposit
+ : true;
+ const { offerImg, animationUrl, images } = offer
+ ? getOfferDetails(offer)
+ : ({} as ReturnType);
+ const allImages = useMemo(() => {
+ return Array.from(new Set([offerImg || "", ...(images || [])])).filter(
+ isTruthy
+ );
+ }, [offerImg, images]);
+ const {
+ store: { tokens: defaultTokens }
+ } = useConvertionRate();
+
+ const exchangePolicyCheckResult = useCheckExchangePolicy({
+ offerId: offer.id,
+ fairExchangePolicyRules,
+ defaultDisputeResolverId: defaultDisputeResolverId || "unknown",
+ defaultTokens: defaultTokens || []
+ });
+ const dispatch = useNonModalContext();
+ useEffect(() => {
+ dispatch({
+ payload: {
+ headerComponent: (
+
+ {offer && (
+
+ {offer.metadata.name}
+
+ )}
+
+ ),
+ contentStyle: {
+ background: colors.lightGrey
+ }
+ }
+ });
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [dispatch, offer]);
+ return (
+ <>
+ {isLoading ? (
+
+ ) : !offer ? (
+ This exchange does not exist
+ ) : isError ? (
+
+ There has been an error, please try again later...
+
+ ) : (
+
+
+
+ <>
+ {(allImages.length > 0 || animationUrl) && (
+
+ )}
+ >
+
+
+
+
+
+ {hasVariations && (
+
+
+
+ )}
+
+
+
+ )}
+ >
+ );
+}
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/DetailView/DetailView.tsx b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/DetailView/DetailView.tsx
index 038bd7643..83b3a2aae 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/DetailView/DetailView.tsx
+++ b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/DetailView/DetailView.tsx
@@ -33,7 +33,7 @@ import {
StyledCancelButton,
Widget,
WidgetUpperGrid
-} from "../detail/Detail.style";
+} from "../../../common/detail/Detail.style";
import TokenGated from "./TokenGated";
import { exchanges, offers, subgraph } from "@bosonprotocol/core-sdk";
import Price from "../../../../../price/Price";
@@ -43,7 +43,7 @@ import {
} from "../../../../../../lib/price/prices";
import { useConfigContext } from "../../../../../config/ConfigContext";
import { titleCase } from "../../../../../../lib/string/formatText";
-import DetailTable from "../detail/DetailTable";
+import DetailTable from "../../../common/detail/DetailTable";
import { DetailDisputeResolver } from "./DetailDisputeResolver";
import { IPrice } from "../../../../../../lib/price/convertPrice";
import useCheckTokenGatedOffer from "../../../../../../hooks/tokenGated/useCheckTokenGatedOffer";
@@ -149,7 +149,7 @@ const getOfferDetailData = (
Redeemable
- If you don’t redeem your NFT during the redemption period, it
+ If you don't redeem your NFT during the redemption period, it
will expire and you will receive back the price minus the
Buyer cancel penalty
@@ -169,7 +169,7 @@ const getOfferDetailData = (
Redeemable
- If you don’t redeem your NFT during the redemption period, it will
+ If you don't redeem your NFT during the redemption period, it will
expire and you will receive back the price minus the Buyer cancel
penalty
@@ -305,13 +305,14 @@ interface IDetailWidget {
exchange?: Exchange;
hasSellerEnoughFunds: boolean;
isPreview?: boolean;
- onCancelExchange: () => void;
+ onCancelExchange?: () => void;
hasMultipleVariants?: boolean;
onExchangePolicyClick: () => void;
- onRedeem: () => void;
+ onRedeem?: () => void;
+ onCommit?: () => void;
onPurchaseOverview: () => void;
- onExpireVoucherClick: () => void;
- onRaiseDisputeClick: () => void;
+ onExpireVoucherClick?: () => void;
+ onRaiseDisputeClick?: () => void;
exchangePolicyCheckResult?: offers.CheckExchangePolicyResult;
}
@@ -328,6 +329,7 @@ const DetailView: React.FC = ({
onPurchaseOverview,
onRaiseDisputeClick,
onRedeem,
+ onCommit,
exchangePolicyCheckResult
}) => {
const core = useCoreSDKWithContext();
@@ -427,7 +429,7 @@ const DetailView: React.FC = ({
if (!exchange) {
return;
}
- onCancelExchange();
+ onCancelExchange?.();
};
const isOfferEmpty = quantity < 1;
@@ -477,207 +479,205 @@ const DetailView: React.FC = ({
offer
});
return (
- <>
-
- {isExchange && isToRedeem && (
+
+ {isExchange && isToRedeem && (
+
+ {redeemableDays > 0
+ ? `${redeemableDays} days left to Redeem`
+ : `${redeemableHours} hours left to Redeem`}
+
+ )}
+
+ {isExchange && isExchangeExpired && (
- {redeemableDays > 0
- ? `${redeemableDays} days left to Redeem`
- : `${redeemableHours} hours left to Redeem`}
+ {
+ if (exchange) {
+ onExpireVoucherClick?.();
+ }
+ }}
+ >
+
+ You can withdraw your funds here
+
+
+
)}
-
- {isExchange && isExchangeExpired && (
-
- {
- if (exchange) {
- onExpireVoucherClick();
- }
- }}
- >
-
- You can withdraw your funds here
-
-
-
-
- )}
-
-
+
+
- {isOffer && !isNotCommittableOffer && (
-
- )}
+ {isOffer && !isNotCommittableOffer && (
+
+ )}
- {isOffer && isNotCommittableOffer && (
-
- {!isPreview && notCommittableOfferStatus}
-
- )}
- {isToRedeem && (
- {
- onRedeem();
- }}
- >
- Redeem
-
- )}
- {!isToRedeem && (
-
- {disabledRedeemText}
-
-
- )}
-
-
-
- {isBeforeRedeem ? (
-
- How it works?
-
- ) : (
-
+ {!isPreview && notCommittableOfferStatus}
+
+ )}
+ {isToRedeem && (
+ {
+ onRedeem?.();
+ }}
>
-
-
+ Redeem
+
)}
-
-
- {offer.condition && (
-
- )}
-
-
-
- {isExchange && (
- <>
-
-
- {
- const contactSellerForExchangeUrlWithId =
- contactSellerForExchangeUrl.replace(
- "{id}",
- exchange?.id || ""
- );
- window.open(contactSellerForExchangeUrlWithId, "_blank");
- }}
- theme="blank"
- type="button"
- style={{ fontSize: "0.875rem" }}
- disabled={
- isInWrongChain || !isBuyer || !contactSellerForExchangeUrl
- }
- >
- Contact seller
-
- {isBeforeRedeem ? (
- <>
- {![
- exchanges.ExtendedExchangeState.Expired,
- subgraph.ExchangeState.Cancelled,
- subgraph.ExchangeState.Revoked,
- subgraph.ExchangeState.Completed
- ].includes(
- exchangeStatus as
- | exchanges.ExtendedExchangeState
- | subgraph.ExchangeState
- ) && (
-
- Cancel
-
- )}
- >
- ) : (
- <>
- {!exchange?.disputed && (
- {
- onRaiseDisputeClick();
- }}
- type="button"
- theme="blank"
- style={{ fontSize: "0.875rem" }}
- disabled={
- exchange?.state !== "REDEEMED" ||
- !isBuyer ||
- isInWrongChain
- }
- >
- Raise a problem
-
-
- )}
- >
- )}
-
- >
+ {!isToRedeem && (
+
+ {disabledRedeemText}
+
+
+ )}
+
+
+
+ {isBeforeRedeem ? (
+
+ How it works?
+
+ ) : (
+
+
+
)}
-
- >
+
+
+ {offer.condition && (
+
+ )}
+
+
+
+ {isExchange && (
+ <>
+
+
+ {
+ const contactSellerForExchangeUrlWithId =
+ contactSellerForExchangeUrl.replace(
+ "{id}",
+ exchange?.id || ""
+ );
+ window.open(contactSellerForExchangeUrlWithId, "_blank");
+ }}
+ theme="blank"
+ type="button"
+ style={{ fontSize: "0.875rem" }}
+ disabled={
+ isInWrongChain || !isBuyer || !contactSellerForExchangeUrl
+ }
+ >
+ Contact seller
+
+ {isBeforeRedeem ? (
+ <>
+ {![
+ exchanges.ExtendedExchangeState.Expired,
+ subgraph.ExchangeState.Cancelled,
+ subgraph.ExchangeState.Revoked,
+ subgraph.ExchangeState.Completed
+ ].includes(
+ exchangeStatus as
+ | exchanges.ExtendedExchangeState
+ | subgraph.ExchangeState
+ ) && (
+
+ Cancel
+
+ )}
+ >
+ ) : (
+ <>
+ {!exchange?.disputed && (
+ {
+ onRaiseDisputeClick?.();
+ }}
+ type="button"
+ theme="blank"
+ style={{ fontSize: "0.875rem" }}
+ disabled={
+ exchange?.state !== "REDEEMED" ||
+ !isBuyer ||
+ isInWrongChain
+ }
+ >
+ Raise a problem
+
+
+ )}
+ >
+ )}
+
+ >
+ )}
+
);
};
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/ExchangeFullDescriptionView/ExchangeFullDescription.tsx b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/ExchangeFullDescriptionView/ExchangeFullDescription.tsx
index 84e7e6997..cdc6bc021 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/ExchangeFullDescriptionView/ExchangeFullDescription.tsx
+++ b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/ExchangeFullDescriptionView/ExchangeFullDescription.tsx
@@ -1,14 +1,7 @@
import React from "react";
-import { getOfferDetails } from "../../../../../../lib/offer/getOfferDetails";
-import { theme } from "../../../../../../theme";
import { Exchange } from "../../../../../../types/exchange";
-import Grid from "../../../../../ui/Grid";
-import GridContainer from "../../../../../ui/GridContainer";
-import Typography from "../../../../../ui/Typography";
-import DetailTable from "../detail/DetailTable";
-import DetailTransactions from "../detail/DetailTransactions";
-
-const colors = theme.colors.light;
+import DetailTransactions from "../../../common/detail/DetailTransactions";
+import { OfferFullDescription } from "../../../common/OfferFullDescription";
interface ExchangeFullDescriptionProps {
exchange: Exchange;
@@ -18,58 +11,16 @@ export const ExchangeFullDescription: React.FC<
ExchangeFullDescriptionProps
> = ({ exchange }) => {
const { offer } = exchange;
- const { description, artistDescription, shippingInfo } =
- getOfferDetails(offer);
const buyerAddress = exchange.buyer.wallet;
return (
- <>
-
-
- Product description
-
- {description}
-
-
-
-
- About the creator
-
- {artistDescription}
-
-
-
-
-
- {(shippingInfo.returnPeriodInDays !== undefined ||
- !!shippingInfo.shippingTable.length) && (
-
- Shipping information
-
- Return period: {shippingInfo.returnPeriodInDays}{" "}
- {shippingInfo.returnPeriodInDays === 1 ? "day" : "days"}
-
-
-
- )}
-
- >
+
+
+
);
};
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/ExchangeView.tsx b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/ExchangeView.tsx
index 119e7186f..5df4f662d 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/ExchangeView.tsx
+++ b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/ExchangeView.tsx
@@ -8,17 +8,17 @@ import { VariantV1 } from "../../../../../types/variants";
import Grid from "../../../../ui/Grid";
import Loading from "../../../../ui/loading/Loading";
import Typography from "../../../../ui/Typography";
-import DetailOpenSea from "./detail/DetailOpenSea";
+import DetailOpenSea from "../../common/DetailOpenSea";
import DetailView from "./DetailView/DetailView";
import VariationSelects from "./VariationSelects";
-import DetailSlider from "./detail/DetailSlider";
import { isTruthy } from "../../../../../types/helpers";
import GridContainer from "../../../../ui/GridContainer";
import { theme } from "../../../../../theme";
-import { SellerAndDescription } from "./detail/SellerAndDescription";
import { useConvertionRate } from "../../../../widgets/finance/convertion-rate/useConvertionRate";
import useCheckExchangePolicy from "../../../../../hooks/useCheckExchangePolicy";
import { useNonModalContext } from "../../../nonModal/NonModal";
+import { SellerAndDescription } from "../../common/detail/SellerAndDescription";
+import DetailSlider from "../../common/detail/DetailSlider";
const colors = theme.colors.light;
@@ -182,7 +182,7 @@ export function ExchangeView({
>
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/RedeemSuccess.tsx b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/RedeemSuccess.tsx
index b1f364bdd..ba1a46d0a 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/RedeemSuccess.tsx
+++ b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/RedeemSuccess.tsx
@@ -7,7 +7,7 @@ import Grid from "../../../../ui/Grid";
import IpfsImage from "../../../../ui/IpfsImage";
import Loading from "../../../../ui/loading/Loading";
import Typography from "../../../../ui/Typography";
-import DetailOpenSea from "./detail/DetailOpenSea";
+import DetailOpenSea from "../../common/DetailOpenSea";
import { useFormikContext } from "formik";
import { FormType } from "../RedeemFormModel";
import { theme } from "../../../../../theme";
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/cancellation/CancelExchange.tsx b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/cancellation/CancelExchange.tsx
index 038932652..d934deab6 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/cancellation/CancelExchange.tsx
+++ b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/cancellation/CancelExchange.tsx
@@ -21,7 +21,7 @@ import SuccessTransactionToast from "../../../../../toasts/SuccessTransactionToa
import Grid from "../../../../../ui/Grid";
import { Spinner } from "../../../../../ui/loading/Spinner";
import ThemedButton from "../../../../../ui/ThemedButton";
-import DetailTable from "../detail/DetailTable";
+import DetailTable from "../../../common/detail/DetailTable";
import { useSigner } from "../../../../../../hooks/connection/connection";
import {
RedemptionWidgetAction,
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/expireVoucher/ExpireVoucher.tsx b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/expireVoucher/ExpireVoucher.tsx
index 52a414094..f744ad1b7 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/expireVoucher/ExpireVoucher.tsx
+++ b/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/expireVoucher/ExpireVoucher.tsx
@@ -19,7 +19,7 @@ import Grid from "../../../../../ui/Grid";
import { Spinner } from "../../../../../ui/loading/Spinner";
import ThemedButton from "../../../../../ui/ThemedButton";
import Typography from "../../../../../ui/Typography";
-import DetailTable from "../detail/DetailTable";
+import DetailTable from "../../../common/detail/DetailTable";
import { useSigner } from "../../../../../../hooks/connection/connection";
import { extractUserFriendlyError } from "../../../../../../lib/errors/transactions";
diff --git a/packages/react-kit/src/components/modal/components/Redeem/LicenseAgreementView/LicenseAgreementView.tsx b/packages/react-kit/src/components/modal/components/Redeem/LicenseAgreementView/LicenseAgreementView.tsx
index c9bdf9a20..1e9a63ec4 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/LicenseAgreementView/LicenseAgreementView.tsx
+++ b/packages/react-kit/src/components/modal/components/Redeem/LicenseAgreementView/LicenseAgreementView.tsx
@@ -10,10 +10,10 @@ import { theme } from "../../../../../theme";
const colors = theme.colors.light;
interface Props {
onBackClick: () => void;
- exchange: Exchange | null;
+ offer: Exchange["offer"] | null | undefined;
}
-export function LicenseAgreementView({ onBackClick, exchange }: Props) {
+export function LicenseAgreementView({ onBackClick, offer }: Props) {
const dispatch = useNonModalContext();
useEffect(() => {
dispatch({
@@ -37,8 +37,8 @@ export function LicenseAgreementView({ onBackClick, exchange }: Props) {
}, [dispatch]);
return (
<>
- {exchange ? (
-
+ {offer ? (
+
) : (
Exchange could not be retrieved
)}
diff --git a/packages/react-kit/src/components/modal/components/Redeem/OfferPolicyView/RedeemOfferPolicyView.tsx b/packages/react-kit/src/components/modal/components/Redeem/OfferPolicyView/RedeemOfferPolicyView.tsx
new file mode 100644
index 000000000..b5790e76d
--- /dev/null
+++ b/packages/react-kit/src/components/modal/components/Redeem/OfferPolicyView/RedeemOfferPolicyView.tsx
@@ -0,0 +1,67 @@
+import React, { useEffect } from "react";
+import Grid from "../../../../ui/Grid";
+import Typography from "../../../../ui/Typography";
+import { ArrowLeft } from "phosphor-react";
+import { Exchange } from "../../../../../types/exchange";
+import { offers } from "@bosonprotocol/core-sdk";
+import OfferPolicyDetails, {
+ OfferPolicyDetailsProps
+} from "../../../../offerPolicy/OfferPolicyDetails";
+import { useNonModalContext } from "../../../nonModal/NonModal";
+import { theme } from "../../../../../theme";
+
+const colors = theme.colors.light;
+interface Props {
+ onBackClick: () => void;
+ offer: Exchange["offer"] | null | undefined;
+ onContractualAgreementClick: OfferPolicyDetailsProps["onContractualAgreementClick"];
+ onLicenseAgreementClick: OfferPolicyDetailsProps["onLicenseAgreementClick"];
+ exchangePolicyCheckResult?: offers.CheckExchangePolicyResult;
+}
+
+export function RedeemOfferPolicyView({
+ onBackClick,
+ offer,
+ onContractualAgreementClick,
+ onLicenseAgreementClick,
+ exchangePolicyCheckResult
+}: Props) {
+ const offerName = offer?.metadata.name || "";
+ const dispatch = useNonModalContext();
+ useEffect(() => {
+ dispatch({
+ payload: {
+ headerComponent: (
+
+
+
+ {offerName}
+
+
+ ),
+ contentStyle: {
+ background: colors.white
+ }
+ }
+ });
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [dispatch, offerName]);
+ return (
+ <>
+ {offer ? (
+
+ ) : (
+ Offer could not be retrieved
+ )}
+ >
+ );
+}
diff --git a/packages/react-kit/src/components/modal/components/Redeem/RedeemNonModal.tsx b/packages/react-kit/src/components/modal/components/Redeem/RedeemNonModal.tsx
index 12e0b67ae..a72e1d9b6 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/RedeemNonModal.tsx
+++ b/packages/react-kit/src/components/modal/components/Redeem/RedeemNonModal.tsx
@@ -8,10 +8,9 @@ import React, {
} from "react";
import { useDisconnect } from "wagmi";
import * as Yup from "yup";
-import { ExchangePolicy } from "./ExchangePolicy/ExchangePolicy";
+import { RedeemOfferPolicyView } from "./OfferPolicyView/RedeemOfferPolicyView";
import { MyItems, MyItemsProps } from "./MyItems/MyItems";
import { FormModel } from "./RedeemFormModel";
-import StepsOverview from "./StepsOverview/StepsOverview";
import { Exchange } from "../../../../types/exchange";
import { ContractualAgreementView } from "./ContractualAgreementView/ContractualAgreementView";
import { LicenseAgreementView } from "./LicenseAgreementView/LicenseAgreementView";
@@ -20,7 +19,6 @@ import {
ConfirmationViewProps
} from "./Confirmation/ConfirmationView";
import RedeemFormView from "./RedeemForm/RedeemFormView";
-import { PurchaseOverviewView } from "./StepsOverview/PurchaseOverviewView";
import { RedeemSuccess } from "./ExchangeView/RedeemSuccess";
import {
@@ -45,9 +43,11 @@ import {
RedemptionWidgetAction,
useRedemptionContext
} from "../../../widgets/redemption/provider/RedemptionContext";
-import { BosonFooter } from "./BosonFooter";
+import { BosonFooter } from "../common/BosonFooter";
import { theme } from "../../../../theme";
import { useAccount } from "../../../../hooks/connection/connection";
+import StepsOverview from "../common/StepsOverview/StepsOverview";
+import { PurchaseOverviewView } from "../common/StepsOverview/PurchaseOverviewView";
const colors = theme.colors.light;
enum ActiveStep {
@@ -463,8 +463,8 @@ function RedeemNonModal({
isValid={isRedeemFormOK}
/>
) : currentStep === ActiveStep.EXCHANGE_POLICY ? (
-
setActiveStep(ActiveStep.CONTRACTUAL_AGREEMENT)
@@ -481,7 +481,7 @@ function RedeemNonModal({
/>
) : currentStep === ActiveStep.LICENSE_AGREEMENT ? (
) : currentStep === ActiveStep.REDEEM_FORM_CONFIRMATION ? (
diff --git a/packages/react-kit/src/components/modal/components/Redeem/BosonFooter.tsx b/packages/react-kit/src/components/modal/components/common/BosonFooter.tsx
similarity index 100%
rename from packages/react-kit/src/components/modal/components/Redeem/BosonFooter.tsx
rename to packages/react-kit/src/components/modal/components/common/BosonFooter.tsx
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailOpenSea.tsx b/packages/react-kit/src/components/modal/components/common/DetailOpenSea.tsx
similarity index 89%
rename from packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailOpenSea.tsx
rename to packages/react-kit/src/components/modal/components/common/DetailOpenSea.tsx
index 18e062d72..d2d97c1f5 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailOpenSea.tsx
+++ b/packages/react-kit/src/components/modal/components/common/DetailOpenSea.tsx
@@ -1,11 +1,11 @@
import { exchanges, subgraph } from "@bosonprotocol/core-sdk";
import { ArrowSquareOut } from "phosphor-react";
import React, { useMemo } from "react";
-import { Exchange } from "../../../../../../types/exchange";
-import { useEnvContext } from "../../../../../environment/EnvironmentContext";
+import { Exchange } from "../../../../types/exchange";
+import { useEnvContext } from "../../../environment/EnvironmentContext";
-import { OpenSeaButton } from "./Detail.style";
-import { getExchangeTokenId } from "../../../../../../lib/utils/exchange";
+import { getExchangeTokenId } from "../../../../lib/utils/exchange";
+import { OpenSeaButton } from "./detail/Detail.style";
interface Props {
exchange?: Exchange;
diff --git a/packages/react-kit/src/components/modal/components/common/OfferFullDescription.tsx b/packages/react-kit/src/components/modal/components/common/OfferFullDescription.tsx
new file mode 100644
index 000000000..452583f80
--- /dev/null
+++ b/packages/react-kit/src/components/modal/components/common/OfferFullDescription.tsx
@@ -0,0 +1,69 @@
+import React, { ReactNode } from "react";
+import { Offer } from "../../../../types/offer";
+import { getOfferDetails } from "../../../../lib/offer/getOfferDetails";
+import { theme } from "../../../../theme";
+import GridContainer from "../../../ui/GridContainer";
+import Typography from "../../../ui/Typography";
+import Grid from "../../../ui/Grid";
+import DetailTable from "./detail/DetailTable";
+
+const colors = theme.colors.light;
+
+interface OfferFullDescriptionProps {
+ offer: Offer;
+ children?: ReactNode;
+}
+
+export const OfferFullDescription: React.FC = ({
+ offer,
+ children
+}) => {
+ const { description, artistDescription, shippingInfo } =
+ getOfferDetails(offer);
+
+ return (
+ <>
+
+
+ Product description
+
+ {description}
+
+
+
+
+ About the creator
+
+ {artistDescription}
+
+
+
+
+ {children}
+ {(shippingInfo.returnPeriodInDays !== undefined ||
+ !!shippingInfo.shippingTable.length) && (
+
+ Shipping information
+
+ Return period: {shippingInfo.returnPeriodInDays}{" "}
+ {shippingInfo.returnPeriodInDays === 1 ? "day" : "days"}
+
+
+
+ )}
+
+ >
+ );
+};
diff --git a/packages/react-kit/src/components/modal/components/Redeem/StepsOverview/PurchaseOverview.tsx b/packages/react-kit/src/components/modal/components/common/StepsOverview/PurchaseOverview.tsx
similarity index 97%
rename from packages/react-kit/src/components/modal/components/Redeem/StepsOverview/PurchaseOverview.tsx
rename to packages/react-kit/src/components/modal/components/common/StepsOverview/PurchaseOverview.tsx
index e144dd79b..daf6acd1e 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/StepsOverview/PurchaseOverview.tsx
+++ b/packages/react-kit/src/components/modal/components/common/StepsOverview/PurchaseOverview.tsx
@@ -8,10 +8,7 @@ import {
import { useBreakpoints } from "../../../../../hooks/useBreakpoints";
import Grid from "../../../../ui/Grid";
import Typography from "../../../../ui/Typography";
-import {
- LearnMore,
- ModalBackground
-} from "../ExchangeView/detail/Detail.style";
+import { LearnMore, ModalBackground } from "../detail/Detail.style";
import { CommitStep } from "./style";
import styled from "styled-components";
import { breakpoint } from "../../../../../lib/ui/breakpoint";
diff --git a/packages/react-kit/src/components/modal/components/Redeem/StepsOverview/PurchaseOverviewView.tsx b/packages/react-kit/src/components/modal/components/common/StepsOverview/PurchaseOverviewView.tsx
similarity index 100%
rename from packages/react-kit/src/components/modal/components/Redeem/StepsOverview/PurchaseOverviewView.tsx
rename to packages/react-kit/src/components/modal/components/common/StepsOverview/PurchaseOverviewView.tsx
diff --git a/packages/react-kit/src/components/modal/components/Redeem/StepsOverview/StepsOverview.tsx b/packages/react-kit/src/components/modal/components/common/StepsOverview/StepsOverview.tsx
similarity index 100%
rename from packages/react-kit/src/components/modal/components/Redeem/StepsOverview/StepsOverview.tsx
rename to packages/react-kit/src/components/modal/components/common/StepsOverview/StepsOverview.tsx
diff --git a/packages/react-kit/src/components/modal/components/Redeem/StepsOverview/style.tsx b/packages/react-kit/src/components/modal/components/common/StepsOverview/style.tsx
similarity index 100%
rename from packages/react-kit/src/components/modal/components/Redeem/StepsOverview/style.tsx
rename to packages/react-kit/src/components/modal/components/common/StepsOverview/style.tsx
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/Detail.style.tsx b/packages/react-kit/src/components/modal/components/common/detail/Detail.style.tsx
similarity index 96%
rename from packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/Detail.style.tsx
rename to packages/react-kit/src/components/modal/components/common/detail/Detail.style.tsx
index 9b7cd077e..de125a945 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/Detail.style.tsx
+++ b/packages/react-kit/src/components/modal/components/common/detail/Detail.style.tsx
@@ -1,13 +1,13 @@
import styled, { css } from "styled-components";
-import { breakpoint } from "../../../../../../lib/ui/breakpoint";
-import { theme } from "../../../../../../theme";
-import Grid from "../../../../../ui/Grid";
-import ThemedButton from "../../../../../ui/ThemedButton";
-import { zIndex } from "../../../../../ui/zIndex";
-
-import frameImage from "../../../../../../assets/frame.png";
-import { buttonText } from "../../../../../ui/styles";
-import Typography from "../../../../../ui/Typography";
+import { breakpoint } from "../../../../../lib/ui/breakpoint";
+import { theme } from "../../../../../theme";
+import Grid from "../../../../ui/Grid";
+import ThemedButton from "../../../../ui/ThemedButton";
+import { zIndex } from "../../../../ui/zIndex";
+
+import frameImage from "../../../../../assets/frame.png";
+import { buttonText } from "../../../../ui/styles";
+import Typography from "../../../../ui/Typography";
const colors = theme.colors.light;
export const ChartWrapper = styled.div`
@@ -498,6 +498,7 @@ export const Widget = styled.div`
width: 100%;
background: ${colors.white};
font-family: "Plus Jakarta Sans";
+ padding-top: 2rem;
> div {
padding-left: 2rem;
padding-right: 2rem;
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailSlider.tsx b/packages/react-kit/src/components/modal/components/common/detail/DetailSlider.tsx
similarity index 91%
rename from packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailSlider.tsx
rename to packages/react-kit/src/components/modal/components/common/detail/DetailSlider.tsx
index b14b44e1c..2f778ef42 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailSlider.tsx
+++ b/packages/react-kit/src/components/modal/components/common/detail/DetailSlider.tsx
@@ -5,13 +5,13 @@ import { CaretLeft, CaretRight } from "phosphor-react";
import React, { useEffect, useMemo, useReducer, useRef } from "react";
import { GlideSlide, GlideWrapper } from "./Detail.style";
-import { breakpointNumbers } from "../../../../../../lib/ui/breakpoint";
-import Grid from "../../../../../ui/Grid";
-import ThemedButton from "../../../../../ui/ThemedButton";
-import IpfsImage from "../../../../../ui/IpfsImage";
-import { zIndex } from "../../../../../ui/zIndex";
-import Video from "../../../../../ui/Video";
-import { theme } from "../../../../../../theme";
+import { breakpointNumbers } from "../../../../../lib/ui/breakpoint";
+import Grid from "../../../../ui/Grid";
+import ThemedButton from "../../../../ui/ThemedButton";
+import IpfsImage from "../../../../ui/IpfsImage";
+import { zIndex } from "../../../../ui/zIndex";
+import Video from "../../../../ui/Video";
+import { theme } from "../../../../../theme";
import styled from "styled-components";
const colors = theme.colors.light;
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailTable.tsx b/packages/react-kit/src/components/modal/components/common/detail/DetailTable.tsx
similarity index 91%
rename from packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailTable.tsx
rename to packages/react-kit/src/components/modal/components/common/detail/DetailTable.tsx
index 2e62cb171..adaef5925 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailTable.tsx
+++ b/packages/react-kit/src/components/modal/components/common/detail/DetailTable.tsx
@@ -1,7 +1,7 @@
import React, { Fragment } from "react";
-import { Tooltip } from "../../../../../tooltip/Tooltip";
-import Grid from "../../../../../ui/Grid";
-import Typography from "../../../../../ui/Typography";
+import { Tooltip } from "../../../../tooltip/Tooltip";
+import Grid from "../../../../ui/Grid";
+import Typography from "../../../../ui/Typography";
import { Table } from "./Detail.style";
export interface Data {
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailTransactions.tsx b/packages/react-kit/src/components/modal/components/common/detail/DetailTransactions.tsx
similarity index 84%
rename from packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailTransactions.tsx
rename to packages/react-kit/src/components/modal/components/common/detail/DetailTransactions.tsx
index 2cee85bd0..16898cb8d 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/DetailTransactions.tsx
+++ b/packages/react-kit/src/components/modal/components/common/detail/DetailTransactions.tsx
@@ -1,12 +1,12 @@
import dayjs from "dayjs";
import React, { useMemo } from "react";
-import useTransactionHistory from "../../../../../../hooks/useTransactionHistory";
-import { getDateTimestamp } from "../../../../../../lib/dates/getDateTimestamp";
-import { IPrice } from "../../../../../../lib/price/convertPrice";
-import { Exchange } from "../../../../../../types/exchange";
-import { Offer } from "../../../../../../types/offer";
-import { useConvertedPrice } from "../../../../../price/useConvertedPrice";
-import Typography from "../../../../../ui/Typography";
+import useTransactionHistory from "../../../../../hooks/useTransactionHistory";
+import { getDateTimestamp } from "../../../../../lib/dates/getDateTimestamp";
+import { IPrice } from "../../../../../lib/price/convertPrice";
+import { Exchange } from "../../../../../types/exchange";
+import { Offer } from "../../../../../types/offer";
+import { useConvertedPrice } from "../../../../price/useConvertedPrice";
+import Typography from "../../../../ui/Typography";
import { Transactions } from "./Detail.style";
const HEADER = ["Event", "From", "To", "Price", "Date"];
diff --git a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/SellerAndDescription.tsx b/packages/react-kit/src/components/modal/components/common/detail/SellerAndDescription.tsx
similarity index 72%
rename from packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/SellerAndDescription.tsx
rename to packages/react-kit/src/components/modal/components/common/detail/SellerAndDescription.tsx
index 14d79bcb0..e0e458fe5 100644
--- a/packages/react-kit/src/components/modal/components/Redeem/ExchangeView/detail/SellerAndDescription.tsx
+++ b/packages/react-kit/src/components/modal/components/common/detail/SellerAndDescription.tsx
@@ -1,12 +1,12 @@
import { TextAlignLeft } from "phosphor-react";
import React from "react";
import styled from "styled-components";
-import { theme } from "../../../../../../theme";
-import { Exchange } from "../../../../../../types/exchange";
-import SellerID from "../../../../../avatar/SellerID";
-import Grid from "../../../../../ui/Grid";
-import ThemedButton from "../../../../../ui/ThemedButton";
-import Typography from "../../../../../ui/Typography";
+import { theme } from "../../../../../theme";
+import SellerID from "../../../../avatar/SellerID";
+import Grid from "../../../../ui/Grid";
+import ThemedButton from "../../../../ui/ThemedButton";
+import Typography from "../../../../ui/Typography";
+import { Offer } from "../../../../../types/offer";
const colors = theme.colors.light;
@@ -26,15 +26,11 @@ const Container = styled(Grid)`
`;
type Props = {
- exchange: Exchange;
+ offer: Offer;
onViewFullDescription: () => void;
};
-export function SellerAndDescription({
- exchange,
- onViewFullDescription
-}: Props) {
- const { offer } = exchange;
+export function SellerAndDescription({ offer, onViewFullDescription }: Props) {
return (
void;
onLicenseAgreementClick: () => void;
}
-export default function ExchangePolicyDetails({
- exchange,
+export default function OfferPolicyDetails({
+ offer: offerData,
exchangePolicyCheckResult,
onContractualAgreementClick,
onLicenseAgreementClick
-}: ExchangePolicyDetailsProps) {
- const offerData: subgraph.OfferFieldsFragment = exchange.offer;
+}: OfferPolicyDetailsProps) {
const isExchangePolicyValid =
exchangePolicyCheckResult &&
(exchangePolicyCheckResult.isValid ||
diff --git a/packages/react-kit/src/components/widgets/commit/CommitModalWithOffer.tsx b/packages/react-kit/src/components/widgets/commit/CommitModalWithOffer.tsx
new file mode 100644
index 000000000..58e0f02a2
--- /dev/null
+++ b/packages/react-kit/src/components/widgets/commit/CommitModalWithOffer.tsx
@@ -0,0 +1,55 @@
+import React from "react";
+import CommitNonModal, {
+ CommitNonModalProps
+} from "../../modal/components/Commit/CommitNonModal";
+import useProductByUuid from "../../../hooks/products/useProductByUuid";
+// TODO: implement hook in this repo
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+const useOffer = (a, b) => ({ data: undefined } as any);
+
+function WithProductOrOffer(
+ WrappedComponent: React.ComponentType
+) {
+ const ComponentWithProductOrOffer = (
+ props: Omit<
+ CommitNonModalProps,
+ "product" | "singleOffer" | "isLoading"
+ > & {
+ offerId?: string | undefined;
+ sellerId?: string | undefined;
+ productUuid?: string | undefined;
+ }
+ ) => {
+ const allProductByUuidParamsDefined =
+ !!props.sellerId && !!props.productUuid;
+ const { data: product, isLoading: isProductLoading } = useProductByUuid(
+ props.sellerId,
+ props.productUuid,
+ {
+ enabled:
+ (!props.offerId && allProductByUuidParamsDefined) ||
+ !!(props.offerId && allProductByUuidParamsDefined)
+ }
+ );
+ const { data: offer, isLoading: isOfferLoading } = useOffer(
+ {
+ id: props.offerId
+ },
+ {
+ enabled: !props.productUuid && props.offerId
+ }
+ );
+ return (
+
+ );
+ };
+ return ComponentWithProductOrOffer;
+}
+
+export const CommitModalWithOffer = WithProductOrOffer(CommitNonModal);
diff --git a/packages/react-kit/src/components/widgets/commit/CommitWidget.tsx b/packages/react-kit/src/components/widgets/commit/CommitWidget.tsx
new file mode 100644
index 000000000..10e8310cb
--- /dev/null
+++ b/packages/react-kit/src/components/widgets/commit/CommitWidget.tsx
@@ -0,0 +1,98 @@
+import React, { ComponentType } from "react";
+import { ButtonProps } from "../../buttons/Button";
+import {
+ EnvironmentProvider,
+ EnvironmentProviderProps
+} from "../../environment/EnvironmentProvider";
+import { IpfsProvider, IpfsProviderProps } from "../../ipfs/IpfsProvider";
+import ModalProvider from "../../modal/ModalProvider";
+import GlobalStyle from "../../styles/GlobalStyle";
+import WalletConnectionProvider, {
+ WalletConnectionProviderProps
+} from "../../wallet/WalletConnectionProvider";
+import { QueryClient, QueryClientProvider } from "react-query";
+import {
+ ConfigProvider,
+ ConfigProviderProps
+} from "../../config/ConfigProvider";
+import ChatProvider from "../../chat/ChatProvider/ChatProvider";
+import ConvertionRateProvider, {
+ ConvertionRateProviderProps
+} from "../finance/convertion-rate/ConvertionRateProvider";
+import { CommitNonModalProps } from "../../modal/components/Commit/CommitNonModal";
+import { CommitModalWithOffer } from "./CommitModalWithOffer";
+import { MagicProvider } from "../../magicLink/MagicContext";
+import { CONFIG } from "../../../lib/config/config";
+
+type CommitProps = {
+ buttonProps?: Omit;
+ trigger?: ComponentType<{ onClick: () => unknown }> | undefined;
+} & Omit<
+ CommitNonModalProps,
+ "product" | "singleOffer" | "isLoading" | "hideModal"
+> & {
+ closeWidgetClick?: () => void;
+ modalMargin?: string;
+ offerId?: string;
+ sellerId?: string;
+ productUuid?: string;
+ };
+
+type WidgetProps = CommitProps &
+ IpfsProviderProps &
+ Omit &
+ EnvironmentProviderProps &
+ ConvertionRateProviderProps &
+ Omit;
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ refetchOnWindowFocus: false
+ }
+ }
+});
+
+const { infuraKey, magicLinkKey } = CONFIG;
+
+export function CommitWidget(props: WidgetProps) {
+ return (
+
+
+ {
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment, prettier/prettier
+ /* @ts-ignore */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/react-kit/src/hooks/products/useProductByUuid.ts b/packages/react-kit/src/hooks/products/useProductByUuid.ts
new file mode 100644
index 000000000..360beda12
--- /dev/null
+++ b/packages/react-kit/src/hooks/products/useProductByUuid.ts
@@ -0,0 +1,30 @@
+import { useQuery } from "react-query";
+import { useCoreSDKWithContext } from "../useCoreSdkWithContext";
+
+export default function useProductByUuid(
+ sellerId: string | undefined | null,
+ uuid: string | undefined | null,
+ options: {
+ enabled?: boolean;
+ } = {}
+) {
+ const coreSDK = useCoreSDKWithContext();
+
+ return useQuery(
+ ["get-product-by-uuid", uuid, coreSDK, sellerId],
+ async () => {
+ if (!uuid || !sellerId) {
+ return;
+ }
+ return await coreSDK?.getProductWithVariants(sellerId, uuid);
+ },
+ {
+ ...options,
+ enabled: options.enabled && !!coreSDK
+ }
+ );
+}
+
+export type ReturnUseProductByUuid = ReturnType<
+ typeof useProductByUuid
+>["data"];
diff --git a/packages/react-kit/src/stories/widgets/Commit.stories.tsx b/packages/react-kit/src/stories/widgets/Commit.stories.tsx
new file mode 100644
index 000000000..431061f4a
--- /dev/null
+++ b/packages/react-kit/src/stories/widgets/Commit.stories.tsx
@@ -0,0 +1,59 @@
+import React from "react";
+import { ComponentMeta, ComponentStory, Story } from "@storybook/react";
+
+import { CommitWidget } from "../../components/widgets/commit/CommitWidget";
+import { CtaButtonWrapper } from "../helpers/CtaButtonWrapper";
+import { EnvironmentType, getEnvConfigs } from "@bosonprotocol/core-sdk";
+// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
+export default {
+ title: "Widgets/Commit",
+ component: CommitWidget
+} as ComponentMeta;
+
+// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
+const Template: ComponentStory = (args) => (
+
+
+
+);
+
+const wrapper = (Story: Story) => (
+
+
+
+);
+
+export const Commit: ComponentStory = Template.bind({});
+
+const envName =
+ (process.env.STORYBOOK_DATA_ENV_NAME as EnvironmentType) || "testing";
+const envConfig = getEnvConfigs(envName);
+// More on args: https://storybook.js.org/docs/react/writing-stories/args
+Commit.args = {
+ envName,
+ configId: envConfig[0].configId,
+ walletConnectProjectId: process.env.REACT_APP_WALLET_CONNECT_PROJECT_ID,
+ dateFormat: "YYYY/MM/DD",
+ defaultCurrencySymbol: "$",
+ defaultCurrencyTicker: "USD",
+ contactSellerForExchangeUrl: "https://bosonapp.io/#/chat/{id}",
+ fairExchangePolicyRules:
+ "ipfs://QmV3Wy2wmrFdEXzhyhvvaW25Q8w2wTd2UypFVyhwsdBE8T",
+ ipfsGateway: process.env.STORYBOOK_DATA_IPFS_GATEWAY,
+ ipfsProjectId: process.env.STORYBOOK_DATA_IPFS_PROJECT_ID,
+ ipfsProjectSecret: process.env.STORYBOOK_DATA_IPFS_PROJECT_SECRET,
+ offerId: undefined,
+ productUuid: "28f220-3c44-d7f4-cf0-0c72702cd4",
+ sellerId: "26",
+ metaTx: {
+ apiKey: process.env.STORYBOOK_DATA_META_TX_API_KEY as string,
+ apiIds: process.env.STORYBOOK_DATA_META_TX_API_IDS as string
+ },
+ closeWidgetClick: () => {
+ console.log("closeWidgetClick()");
+ },
+ modalMargin: "2%",
+ forcedAccount: ""
+};
+
+Commit.decorators = [(Story) => wrapper(Story)];