diff --git a/.secrets.baseline b/.secrets.baseline index 91ff5c3b767..057b31dfb6f 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -412,14 +412,14 @@ "filename": "src/app/Scenes/MyCollection/Screens/ArtworkForm/MyCollectionArtworkForm.tests.tsx", "hashed_secret": "67d1be5993e49fbaba0bbd38492c33a2bc007ef7", "is_verified": false, - "line_number": 626 + "line_number": 621 }, { "type": "Base64 High Entropy String", "filename": "src/app/Scenes/MyCollection/Screens/ArtworkForm/MyCollectionArtworkForm.tests.tsx", "hashed_secret": "6414700358f2ae5762917a164e2e30df8783fc4e", "is_verified": false, - "line_number": 712 + "line_number": 707 } ], "src/app/Scenes/MyCollection/Screens/Insights/SelectArtist.tests.tsx": [ @@ -1150,5 +1150,5 @@ } ] }, - "generated_at": "2025-01-28T13:31:59Z" + "generated_at": "2025-02-10T11:24:13Z" } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 20d8271d616..01550e33ae5 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -132,7 +132,6 @@ - diff --git a/images/SellWithArtsyHeader.webp b/images/SellWithArtsyHeader.webp deleted file mode 100644 index f2dd49f5a93..00000000000 Binary files a/images/SellWithArtsyHeader.webp and /dev/null differ diff --git a/images/sell.webp b/images/sell.webp deleted file mode 100644 index 42c01437408..00000000000 Binary files a/images/sell.webp and /dev/null differ diff --git a/images/sell@2x.webp b/images/sell@2x.webp deleted file mode 100644 index 1f348fd8ce1..00000000000 Binary files a/images/sell@2x.webp and /dev/null differ diff --git a/images/sell@3x.webp b/images/sell@3x.webp deleted file mode 100644 index e5344c2b0e3..00000000000 Binary files a/images/sell@3x.webp and /dev/null differ diff --git a/images/submit_artwork_complete_submission.webp b/images/submit_artwork_complete_submission.webp deleted file mode 100644 index 9c1fef0b733..00000000000 Binary files a/images/submit_artwork_complete_submission.webp and /dev/null differ diff --git a/images/submit_artwork_complete_submission@2x.webp b/images/submit_artwork_complete_submission@2x.webp deleted file mode 100644 index 35bd9b1e07d..00000000000 Binary files a/images/submit_artwork_complete_submission@2x.webp and /dev/null differ diff --git a/images/submit_artwork_complete_submission@3x.webp b/images/submit_artwork_complete_submission@3x.webp deleted file mode 100644 index 8bda1487ae7..00000000000 Binary files a/images/submit_artwork_complete_submission@3x.webp and /dev/null differ diff --git a/images/submit_artwork_tell_us_about_your_work.webp b/images/submit_artwork_tell_us_about_your_work.webp deleted file mode 100644 index 5afc48a1348..00000000000 Binary files a/images/submit_artwork_tell_us_about_your_work.webp and /dev/null differ diff --git a/images/submit_artwork_tell_us_about_your_work@2x.webp b/images/submit_artwork_tell_us_about_your_work@2x.webp deleted file mode 100644 index 977171f24f2..00000000000 Binary files a/images/submit_artwork_tell_us_about_your_work@2x.webp and /dev/null differ diff --git a/images/submit_artwork_tell_us_about_your_work@3x.webp b/images/submit_artwork_tell_us_about_your_work@3x.webp deleted file mode 100644 index 30e01eb1c0c..00000000000 Binary files a/images/submit_artwork_tell_us_about_your_work@3x.webp and /dev/null differ diff --git a/images/submit_artwork_upload_artwork_image.webp b/images/submit_artwork_upload_artwork_image.webp deleted file mode 100644 index 5bf6026a5ef..00000000000 Binary files a/images/submit_artwork_upload_artwork_image.webp and /dev/null differ diff --git a/images/submit_artwork_upload_artwork_image@2x.webp b/images/submit_artwork_upload_artwork_image@2x.webp deleted file mode 100644 index 258f368e549..00000000000 Binary files a/images/submit_artwork_upload_artwork_image@2x.webp and /dev/null differ diff --git a/images/submit_artwork_upload_artwork_image@3x.webp b/images/submit_artwork_upload_artwork_image@3x.webp deleted file mode 100644 index ecbc2709ad4..00000000000 Binary files a/images/submit_artwork_upload_artwork_image@3x.webp and /dev/null differ diff --git a/images/swa-faq-image.webp b/images/swa-faq-image.webp deleted file mode 100644 index 67cfb48b891..00000000000 Binary files a/images/swa-faq-image.webp and /dev/null differ diff --git a/images/swa-faq-image@2x.webp b/images/swa-faq-image@2x.webp deleted file mode 100644 index cdb48181081..00000000000 Binary files a/images/swa-faq-image@2x.webp and /dev/null differ diff --git a/images/swa-faq-image@3x.webp b/images/swa-faq-image@3x.webp deleted file mode 100644 index c919e907218..00000000000 Binary files a/images/swa-faq-image@3x.webp and /dev/null differ diff --git a/images/swa-landing-page-header.webp b/images/swa-landing-page-header.webp deleted file mode 100644 index 13d3517c623..00000000000 Binary files a/images/swa-landing-page-header.webp and /dev/null differ diff --git a/images/swa-landing-page-header@2x.webp b/images/swa-landing-page-header@2x.webp deleted file mode 100644 index ed67bb49be2..00000000000 Binary files a/images/swa-landing-page-header@2x.webp and /dev/null differ diff --git a/images/swa-landing-page-header@3x.webp b/images/swa-landing-page-header@3x.webp deleted file mode 100644 index 0d39b2b8154..00000000000 Binary files a/images/swa-landing-page-header@3x.webp and /dev/null differ diff --git a/images/test-webp.webp b/images/test-webp.webp deleted file mode 100644 index 13d3517c623..00000000000 Binary files a/images/test-webp.webp and /dev/null differ diff --git a/images/test-webp@2x.webp b/images/test-webp@2x.webp deleted file mode 100644 index ed67bb49be2..00000000000 Binary files a/images/test-webp@2x.webp and /dev/null differ diff --git a/images/test-webp@3x.webp b/images/test-webp@3x.webp deleted file mode 100644 index 0d39b2b8154..00000000000 Binary files a/images/test-webp@3x.webp and /dev/null differ diff --git a/images/ways-we-sell-auction.webp b/images/ways-we-sell-auction.webp deleted file mode 100644 index e8550ecc110..00000000000 Binary files a/images/ways-we-sell-auction.webp and /dev/null differ diff --git a/images/ways-we-sell-auction@2x.webp b/images/ways-we-sell-auction@2x.webp deleted file mode 100644 index d5ee8747920..00000000000 Binary files a/images/ways-we-sell-auction@2x.webp and /dev/null differ diff --git a/images/ways-we-sell-auction@3x.webp b/images/ways-we-sell-auction@3x.webp deleted file mode 100644 index 18a7a3ed43c..00000000000 Binary files a/images/ways-we-sell-auction@3x.webp and /dev/null differ diff --git a/images/ways-we-sell-online-storefront.webp b/images/ways-we-sell-online-storefront.webp deleted file mode 100644 index 32c629d491c..00000000000 Binary files a/images/ways-we-sell-online-storefront.webp and /dev/null differ diff --git a/images/ways-we-sell-online-storefront@2x.webp b/images/ways-we-sell-online-storefront@2x.webp deleted file mode 100644 index ae757c08e9b..00000000000 Binary files a/images/ways-we-sell-online-storefront@2x.webp and /dev/null differ diff --git a/images/ways-we-sell-online-storefront@3x.webp b/images/ways-we-sell-online-storefront@3x.webp deleted file mode 100644 index 550391971f9..00000000000 Binary files a/images/ways-we-sell-online-storefront@3x.webp and /dev/null differ diff --git a/images/ways-we-sell-private-sales.webp b/images/ways-we-sell-private-sales.webp deleted file mode 100644 index 93b172ca8da..00000000000 Binary files a/images/ways-we-sell-private-sales.webp and /dev/null differ diff --git a/images/ways-we-sell-private-sales@2x.webp b/images/ways-we-sell-private-sales@2x.webp deleted file mode 100644 index 3af5dcb6da9..00000000000 Binary files a/images/ways-we-sell-private-sales@2x.webp and /dev/null differ diff --git a/images/ways-we-sell-private-sales@3x.webp b/images/ways-we-sell-private-sales@3x.webp deleted file mode 100644 index ee9d8eff273..00000000000 Binary files a/images/ways-we-sell-private-sales@3x.webp and /dev/null differ diff --git a/src/app/Components/ArtistAutosuggest/ArtistAutosuggest.tsx b/src/app/Components/ArtistAutosuggest/ArtistAutosuggest.tsx index 1e7ae4618de..d7f4e05dd3e 100644 --- a/src/app/Components/ArtistAutosuggest/ArtistAutosuggest.tsx +++ b/src/app/Components/ArtistAutosuggest/ArtistAutosuggest.tsx @@ -1,7 +1,7 @@ import { Box, Input } from "@artsy/palette-mobile" import SearchIcon from "app/Components/Icons/SearchIcon" +import { ArtworkFormValues } from "app/Scenes/MyCollection/State/MyCollectionArtworkModel" import { SearchContext, useSearchProviderValues } from "app/Scenes/Search/SearchContext" -import { ArtworkDetailsFormModel } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/validation" import { AnimateHeight } from "app/utils/animations/AnimateHeight" import { useFormikContext } from "formik" import React, { useEffect, useState } from "react" @@ -23,7 +23,7 @@ export const ArtistAutosuggest: React.FC = ({ setFieldValue, errors, validateField, - } = useFormikContext() + } = useFormikContext() const searchProviderValues = useSearchProviderValues(artist) const [isArtistSelected, setIsArtistSelected] = useState(false) diff --git a/src/app/Components/ArtworkGrids/InfiniteScrollArtworksGrid.tsx b/src/app/Components/ArtworkGrids/InfiniteScrollArtworksGrid.tsx index b608b499941..51962c641f7 100644 --- a/src/app/Components/ArtworkGrids/InfiniteScrollArtworksGrid.tsx +++ b/src/app/Components/ArtworkGrids/InfiniteScrollArtworksGrid.tsx @@ -530,9 +530,6 @@ export const InfiniteScrollMyCollectionArtworksGridContainer = createFragmentCon blurhash } artistNames - consignmentSubmission { - state - } medium artist { targetSupply { diff --git a/src/app/Components/PhotoRow/PhotoRow.tests.tsx b/src/app/Components/PhotoRow/PhotoRow.tests.tsx index 958dde3b5c3..07b92b08eec 100644 --- a/src/app/Components/PhotoRow/PhotoRow.tests.tsx +++ b/src/app/Components/PhotoRow/PhotoRow.tests.tsx @@ -1,5 +1,5 @@ -import { fireEvent } from "@testing-library/react-native" -import { Photo } from "app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/validation" +import { fireEvent, screen } from "@testing-library/react-native" +import { Photo } from "app/Components/PhotoRow/utils/validation" import { getMockRelayEnvironment } from "app/system/relay/defaultEnvironment" import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" import { RelayEnvironmentProvider } from "react-relay" @@ -19,23 +19,23 @@ describe("PhotoRow", () => { beforeEach(() => mockEnvironment.mockClear()) it("renders photo as a thumbnail", () => { - const { getByTestId } = renderWithWrappers() - expect(getByTestId("Submission_Image")).toBeTruthy() + renderWithWrappers() + expect(screen.getByTestId("Submission_Image")).toBeTruthy() }) it("renders photo size", () => { - const { getByText } = renderWithWrappers() - expect(getByText("3.3 MB")).toBeTruthy() + renderWithWrappers() + expect(screen.getByText("3.3 MB")).toBeTruthy() }) it("renders Delete button", () => { - const { getByTestId } = renderWithWrappers() - expect(getByTestId("Submission_Delete_Photo_Button")).toBeTruthy() + renderWithWrappers() + expect(screen.getByTestId("Submission_Delete_Photo_Button")).toBeTruthy() }) it("fires handlePhotoDelete with correct photo when Delete button pressed", () => { - const { getByTestId } = renderWithWrappers() - const DeleteButton = getByTestId("Submission_Delete_Photo_Button") + renderWithWrappers() + const DeleteButton = screen.getByTestId("Submission_Delete_Photo_Button") fireEvent.press(DeleteButton) @@ -54,8 +54,8 @@ describe("PhotoRow", () => { beforeEach(() => mockEnvironment.mockClear()) it("renders correct error message", () => { - const { getByText } = renderWithWrappers() - expect(getByText("some error")).toBeTruthy() + renderWithWrappers() + expect(screen.getByText("some error")).toBeTruthy() }) }) }) diff --git a/src/app/Components/PhotoRow/PhotoRow.tsx b/src/app/Components/PhotoRow/PhotoRow.tsx index 0a5cd453ae0..054f98a2ede 100644 --- a/src/app/Components/PhotoRow/PhotoRow.tsx +++ b/src/app/Components/PhotoRow/PhotoRow.tsx @@ -1,5 +1,5 @@ import { Spacer, Flex, ProgressBar, Text, Button } from "@artsy/palette-mobile" -import { Photo } from "app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/validation" +import { Photo } from "app/Components/PhotoRow/utils/validation" import { PlaceholderBox, ProvidePlaceholderContext } from "app/utils/placeholders" import { Image } from "react-native" diff --git a/src/app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/gemini/createGeminiAssetWithS3Credentials.ts b/src/app/Components/PhotoRow/utils/gemini/createGeminiAssetWithS3Credentials.ts similarity index 100% rename from src/app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/gemini/createGeminiAssetWithS3Credentials.ts rename to src/app/Components/PhotoRow/utils/gemini/createGeminiAssetWithS3Credentials.ts diff --git a/src/app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/gemini/getConvectionGeminiKey.ts b/src/app/Components/PhotoRow/utils/gemini/getConvectionGeminiKey.ts similarity index 100% rename from src/app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/gemini/getConvectionGeminiKey.ts rename to src/app/Components/PhotoRow/utils/gemini/getConvectionGeminiKey.ts diff --git a/src/app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/gemini/getGeminiCredentialsForEnvironment.ts b/src/app/Components/PhotoRow/utils/gemini/getGeminiCredentialsForEnvironment.ts similarity index 100% rename from src/app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/gemini/getGeminiCredentialsForEnvironment.ts rename to src/app/Components/PhotoRow/utils/gemini/getGeminiCredentialsForEnvironment.ts diff --git a/src/app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/uploadFileToS3.ts b/src/app/Components/PhotoRow/utils/uploadFileToS3.ts similarity index 100% rename from src/app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/uploadFileToS3.ts rename to src/app/Components/PhotoRow/utils/uploadFileToS3.ts diff --git a/src/app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/validation.ts b/src/app/Components/PhotoRow/utils/validation.ts similarity index 100% rename from src/app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/validation.ts rename to src/app/Components/PhotoRow/utils/validation.ts diff --git a/src/app/Navigation/routes.tsx b/src/app/Navigation/routes.tsx index 05ded47ad5f..cadc3a48068 100644 --- a/src/app/Navigation/routes.tsx +++ b/src/app/Navigation/routes.tsx @@ -85,8 +85,6 @@ import { MyCollectionScreenQuery, } from "app/Scenes/MyCollection/MyCollection" import { AddMyCollectionArtist } from "app/Scenes/MyCollection/Screens/Artist/AddMyCollectionArtist" -import { RequestForPriceEstimateConfirmationScreen } from "app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateConfirmationScreen" -import { RequestForPriceEstimateScreen } from "app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateScreen" import { MyCollectionArtworkScreen, MyCollectionArtworkScreenQuery, @@ -941,21 +939,6 @@ export const artsyDotNetRoutes = defineRoutes([ }, queries: [MyCollectionArtworkScreenQuery], }, - { - path: "/my-collection/artwork/:artworkID/price-estimate", - name: "RequestForPriceEstimateScreen", - Component: RequestForPriceEstimateScreen, - }, - { - path: "/my-collection/artwork/:artworkID/price-estimate/success", - name: "RequestForPriceEstimateConfirmationScreen", - Component: RequestForPriceEstimateConfirmationScreen, - options: { - screenOptions: { - headerShown: false, - }, - }, - }, { path: "/my-collection/artworks/:artworkID/edit", name: "MyCollectionArtworkEdit", diff --git a/src/app/Scenes/Artwork/Artwork.tsx b/src/app/Scenes/Artwork/Artwork.tsx index 3585c5e9c3f..bd3c56c0ae4 100644 --- a/src/app/Scenes/Artwork/Artwork.tsx +++ b/src/app/Scenes/Artwork/Artwork.tsx @@ -749,9 +749,6 @@ export const ArtworkContainer = createRefetchContainer( } } } - artists(shallow: true) { - isConsignable - } isEligibleForArtsyGuarantee } `, diff --git a/src/app/Scenes/Artwork/Components/ArtworkExtraLinks/index.tests.tsx b/src/app/Scenes/Artwork/Components/ArtworkExtraLinks/index.tests.tsx index b1748dc1d8b..f71cfd0796c 100644 --- a/src/app/Scenes/Artwork/Components/ArtworkExtraLinks/index.tests.tsx +++ b/src/app/Scenes/Artwork/Components/ArtworkExtraLinks/index.tests.tsx @@ -28,7 +28,6 @@ describe("ArtworkExtraLinks", () => { artists: [ { name: "Santa", - isConsignable: true, }, ], } @@ -51,7 +50,6 @@ describe("ArtworkExtraLinks", () => { artists: [ { name: "Santa", - isConsignable: true, }, ], } @@ -81,7 +79,6 @@ describe("ArtworkExtraLinks", () => { artists: [ { name: "Santa", - isConsignable: false, }, ], } diff --git a/src/app/Scenes/Artwork/Components/ArtworkExtraLinks/index.tsx b/src/app/Scenes/Artwork/Components/ArtworkExtraLinks/index.tsx index 52db49b1d6a..e4d637ecfb0 100644 --- a/src/app/Scenes/Artwork/Components/ArtworkExtraLinks/index.tsx +++ b/src/app/Scenes/Artwork/Components/ArtworkExtraLinks/index.tsx @@ -28,7 +28,6 @@ export const ArtworkExtraLinksFragmentContainer = createFragmentContainer(Artwor } } artists { - isConsignable name } artist { diff --git a/src/app/Scenes/HomeView/Components/ModalCarouselComponents/ModalCarousel.tsx b/src/app/Scenes/HomeView/Components/ModalCarouselComponents/ModalCarousel.tsx index e0fb1ed6609..90fd15f7eb3 100644 --- a/src/app/Scenes/HomeView/Components/ModalCarouselComponents/ModalCarousel.tsx +++ b/src/app/Scenes/HomeView/Components/ModalCarouselComponents/ModalCarousel.tsx @@ -1,5 +1,4 @@ -import { Spacer, GraphIcon, Text, ArtworkIcon, Flex, Join, IconProps } from "@artsy/palette-mobile" -import { SellWithEaseIcon } from "app/Components/Icons/HomeFeedOnboarding/SellWithEaseIcon" +import { ArtworkIcon, Flex, GraphIcon, IconProps, Join, Spacer, Text } from "@artsy/palette-mobile" import { ModalCarouselContainer } from "./ModalCarouselContainer" import { ModalCarouselScreenWrapper } from "./ModalCarouselScreenWrapper" @@ -52,16 +51,6 @@ const HowItWorksScreenNew = () => { text="Get free insights into the markets and careers of the artists in your collection." icon={GraphIcon} /> - - ) diff --git a/src/app/Scenes/MyCollection/Components/MyCollectionImageView.tsx b/src/app/Scenes/MyCollection/Components/MyCollectionImageView.tsx index 92b50255388..d899eb4096d 100644 --- a/src/app/Scenes/MyCollection/Components/MyCollectionImageView.tsx +++ b/src/app/Scenes/MyCollection/Components/MyCollectionImageView.tsx @@ -8,7 +8,6 @@ export interface MyCollectionImageViewProps { imageHeight?: number aspectRatio?: number artworkSlug: string - artworkSubmissionId?: string | null useRawURL?: boolean internalID?: string | null versions?: string[] diff --git a/src/app/Scenes/MyCollection/Components/MyCollectionStickyHeader.tsx b/src/app/Scenes/MyCollection/Components/MyCollectionStickyHeader.tsx index 0c1d3d9df5c..af4c7a5693b 100644 --- a/src/app/Scenes/MyCollection/Components/MyCollectionStickyHeader.tsx +++ b/src/app/Scenes/MyCollection/Components/MyCollectionStickyHeader.tsx @@ -1,13 +1,10 @@ -import { AddIcon, CloseIcon, Flex, Spacer, Touchable, useSpace, Pill } from "@artsy/palette-mobile" +import { AddIcon, CloseIcon, Flex, Pill, Spacer, Touchable, useSpace } from "@artsy/palette-mobile" import AsyncStorage from "@react-native-async-storage/async-storage" import { MyCollectionArtworkFilters } from "app/Scenes/MyCollection/Components/MyCollectionArtworkFiltersStickyTab" import { MyCollectionArtworksKeywordStore } from "app/Scenes/MyCollection/Components/MyCollectionArtworksKeywordStore" import { HAS_SEEN_MY_COLLECTION_NEW_WORKS_BANNER } from "app/Scenes/MyCollection/MyCollection" import { MyCollectionArtworkUploadMessages } from "app/Scenes/MyCollection/Screens/ArtworkForm/MyCollectionArtworkUploadMessages" -import { - PurchasedArtworkAddedMessage, - SubmittedArtworkAddedMessage, -} from "app/Scenes/MyCollection/Screens/Insights/MyCollectionMessages" +import { PurchasedArtworkAddedMessage } from "app/Scenes/MyCollection/Screens/Insights/MyCollectionMessages" import { CollectedTab, MyCollectionTabsStore, @@ -15,7 +12,6 @@ import { import { Tab } from "app/Scenes/MyProfile/MyProfileHeaderMyCollectionAndSavedWorks" import { navigate } from "app/system/navigation/navigate" import { useMeasure } from "app/utils/hooks/useMeasure" -import { setVisualClueAsSeen, useVisualClue } from "app/utils/hooks/useVisualClue" import { debounce } from "lodash" import { MotiView } from "moti" import { useMemo, useRef } from "react" @@ -40,9 +36,6 @@ export const MyCollectionStickyHeader: React.FC = showModal, showNewWorksMessage, }) => { - const { showVisualClue } = useVisualClue() - - const showSubmissionMessage = showVisualClue("ArtworkSubmissionMessage") const selectedTab = MyCollectionTabsStore.useStoreState((state) => state.selectedTab) const showArtworkFilters = useMemo(() => { @@ -51,11 +44,7 @@ export const MyCollectionStickyHeader: React.FC = return ( - + @@ -260,9 +249,8 @@ const AnimatedPill: React.FC<{ const Messages: React.FC<{ hasMarketSignals: boolean showNewWorksMessage: boolean - showSubmissionMessage: boolean -}> = ({ hasMarketSignals, showNewWorksMessage, showSubmissionMessage }) => { - if (!hasMarketSignals && !showNewWorksMessage && !showSubmissionMessage) { +}> = ({ hasMarketSignals, showNewWorksMessage }) => { + if (!hasMarketSignals && !showNewWorksMessage) { return null } @@ -273,11 +261,6 @@ const Messages: React.FC<{ onClose={() => AsyncStorage.setItem(HAS_SEEN_MY_COLLECTION_NEW_WORKS_BANNER, "true")} /> )} - {!!showSubmissionMessage && ( - setVisualClueAsSeen("ArtworkSubmissionMessage")} - /> - )} { - let mockEnvironment: ReturnType - const TestRenderer = () => ( - - environment={mockEnvironment} - query={graphql` - query PriceEstimateRequestedTestsQuery @relay_test_operation { - artwork(id: "foo") { - ...RequestForPriceEstimateBanner_artwork - } - me { - ...RequestForPriceEstimateBanner_me - } - } - `} - variables={{}} - render={({ props }) => { - if (props?.artwork && props?.me) { - return ( - - - - ) - } - return null - }} - /> - ) - - beforeEach(() => { - mockEnvironment = createMockEnvironment() - }) - - afterEach(() => { - jest.clearAllMocks() - __globalStoreTestUtils__?.reset() - }) - - const resolveData = (passedProps = {}) => { - mockEnvironment.mock.resolveMostRecentOperation((operation) => - MockPayloadGenerator.generate(operation, passedProps) - ) - } - - it("renders 'requested' state if in global store without throwing an error", async () => { - renderWithWrappers() - resolveData({ - Artwork: () => ({ - internalID: "artwork-id", - slug: "artwork-id", - hasPriceEstimateRequest: null, - }), - }) - __globalStoreTestUtils__?.injectState({ - requestedPriceEstimates: { - requestedPriceEstimates: { - "artwork-id": { - artworkId: "artwork-id", - requestedAt: 1666015648950, - }, - }, - }, - }) - - await flushPromiseQueue() - - expect(screen.getByText("Price Estimate Request Sent")).toBeDefined() - }) - - it("renders 'requested' state if hasPriceEstimateRequest is true", () => { - renderWithWrappers() - resolveData({ - Artwork: () => ({ - internalID: "artwork-id", - slug: "artwork-id", - hasPriceEstimateRequest: true, - }), - }) - expect(screen.getByText("Price Estimate Request Sent")).toBeDefined() - }) -}) diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/PriceEstimateRequested.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/PriceEstimateRequested.tsx deleted file mode 100644 index 1a0a189b845..00000000000 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/PriceEstimateRequested.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { Box, CheckCircleIcon, Flex, Separator, Text } from "@artsy/palette-mobile" -import { RequestForPriceEstimateBanner_artwork$key } from "__generated__/RequestForPriceEstimateBanner_artwork.graphql" -import { RequestForPriceEstimateBanner_me$key } from "__generated__/RequestForPriceEstimateBanner_me.graphql" -import { artworkFragment } from "app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateBanner" -import { usePriceEstimateRequested } from "app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/usePriceEstimateRequested" -import { useFragment } from "react-relay" - -interface PriceEstimateRequestedProps { - artwork: RequestForPriceEstimateBanner_artwork$key - me: RequestForPriceEstimateBanner_me$key | null | undefined -} - -export const PriceEstimateRequested: React.FC = ({ - ...otherProps -}) => { - const artwork = useFragment(artworkFragment, otherProps.artwork) - const priceEstimateRequested = usePriceEstimateRequested(artwork) - - if (!priceEstimateRequested) return null - - return ( - - - - - Price Estimate Request Sent - - - - - ) -} diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateBanner.tests.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateBanner.tests.tsx deleted file mode 100644 index b4c27d09569..00000000000 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateBanner.tests.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import { fireEvent, screen } from "@testing-library/react-native" -import { RequestForPriceEstimateBannerTestsQuery } from "__generated__/RequestForPriceEstimateBannerTestsQuery.graphql" -import { __globalStoreTestUtils__ } from "app/store/GlobalStore" -import { flushPromiseQueue } from "app/utils/tests/flushPromiseQueue" -import { mockTrackEvent } from "app/utils/tests/globallyMockedStuff" -import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" -import { graphql, QueryRenderer } from "react-relay" -import { createMockEnvironment, MockPayloadGenerator } from "relay-test-utils" -import { RequestForPriceEstimateBanner } from "./RequestForPriceEstimateBanner" - -describe("RequestForPriceEstimateBanner", () => { - let mockEnvironment: ReturnType - const TestRenderer = () => ( - - environment={mockEnvironment} - query={graphql` - query RequestForPriceEstimateBannerTestsQuery @relay_test_operation { - artwork(id: "foo") { - ...RequestForPriceEstimateBanner_artwork - } - marketPriceInsights(artistId: "some-artist-id", medium: "painting") { - ...RequestForPriceEstimateBanner_marketPriceInsights - } - me { - ...RequestForPriceEstimateBanner_me - } - } - `} - variables={{}} - render={({ props }) => { - if (props?.artwork && props?.marketPriceInsights && props?.me) { - return ( - - ) - } - return null - }} - /> - ) - - beforeEach(() => { - mockEnvironment = createMockEnvironment() - }) - - afterEach(() => { - jest.clearAllMocks() - __globalStoreTestUtils__?.reset() - }) - - const resolveData = (passedProps = {}) => { - mockEnvironment.mock.resolveMostRecentOperation((operation) => - MockPayloadGenerator.generate(operation, passedProps) - ) - } - - it("renders without throwing an error", async () => { - renderWithWrappers() - resolveData({ - Artwork: () => ({ - internalID: "some-internal-id", - hasPriceEstimateRequest: false, - isPriceEstimateRequestable: true, - }), - MarketPriceInsights: () => ({ - demandRank: 7.5, - }), - }) - - await flushPromiseQueue() - - expect(screen.getByTestId("request-price-estimate-button")).toBeDefined() - expect(screen.getByTestId("request-price-estimate-banner-title")).toBeDefined() - expect(screen.getByTestId("request-price-estimate-banner-description")).toBeDefined() - }) - - it("rendering nothing if the price estimate is not requestable", () => { - renderWithWrappers() - resolveData({ - Artwork: () => ({ - internalID: "some-internal-id", - hasPriceEstimateRequest: false, - isPriceEstimateRequestable: false, - }), - }) - - expect(screen.queryByTestId("request-price-estimate-button")).toBeNull() - expect(screen.queryByTestId("request-price-estimate-banner-title")).toBeNull() - expect(screen.queryByTestId("request-price-estimate-banner-description")).toBeNull() - }) - - it("tracks analytics event when RequestForEstimate button is tapped", () => { - renderWithWrappers() - resolveData({ - Artwork: () => ({ - internalID: "artwork-id", - slug: "artwork-slug", - hasPriceEstimateRequest: false, - isPriceEstimateRequestable: true, - }), - MarketPriceInsights: () => ({ - demandRank: 7.5, - }), - }) - - const TheButton = screen.getByTestId("request-price-estimate-button") - - fireEvent.press(TheButton) - - expect(mockTrackEvent).toHaveBeenCalledTimes(1) - expect(mockTrackEvent).toHaveBeenCalledWith({ - action: "tappedRequestPriceEstimate", - context_module: "myCollectionArtworkInsights", - context_screen: "MyCollectionArtworkInsights", - context_screen_owner_type: "myCollectionArtwork", - context_screen_owner_id: "artwork-id", - context_screen_owner_slug: "artwork-slug", - demand_index: 7.5, - }) - }) -}) diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateBanner.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateBanner.tsx deleted file mode 100644 index 1d9ea3abb1a..00000000000 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateBanner.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { ActionType, ContextModule, OwnerType, TappedRequestPriceEstimate } from "@artsy/cohesion" -import { Box, Button, Separator, Text } from "@artsy/palette-mobile" -import { RequestForPriceEstimateBanner_artwork$key } from "__generated__/RequestForPriceEstimateBanner_artwork.graphql" -import { RequestForPriceEstimateBanner_marketPriceInsights$key } from "__generated__/RequestForPriceEstimateBanner_marketPriceInsights.graphql" -import { RequestForPriceEstimateBanner_me$key } from "__generated__/RequestForPriceEstimateBanner_me.graphql" -import { Toast } from "app/Components/Toast/Toast" -import { usePriceEstimateRequested } from "app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/usePriceEstimateRequested" -import { navigate } from "app/system/navigation/navigate" -import { graphql, useFragment } from "react-relay" -import { useTracking } from "react-tracking" - -interface RequestForPriceEstimateProps { - artwork: RequestForPriceEstimateBanner_artwork$key - marketPriceInsights: RequestForPriceEstimateBanner_marketPriceInsights$key | null | undefined - me: RequestForPriceEstimateBanner_me$key | null | undefined -} - -export const RequestForPriceEstimateBanner: React.FC = ({ - ...otherProps -}) => { - const { trackEvent } = useTracking() - - const artwork = useFragment(artworkFragment, otherProps.artwork) - const priceEstimateRequested = usePriceEstimateRequested(artwork) - - const marketPriceInsights = useFragment( - marketPriceInsightsFragment, - otherProps.marketPriceInsights - ) - - const me = useFragment(meFragment, otherProps.me) - - if (priceEstimateRequested) return null - if (!artwork.isPriceEstimateRequestable) return null - - return ( - - - Get a Free Price Estimate - - - This artwork is eligible for a free evaluation from an Artsy specialist. - - - - - - ) -} - -export const artworkFragment = graphql` - fragment RequestForPriceEstimateBanner_artwork on Artwork { - internalID - slug - hasPriceEstimateRequest - isPriceEstimateRequestable - } -` - -const marketPriceInsightsFragment = graphql` - fragment RequestForPriceEstimateBanner_marketPriceInsights on MarketPriceInsights { - demandRank - } -` - -const meFragment = graphql` - fragment RequestForPriceEstimateBanner_me on Me { - name - email - phone - } -` - -const tracks = { - trackTappedRequestPriceEstimate: ( - artworkId: string, - artworkSlug?: string, - demandRank?: number - ): TappedRequestPriceEstimate => ({ - action: ActionType.tappedRequestPriceEstimate, - context_module: ContextModule.myCollectionArtworkInsights, - context_screen: OwnerType.myCollectionArtworkInsights, - context_screen_owner_type: OwnerType.myCollectionArtwork, - context_screen_owner_id: artworkId, - context_screen_owner_slug: artworkSlug, - demand_index: demandRank, - }), -} diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateConfirmationScreen.tests.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateConfirmationScreen.tests.tsx deleted file mode 100644 index 0acf49a4d8d..00000000000 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateConfirmationScreen.tests.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { fireEvent } from "@testing-library/react-native" -import { goBack } from "app/system/navigation/navigate" -import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" -import { RequestForPriceEstimateConfirmationScreen } from "./RequestForPriceEstimateConfirmationScreen" - -describe("RequestForPriceEstimateConfirmationScreen", () => { - const getWrapper = () => { - return renderWithWrappers() - } - it("renders without errors", () => { - const { getByText } = getWrapper() - expect(getByText("Price Estimate Request Sent")).toBeTruthy() - expect( - getByText( - "An Artsy Specialist will evaluate your artwork and contact you with a free price estimate." - ) - ).toBeTruthy() - }) - - it("navigates correctly", () => { - const { getByTestId } = getWrapper() - fireEvent.press(getByTestId("back-to-my-collection-button")) - expect(goBack).toHaveBeenCalled() - }) -}) diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateConfirmationScreen.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateConfirmationScreen.tsx deleted file mode 100644 index 8911174470d..00000000000 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateConfirmationScreen.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { ArtsyLogoBlackIcon, Flex, Box, Text, Button } from "@artsy/palette-mobile" -import { goBack } from "app/system/navigation/navigate" - -export const RequestForPriceEstimateConfirmationScreen: React.FC<{}> = () => { - return ( - - - - - - Price Estimate Request Sent - - - An Artsy Specialist will evaluate your artwork and contact you with a free price estimate. - - - - ) -} diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateForm.tests.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateForm.tests.tsx deleted file mode 100644 index 0fb2941b4b7..00000000000 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateForm.tests.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" -import { RequestForPriceEstimateForm } from "./RequestForPriceEstimateForm" - -const initialValues = { - requesterName: "tester name", - requesterEmail: "email@hq.com", - requesterPhoneNumber: "+4912345", -} - -jest.mock("formik", () => ({ - useFormikContext: () => { - return { - values: initialValues, - handleChange: jest.fn(() => jest.fn()), - errors: {}, - isValid: true, - } - }, -})) - -describe("RequestForPriceEstimateForm", () => { - const getWrapper = () => renderWithWrappers() - it("renders with fields prepopulated", () => { - const tree = getWrapper() - const nameInput = tree.getByTestId("request-price-estimate-name-input") - const emailInput = tree.getByTestId("request-price-estimate-email-input") - const phoneInput = tree.getByTestId("request-price-estimate-phone-input") - expect(nameInput.props.value).toBe(initialValues.requesterName) - expect(emailInput.props.value).toBe(initialValues.requesterEmail) - expect(phoneInput.props.value).toBe("12 345") // excluding area code and spaced - }) -}) diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateForm.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateForm.tsx deleted file mode 100644 index 5f445faeeef..00000000000 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateForm.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { Box, Button, Input, LinkText, Spacer, Text } from "@artsy/palette-mobile" -import { PhoneInput } from "app/Components/Input/PhoneInput" -import { navigate } from "app/system/navigation/navigate" -import { useScreenDimensions } from "app/utils/hooks" -import { useFormikContext } from "formik" -import { KeyboardAvoidingView, Platform, ScrollView } from "react-native" -import { RequestForPriceEstimateFormikSchema } from "./RequestForPriceEstimateScreen" - -export const RequestForPriceEstimateForm = () => { - const { safeAreaInsets } = useScreenDimensions() - const { values, handleChange, errors, setErrors, handleSubmit, isValid } = - useFormikContext() - - return ( - - - - - - Let us know how to reach you - - { - if (errors.requesterName) { - setErrors({ - requesterName: undefined, - }) - } - handleChange("requesterName")(text) - }} - blurOnSubmit={false} - placeholder="First and last name" - returnKeyType="done" - maxLength={128} - showLimit - value={values.requesterName} - error={errors.requesterName} - /> - { - if (errors.requesterEmail) { - setErrors({ - requesterEmail: undefined, - }) - } - handleChange("requesterEmail")(text.trim()) - }} - blurOnSubmit={false} - placeholder="Email address" - value={values.requesterEmail} - returnKeyType="next" - spellCheck={false} - autoCorrect={false} - textContentType={Platform.OS === "ios" ? "username" : "emailAddress"} - error={errors.requesterEmail} - /> - - - - - By continuing, you agree to{" "} - navigate("/privacy")}> - Artsy’s Privacy Policy. - {" "} - - - - - - - ) -} diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateScreen.tests.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateScreen.tests.tsx deleted file mode 100644 index 09d08067261..00000000000 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateScreen.tests.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { act } from "@testing-library/react-native" -import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" -import { createMockEnvironment, MockPayloadGenerator } from "relay-test-utils" -import { - requestForPriceEstimateMutation, - RequestForPriceEstimateScreen, -} from "./RequestForPriceEstimateScreen" - -describe("RequestForPriceEstimateScreen", () => { - const props = { - artworkID: "artworkId", - artworkSlug: "artworkSlug", - name: "Tester HQ", - email: "tester@hq.com", - phone: "+49123456898", - } - - it("renders without errors", () => { - renderWithWrappers() - }) - - describe("requestForPriceEstimateMutation", () => { - const input = { - artworkId: "artworkId", - artworkSlug: "artworkSlug", - requesterName: "My Name is", - requesterEmail: "email@email.com", - requesterPhoneNumber: "+4912345", - } - - const environment = createMockEnvironment() - - const onCompleted = jest.fn() - - it("sends Request", () => { - requestForPriceEstimateMutation(environment, onCompleted, jest.fn(), input) - const operation = environment.mock.getMostRecentOperation() - act(() => { - environment.mock.resolve(operation, MockPayloadGenerator.generate(operation)) - }) - expect(onCompleted).toBeCalled() - }) - }) -}) diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateScreen.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateScreen.tsx deleted file mode 100644 index cb181d16d1e..00000000000 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/RequestForPriceEstimateScreen.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import { ActionType, ContextModule, OwnerType, SentRequestPriceEstimate } from "@artsy/cohesion" -import { CommonActions, useNavigation } from "@react-navigation/native" -import { RequestForPriceEstimateScreenMutation } from "__generated__/RequestForPriceEstimateScreenMutation.graphql" -import { Toast } from "app/Components/Toast/Toast" -import { GlobalStore } from "app/store/GlobalStore" -import { navigate } from "app/system/navigation/navigate" -import { getRelayEnvironment } from "app/system/relay/defaultEnvironment" -import { FormikProvider, useFormik } from "formik" -import { Environment, commitMutation, graphql } from "react-relay" -import { useTracking } from "react-tracking" -import * as Yup from "yup" -import { RequestForPriceEstimateForm } from "./RequestForPriceEstimateForm" - -interface RequestForPriceEstimateScreenProps { - artworkID: string - artworkSlug: string - demandRank?: number - email: string - name: string - phone: string -} - -export interface RequestForPriceEstimateFormikSchema { - requesterName: string - requesterEmail: string - requesterPhoneNumber: string -} - -const ValidationSchema = Yup.object().shape({ - requesterName: Yup.string().required("Name field is required").min(1, "Name field is required"), - requesterEmail: Yup.string() - .required("Email field is required") - .email("Please provide a valid email address"), -}) - -export const requestForPriceEstimateMutation = ( - environment: Environment, - onCompleted: (response: RequestForPriceEstimateScreenMutation["response"]) => void, - onError: () => void, - input: RequestForPriceEstimateFormikSchema & { artworkId: string } -) => { - commitMutation(environment, { - mutation: graphql` - mutation RequestForPriceEstimateScreenMutation($input: RequestPriceEstimateInput!) { - requestPriceEstimate(input: $input) { - priceEstimateParamsOrError { - ... on RequestPriceEstimatedMutationSuccess { - submittedPriceEstimateParams { - artworkId - } - } - ... on RequestPriceEstimatedMutationFailure { - mutationError { - error - } - } - } - } - } - `, - variables: { input }, - onCompleted, - onError, - }) -} - -export const RequestForPriceEstimateScreen: React.FC = ({ - artworkID, - artworkSlug, - demandRank, - email, - name, - phone, -}) => { - const { trackEvent } = useTracking() - const navigation = useNavigation() - - const formik = useFormik({ - validateOnChange: true, - initialValues: { - requesterEmail: email, - requesterName: name, - requesterPhoneNumber: phone, - }, - onSubmit: async ({ requesterEmail, requesterName, requesterPhoneNumber }) => { - const input = { artworkId: artworkID, requesterEmail, requesterName, requesterPhoneNumber } - const onCompleted = (response: RequestForPriceEstimateScreenMutation["response"]) => { - const myCollectionArtworkId = - response.requestPriceEstimate?.priceEstimateParamsOrError?.submittedPriceEstimateParams - ?.artworkId - if (myCollectionArtworkId) { - GlobalStore.actions.requestedPriceEstimates.addRequestedPriceEstimate({ - artworkId: myCollectionArtworkId, - requestedAt: new Date().getTime(), - }) - trackEvent( - tracks.sentRequestPriceEstimate( - myCollectionArtworkId, - artworkSlug, - demandRank ?? undefined - ) - ) - // Remove this screen from the nav stack. This way when we go back we won't land on this screen again - navigation.dispatch((state) => { - const routes = state.routes.slice(0, state.routes.length - 1) - return CommonActions.reset({ - ...state, - routes, - index: 0, - }) - }) - navigate(`/my-collection/artwork/${artworkID}/price-estimate/success`) - } - - if (response.requestPriceEstimate?.priceEstimateParamsOrError?.mutationError) { - Toast.show("Error: Failed to send a price estimate request.", "top", { - backgroundColor: "red100", - }) - } - } - const onError = () => { - Toast.show("Error: Failed to send a price estimate request.", "top", { - backgroundColor: "red100", - }) - } - requestForPriceEstimateMutation(getRelayEnvironment(), onCompleted, onError, input) - }, - validationSchema: ValidationSchema, - }) - - return ( - - - - ) -} - -const tracks = { - sentRequestPriceEstimate: ( - artworkId: string, - artworkSlug: string, - demandRank?: number - ): SentRequestPriceEstimate => ({ - action: ActionType.sentRequestPriceEstimate, - context_module: ContextModule.myCollectionArtworkInsights, - context_screen: OwnerType.myCollectionArtworkInsights, - context_screen_owner_type: OwnerType.myCollectionArtwork, - context_screen_owner_id: artworkId, - context_screen_owner_slug: artworkSlug, - demand_index: demandRank, - }), -} diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/usePriceEstimateRequested.ts b/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/usePriceEstimateRequested.ts deleted file mode 100644 index f033e566cd2..00000000000 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/ArtworkInsights/RequestForPriceEstimate/usePriceEstimateRequested.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { RequestForPriceEstimateBanner_artwork$data } from "__generated__/RequestForPriceEstimateBanner_artwork.graphql" -import { GlobalStore } from "app/store/GlobalStore" - -export const usePriceEstimateRequested = (artwork: RequestForPriceEstimateBanner_artwork$data) => { - const localRequestedPriceEstimates = GlobalStore.useAppState( - (state) => state.requestedPriceEstimates.requestedPriceEstimates - ) - - const priceEstimateRequested = - artwork.hasPriceEstimateRequest || !!localRequestedPriceEstimates[artwork.internalID] - - return priceEstimateRequested -} diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/Components/MyCollectionArtworkHeader.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/Components/MyCollectionArtworkHeader.tsx index 8929aa896de..c19df2f5971 100644 --- a/src/app/Scenes/MyCollection/Screens/Artwork/Components/MyCollectionArtworkHeader.tsx +++ b/src/app/Scenes/MyCollection/Screens/Artwork/Components/MyCollectionArtworkHeader.tsx @@ -87,10 +87,6 @@ const myCollectionArtworkHeaderFragment = graphql` internalID slug title - consignmentSubmission { - state - } - submissionId } ` diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtwork.tests.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtwork.tests.tsx index f746cd101bf..11b9ac0abdd 100644 --- a/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtwork.tests.tsx +++ b/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtwork.tests.tsx @@ -33,11 +33,10 @@ describe("MyCollectionArtwork", () => { }) describe("Edit button", () => { - it("should be visible, greyed out and open a popover when submission process is not complete", async () => { + it("should be visible always", async () => { renderWithRelay({ Artwork: () => ({ ...artwork, - consignmentSubmission: { internalID: "submission-id", isEditable: false }, }), }) @@ -45,45 +44,6 @@ describe("MyCollectionArtwork", () => { screen.queryByTestId("my-collection-artwork-placeholder") ) - expect(screen.getByText("Edit")).toBeOnTheScreen() - expect(screen.getByText("Edit").props.color).toEqual("black60") - - fireEvent.press(screen.getByText("Edit")) - - expect(screen.getByText("Popover")).toBeOnTheScreen() - }) - - it("should be visible when the artwork submission is complete", async () => { - renderWithRelay({ - Artwork: () => ({ - ...artwork, - consignmentSubmission: { internalID: "submission-id", isEditable: true }, - }), - }) - - await waitForElementToBeRemoved(() => - screen.queryByTestId("my-collection-artwork-placeholder") - ) - - expect(screen.getByText("Edit")).toBeOnTheScreen() - expect(screen.getByText("Edit").props.color).toEqual("black100") - - fireEvent.press(screen.getByText("Edit")) - expect(navigate).toHaveBeenCalledWith( - 'my-collection/artworks//edit', - { passProps: { mode: "edit" } } - ) - }) - - it("should be visible when the artwork does not have an associated submission", async () => { - renderWithRelay({ - Artwork: () => ({ ...artwork, consignmentSubmission: null }), - }) - - await waitForElementToBeRemoved(() => - screen.queryByTestId("my-collection-artwork-placeholder") - ) - expect(screen.getByText("Edit")).toBeOnTheScreen() expect(screen.getByText("Edit").props.color).toEqual("black100") diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtwork.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtwork.tsx index d0de859cc93..d2855512001 100644 --- a/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtwork.tsx +++ b/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtwork.tsx @@ -1,13 +1,5 @@ import { ActionType, ContextModule, EditCollectedArtwork, OwnerType } from "@artsy/cohesion" -import { - DEFAULT_HIT_SLOP, - Flex, - Join, - Popover, - Screen, - Separator, - Text, -} from "@artsy/palette-mobile" +import { DEFAULT_HIT_SLOP, Flex, Join, Screen, Separator, Text } from "@artsy/palette-mobile" import { MyCollectionArtworkQuery } from "__generated__/MyCollectionArtworkQuery.graphql" import { LoadingSpinner } from "app/Components/Modals/LoadingModal" import { RetryErrorBoundary } from "app/Components/RetryErrorBoundary" @@ -42,7 +34,6 @@ const MyCollectionArtwork: React.FC = ({ const { trackEvent } = useTracking() const [isRefreshing, setIsRefetching] = useState(false) - const [isToolTipVisible, setIsToolTipVisible] = useState(false) const queryVariables = { artworkId: artworkId || "", @@ -85,10 +76,6 @@ const MyCollectionArtwork: React.FC = ({ }) }, [artwork]) - const handleNotEditable = () => { - setIsToolTipVisible(true) - } - if (!artwork) { return ( @@ -99,39 +86,14 @@ const MyCollectionArtwork: React.FC = ({ const articles = extractNodes(artwork.artist?.articles) - const isEditingDisabled = artwork.consignmentSubmission?.isEditable === false - return ( setIsToolTipVisible(false)} - onPressOutside={() => setIsToolTipVisible(false)} - placement="bottom" - title={ - - Thank you for submitting! - - } - content={ - - Editing will be available once the submission process is complete. - - } - > - - Edit - - - ) : ( - - Edit - - ) + + Edit + } /> @@ -300,13 +262,6 @@ export const ArtworkMetaProps = graphql` countryCode } confidentialNotes - # needed to show the banner inside the edit artwork view - # TODO: move logic to the edit artwork view https://artsyproduct.atlassian.net/browse/CX-2846 - consignmentSubmission @optionalField { - internalID - isEditable - displayText - } pricePaid { display minor diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtworkInsights.tests.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtworkInsights.tests.tsx index f3f6d8725b5..ded29d995d4 100644 --- a/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtworkInsights.tests.tsx +++ b/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtworkInsights.tests.tsx @@ -16,9 +16,6 @@ describe("MyCollectionArtworkInsights", () => { query MyCollectionArtworkInsightsTestsQuery @relay_test_operation { artwork(id: "some-artwork-id") { ...MyCollectionArtworkInsights_artwork - consignmentSubmission { - state - } } } `, @@ -51,32 +48,6 @@ describe("MyCollectionArtworkInsights", () => { expect(screen.getByText("Comparable Works")).toBeTruthy() }) - - describe("Conditional Display of RequestForPriceEstimateBanner", () => { - it("does not display RequestForPriceEstimateBanner when Artist is not P1", () => { - renderWithRelay({ - Query: () => ({ - artwork: mockArtwork, - marketPriceInsights: mockMarketPriceInsightsForHighDemandIndex, - }), - }) - expect(screen.queryByTestId("request-price-estimate-button")).toBeNull() - }) - - it("does not display when artwork is submitted", () => { - renderWithRelay({ - Query: () => ({ - artwork: { - ...mockArtworkForP1Artist, - consignmentsSubmission: { displayText: "Consignment" }, - }, - marketPriceInsights: mockMarketPriceInsightsForHighDemandIndex, - }), - }) - - expect(screen.queryByTestId("request-price-estimate-button")).toBeNull() - }) - }) }) const mockMarketPriceInsights = { @@ -130,32 +101,3 @@ const mockArtwork = { }, marketPriceInsights: mockMarketPriceInsights, } - -const mockMarketPriceInsightsForHighDemandIndex = { - ...mockMarketPriceInsights, - demandRank: 0.95, -} - -const mockArtworkForP1Artist = { - ...mockArtwork, - ...{ - comparableAuctionResults: { - edges: [ - { - ...mockArtwork.comparableAuctionResults.edges[0], - ...{ - node: { - ...mockArtwork.comparableAuctionResults.edges[0].node, - artist: { - name: "Takashi Murakami", - targetSupply: { - isTargetSupply: true, - }, - }, - }, - }, - }, - ], - }, - }, -} diff --git a/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtworkInsights.tsx b/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtworkInsights.tsx index ae9f42be7d1..d8a01d2fc2f 100644 --- a/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtworkInsights.tsx +++ b/src/app/Scenes/MyCollection/Screens/Artwork/MyCollectionArtworkInsights.tsx @@ -52,7 +52,6 @@ const artworkFragment = graphql` isTargetSupply } } - ...RequestForPriceEstimateBanner_artwork ...MyCollectionArtworkDemandIndex_artwork ...MyCollectionArtworkArtistMarket_artwork ...MyCollectionArtworkComparableWorks_artwork @@ -61,8 +60,5 @@ const artworkFragment = graphql` ...MyCollectionArtworkArtistMarket_artworkPriceInsights ...MyCollectionArtworkDemandIndex_artworkPriceInsights } - consignmentSubmission { - state - } } ` diff --git a/src/app/Scenes/MyCollection/Screens/ArtworkForm/MyCollectionArtworkForm.tests.tsx b/src/app/Scenes/MyCollection/Screens/ArtworkForm/MyCollectionArtworkForm.tests.tsx index 49f1f1f0b2e..018ab63526a 100644 --- a/src/app/Scenes/MyCollection/Screens/ArtworkForm/MyCollectionArtworkForm.tests.tsx +++ b/src/app/Scenes/MyCollection/Screens/ArtworkForm/MyCollectionArtworkForm.tests.tsx @@ -1,15 +1,15 @@ import { act, fireEvent, screen } from "@testing-library/react-native" import { AutosuggestResultsQuery } from "__generated__/AutosuggestResultsQuery.graphql" import { myCollectionCreateArtworkMutation } from "__generated__/myCollectionCreateArtworkMutation.graphql" -import { saveOrUpdateArtwork } from "app/Scenes/MyCollection/Screens/ArtworkForm/methods/uploadArtwork" -import { ArtworkFormValues } from "app/Scenes/MyCollection/State/MyCollectionArtworkModel" -import * as artworkMutations from "app/Scenes/MyCollection/mutations/myCollectionCreateArtwork" -import { Tab } from "app/Scenes/MyProfile/MyProfileHeaderMyCollectionAndSavedWorks" import { getConvectionGeminiKey, getGeminiCredentialsForEnvironment, uploadFileToS3, -} from "app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/uploadFileToS3" +} from "app/Components/PhotoRow/utils/uploadFileToS3" +import { saveOrUpdateArtwork } from "app/Scenes/MyCollection/Screens/ArtworkForm/methods/uploadArtwork" +import { ArtworkFormValues } from "app/Scenes/MyCollection/State/MyCollectionArtworkModel" +import * as artworkMutations from "app/Scenes/MyCollection/mutations/myCollectionCreateArtwork" +import { Tab } from "app/Scenes/MyProfile/MyProfileHeaderMyCollectionAndSavedWorks" import { GlobalStore } from "app/store/GlobalStore" import { getMockRelayEnvironment } from "app/system/relay/defaultEnvironment" import * as LocalImageStore from "app/utils/LocalImageStore" @@ -23,7 +23,7 @@ import { } from "./MyCollectionArtworkForm" import * as photoUtil from "./MyCollectionImageUtil" -jest.mock("app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/uploadFileToS3", () => ({ +jest.mock("app/Components/PhotoRow/utils/uploadFileToS3", () => ({ getConvectionGeminiKey: jest.fn(), getGeminiCredentialsForEnvironment: jest.fn(), uploadFileToS3: jest.fn(), @@ -479,11 +479,6 @@ describe("MyCollectionArtworkForm", () => { countryCode: "some-country-code", }, confidentialNotes: "some-notes", - consignmentSubmission: { - displayText: "In progress", - internalID: "submission-id", - isEditable: false, - }, dimensions: { in: "23", cm: "26", diff --git a/src/app/Scenes/MyCollection/Screens/ArtworkForm/Screens/MyCollectionArtworkFormMain.tsx b/src/app/Scenes/MyCollection/Screens/ArtworkForm/Screens/MyCollectionArtworkFormMain.tsx index abed51cb619..06311462a92 100644 --- a/src/app/Scenes/MyCollection/Screens/ArtworkForm/Screens/MyCollectionArtworkFormMain.tsx +++ b/src/app/Scenes/MyCollection/Screens/ArtworkForm/Screens/MyCollectionArtworkFormMain.tsx @@ -5,13 +5,11 @@ import { Flex, Input, Join, - Message, Separator, Spacer, Text, useColor, useScreenDimensions, - useSpace, } from "@artsy/palette-mobile" import { useActionSheet } from "@expo/react-native-action-sheet" import { StackScreenProps } from "@react-navigation/stack" @@ -42,14 +40,7 @@ import { refreshMyCollection } from "app/utils/refreshHelpers" import { showPhotoActionSheet } from "app/utils/requestPhotos" import { isEmpty } from "lodash" import React, { useCallback, useEffect, useRef, useState } from "react" -import { - Alert, - Image, - KeyboardAvoidingView, - Platform, - ScrollView, - TouchableOpacity, -} from "react-native" +import { Alert, KeyboardAvoidingView, Platform, ScrollView, TouchableOpacity } from "react-native" import { useTracking } from "react-tracking" const SHOW_FORM_VALIDATION_ERRORS_IN_DEV = false @@ -67,7 +58,6 @@ export const MyCollectionArtworkFormMain: React.FC< const { formik } = useArtworkForm() const color = useColor() - const space = useSpace() const { showActionSheetWithOptions } = useActionSheet() @@ -196,10 +186,6 @@ export const MyCollectionArtworkFormMain: React.FC< navigation.goBack() } } - - const isSubmission = - mode === "edit" && artwork ? !!artwork.consignmentSubmission?.displayText : false - // To make the location input auto-suggestion dropdown visible when the keyboard is up, // we scroll the y position of the location input to move it to the top of the screen. const [locationInputYCoordinate, setLocationInputYCoordinate] = useState(0) @@ -290,19 +276,6 @@ export const MyCollectionArtworkFormMain: React.FC< ref={scrollViewRef} > - {!!isSubmission && ( - ( - - )} - /> - )} - }> diff --git a/src/app/Scenes/MyCollection/Screens/ArtworkList/MyCollectionArtworkGridItem.tests.tsx b/src/app/Scenes/MyCollection/Screens/ArtworkList/MyCollectionArtworkGridItem.tests.tsx index cd5b5c43ffe..2df8a2c3cf8 100644 --- a/src/app/Scenes/MyCollection/Screens/ArtworkList/MyCollectionArtworkGridItem.tests.tsx +++ b/src/app/Scenes/MyCollection/Screens/ArtworkList/MyCollectionArtworkGridItem.tests.tsx @@ -113,7 +113,6 @@ describe("MyCollectionArtworkGridItem", () => { marketPriceInsights: { demandRank: 0.91, }, - consignmentSubmission: null, }), }) @@ -135,9 +134,6 @@ describe("MyCollectionArtworkGridItem", () => { marketPriceInsights: { demandRank: 0.91, }, - consignmentSubmission: { - internalID: "submission-id", - }, }), }) diff --git a/src/app/Scenes/MyCollection/Screens/ArtworkList/MyCollectionArtworkGridItem.tsx b/src/app/Scenes/MyCollection/Screens/ArtworkList/MyCollectionArtworkGridItem.tsx index 2f309a540d1..3ab7ccf3895 100644 --- a/src/app/Scenes/MyCollection/Screens/ArtworkList/MyCollectionArtworkGridItem.tsx +++ b/src/app/Scenes/MyCollection/Screens/ArtworkList/MyCollectionArtworkGridItem.tsx @@ -25,18 +25,7 @@ const MyCollectionArtworkGridItem: React.FC = const localImage = useLocalImage(displayImage) - const { - artist, - artistNames, - internalID, - medium, - mediumType, - slug, - title, - image, - date, - submissionId, - } = artwork + const { artist, artistNames, internalID, medium, mediumType, slug, title, image, date } = artwork // consistent with how sections are derived in InfiniteScrollArtworksGrid const screen = useScreenDimensions() @@ -75,7 +64,6 @@ const MyCollectionArtworkGridItem: React.FC = imageURL={(localImage?.path || displayImage?.url) ?? undefined} aspectRatio={localImage?.aspectRatio || image?.aspectRatio} artworkSlug={slug} - artworkSubmissionId={submissionId} useRawURL={!!localImage} blurhash={showBlurhash ? image?.blurhash : undefined} /> @@ -139,7 +127,6 @@ export const MyCollectionArtworkGridItemFragmentContainer = createFragmentContai artistNames medium slug - submissionId title date marketPriceInsights { diff --git a/src/app/Scenes/MyCollection/Screens/Insights/MyCollectionMessages.tsx b/src/app/Scenes/MyCollection/Screens/Insights/MyCollectionMessages.tsx index d7194bd793b..474977c96d5 100644 --- a/src/app/Scenes/MyCollection/Screens/Insights/MyCollectionMessages.tsx +++ b/src/app/Scenes/MyCollection/Screens/Insights/MyCollectionMessages.tsx @@ -12,18 +12,6 @@ export const PurchasedArtworkAddedMessage: React.FC> = (pr ) } -export const SubmittedArtworkAddedMessage: React.FC> = (props) => { - return ( - - ) -} - export const AddedArtworkWithInsightsMessage: React.FC> = (props) => { return ( { - GlobalStore.actions.artworkSubmission.submission.resetSessionState() - let category = artwork.mediumType?.name - ? (formatCategoryValueForSubmission(artwork.mediumType?.name) as AcceptableCategoryValue) - : null - category = category ? ACCEPTABLE_CATEGORY_VALUES_MAP[category] ?? null : null - - GlobalStore.actions.artworkSubmission.submission.initializeArtworkDetailsForm({ - artist: artwork.artist?.name ?? "", - artistId: artwork.artist?.internalID ?? "", - title: artwork.title ?? "", - year: artwork.date ?? "", - medium: artwork.medium ?? "", - category, - attributionClass: getAttributionClassValueByName(artwork.attributionClass?.name), - editionNumber: artwork.editionNumber ?? "", - editionSizeFormatted: artwork.editionSize ?? "", - dimensionsMetric: artwork.metric ?? "", - height: artwork.height ?? "", - width: artwork.width ?? "", - depth: artwork.depth ?? "", - provenance: artwork.provenance ?? "", - source: "MY_COLLECTION", - myCollectionArtworkID: artwork.internalID, - }) - - const photos = artwork.images?.map((image: any) => ({ - path: image?.url?.replace(":version", "large") ?? "", - automaticallyAdded: true, - })) - - GlobalStore.actions.artworkSubmission.submission.initializePhotos(photos ?? []) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddDetails.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddDetails.tsx deleted file mode 100644 index 56322a19297..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddDetails.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { Flex, Input, Join, Spacer, Text } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { SelectOption } from "app/Components/Select" -import { useToast } from "app/Components/Toast/toastHook" -import { CategoryPicker } from "app/Scenes/MyCollection/Screens/ArtworkForm/Components/CategoryPicker" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useNavigationListeners } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { - AcceptableCategoryValue, - acceptableCategoriesForSubmission, -} from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/acceptableCategoriesForSubmission" -import { createOrUpdateSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission" -import { useFormikContext } from "formik" -import { useRef } from "react" -import { ScrollView } from "react-native" - -export const SubmitArtworkAddDetails = () => { - const { handleChange, setFieldValue, values } = useFormikContext() - - const { show: showToast } = useToast() - const setIsLoading = SubmitArtworkFormStore.useStoreActions((actions) => actions.setIsLoading) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - const navigation = useNavigation>() - - const { currentStep, useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("AddDetails") - - useNavigationListeners({ - onNextStep: async () => { - try { - setIsLoading(true) - await createOrUpdateSubmission( - { - year: values.year, - category: values.category, - medium: values.medium, - }, - values.externalId - ) - - navigation.navigate("PurchaseHistory") - setCurrentStep("PurchaseHistory") - } catch (error) { - console.error("Error setting title", error) - showToast("Something went wrong. The submission could not be updated.", "bottom") - } finally { - setIsLoading(false) - } - }, - }) - - const categories = useRef>>( - acceptableCategoriesForSubmission() - ).current - - return ( - - - - Artwork details - - - }> - - setFieldValue("year", e)} - accessibilityLabel="Year" - style={{ width: "50%" }} - // Only focus on the input and toggle the keyboard if this step is visible to the user. - autoFocus={currentStep === "AddDetails"} - /> - - - - handleChange={(category) => setFieldValue("category", category)} - options={categories} - required - value={values.category} - /> - - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddDimensions.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddDimensions.tsx deleted file mode 100644 index 07f444ae4cd..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddDimensions.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import { Box, Flex, Input, RadioButton, Spacer, Text } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { useToast } from "app/Components/Toast/toastHook" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useNavigationListeners } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { createOrUpdateSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission" -import { useFormikContext } from "formik" -import { useRef, useState } from "react" -import { ScrollView } from "react-native" -import { useDebounce } from "react-use" - -export const SubmitArtworkAddDimensions = () => { - const { setFieldValue, values } = useFormikContext() - const [dimensionMetric, setDimensionMetric] = useState(values.dimensionsMetric) - - const widthRef = useRef(null) - const depthRef = useRef(null) - - const { show: showToast } = useToast() - - const setIsLoading = SubmitArtworkFormStore.useStoreActions((actions) => actions.setIsLoading) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - const navigation = useNavigation>() - - const { useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("AddDimensions") - - useNavigationListeners({ - onNextStep: async () => { - try { - setIsLoading(true) - 20 - await createOrUpdateSubmission( - { - dimensionsMetric: dimensionMetric, - width: values.width, - height: values.height, - depth: values.depth, - }, - values.externalId - ) - - navigation.navigate("AddPhoneNumber") - setCurrentStep("AddPhoneNumber") - } catch (error) { - console.error("Error setting dimensions", error) - showToast("Could not save your submission, please try again.", "bottom", { - backgroundColor: "red100", - }) - } finally { - setIsLoading(false) - } - }, - }) - - // Debounce the metric change to improve the radio buttons UX - useDebounce( - () => { - setFieldValue("dimensionsMetric", dimensionMetric) - }, - 500, - [dimensionMetric] - ) - - return ( - - - - Artwork dimensions - - - - { - setDimensionMetric("in") - }} - /> - - - - { - setDimensionMetric("cm") - }} - /> - - - - - - - setFieldValue("height", e)} - fixedRightPlaceholder={dimensionMetric} - accessibilityLabel="Height" - onSubmitEditing={() => { - widthRef.current?.focus() - }} - returnKeyLabel="Next" - /> - - - - setFieldValue("width", e)} - fixedRightPlaceholder={dimensionMetric} - accessibilityLabel="Width" - ref={widthRef} - onSubmitEditing={() => { - depthRef.current?.focus() - }} - returnKeyLabel="Next" - /> - - - - setFieldValue("depth", e)} - fixedRightPlaceholder={dimensionMetric} - accessibilityLabel="Depth" - ref={depthRef} - /> - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddPhoneNumber.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddPhoneNumber.tsx deleted file mode 100644 index b134504ef03..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddPhoneNumber.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { Flex, Text } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { PhoneInput } from "app/Components/Input/PhoneInput" -import { useToast } from "app/Components/Toast/toastHook" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { TIER_1_STATES } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/constants" -import { useNavigationListeners } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { createOrUpdateSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission" -import { GlobalStore } from "app/store/GlobalStore" -import { refreshMyCollection } from "app/utils/refreshHelpers" -import { useFormikContext } from "formik" -import { ScrollView } from "react-native" - -export const SubmitArtworkAddPhoneNumber = () => { - const { handleChange, values } = useFormikContext() - - const { show: showToast } = useToast() - - const setIsLoading = SubmitArtworkFormStore.useStoreActions((actions) => actions.setIsLoading) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - - const navigation = useNavigation>() - - const { currentStep, useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("AddPhoneNumber") - - useNavigationListeners({ - onNextStep: async () => { - try { - setIsLoading(true) - - const nextStep = - values.state && TIER_1_STATES.includes(values.state) - ? "CompleteYourSubmission" - : "ShippingLocation" - const newValues = { - userPhone: values.userPhone, - state: values.state && TIER_1_STATES.includes(values.state) ? "SUBMITTED" : undefined, - } as const - - await createOrUpdateSubmission(newValues, values.externalId) - - navigation.navigate(nextStep) - setCurrentStep(nextStep) - - if (nextStep === "CompleteYourSubmission") { - // Reset saved draft if submission is successful - GlobalStore.actions.artworkSubmission.setDraft(null) - refreshMyCollection() - } - } catch (error) { - console.error("Error setting title", error) - showToast("Could not save your submission, please try again.", "bottom", { - backgroundColor: "red100", - }) - } finally { - setIsLoading(false) - } - }, - }) - - return ( - - - - Add phone number - - - - Add your number (optional) to allow an Artsy Advisor to contact you by phone. - - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddPhotos.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddPhotos.tsx deleted file mode 100644 index 5e8cfa43257..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddPhotos.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { Flex, Join, Message, Spacer, Text, Touchable } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { TipsForTakingPhotos } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkTipsForTakingPhotos" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useNavigationListeners } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { InfoModal } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/InfoModal/InfoModal" -import { UploadPhotosForm } from "app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/UploadPhotosForm" -import { useFormikContext } from "formik" -import { useState } from "react" -import { ScrollView } from "react-native" - -export const SubmitArtworkAddPhotos = () => { - const { values } = useFormikContext() - const [isModalVisible, setIsModalVisible] = useState(false) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - const navigation = useNavigation>() - - const { useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("AddPhotos") - - useNavigationListeners({ - onNextStep: () => { - setCurrentStep("AddDetails") - navigation.navigate("AddDetails") - }, - }) - - return ( - - - }> - Upload photos of your artwork - - - Make your work stand out and get your submission evaluated faster by uploading - high-quality photos of the work's front and back. - - - setIsModalVisible(true)}> - - Tips for taking photos - - - - {(values.photos.length === 1 || values.photos.length === 2) && ( - - )} - - - - - setIsModalVisible(false)} - buttonVariant="outline" - containerStyle={{ margin: 0 }} - fullScreen - > - setIsModalVisible(false)} /> - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddTitle.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddTitle.tsx deleted file mode 100644 index cb32d27b90a..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddTitle.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { Flex, Input, Spacer, Text } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { useToast } from "app/Components/Toast/toastHook" -import { ArtistSearchResult } from "app/Scenes/MyCollection/Screens/ArtworkForm/Components/ArtistSearchResult" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useNavigationListeners } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { createOrUpdateSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission" -import { useFormikContext } from "formik" -import { ScrollView } from "react-native" - -export const SubmitArtworkAddTitle = () => { - const { handleChange, values, setFieldValue } = useFormikContext() - - const { show: showToast } = useToast() - - const setIsLoading = SubmitArtworkFormStore.useStoreActions((actions) => actions.setIsLoading) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - - const navigation = useNavigation>() - - const { currentStep, useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("AddTitle") - - useNavigationListeners({ - onNextStep: async () => { - try { - setIsLoading(true) - const externalId = values.externalId - - // If no submission is present, create one - // This is the case when the user is submitting an artwork from my collection - if (!externalId) { - const response = await createOrUpdateSubmission(values, null) - setFieldValue("externalId", response?.externalID || externalId) - } - - await createOrUpdateSubmission( - { - title: values.title, - }, - externalId - ) - - navigation.navigate("AddPhotos") - setCurrentStep("AddPhotos") - } catch (error) { - console.error("Error setting title", error) - showToast("Could not save your submission, please try again.", "bottom", { - backgroundColor: "red100", - }) - } finally { - setIsLoading(false) - } - }, - }) - - return ( - - - - Add artwork title - - - - {!!values.artistSearchResult && } - - - - - - - - - Add ‘Unknown’ if unsure - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAdditionalDocuments.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAdditionalDocuments.tsx deleted file mode 100644 index 77a94aba25d..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAdditionalDocuments.tsx +++ /dev/null @@ -1,284 +0,0 @@ -import { - Button, - CloseIcon, - DocumentIcon, - Flex, - INPUT_BORDER_RADIUS, - Join, - ProgressBar, - Spacer, - Text, - Touchable, -} from "@artsy/palette-mobile" -import { useActionSheet } from "@expo/react-native-action-sheet" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { useToast } from "app/Components/Toast/toastHook" -import { ICON_HIT_SLOP } from "app/Components/constants" -import { isImage } from "app/Scenes/MyCollection/Screens/ArtworkForm/MyCollectionImageUtil" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useNavigationListeners } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { ICON_SIZE } from "app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/UploadPhotosForm" -import { addDocumentToSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/addDocumentToSubmission" // pragma: allowlist secret -import { deleteDocument } from "app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/deleteDocument" -import { NormalizedDocument, normalizeUploadedDocument } from "app/utils/normalizeUploadedDocument" -import { showDocumentsAndPhotosActionSheet } from "app/utils/showDocumentsAndPhotosActionSheet" -import { useFormikContext } from "formik" -import { useState } from "react" -import { Image, LayoutAnimation, Platform, ScrollView } from "react-native" - -// 50 MB in bytes -const FILE_SIZE_LIMIT = 50 * 1024 * 1024 - -export const SubmitArtworkAdditionalDocuments = () => { - const { values, setFieldValue } = useFormikContext() - const [progress, setProgress] = useState>({}) - - const { showActionSheetWithOptions } = useActionSheet() - - const { show: showToast } = useToast() - - const setIsLoading = SubmitArtworkFormStore.useStoreActions((actions) => actions.setIsLoading) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - - const navigation = - useNavigation>() - - const { useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("AdditionalDocuments") - - useNavigationListeners({ - onNextStep: async () => { - try { - setIsLoading(true) - - navigation.navigate("Condition") - setCurrentStep("Condition") - } catch (error) { - console.error("Error setting title", error) - showToast("Could not save your submission, please try again.", "bottom", { - backgroundColor: "red100", - }) - } finally { - setIsLoading(false) - } - }, - }) - - const handleUpload = async () => { - try { - const results = await showDocumentsAndPhotosActionSheet(showActionSheetWithOptions, true) - - const normalizedFiles = results.map((document) => normalizeUploadedDocument(document)) - - const filteredDocuments: NormalizedDocument[] = normalizedFiles - // Remove duplicates - .filter((document) => !values.additionalDocuments.find((doc) => doc.id === document.id)) - .map((document) => { - if (document.size && parseInt(document.size, 10) > FILE_SIZE_LIMIT) { - return { - ...document, - errorMessage: "File is too large (max. 50 MB)", - } - } - return document - }) - - if (filteredDocuments.length > 0) { - setIsLoading(true) - LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) - setFieldValue("additionalDocuments", values.additionalDocuments.concat(filteredDocuments)) - await Promise.all( - filteredDocuments - .filter((document) => !document.errorMessage) - .map((document) => { - if (values.externalId && values.submissionId) { - return addDocumentToSubmission({ - document, - externalId: values.externalId, - submissionId: values.submissionId, - updateProgress: (progress) => { - setProgress((previousProgress) => ({ - ...previousProgress, - [document.id]: progress, - })) - }, - onError: () => { - showToast("Could not upload file", "bottom", { - backgroundColor: "red100", - }) - }, - }) - } - }) - ) - } - } catch (error) { - if (typeof error === "object" && (error as any).code === "DOCUMENT_PICKER_CANCELED") { - return - } - console.error("Error uploading document", error) - - showToast("Could not upload documents, please try again.", "bottom", { - backgroundColor: "red100", - }) - } finally { - setIsLoading(false) - } - } - - // remove image assets from submission - const handleDelete = async (document: NormalizedDocument) => { - await deleteDocument({ - document, - onComplete: () => { - LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) - const filteredFiles = values.additionalDocuments.filter((doc) => doc.id !== document.id) - setFieldValue("additionalDocuments", filteredFiles) - }, - onError: () => { - showToast("Could not delete file", "bottom", { - backgroundColor: "red100", - }) - }, - }) - } - - return ( - - - - }> - Additional documents - - - Please add any of the follow if you have them: Proof of purchase, Certificate of - Authentication, Fact Sheet, Condition Report - - - - - - Maximum size: 50 MB. - - - - {values.additionalDocuments.map((document) => { - return ( - { - handleDelete(document) - }} - /> - ) - })} - - - - - - ) -} - -const CONTAINER_HEIGHT = 60 - -const UploadedFile: React.FC<{ - document: NormalizedDocument - onRemove: () => void - progress?: number | null -}> = ({ document, onRemove, progress }) => { - const sizeInMb = document.size ? (parseFloat(document.size) / 1024 / 1024).toFixed(2) : 0 - - return ( - - - - {isImage(document.item) && document.item.path ? ( - - ) : ( - - )} - - - - {document.name} - - {document.errorMessage ? ( - - {document.errorMessage} - - ) : ( - - {sizeInMb} MB - - )} - - - - - - - - - {!!progress && ( - - - - )} - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkArtistRejected.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkArtistRejected.tsx deleted file mode 100644 index 03e79a2149e..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkArtistRejected.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import { BulletedItem, Flex, Spacer, Text } from "@artsy/palette-mobile" -import { SubmitArtworkArtistRejectedQuery } from "__generated__/SubmitArtworkArtistRejectedQuery.graphql" -import { ArtistSearchResult } from "app/Scenes/MyCollection/Screens/ArtworkForm/Components/ArtistSearchResult" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { useSubmitArtworkTracking } from "app/Scenes/SellWithArtsy/Hooks/useSubmitArtworkTracking" -import { InfoModal } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/InfoModal/InfoModal" -import { navigate } from "app/system/navigation/navigate" -import { useFormikContext } from "formik" -import { useState } from "react" -import { ScrollView } from "react-native" -import { graphql, useLazyLoadQuery } from "react-relay" - -export const SubmitArtworkArtistRejected: React.FC<{}> = () => { - const { trackTappedContactAdvisor } = useSubmitArtworkTracking() - const { values } = useFormikContext() - const [isEligibilityModalVisible, setIsEligibilityModalVisible] = useState(false) - - const meData = useLazyLoadQuery( - SubmitArtworkArtistRejectedStepQuery, - {} - ) - const me = meData.me ?? null - - const { useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("ArtistRejected") - - return ( - - - - This artist isn't currently eligible to sell on our platform - - - - - {!!values.artistSearchResult && } - - - - - Try again with another artist or add your artwork to My Collection, your personal space to - manage your collection, track demand for your artwork and see updates about the artist. - {"\n"} - {"\n"}If you'd like to know more, you can{" "} - { - trackTappedContactAdvisor(me?.internalID, me?.email || undefined) - navigate("/sell/inquiry", { - passProps: { - email: me?.email ?? "", - name: me?.name ?? "", - phone: me?.phone ?? "", - userId: me?.internalID ?? undefined, - }, - }) - }} - > - contact an advisor - {" "} - or read about{" "} - { - setIsEligibilityModalVisible(true) - }} - > - what our advisors are looking for - - . {"\n"} - {"\n"}After adding to My Collection, an Artsy Advisor will be in touch if there is an - opportunity to sell your work in the future. - - - setIsEligibilityModalVisible(false)} - buttonVariant="outline" - fullScreen - > - - Eligible artist criteria - - - - - We are currently accepting unique and limited-edition works of art by modern, - contemporary, and emerging artists who have collector demand on Artsy. - {"\n"} - {"\n"} Our experts assess a number of factors to determine whether your work qualifies - for our program, including the following:{"\n"} - - - Market data like the number, recency, and value of auction results for works by the - artist. - - Authenticity and provenance information. - - Artwork details you provide, including images (front, back, signature), unframed - dimensions, and additional documentation. - - The price you’re looking for. - - - - ) -} - -export const SubmitArtworkArtistRejectedStepQuery = graphql` - query SubmitArtworkArtistRejectedQuery { - me { - internalID - email - name - phone - } - } -` diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkBottomNavigation.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkBottomNavigation.tsx deleted file mode 100644 index 5e4b5f63ec7..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkBottomNavigation.tsx +++ /dev/null @@ -1,231 +0,0 @@ -import { Button, Flex, Spacer, Text, Touchable, useSpace } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { - INITIAL_EDIT_STEP, - SubmitArtworkStackNavigation, -} from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { useSubmitArtworkTracking } from "app/Scenes/SellWithArtsy/Hooks/useSubmitArtworkTracking" -import { Photo } from "app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/validation" -import { GlobalStore } from "app/store/GlobalStore" -import { dismissModal, navigate, popToRoot, switchTab } from "app/system/navigation/navigate" -import { useIsKeyboardVisible } from "app/utils/hooks/useIsKeyboardVisible" -import { NormalizedDocument } from "app/utils/normalizeUploadedDocument" -import { useFormikContext } from "formik" -import { useEffect } from "react" -import { LayoutAnimation } from "react-native" -import { useSafeAreaInsets } from "react-native-safe-area-context" - -export const SubmitArtworkBottomNavigation: React.FC<{}> = () => { - const { - trackTappedSubmissionBack, - trackTappedSubmitAnotherWork, - trackTappedViewArtworkInMyCollection, - } = useSubmitArtworkTracking() - const { - navigateToNextStep, - navigateToPreviousStep, - isFinalStep, - isValid, - currentStep, - isLoading, - } = useSubmissionContext() - const { values } = useFormikContext() - const navigation = useNavigation>() - - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - - const { trackTappedNewSubmission, trackTappedStartMyCollection, trackConsignmentSubmitted } = - useSubmitArtworkTracking() - - const isUploadingAdditionalDocuments = values.additionalDocuments.some( - (document: NormalizedDocument) => document.loading - ) - const allDocumentsAreValid = values.additionalDocuments.every( - (document: NormalizedDocument) => !document.errorMessage - ) - - const isUploadingPhotos = values.photos.some((photo: Photo) => photo.loading) - const allPhotosAreValid = values.photos.every( - (photo: Photo) => !photo.error && !photo.errorMessage - ) - - const handleBackPress = () => { - trackTappedSubmissionBack(values.externalId, currentStep) - navigateToPreviousStep() - } - - const handleNextPress = () => { - if (isFinalStep) { - trackConsignmentSubmitted(values.externalId) - } - - navigateToNextStep() - } - - useEffect(() => { - LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) - }, [currentStep]) - - if ( - !currentStep || - currentStep === "SelectArtist" || - currentStep === "SubmitArtworkFromMyCollection" - ) { - return null - } - - if (currentStep === "StartFlow") { - return ( - - - - - ) - } - - if (currentStep === "CompleteYourSubmission") { - return ( - - - - - - - ) - } - - if (currentStep === "ArtistRejected") { - return ( - - - - - - - - - - - - ) - } - - // Hide the "Back" button in the Title step when editing a submission to disallow updating the artist. - const displayBackButton = !(values.externalId && currentStep === INITIAL_EDIT_STEP) - - return ( - - - - {!!displayBackButton && ( - - Back - - )} - - - - - ) -} - -const Wrapper: React.FC<{}> = ({ children }) => { - const isKeyboardVisible = useIsKeyboardVisible(true) - const { bottom: bottomInset } = useSafeAreaInsets() - const space = useSpace() - - return ( - - {children} - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkCompleteYourSubmission.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkCompleteYourSubmission.tsx deleted file mode 100644 index 39577062af8..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkCompleteYourSubmission.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { Flex, Message, Spacer, Text } from "@artsy/palette-mobile" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { useFormikContext } from "formik" -import { useEffect } from "react" -import { BackHandler, ScrollView } from "react-native" - -export const SubmitArtworkCompleteYourSubmission = () => { - const { values } = useFormikContext() - // Do not allow the user to go back when pressing the back button on Android - useEffect(() => { - const subscription = BackHandler.addEventListener("hardwareBackPress", () => { - return true - }) - - return () => subscription.remove() - }, []) - - const { useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking( - values.state === "APPROVED" ? "CompleteYourSubmissionPostApproval" : "CompleteYourSubmission" - ) - - if (values.state === "APPROVED") { - return ( - - - - - - Thank you for submitting additional information - - - - - - This will be used to list, sell and fulfill your work. Additional information may be - requested. - - - - - - - - ) - } - - return ( - - - - - - Thank you for submitting your artwork - - - - - - An Artsy Advisor will email you within 3-5 days to review your submission and discuss next - steps. In the meantime you can view your submission in My Collection. - - - - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkCondition.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkCondition.tsx deleted file mode 100644 index 1a620fdb170..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkCondition.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import { Flex, Input, Spacer, Text } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { captureException } from "@sentry/react-native" -import { myCollectionUpdateArtworkMutation } from "__generated__/myCollectionUpdateArtworkMutation.graphql" -import { Select } from "app/Components/Select" -import { useToast } from "app/Components/Toast/toastHook" -import { myCollectionUpdateArtwork } from "app/Scenes/MyCollection/mutations/myCollectionUpdateArtwork" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useNavigationListeners } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { InfoModal } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/InfoModal/InfoModal" -import { createOrUpdateSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission" -import { GlobalStore } from "app/store/GlobalStore" -import { refreshMyCollection } from "app/utils/refreshHelpers" -import { useFormikContext } from "formik" -import { useState } from "react" -import { ScrollView } from "react-native" - -export const SubmitArtworkCondition = () => { - const { values, handleChange, setFieldValue } = useFormikContext() - - const { show: showToast } = useToast() - - const [isModalVisible, setIsModalVisible] = useState(false) - - const setIsLoading = SubmitArtworkFormStore.useStoreActions((actions) => actions.setIsLoading) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - - const navigation = useNavigation>() - - const { useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("Condition") - - useNavigationListeners({ - onNextStep: async () => { - try { - setIsLoading(true) - - if (!values.artwork.internalID) { - captureException("Artwork ID is required") - showToast("Could not save your submission, please try again.", "bottom", { - backgroundColor: "red100", - }) - return - } - - // Make API call to update related My Collection artwork - const newValues: myCollectionUpdateArtworkMutation["variables"]["input"] = { - artworkId: values.artwork.internalID, - condition: values.artwork.condition, - conditionDescription: values.artwork.conditionDescription, - } - - // Make API call to update related My Collection artwork - await myCollectionUpdateArtwork(newValues) - - // Update submission state - await createOrUpdateSubmission( - { - state: "RESUBMITTED", - }, - values.externalId - ) - // Reset saved draft if submission is successful - GlobalStore.actions.artworkSubmission.setDraft(null) - - refreshMyCollection() - - navigation.navigate("CompleteYourSubmission") - setCurrentStep("CompleteYourSubmission") - } catch (error) { - console.error("Error setting title", error) - showToast("Could not save your submission, please try again.", "bottom", { - backgroundColor: "red100", - }) - } finally { - setIsLoading(false) - } - }, - }) - - return ( - - - - Condition - - - - - Please specify the condition of the piece. Note that the seller is liable for providing - an accurate description. - - - - - - - - setIsModalVisible(false)} - buttonVariant="outline" - fullScreen - > - - Condition Definitions - - - - {CONDITION_DEFINITIONS.map((definition) => { - return ( - - - {definition.title}: - - {definition.description} - - ) - })} - - - - ) -} - -const CONDITION_DEFINITIONS = [ - { - title: "Excellent Condition", - description: - "No signs of age or wear, undulation associated with hinging. Work may be unsealed in original packaging.", - }, - { - title: "Very Good Condition", - description: - "Overall very good condition, minor signs of wear or age such as light handling creases, scuffing, foxing, discoloration, buckling, and pinholes. Also includes works that have been previously restored.", - }, - { - title: "Good Condition", - description: - "Overall good condition but with noticeable wear or age such as hard creases, scratches, indentations, water damage (associated buckling), foxing, discoloration, attenuation, material loss and tearing. May require the attention of a conservator.", - }, - { - title: "Fair Condition", - description: - "Overall fair condition with significant wear and age that requires the attention of a conservator.", - }, -] diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore.tsx deleted file mode 100644 index 2bdb80bfd1a..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { - SUBMIT_ARTWORK_DRAFT_SUBMISSION_STEPS, - SubmitArtworkScreen, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/constants" -import { Action, State, action, createContextStore } from "easy-peasy" - -export interface SubmitArtworkFormStoreModel { - currentStep: SubmitArtworkScreen - isLoading: boolean - setCurrentStep: Action - setIsLoading: Action -} - -export type SubmitArtworkFormStoreModelState = State - -export const SubmitArtworkFormStoreModel: SubmitArtworkFormStoreModel = { - currentStep: SUBMIT_ARTWORK_DRAFT_SUBMISSION_STEPS[0], - isLoading: false, - setCurrentStep: action((state, payload) => { - state.currentStep = payload - }), - setIsLoading: action((state, payload) => { - state.isLoading = payload - }), -} - -export const SubmitArtworkFormStore = createContextStore((injections) => ({ - ...SubmitArtworkFormStoreModel, - ...injections, -})) - -export const SubmitArtworkFormStoreProvider = SubmitArtworkFormStore.Provider diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFrameInformation.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFrameInformation.tsx deleted file mode 100644 index f43edcaed62..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFrameInformation.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import { Box, Flex, Input, RadioButton, Spacer, Text } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { useToast } from "app/Components/Toast/toastHook" -import { myCollectionUpdateArtwork } from "app/Scenes/MyCollection/mutations/myCollectionUpdateArtwork" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useNavigationListeners } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { useFormikContext } from "formik" -import { useRef } from "react" -import { LayoutAnimation, ScrollView } from "react-native" - -export const SubmitArtworkFrameInformation = () => { - const { values, setFieldValue, handleChange } = useFormikContext() - - const { show: showToast } = useToast() - - const widthRef = useRef(null) - const depthRef = useRef(null) - - const setIsLoading = SubmitArtworkFormStore.useStoreActions((actions) => actions.setIsLoading) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - - const navigation = - useNavigation>() - - const { useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("FrameInformation") - - useNavigationListeners({ - onNextStep: async () => { - try { - setIsLoading(true) - - if (!values.artwork.internalID) { - throw new Error("Artwork ID is required") - } - - const newValues = { - artworkId: values.artwork.internalID, - framedMetric: values.artwork.framedMetric, - framedWidth: values.artwork.framedWidth, - framedHeight: values.artwork.framedHeight, - framedDepth: values.artwork.framedDepth, - isFramed: values.artwork.isFramed, - } - - // Make API call to update related My Collection artwork - await myCollectionUpdateArtwork(newValues) - - navigation.navigate("AdditionalDocuments") - setCurrentStep("AdditionalDocuments") - } catch (error) { - console.error("Error setting title", error) - showToast("Could not save your submission, please try again.", "bottom", { - backgroundColor: "red100", - }) - } finally { - setIsLoading(false) - } - }, - }) - - return ( - - - - Frame - - - Is the work framed? - - - - { - LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) - setFieldValue("artwork.isFramed", true) - }} - /> - - - - { - LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) - setFieldValue("artwork.isFramed", false) - setFieldValue("artwork.framedMetric", null) - setFieldValue("artwork.framedWidth", null) - setFieldValue("artwork.framedHeight", null) - setFieldValue("artwork.framedDepth", null) - }} - /> - - - {values.artwork.isFramed === true && ( - - - - { - widthRef.current?.focus() - }} - returnKeyLabel="Next" - /> - - - - { - depthRef.current?.focus() - }} - returnKeyLabel="Next" - /> - - - - - - - - - - { - setFieldValue("artwork.framedMetric", "in") - }} - /> - - - - { - setFieldValue("artwork.framedMetric", "cm") - }} - /> - - - )} - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFromMyCollection.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFromMyCollection.tsx deleted file mode 100644 index 3844d26312d..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFromMyCollection.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Flex } from "@artsy/palette-mobile" -import { - SubmitArtworkFromMyCollectionArtworks, - SubmitArtworkFromMyCollectionHeader, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFromMyCollectionArtworks" -import { PlaceholderGrid } from "app/utils/placeholderGrid" -import { Suspense } from "react" - -export const SubmitArtworkFromMyCollection: React.FC = ({}) => { - return ( - - - - - - - } - > - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFromMyCollectionArtworks.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFromMyCollectionArtworks.tsx deleted file mode 100644 index b64ef3f6c80..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFromMyCollectionArtworks.tsx +++ /dev/null @@ -1,196 +0,0 @@ -import { OwnerType } from "@artsy/cohesion" -import { Button, Flex, LinkText, Message, Spacer, Text } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { SubmitArtworkFromMyCollectionArtworksQuery } from "__generated__/SubmitArtworkFromMyCollectionArtworksQuery.graphql" -import { SubmitArtworkFromMyCollectionArtworks_me$key } from "__generated__/SubmitArtworkFromMyCollectionArtworks_me.graphql" -import { MasonryInfiniteScrollArtworkGrid } from "app/Components/ArtworkGrids/MasonryInfiniteScrollArtworkGrid" -import LoadingModal from "app/Components/Modals/LoadingModal" -import { PAGE_SIZE } from "app/Components/constants" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { fetchArtworkInformation } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/fetchArtworkInformation" -import { getInitialSubmissionFormValuesFromArtwork } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialSubmissionValuesFromArtwork" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { createOrUpdateSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission" -import { dismissModal, switchTab } from "app/system/navigation/navigate" -import { extractNodes } from "app/utils/extractNodes" -import { useRefreshControl } from "app/utils/refreshHelpers" -import { useFormikContext } from "formik" -import { useState } from "react" -import { Alert } from "react-native" -import { graphql, useLazyLoadQuery, usePaginationFragment } from "react-relay" - -export const SubmitArtworkFromMyCollectionArtworks: React.FC<{}> = () => { - const [isLoading, setIsLoading] = useState(false) - - const queryData = useLazyLoadQuery( - submitArtworkFromMyCollectionQuery, - submitArtworkFromMyCollectionQueryVariables - ) - - const { data, loadNext, hasNext, isLoadingNext, refetch } = usePaginationFragment< - SubmitArtworkFromMyCollectionArtworksQuery, - SubmitArtworkFromMyCollectionArtworks_me$key - >(artworkConnectionFragment, queryData.me) - - const artworks = extractNodes(data?.myCollectionConnection) - - const nonSubmittedArtworks = artworks.filter((artwork) => !artwork.submissionId) - - const navigation = useNavigation>() - - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - - const RefreshControl = useRefreshControl(refetch) - - const { setValues, values } = useFormikContext() - - const handlePress = async (artworkID: string) => { - try { - setIsLoading(true) - // Fetch Artwork Details - - const artwork = await fetchArtworkInformation(artworkID) - - if (artwork) { - const artworkValues = { - ...getInitialSubmissionFormValuesFromArtwork(artwork), - submissionId: values.submissionId, - externalId: values.externalId, - userName: values.userName, - userEmail: values.userEmail, - userPhone: values.userPhone, - } - - const submission = await createOrUpdateSubmission(artworkValues, values.submissionId) - - setValues({ - ...artworkValues, - submissionId: submission?.internalID || values.submissionId, - externalId: submission?.externalID || values.externalId, - }) - - setIsLoading(false) - - navigation.navigate("SelectArtist") - setCurrentStep("SelectArtist") - } - } catch (error) { - console.error( - "Failed to fetch artwork details or create submission when starting sell flow from My Collection.", - error - ) - Alert.alert( - "Failed to fetch artwork details or create submission.", - "Please try again or enter details manually." - ) - } finally { - setIsLoading(false) - } - } - - if (!nonSubmittedArtworks.length) { - return ( - - - - - - You have no eligible works in{" "} - { - dismissModal() - switchTab("profile") - }} - > - My Collection.{"\n"} - - - - - - - - - ) - } - - return ( - - loadNext(pageSize)} - hasMore={hasNext} - isLoading={isLoadingNext} - onPress={handlePress} - extraData={artworks} - hideSaleInfo - hideSaveIcon - refreshControl={RefreshControl} - ListHeaderComponent={SubmitArtworkFromMyCollectionHeader} - /> - - - ) -} - -export const SubmitArtworkFromMyCollectionHeader: React.FC = () => { - return ( - <> - Select artwork from My Collection - - - You will only see eligible artworks. Artworks that have already been submitted won't be - shown. - - - ) -} -export const submitArtworkFromMyCollectionQueryVariables = { - count: PAGE_SIZE, -} -const submitArtworkFromMyCollectionQuery = graphql` - query SubmitArtworkFromMyCollectionArtworksQuery($count: Int, $after: String) { - me { - ...SubmitArtworkFromMyCollectionArtworks_me @arguments(count: $count, after: $after) - } - } -` - -const artworkConnectionFragment = graphql` - fragment SubmitArtworkFromMyCollectionArtworks_me on Me - @refetchable(queryName: "SubmitArtworkFromMyCollectionArtworks_meRefetch") - @argumentDefinitions(count: { type: "Int", defaultValue: 10 }, after: { type: "String" }) { - myCollectionConnection( - first: $count - after: $after - includeOnlyTargetSupply: true - sort: CREATED_AT_DESC - ) @connection(key: "SubmitArtworkFromMyCollectionArtworks_myCollectionConnection") { - edges { - cursor - node { - id - slug - submissionId - image(includeAll: false) { - aspectRatio - blurhash - } - ...ArtworkGridItem_artwork @arguments(includeAllImages: false) - } - } - } - } -` diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkNewScreenTemplate.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkNewScreenTemplate.tsx deleted file mode 100644 index 57e00020a7f..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkNewScreenTemplate.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { Flex, Input, Spacer, Text } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { useToast } from "app/Components/Toast/toastHook" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useNavigationListeners } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { createOrUpdateSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission" -import { useFormikContext } from "formik" -import { ScrollView } from "react-native" - -export const SubmitArtworkNewScreenTemplate = () => { - const { handleChange, values } = useFormikContext() - - const { show: showToast } = useToast() - - const { currentStep } = useSubmissionContext() - - const setIsLoading = SubmitArtworkFormStore.useStoreActions((actions) => actions.setIsLoading) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - - // TODO: Replace with the correct screen name - // @ts-expect-error - const navigation = useNavigation>() - - useNavigationListeners({ - onNextStep: async () => { - try { - setIsLoading(true) - - await createOrUpdateSubmission( - { - // values you want to update - }, - values.externalId - ) - - // TODO: Replace with the correct next screen name - // @ts-expect-error - navigation.navigate("NextScreenName") - // TODO: Replace with the correct next screen name - // @ts-expect-error - setCurrentStep("NextScreenName") - } catch (error) { - console.error("Error setting title", error) - showToast("Could not save your submission, please try again.", "bottom", { - backgroundColor: "red100", - }) - } finally { - setIsLoading(false) - } - }, - }) - - return ( - - - - New Screen Title - - - - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkProgressBar.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkProgressBar.tsx deleted file mode 100644 index e4fb7433262..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkProgressBar.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { CheckCircleFillIcon, Flex, ProgressBar } from "@artsy/palette-mobile" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { __unsafe__SubmissionArtworkFormNavigationRef } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { - SUBMIT_ARTWORK_APPROVED_SUBMISSION_STEPS, - SUBMIT_ARTWORK_DRAFT_SUBMISSION_STEPS, - SubmitArtworkScreen, - TIER_1_STATES, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/constants" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { useFormikContext } from "formik" -import { useCallback, useMemo } from "react" - -// Steps that should not be counted in the progress bar -const NON_COUNTABLE_STEPS: SubmitArtworkScreen[] = ["StartFlow", "ArtistRejected"] - -// Steps that should be counted in the progress bar -const DRAFT_SUBMISSION_COUNTABLE_STEPS = SUBMIT_ARTWORK_DRAFT_SUBMISSION_STEPS.filter( - (step) => NON_COUNTABLE_STEPS.indexOf(step) === -1 -) - -const APPROVED_SUBMISSION_COUNTABLE_STEPS = SUBMIT_ARTWORK_APPROVED_SUBMISSION_STEPS.filter( - (step) => NON_COUNTABLE_STEPS.indexOf(step) === -1 -) - -const PROGRESS_BAR_CONTAINER_HEIGHT = 22 -const PROGRESS_BAR_HEIGHT = 4 -const ICON_SIZE = 22 - -export const SubmitArtworkProgressBar: React.FC = ({}) => { - const currentStep = SubmitArtworkFormStore.useStoreState((state) => state.currentStep) - const { values } = useFormikContext() - - const hasStartedFlowFromMyCollection = useMemo(() => { - const routes = ( - __unsafe__SubmissionArtworkFormNavigationRef?.current?.getState()?.routes || [] - ).map((route) => route.name) - - // This is required in case the reference value comes later than the first render - if (currentStep === "SubmitArtworkFromMyCollection") { - return true - } - - if (routes && routes.includes("SubmitArtworkFromMyCollection")) { - return true - } - - return false - }, [currentStep]) - - // Returns the total steps based on whether the flow has started from My Collection or not - // This is required for accurate progress bar calculation - const getTotalSteps = useCallback(() => { - const allSteps = - values.state && !TIER_1_STATES.includes(values.state) - ? APPROVED_SUBMISSION_COUNTABLE_STEPS - : DRAFT_SUBMISSION_COUNTABLE_STEPS - - return hasStartedFlowFromMyCollection - ? allSteps - : allSteps.filter((step) => step !== "SubmitArtworkFromMyCollection") - }, [hasStartedFlowFromMyCollection]) - - const totalSteps = getTotalSteps() - - const progress = (totalSteps.indexOf(currentStep) + 1) / totalSteps.length - - if (!currentStep || NON_COUNTABLE_STEPS.includes(currentStep)) { - // Returning a Flex with the same height as the progress bar to keep the layout consistent - return - } - - const hasCompletedForm = currentStep === "CompleteYourSubmission" - - return ( - - - - - - {!!hasCompletedForm && ( - - )} - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkPurchaseHistory.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkPurchaseHistory.tsx deleted file mode 100644 index 93dea76e2f6..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkPurchaseHistory.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import { Flex, Join, RadioButton, Spacer, Text } from "@artsy/palette-mobile" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { Select } from "app/Components/Select" -import { useToast } from "app/Components/Toast/toastHook" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useNavigationListeners } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { createOrUpdateSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission" -import { useFormikContext } from "formik" -import { useEffect, useState } from "react" -import { ScrollView } from "react-native" - -export const PROVENANCE_LIST = [ - "Purchased directly from gallery", - "Purchased directly from artist", - "Purchased at auction", - "Gift from the artist", - "Other", - "I don’t know", -].map((provenance) => ({ - value: provenance, - label: provenance, -})) - -export const SubmitArtworkPurchaseHistory = () => { - const { setFieldValue, values } = useFormikContext() - - const [isSigned, setIsSigned] = useState(values.signature) - - const { show: showToast } = useToast() - - const setIsLoading = SubmitArtworkFormStore.useStoreActions((actions) => actions.setIsLoading) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - - const navigation = - useNavigation>() - - const { useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("PurchaseHistory") - - useNavigationListeners({ - onNextStep: async () => { - try { - setIsLoading(true) - - await createOrUpdateSubmission( - { - provenance: values.provenance, - signature: values.signature, - }, - values.externalId - ) - - navigation.navigate("AddDimensions") - setCurrentStep("AddDimensions") - } catch (error) { - console.error("Error setting title", error) - showToast("Could not save your submission, please try again.", "bottom", { - backgroundColor: "red100", - }) - } finally { - setIsLoading(false) - } - }, - }) - - useEffect(() => { - // This is required for performance reasons - // We don't want to set the value of the form field on every render - if (isSigned !== null && isSigned !== undefined) { - setFieldValue("signature", isSigned) - } - }, [isSigned, setFieldValue]) - - return ( - - - - Where did you purchase the artwork? - - - - - }> - - (null) - const address2Ref = useRef(null) - const cityRef = useRef(null) - const postalCodeRef = useRef(null) - const stateRef = useRef(null) - - const { show: showToast } = useToast() - - const setIsLoading = SubmitArtworkFormStore.useStoreActions((actions) => actions.setIsLoading) - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - - const navigation = - useNavigation>() - - const { useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("ShippingLocation") - - useNavigationListeners({ - onNextStep: async () => { - try { - setIsLoading(true) - - await createOrUpdateSubmission( - { - location: { - city: values.location?.city, - state: values.location?.state, - country: values.location?.country, - countryCode: values.location?.countryCode, - zipCode: values.location?.zipCode, - address: values.location?.address, - address2: values.location?.address2, - }, - }, - values.externalId - ) - - navigation.navigate("FrameInformation") - setCurrentStep("FrameInformation") - } catch (error) { - console.error("Error setting title", error) - showToast("Could not save your submission, please try again.", "bottom", { - backgroundColor: "red100", - }) - } finally { - setIsLoading(false) - } - }, - }) - - return ( - - - } flatten> - Shipping Location - - - Location is where the artwork ships from. It’s required so we can estimate shipping - costs and tax. - - - { - const newCountry = COUNTRY_SELECT_OPTIONS.find(({ value }) => value === countryCode) - - if (newCountry) { - setFieldValue("location.country", newCountry.label) - setFieldValue("location.countryCode", newCountry.value) - } - }} - value={ - values.location?.countryCode || - COUNTRY_SELECT_OPTIONS.find(({ label }) => label === values.location?.country)?.value - } - required - testID="country-select" - /> - - {!!values.location?.country && ( - }> - setFieldValue("location.address", text)} - required - ref={addressRef} - onSubmitEditing={() => { - address2Ref.current?.focus() - }} - /> - - setFieldValue("location.address2", text)} - ref={address2Ref} - onSubmitEditing={() => { - cityRef.current?.focus() - }} - /> - - setFieldValue("location.city", text)} - required - ref={cityRef} - onSubmitEditing={() => { - postalCodeRef.current?.focus() - }} - /> - - setFieldValue("location.zipCode", text)} - required - ref={postalCodeRef} - onSubmitEditing={() => { - stateRef.current?.focus() - }} - /> - - setFieldValue("location.state", text)} - required - ref={stateRef} - /> - - )} - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkStartFlow.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkStartFlow.tsx deleted file mode 100644 index 8e7a0d44c4f..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkStartFlow.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { Flex, Spacer, Text } from "@artsy/palette-mobile" -import { useSubmissionContext } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { Image, ScrollView } from "react-native" - -const SECTIONS = [ - { - title: "Tell us about your work", - description: - "Start by adding an artist from our list of approved artists. Include information such as year, medium, dimensions and materials.", - image: require("images/submit_artwork_tell_us_about_your_work.webp"), - }, - { - title: "Upload artwork images", - description: - "Improve your chances of selling by providing clear images of the front, back, frame, signature and other details.", - image: require("images/submit_artwork_upload_artwork_image.webp"), - }, - { - title: "Complete submission", - description: - "Your artwork will be reviewed by an Artsy Advisor who will assess whether your work is eligible and help guide you on next steps.", - image: require("images/submit_artwork_complete_submission.webp"), - }, -] -export const SubmitArtworkStartFlow: React.FC = () => { - const { useSubmitArtworkScreenTracking } = useSubmissionContext() - - useSubmitArtworkScreenTracking("StartFlow") - - return ( - - - - It’s easy to sell on Artsy - - - - {SECTIONS.map((section, index) => ( - - - {index + 1} - - - - {section.title} - - - {section.description} - - - - - - ))} - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkTipsForTakingPhotos.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkTipsForTakingPhotos.tsx deleted file mode 100644 index 9ef596b4ba0..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkTipsForTakingPhotos.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import { Button, Flex, Join, Spacer, Text, useSpace } from "@artsy/palette-mobile" -import { Image, ScrollView } from "react-native" - -export const TipsForTakingPhotos: React.FC<{ onDismiss: () => void }> = ({ onDismiss }) => { - const space = useSpace() - - return ( - - - - Three tips to improve your chances of selling - - }> - <> - - }> - - - - - - - - - Upload high-quality photos of the artwork’s front and back using natural light and a - neutral backdrop. Shoot from various angles. - - - <> - - }> - - - - - - - - - Include signatures, edition numbers or close-ups of details to give confidence to - buyers. - - - <> - - }> - - - - - - - - - Include framed images or display the artwork in real-life settings to help buyers - visualize how it will look in their own spaces. - - - - - - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkTopNavigation.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkTopNavigation.tsx deleted file mode 100644 index 84d2c251a3d..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkTopNavigation.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import { BackButton, Flex, Text, Touchable } from "@artsy/palette-mobile" -import { useToast } from "app/Components/Toast/toastHook" -import { myCollectionUpdateArtwork } from "app/Scenes/MyCollection/mutations/myCollectionUpdateArtwork" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkProgressBar } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkProgressBar" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { useSubmitArtworkTracking } from "app/Scenes/SellWithArtsy/Hooks/useSubmitArtworkTracking" -import { createOrUpdateSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission" -import { GlobalStore } from "app/store/GlobalStore" -import { goBack } from "app/system/navigation/navigate" -import { refreshSellScreen } from "app/utils/refreshHelpers" -import { useFormikContext } from "formik" -import { useEffect } from "react" -import { Alert, Keyboard, LayoutAnimation } from "react-native" - -const HEADER_HEIGHT = 50 - -export const SubmitArtworkTopNavigation: React.FC<{}> = () => { - const toast = useToast() - const { trackTappedSubmissionSaveExit } = useSubmitArtworkTracking() - const currentStep = SubmitArtworkFormStore.useStoreState((state) => state.currentStep) - const hasCompletedForm = currentStep === "CompleteYourSubmission" - - const { values } = useFormikContext() - - const handleSaveAndExitPress = async () => { - Keyboard.dismiss() - - if (hasCompletedForm) { - // Reset form if user is on the last step - // This is to ensure that the user can start a new submission - // This is not required but is a nice to have as a second layer of protection - GlobalStore.actions.artworkSubmission.setDraft(null) - return goBack() - } - - try { - trackTappedSubmissionSaveExit(values.externalId, currentStep) - - await createOrUpdateSubmission(values, values.externalId) - - // If an submission has a my collection artwork, we need to update its values - if (values.artwork.internalID) { - try { - const newValues = { - artworkId: values.artwork.internalID, - framedMetric: values.artwork.framedMetric, - framedWidth: values.artwork.framedWidth, - framedHeight: values.artwork.framedHeight, - framedDepth: values.artwork.framedDepth, - isFramed: values.artwork.isFramed, - condition: values.artwork.condition || undefined, - conditionDescription: values.artwork.conditionDescription, - } - - // Make API call to update my collection artwork - await myCollectionUpdateArtwork(newValues) - } catch (error) { - console.error( - "Something went wrong. Some values on the MyC artwork could not be updated.", - error - ) - toast.show("Something went wrong. Some values could not be updated.", "bottom", { - backgroundColor: "yellow100", - }) - } - } - - if (values.externalId) { - GlobalStore.actions.artworkSubmission.setDraft({ - submissionID: values.externalId, - currentStep, - }) - } - - refreshSellScreen() - } catch (error) { - console.log({ error }) - console.error("Something went wrong. The submission could not be saved.", error) - - Alert.alert("Something went wrong. The submission could not be saved.") - } - - goBack() - } - - useEffect(() => { - LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) - }, [currentStep]) - - if (!currentStep) { - return null - } - - const showXButton = [ - "StartFlow", - "ArtistRejected", - "SelectArtist", - "SubmitArtworkFromMyCollection", - ].includes(currentStep) - const showProgressBar = !["StartFlow", "ArtistRejected"].includes(currentStep) - const showSaveAndExit = ![ - "StartFlow", - "ArtistRejected", - "SelectArtist", - "SubmitArtworkFromMyCollection", - ].includes(currentStep) - - const handleBackPress = () => { - goBack() - } - - return ( - - - {!!showXButton && ( - handleBackPress()} - /> - )} - {!!showSaveAndExit && ( - - - {!hasCompletedForm ? "Save & " : ""}Exit - - - )} - - {!!showProgressBar && } - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddDetails.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddDetails.tests.tsx deleted file mode 100644 index 54c42cf3526..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddDetails.tests.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { fireEvent, screen } from "@testing-library/react-native" -import { SubmitArtworkAddDetails } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddDetails" -import { renderWithSubmitArtworkWrapper } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" -import { flushPromiseQueue } from "app/utils/tests/flushPromiseQueue" - -describe("SubmitArtworkAddDetails", () => { - it("Shows and updates the artwork details properly", async () => { - renderWithSubmitArtworkWrapper({ - component: , - }) - - const yearInput = screen.getByTestId("Submission_YearInput") - expect(yearInput).toBeOnTheScreen() - fireEvent.changeText(yearInput, "2024") - expect(yearInput.props.value).toBe("2024") - - const mediumPicker = screen.getByTestId("CategorySelect") - fireEvent.press(mediumPicker) - // Wait for the select modal to show up - await flushPromiseQueue() - fireEvent.press(screen.getByText("Painting")) - - const materialsInput = screen.getByTestId("Submission_MaterialsInput") - expect(materialsInput).toBeOnTheScreen() - fireEvent.changeText(materialsInput, "Whatever") - expect(materialsInput.props.value).toBe("Whatever") - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddDimensions.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddDimensions.tests.tsx deleted file mode 100644 index 76c3cbfc6f3..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddDimensions.tests.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { fireEvent, screen } from "@testing-library/react-native" -import { SubmitArtworkAddDimensions } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddDimensions" -import { renderWithSubmitArtworkWrapper } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" - -describe("SubmitArtworkAddDimensions", () => { - it("shows and updates properly the dimensions inputs", () => { - renderWithSubmitArtworkWrapper({ - component: , - }) - - const inputs = { - height: screen.getByTestId("Submission_HeightInput"), - width: screen.getByTestId("Submission_WidthInput"), - depth: screen.getByTestId("Submission_DepthInput"), - } - expect(inputs.height).toBeOnTheScreen() - expect(inputs.width).toBeOnTheScreen() - expect(inputs.depth).toBeOnTheScreen() - - fireEvent.changeText(inputs.height, "20") - fireEvent.changeText(inputs.width, "30") - fireEvent.changeText(inputs.depth, "40") - - expect(inputs.height.props.value).toEqual("20") - expect(inputs.width.props.value).toEqual("30") - expect(inputs.depth.props.value).toEqual("40") - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddPhoneNumber.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddPhoneNumber.tests.tsx deleted file mode 100644 index 32f23d17f86..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddPhoneNumber.tests.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { fireEvent, screen } from "@testing-library/react-native" -import { SubmitArtworkAddPhoneNumber } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddPhoneNumber" -import { renderWithSubmitArtworkWrapper } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" - -describe("SubmitArtworkAddPhoneNumber", () => { - it("displays the phone number input", () => { - renderWithSubmitArtworkWrapper({ - component: , - }) - - const input = screen.getByTestId("phone-input") - - expect(input).toBeOnTheScreen() - - fireEvent.changeText(input, "1234567890") - - expect(input.props.value).toBe("(123) 456-7890") - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddTitle.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddTitle.tests.tsx deleted file mode 100644 index f22de22869b..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAddTitle.tests.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { fireEvent, screen } from "@testing-library/react-native" -import { SubmitArtworkAddTitle } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddTitle" -import { renderWithSubmitArtworkWrapper } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" - -describe("SubmitArtworkAddTitle", () => { - it("shows the artwork input title", () => { - renderWithSubmitArtworkWrapper({ - component: , - }) - - const input = screen.getByPlaceholderText("Artwork Title") - expect(input).toBeOnTheScreen() - - fireEvent.changeText(input, "My Artwork Title") - - expect(input.props.value).toBe("My Artwork Title") - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAdditionalDocuments.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAdditionalDocuments.tests.tsx deleted file mode 100644 index ed7785c017c..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkAdditionalDocuments.tests.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import { useIsFocused, useNavigation } from "@react-navigation/native" -import { fireEvent, screen } from "@testing-library/react-native" -import { SubmitArtworkAdditionalDocuments } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAdditionalDocuments" -import { renderWithSubmitArtworkWrapper } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" -import { flushPromiseQueue } from "app/utils/tests/flushPromiseQueue" -import relay from "react-relay" - -const mockNavigate = jest.fn() - -const mockShowActionSheetWithOptions = jest.fn() - -const mockCommitMutation = (fn?: typeof relay.commitMutation) => - jest.fn>(fn as any) - -jest.mock("app/utils/showDocumentsAndPhotosActionSheet", () => ({ - showDocumentsAndPhotosActionSheet: () => { - return [ - { - uri: "file:///path/to/file", - fileCopyUri: "file:///path/to/file", - name: "file.pdf", - type: "document/pdf", - size: 10 * 1024 * 1024, - }, - ] - }, - isDocument: () => true, -})) - -jest.mock("app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/utils/uploadDocument", () => ({ - uploadDocument: () => { - return { - key: "key", - bucket: "bucket", - } - }, -})) - -jest.mock("@expo/react-native-action-sheet", () => ({ - useActionSheet: () => ({ showActionSheetWithOptions: mockShowActionSheetWithOptions }), -})) - -jest.mock("@react-navigation/native", () => ({ - ...jest.requireActual("@react-navigation/native"), - useNavigation: jest.fn(), - useIsFocused: jest.fn(), -})) - -describe("SubmitArtworkAdditionalDocuments", () => { - const useNavigationMock = useNavigation as jest.Mock - const useIsFocusedMock = useIsFocused as jest.Mock - - afterEach(() => {}) - - beforeEach(() => { - useIsFocusedMock.mockReturnValue(() => true) - useNavigationMock.mockReturnValue({ - navigate: mockNavigate, - }) - - jest.clearAllMocks() - }) - - it("renders the list of uploaded documents", async () => { - relay.commitMutation = mockCommitMutation((_, { onCompleted }) => { - onCompleted!( - { - addAssetToConsignmentSubmission: { - asset: { - id: "asset-id", - submissionID: "submission-id", - }, - }, - }, - null - ) - return { dispose: jest.fn() } - }) as any - - renderWithSubmitArtworkWrapper({ - props: { currentStep: "AdditionalDocuments" }, - component: , - injectedFormikProps: { - submissionId: "submission-id", - externalId: "external-id", - additionalDocuments: [], - }, - }) - - fireEvent.press(screen.getByText("Add Documents")) - // Wait for the actoin sheet to show up - await flushPromiseQueue() - - expect(relay.commitMutation).toHaveBeenCalledWith( - expect.any(Object), - expect.objectContaining({ - variables: { - input: { - assetType: "additional_file", - clientMutationId: "random-client-mutation-id", - externalSubmissionId: "external-id", - filename: "file.pdf", - size: "10485760", - source: { bucket: "bucket", key: "key" }, - submissionID: "submission-id", - }, - }, - }) - ) - - expect(screen.getByText("file.pdf")).toBeOnTheScreen() - expect(screen.getByText(/10.00/)).toBeOnTheScreen() - - fireEvent(screen.getByText("Continue"), "onPress") - - await flushPromiseQueue() - - expect(mockNavigate).toHaveBeenCalledWith("Condition") - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkBottomNavigation.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkBottomNavigation.tests.tsx deleted file mode 100644 index 49c43c22737..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkBottomNavigation.tests.tsx +++ /dev/null @@ -1,173 +0,0 @@ -import { fireEvent, screen } from "@testing-library/react-native" -import { SubmitArtworkBottomNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkBottomNavigation" -import { renderWithSubmitArtworkWrapper } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" -import { - NAVIGATE_TO_NEXT_STEP_EVENT, - NAVIGATE_TO_PREVIOUS_STEP_EVENT, - SubmitArtworkFormEvents, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { dismissModal, navigate, switchTab } from "app/system/navigation/navigate" - -const mockNavigate = jest.fn() -const mockGoBack = jest.fn() - -jest.mock("@react-navigation/native", () => { - const actualNav = jest.requireActual("@react-navigation/native") - return { - ...actualNav, - useNavigation: () => { - return { - navigate: mockNavigate, - addListener: jest.fn(), - goBack: mockGoBack, - } - }, - } -}) - -describe("SubmitArtworkBottomNavigation", () => { - describe("When the current step is StartFlow", () => { - it("Shows a functional Start a New Submission button", () => { - renderWithSubmitArtworkWrapper({ - includeBottomNavigation: false, - component: , - props: { currentStep: "StartFlow" }, - }) - - const startSubmissionButton = screen.getByText("Start New Submission") - expect(startSubmissionButton).toBeOnTheScreen() - - fireEvent(startSubmissionButton, "onPress") - - expect(mockNavigate).toHaveBeenCalledWith("SelectArtist") - }) - - it("Shows a functional Start from My Collection button", () => { - renderWithSubmitArtworkWrapper({ - includeBottomNavigation: false, - component: , - props: { currentStep: "StartFlow" }, - }) - - const startFromMyCollectionButton = screen.getByText("Start from My Collection") - expect(startFromMyCollectionButton).toBeOnTheScreen() - - fireEvent(startFromMyCollectionButton, "onPress") - - expect(mockNavigate).toHaveBeenCalledWith("SubmitArtworkFromMyCollection") - }) - }) - - describe("When the current step is Complete your submission", () => { - it("Shows a functional Submit Another Work button", () => { - renderWithSubmitArtworkWrapper({ - includeBottomNavigation: false, - component: , - props: { currentStep: "CompleteYourSubmission" }, - }) - - const submitAnotherWork = screen.getByText("Submit Another Work") - expect(submitAnotherWork).toBeOnTheScreen() - - fireEvent(submitAnotherWork, "onPress") - expect(dismissModal).toHaveBeenCalled() - }) - - it("Shows a functional Submit Another Artwork button", () => { - renderWithSubmitArtworkWrapper({ - includeBottomNavigation: false, - component: , - props: { currentStep: "CompleteYourSubmission" }, - }) - - const viewArtworkInMyCollection = screen.getByText("View Artwork In My Collection") - expect(viewArtworkInMyCollection).toBeOnTheScreen() - - fireEvent(viewArtworkInMyCollection, "onPress") - expect(switchTab).toHaveBeenCalledWith("profile") - }) - }) - - describe("When the current step is artist rejected", () => { - it("Shows a functional Add to My Collection button", () => { - renderWithSubmitArtworkWrapper({ - includeBottomNavigation: false, - component: , - props: { currentStep: "ArtistRejected" }, - }) - - const addToMyCollectionButton = screen.getByText("Add to My Collection") - expect(addToMyCollectionButton).toBeOnTheScreen() - - fireEvent(addToMyCollectionButton, "onPress") - expect(navigate).toHaveBeenCalledWith("/my-collection/artworks/new", { - showInTabName: "profile", - replaceActiveModal: true, - }) - }) - - it("Shows a functional Add Another Artist button", () => { - renderWithSubmitArtworkWrapper({ - includeBottomNavigation: false, - component: , - props: { currentStep: "ArtistRejected" }, - }) - - const addAnotherArtistButton = screen.getByText("Add Another Artist") - expect(addAnotherArtistButton).toBeOnTheScreen() - - fireEvent(addAnotherArtistButton, "onPress") - - expect(mockGoBack).toHaveBeenCalled() - }) - }) - - describe("Bottom navigation buttons", () => { - it("Shows a functional continue button", async () => { - renderWithSubmitArtworkWrapper({ - includeBottomNavigation: false, - component: , - props: { currentStep: "AddTitle" }, - injectedFormikProps: { title: "Some title" }, - }) - - const continueButton = screen.getByText("Continue") - expect(continueButton).toBeOnTheScreen() - - const emit = jest.spyOn(SubmitArtworkFormEvents, "emit") - fireEvent(continueButton, "onPress") - - expect(emit).toHaveBeenCalledWith(NAVIGATE_TO_NEXT_STEP_EVENT) - }) - - describe("when the current step is AddTitle", () => { - it("does not show a back button", () => { - renderWithSubmitArtworkWrapper({ - includeBottomNavigation: false, - component: , - props: { currentStep: "ArtistRejected" }, - }) - - expect(screen.queryByText("Back")).toBeNull() - }) - }) - describe("when the current step is not AddTitle", () => { - it("shows a functional back button", () => { - renderWithSubmitArtworkWrapper({ - includeBottomNavigation: false, - component: , - props: { currentStep: "AddPhotos" }, - injectedFormikProps: { title: "Some title" }, - }) - - const backButton = screen.getByText("Back") - expect(backButton).toBeOnTheScreen() - - const emit = jest.spyOn(SubmitArtworkFormEvents, "emit") - fireEvent(backButton, "onPress") - - expect(emit).toHaveBeenCalledWith(NAVIGATE_TO_PREVIOUS_STEP_EVENT) - }) - }) - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkCondition.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkCondition.tests.tsx deleted file mode 100644 index db8463c14cc..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkCondition.tests.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import { useIsFocused, useNavigation } from "@react-navigation/native" -import { fireEvent, screen } from "@testing-library/react-native" -import { SubmitArtworkCondition } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkCondition" -import { renderWithSubmitArtworkWrapper } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { flushPromiseQueue } from "app/utils/tests/flushPromiseQueue" -import relay from "react-relay" - -const mockNavigate = jest.fn() -const mockCommitMutation = (fn?: typeof relay.commitMutation) => - jest.fn>(fn as any) - -jest.mock("@react-navigation/native", () => ({ - ...jest.requireActual("@react-navigation/native"), - useNavigation: jest.fn(), - useIsFocused: jest.fn(), -})) - -describe("SubmitArtworkCondition", () => { - const useNavigationMock = useNavigation as jest.Mock - const useIsFocusedMock = useIsFocused as jest.Mock - - beforeEach(() => { - useIsFocusedMock.mockReturnValue(() => true) - useNavigationMock.mockReturnValue({ - navigate: mockNavigate, - }) - }) - - it("renders the default artwork condition properly", async () => { - renderWithSubmitArtworkWrapper({ - props: { currentStep: "Condition" }, - component: , - injectedFormikProps: { - artwork: { - ...defaultArtworkFixutre, - condition: "FAIR", - conditionDescription: "Pretty fair", - }, - }, - }) - - expect(screen.getByText("Fair")).toBeOnTheScreen() - expect(screen.getByDisplayValue("Pretty fair")).toBeOnTheScreen() - }) - - it("calls the mutation with the new condition details", async () => { - relay.commitMutation = mockCommitMutation((_, { onCompleted }) => { - onCompleted!( - { - updateConsignmentSubmission: { - consignmentSubmission: { - internalID: "submission-id", - }, - }, - }, - null - ) - return { dispose: jest.fn() } - }) as any - - renderWithSubmitArtworkWrapper({ - props: { currentStep: "Condition" }, - component: , - injectedFormikProps: { - artwork: { - ...defaultArtworkFixutre, - }, - }, - }) - - const conditionSelect = screen.getByTestId("ConditionSelect") - fireEvent(conditionSelect, "onPress") - - // Wait for the select modal to show up - await screen.findByText("Fair") - fireEvent.press(screen.getByText("Fair")) - - expect(screen.getAllByText("Fair")).toHaveLength(1) - - fireEvent(screen.getByText("Add Additional Condition Details"), "onChangeText", "Pretty fair") - - fireEvent(screen.getByText("Continue"), "onPress") - - expect(relay.commitMutation).toHaveBeenCalledWith( - expect.any(Object), - expect.objectContaining({ - variables: { - input: { artworkId: "some-id", condition: "FAIR", conditionDescription: "Pretty fair" }, - }, - }) - ) - - await flushPromiseQueue() - - expect(mockNavigate).toHaveBeenCalledWith("CompleteYourSubmission") - }) -}) - -const defaultArtworkFixutre: SubmissionModel["artwork"] = { - internalID: "some-id", - framedDepth: null, - framedHeight: null, - framedMetric: null, - framedWidth: null, - isFramed: null, - condition: null, - conditionDescription: null, -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkFrameInformation.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkFrameInformation.tests.tsx deleted file mode 100644 index c76e33a0ff0..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkFrameInformation.tests.tsx +++ /dev/null @@ -1,220 +0,0 @@ -import { useIsFocused, useNavigation } from "@react-navigation/native" -import { fireEvent, screen } from "@testing-library/react-native" -import { SubmitArtworkFrameInformation } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFrameInformation" -import { renderWithSubmitArtworkWrapper } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { flushPromiseQueue } from "app/utils/tests/flushPromiseQueue" -import relay from "react-relay" - -const mockNavigate = jest.fn() -const mockCommitMutation = (fn?: typeof relay.commitMutation) => - jest.fn>(fn as any) - -jest.mock("@react-navigation/native", () => ({ - ...jest.requireActual("@react-navigation/native"), - useNavigation: jest.fn(), - useIsFocused: jest.fn(), -})) - -describe("SubmitArtworkFrameInformation", () => { - const useNavigationMock = useNavigation as jest.Mock - const useIsFocusedMock = useIsFocused as jest.Mock - - beforeEach(() => { - useIsFocusedMock.mockReturnValue(() => true) - useNavigationMock.mockReturnValue({ - navigate: mockNavigate, - }) - }) - - describe("when the artwork is not framed", () => { - it("does not render the frame information section", async () => { - renderWithSubmitArtworkWrapper({ - props: { currentStep: "FrameInformation" }, - component: , - injectedFormikProps: { - artwork: { - ...defaultArtworkFixutre, - internalID: "some-id", - isFramed: false, - framedMetric: null, - framedWidth: null, - framedHeight: null, - framedDepth: null, - }, - }, - }) - - expect(screen.getByText("Is the work framed?")).toBeOnTheScreen() - expect(screen.queryByText("Height")).not.toBeOnTheScreen() - expect(screen.queryByText("Width")).not.toBeOnTheScreen() - expect(screen.queryByText("Depth")).not.toBeOnTheScreen() - expect(screen.queryByText("in")).not.toBeOnTheScreen() - expect(screen.queryByText("cm")).not.toBeOnTheScreen() - }) - - it("calls the mutation with the correct values when an artwork is framed", async () => { - relay.commitMutation = mockCommitMutation((_, { onCompleted }) => { - onCompleted!( - { - updateConsignmentSubmission: { - consignmentSubmission: { - internalID: "submission-id", - }, - }, - }, - null - ) - return { dispose: jest.fn() } - }) as any - - renderWithSubmitArtworkWrapper({ - props: { currentStep: "FrameInformation" }, - component: , - injectedFormikProps: { - artwork: { - ...defaultArtworkFixutre, - internalID: "some-id", - isFramed: null, - framedMetric: "cm", - framedWidth: "20", - framedHeight: "30", - framedDepth: "3", - }, - }, - }) - - expect(screen.getByText("Is the work framed?")).toBeOnTheScreen() - fireEvent(screen.getByText("No"), "onPress") - - fireEvent(screen.getByText("Continue"), "onPress") - - expect(relay.commitMutation).toHaveBeenCalledWith( - expect.any(Object), - expect.objectContaining({ - variables: { - input: { - artworkId: "some-id", - isFramed: false, - framedHeight: null, - framedMetric: null, - framedWidth: null, - framedDepth: null, - }, - }, - }) - ) - - await flushPromiseQueue() - - expect(mockNavigate).toHaveBeenCalledWith("AdditionalDocuments") - }) - }) - - describe("when the artwork is framed", () => { - it("shows the frame information if the artwork is framed", async () => { - renderWithSubmitArtworkWrapper({ - props: { currentStep: "FrameInformation" }, - component: , - injectedFormikProps: { - artwork: { - ...defaultArtworkFixutre, - internalID: "some-id", - isFramed: null, - framedMetric: "cm", - framedWidth: "20", - framedHeight: "30", - framedDepth: "3", - }, - }, - }) - - fireEvent(screen.getByText("Yes"), "onPress") - - await flushPromiseQueue() - - expect(screen.getByText("Is the work framed?")).toBeOnTheScreen() - expect(screen.getByDisplayValue("20")).toBeOnTheScreen() - expect(screen.getByDisplayValue("30")).toBeOnTheScreen() - expect(screen.getByDisplayValue("3")).toBeOnTheScreen() - // The metric is rendered 4 times because it's also shown in the Input component - // As a fixed right placeholder - expect(screen.queryAllByText("cm")).toHaveLength(4) - }) - - it("calls the mutation with the correct values", async () => { - relay.commitMutation = mockCommitMutation((_, { onCompleted }) => { - onCompleted!( - { - updateConsignmentSubmission: { - consignmentSubmission: { - internalID: "submission-id", - }, - }, - }, - null - ) - return { dispose: jest.fn() } - }) as any - - renderWithSubmitArtworkWrapper({ - props: { currentStep: "FrameInformation" }, - component: , - injectedFormikProps: { - artwork: { - ...defaultArtworkFixutre, - internalID: "some-id", - isFramed: null, - framedMetric: null, - framedWidth: null, - framedHeight: null, - framedDepth: null, - }, - }, - }) - - expect(screen.getByText("Is the work framed?")).toBeOnTheScreen() - fireEvent(screen.getByText("Yes"), "onPress") - - fireEvent.changeText(screen.getByText("Height"), "40") - fireEvent.changeText(screen.getByText("Width"), "20") - fireEvent.changeText(screen.getByText("Depth"), "3") - fireEvent(screen.getByText("cm"), "onPress") - - await flushPromiseQueue() - - fireEvent(screen.getByText("Continue"), "onPress") - - expect(relay.commitMutation).toHaveBeenCalledWith( - expect.any(Object), - expect.objectContaining({ - variables: { - input: { - artworkId: "some-id", - framedDepth: "3", - framedHeight: "40", - framedMetric: "cm", - framedWidth: "20", - isFramed: true, - }, - }, - }) - ) - - await flushPromiseQueue() - - expect(mockNavigate).toHaveBeenCalledWith("AdditionalDocuments") - }) - }) -}) - -const defaultArtworkFixutre: SubmissionModel["artwork"] = { - internalID: "some-id", - framedDepth: null, - framedHeight: null, - framedMetric: null, - framedWidth: null, - isFramed: null, - condition: null, - conditionDescription: null, -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkFromMyCollection.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkFromMyCollection.tests.tsx deleted file mode 100644 index ff3e1adb4ed..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkFromMyCollection.tests.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { screen, waitForElementToBeRemoved } from "@testing-library/react-native" -import { SubmitArtworkFromMyCollection } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFromMyCollection" -import { setupWithSubmitArtworkTestWrappers } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" - -describe("SubmitArtworkFromMyCollection", () => { - it("render the list of my collection artworks", async () => { - const { renderWithRelay } = setupWithSubmitArtworkTestWrappers({ - Component: , - }) - - renderWithRelay({ - Me: () => ({ - myCollectionConnection: { - edges: [ - { - node: { - id: "my-artwork-id", - slug: "my-artwork-slug", - title: "My artwork", - submissionId: null, - artistNames: "Artist Name", - image: { - url: "https://my-artwork.jpg", - }, - }, - }, - ], - }, - }), - }) - - await waitForElementToBeRemoved(() => screen.queryByTestId("placeholder")) - - expect(screen.getByText("My artwork")).toBeOnTheScreen() - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkPurchaseHistory.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkPurchaseHistory.tests.tsx deleted file mode 100644 index 946431ef1a6..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkPurchaseHistory.tests.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { fireEvent, screen } from "@testing-library/react-native" -import { - PROVENANCE_LIST, - SubmitArtworkPurchaseHistory, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkPurchaseHistory" -import { renderWithSubmitArtworkWrapper } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" - -describe("SubmitArtworkPurchaseHistory", () => { - it("shows and updates properly the purchase infromation", async () => { - renderWithSubmitArtworkWrapper({ - component: , - }) - - const purchaseInformationSelect = screen.getByTestId("PurchaseInformation_Select") - expect(purchaseInformationSelect).toBeOnTheScreen() - - fireEvent.press(purchaseInformationSelect) - - fireEvent.press(screen.getByText("Purchase information")) - - // wait for modal to open - await screen.findByText(PROVENANCE_LIST[0].label) - - // check if all options are visible - expect(screen.getByText(PROVENANCE_LIST[1].label)).toBeOnTheScreen() - expect(screen.getByText(PROVENANCE_LIST[2].label)).toBeOnTheScreen() - expect(screen.getByText(PROVENANCE_LIST[3].label)).toBeOnTheScreen() - expect(screen.getByText(PROVENANCE_LIST[4].label)).toBeOnTheScreen() - expect(screen.getByText(PROVENANCE_LIST[5].label)).toBeOnTheScreen() - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkSelectArtist.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkSelectArtist.tests.tsx deleted file mode 100644 index bf4b6e56133..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkSelectArtist.tests.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import { fireEvent, screen } from "@testing-library/react-native" -import { SubmitArtworkSelectArtist } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkSelectArtist" -import { setupWithSubmitArtworkTestWrappers } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" -import { flushPromiseQueue } from "app/utils/tests/flushPromiseQueue" - -const mockNavigateToNextStep = jest.fn() -jest.mock("app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext", () => ({ - useSubmissionContext: () => { - return { - navigateToNextStep: mockNavigateToNextStep, - } - }, -})) - -jest.mock( - "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission", - () => ({ - createOrUpdateSubmission: jest.fn(), - }) -) - -// TODO: Fix this post-release -describe.skip("SubmitArtworkSelectArtist", () => { - it("Navigates to the next step after tapping an artwork", async () => { - const { renderWithRelay } = setupWithSubmitArtworkTestWrappers({ - Component: , - }) - - renderWithRelay({ - Me: () => ({ - userInterestsConnection: userInterestsConnectionFixtures, - }), - }) - - await flushPromiseQueue() - - expect(screen.getByText("Add artist name")).toBeOnTheScreen() - - const input = screen.getByPlaceholderText("Search for artists on Artsy") - - fireEvent(input, "onChangeText", "Andy") - - await flushPromiseQueue() - - renderWithRelay({ - Me: () => ({ - userInterestsConnection: userInterestsConnectionFixtures, - }), - }) - - await flushPromiseQueue() - - expect(screen.getByText("Andy Warhol")).toBeOnTheScreen() - - fireEvent.press(screen.getByText("Andy Warhol"), "onPress") - - await flushPromiseQueue() - - expect(mockNavigateToNextStep).toBeCalled() - }) - - it("Shows only P1 artists", async () => { - const { renderWithRelay } = setupWithSubmitArtworkTestWrappers({ - Component: , - }) - - renderWithRelay({ - Me: () => ({ - userInterestsConnection: userInterestsConnectionFixtures, - }), - }) - - await flushPromiseQueue() - - renderWithRelay({ - Me: () => ({ - userInterestsConnection: userInterestsConnectionFixtures, - }), - }) - - expect(screen.getByText("Andy Warhol")).toBeOnTheScreen() - expect(screen.getByText("Banksy")).toBeOnTheScreen() - expect(screen.queryByText("Unknwon Artist")).not.toBeOnTheScreen() - }) -}) - -const userInterestsConnectionFixtures = { - edges: [ - { - internalID: "random-id-1", - node: { - __isNode: "Artist", - __typename: "Artist", - internalID: "andy-internal-id", - displayLabel: "Andy Warhol", - displayType: "Artist", - href: "andy-warhol-href", - id: "andy-warhol", - imageUrl: "", - slug: "", - targetSupply: { - isTargetSupply: true, - }, - }, - }, - { - internalID: "random-id", - node: { - __isNode: "Artist", - __typename: "Artist", - internalID: "banksy-internal-id", - displayLabel: "Banksy", - displayType: "Artist", - href: "banksy-warhol-href", - id: "banksy", - imageUrl: "", - slug: "", - targetSupply: { - isTargetSupply: true, - }, - }, - }, - - { - internalID: "random-id", - node: { - __isNode: "Artist", - __typename: "Artist", - internalID: "unknown-artist-internal-id", - displayLabel: "Unknown Artist", - displayType: "Artist", - href: "unknown-artist-href", - id: "unknown-artist", - imageUrl: "", - slug: "", - targetSupply: { - isTargetSupply: false, - }, - }, - }, - ], -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkShippingLocation.tests.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkShippingLocation.tests.tsx deleted file mode 100644 index 1c4503318a0..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Components/__tests__/SubmitArtworkShippingLocation.tests.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { useIsFocused, useNavigation } from "@react-navigation/native" -import { fireEvent, screen } from "@testing-library/react-native" -import { COUNTRY_SELECT_OPTIONS } from "app/Components/CountrySelect" -import { SubmitArtworkShippingLocation } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkShippingLocation" -import { renderWithSubmitArtworkWrapper } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers" -import { flushPromiseQueue } from "app/utils/tests/flushPromiseQueue" -import relay from "react-relay" - -const mockNavigate = jest.fn() -const mockCommitMutation = (fn?: typeof relay.commitMutation) => - jest.fn>(fn as any) - -jest.mock("@react-navigation/native", () => ({ - ...jest.requireActual("@react-navigation/native"), - useNavigation: jest.fn(), - useIsFocused: jest.fn(), -})) - -describe("SubmitArtworkShippingLocation", () => { - const useNavigationMock = useNavigation as jest.Mock - const useIsFocusedMock = useIsFocused as jest.Mock - - beforeEach(() => { - useIsFocusedMock.mockReturnValue(() => true) - useNavigationMock.mockReturnValue({ - navigate: mockNavigate, - }) - }) - - it("renders only the country select when all other fields are empty", async () => { - renderWithSubmitArtworkWrapper({ - props: { currentStep: "ShippingLocation" }, - component: , - }) - - const countrySelect = screen.getByTestId("country-select") - expect(countrySelect).toBeOnTheScreen() - - expect(screen.queryByText("Address Line 1")).not.toBeOnTheScreen() - - expect(screen.queryByText("Address Line 2")).not.toBeOnTheScreen() - - expect(screen.queryByText("City")).not.toBeOnTheScreen() - - expect(screen.queryByText("Postal Code")).not.toBeOnTheScreen() - - expect(screen.queryByText("State, Province, or Region")).not.toBeOnTheScreen() - }) - - it("renders all field if a country is available", async () => { - renderWithSubmitArtworkWrapper({ - props: { currentStep: "ShippingLocation" }, - component: , - }) - - const countrySelect = screen.getByTestId("country-select") - expect(countrySelect).toBeOnTheScreen() - - fireEvent.press(countrySelect) - - // Wait for the select modal to show up - await screen.findByText(COUNTRY_SELECT_OPTIONS[0].label as string) - - fireEvent.press(screen.getByText(COUNTRY_SELECT_OPTIONS[0].label as string)) - - expect(screen.getByText("Address Line 1")).toBeOnTheScreen() - - expect(screen.getByText("Address Line 2")).toBeOnTheScreen() - - expect(screen.getByText("City")).toBeOnTheScreen() - - expect(screen.getByText("Postal Code")).toBeOnTheScreen() - - expect(screen.getByText("State, Province, or Region")).toBeOnTheScreen() - }) - - it("calls createOrUpdateSubmission and goes to next step when continue is pressed", async () => { - relay.commitMutation = mockCommitMutation((_, { onCompleted }) => { - onCompleted!( - { - updateConsignmentSubmission: { - consignmentSubmission: { - externalId: "submission-id", - internalID: "submission-id", - }, - }, - }, - null - ) - return { dispose: jest.fn() } - }) as any - - renderWithSubmitArtworkWrapper({ - props: { currentStep: "ShippingLocation" }, - component: , - injectedFormikProps: { - location: { - country: "Germany", - countryCode: "DE", - address: "Street 1", - address2: "5th Floor", - city: "Friedrichshain", - state: "Berlin", - zipCode: "10115", - }, - submissionId: "submission-id", - externalId: "submission-id", - }, - }) - - fireEvent.press(screen.getByTestId("country-select")) - - await flushPromiseQueue() - - expect(screen.getByText("Germany")).toBeOnTheScreen() - expect(screen.getByDisplayValue("Street 1")).toBeOnTheScreen() - expect(screen.getByDisplayValue("5th Floor")).toBeOnTheScreen() - expect(screen.getByDisplayValue("Friedrichshain")).toBeOnTheScreen() - expect(screen.getByDisplayValue("10115")).toBeOnTheScreen() - expect(screen.getByDisplayValue("Berlin")).toBeOnTheScreen() - - // Wait for validation to finish - await flushPromiseQueue() - - fireEvent(screen.getByText("Continue"), "onPress") - - expect(relay.commitMutation).toHaveBeenCalledWith( - expect.any(Object), - expect.objectContaining({ - variables: { - input: { - artistID: undefined, - attributionClass: undefined, - category: undefined, - depth: undefined, - dimensionsMetric: undefined, - editionNumber: undefined, - editionSizeFormatted: undefined, - height: undefined, - externalId: "submission-id", - locationAddress: "Street 1", - locationAddress2: "5th Floor", - locationCity: "Friedrichshain", - locationCountry: "Germany", - locationCountryCode: "DE", - locationPostalCode: "10115", - locationState: "Berlin", - medium: undefined, - provenance: undefined, - signature: undefined, - state: undefined, - title: undefined, - userEmail: undefined, - userName: undefined, - userPhone: undefined, - utmMedium: undefined, - utmSource: undefined, - utmTerm: undefined, - width: undefined, - year: undefined, - }, - }, - }) - ) - - await flushPromiseQueue() - - expect(mockNavigate).toHaveBeenCalledWith("FrameInformation") - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm.tsx deleted file mode 100644 index c407c6cb88f..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm.tsx +++ /dev/null @@ -1,299 +0,0 @@ -import { Screen, useScreenDimensions } from "@artsy/palette-mobile" -import { NavigationContainer, NavigationContainerRef } from "@react-navigation/native" -import { createStackNavigator } from "@react-navigation/stack" -import { SubmitArtworkAddDetails } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddDetails" -import { SubmitArtworkAddDimensions } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddDimensions" -import { SubmitArtworkAddPhoneNumber } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddPhoneNumber" -import { SubmitArtworkAddPhotos } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddPhotos" -import { SubmitArtworkAddTitle } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAddTitle" -import { SubmitArtworkAdditionalDocuments } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkAdditionalDocuments" -import { SubmitArtworkArtistRejected } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkArtistRejected" -import { SubmitArtworkBottomNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkBottomNavigation" -import { SubmitArtworkCompleteYourSubmission } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkCompleteYourSubmission" -import { SubmitArtworkCondition } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkCondition" -import { - SubmitArtworkFormStore, - SubmitArtworkFormStoreProvider, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { SubmitArtworkFrameInformation } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFrameInformation" -import { SubmitArtworkFromMyCollection } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFromMyCollection" -import { SubmitArtworkPurchaseHistory } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkPurchaseHistory" -import { SubmitArtworkSelectArtist } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkSelectArtist" -import { SubmitArtworkShippingLocation } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkShippingLocation" -import { SubmitArtworkStartFlow } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkStartFlow" -import { SubmitArtworkTopNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkTopNavigation" -import { - SUBMIT_ARTWORK_APPROVED_SUBMISSION_STEPS, - SUBMIT_ARTWORK_DRAFT_SUBMISSION_STEPS, - SubmitArtworkScreen, - TIER_1_STATES, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/constants" -import { getInitialNavigationState } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialNavigationState" -import { - getCurrentValidationSchema, - SubmissionModel, - submissionModelInitialValues, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { createOrUpdateSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/createOrUpdateSubmission" -import { fetchUserContactInformation } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/fetchUserContactInformation" -import { FormikProvider, useFormik } from "formik" -import { useEffect } from "react" -import { Keyboard, KeyboardAvoidingView, Platform } from "react-native" -import { isTablet as getIsTablet } from "react-native-device-info" - -export type SubmitArtworkStackNavigation = { - StartFlow: undefined - CompleteYourSubmission: undefined - CompleteYourSubmissionPostApproval: undefined - ArtistRejected: undefined - - // Tier 1 Steps - SubmitArtworkFromMyCollection: undefined - SelectArtist: undefined - AddTitle: undefined - AddPhotos: undefined - AddDetails: undefined - AddDimensions: undefined - AddPhoneNumber: undefined - PurchaseHistory: undefined - - // Tier 2 Steps - ShippingLocation: undefined - FrameInformation: undefined - AdditionalDocuments: undefined - Condition: undefined -} - -export interface SubmitArtworkProps { - initialValues: Partial - initialStep: SubmitArtworkScreen - navigationState?: string - externalID?: string - hasStartedFlowFromMyCollection?: boolean -} - -export const INITIAL_EDIT_STEP: keyof SubmitArtworkStackNavigation = "AddTitle" -export const INITIAL_POST_APPROVAL_STEP: keyof SubmitArtworkStackNavigation = "ShippingLocation" - -export const SubmitArtworkForm: React.FC = (props) => { - const initialScreen: SubmitArtworkScreen = props.initialStep || "StartFlow" - - return ( - - - - - - ) -} - -const SubmitArtworkFormContent: React.FC = ({ - initialValues: injectedValuesProp, - initialStep, - hasStartedFlowFromMyCollection, -}) => { - const currentStep = SubmitArtworkFormStore.useStoreState((state) => state.currentStep) - - const initialValues = { - ...submissionModelInitialValues, - ...injectedValuesProp, - } - - const handleSubmit = (values: SubmissionModel) => { - createOrUpdateSubmission(values, "") - } - - const formik = useFormik({ - enableReinitialize: true, - initialValues, - onSubmit: handleSubmit, - validationSchema: getCurrentValidationSchema, - validateOnChange: false, - }) - - useEffect(() => { - fetchUserContactInformation() - .then((me) => { - if (me.email) { - formik.setFieldValue("userEmail", me.email) - } - if (me.phoneNumber?.isValid && me.phoneNumber?.originalNumber) { - formik.setFieldValue("userPhone", me.phoneNumber.originalNumber) - } - if (me.name) { - formik.setFieldValue("userName", me.name) - } - }) - .catch((error) => { - console.error("Error fetching user contact information", error) - }) - }, []) - - // Revalidate form on step change because the validation schema changes and it does not happen automatically - useEffect(() => { - formik.validateForm() - Keyboard.dismiss() - }, [currentStep]) - - const isTablet = getIsTablet() - const { width: screenWidth } = useScreenDimensions() - - return ( - - - - - { - const opacity = current.progress.interpolate({ - inputRange: [0, 1], - outputRange: [0, 1], - }) - - const nextOpacity = next - ? next.progress.interpolate({ - inputRange: [0, 1], - outputRange: [1, 0.2], // Lower the opacity of the exiting screen - }) - : 1 - - return { - cardStyle: { - opacity: next ? nextOpacity : opacity, - backgroundColor: "white", - }, - overlayStyle: { - opacity: current.progress.interpolate({ - inputRange: [0, 1], - outputRange: [0, 0.5], - }), - backgroundColor: "white", - }, - } - }, - }} - initialRouteName={initialStep} - > - {!hasStartedFlowFromMyCollection && ( - - )} - - - - {!hasStartedFlowFromMyCollection && ( - - )} - - - - - - - - - - - - - - - - - - {!!formik.values.state && !TIER_1_STATES.includes(formik.values.state) && ( - <> - - - - - - )} - - - - - - ) -} - -const Stack = createStackNavigator() - -export const __unsafe__SubmissionArtworkFormNavigationRef: React.MutableRefObject | null> = - { - current: null, - } - -export const getCurrentRoute = () => - __unsafe__SubmissionArtworkFormNavigationRef?.current?.getCurrentRoute()?.name as - | keyof SubmitArtworkStackNavigation - | undefined diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkFormEdit.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkFormEdit.tsx deleted file mode 100644 index cf54ca7ebf9..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkFormEdit.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import { SubmitArtworkFormEditQuery } from "__generated__/SubmitArtworkFormEditQuery.graphql" -import { LoadFailureView } from "app/Components/LoadFailureView" -import { RetryErrorBoundary } from "app/Components/RetryErrorBoundary" -import { - SubmitArtworkForm, - SubmitArtworkProps, -} from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { getInitialSubmissionValues } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialSubmissionValues" -import { SpinnerFallback, withSuspense } from "app/utils/hooks/withSuspense" -import { graphql, useLazyLoadQuery } from "react-relay" - -export const SubmitArtworkFormEdit: React.FC = withSuspense({ - Component: (props) => { - const data = useLazyLoadQuery( - submitArtworkFormEditQuery, - { - id: props.externalID, - }, - { fetchPolicy: "network-only" } - ) - - return ( - <> - {!!data?.submission && ( - - )} - - ) - }, - LoadingFallback: SpinnerFallback, - ErrorFallback: (fallbackProps) => { - return ( - - ) - }, -}) - -export const SubmitArtworkFormEditContainer: React.FC = (props) => { - return ( - - - - ) -} - -const submitArtworkFormEditQuery = graphql` - query SubmitArtworkFormEditQuery($id: ID) { - submission(id: $id) { - id - externalId - artist { - internalID - name - } - category - locationCity - locationCountry - locationState - locationPostalCode - locationCountryCode - locationAddress - locationAddress2 - year - title - signature - medium - myCollectionArtwork { - internalID - isFramed - framedMetric - framedWidth - framedHeight - framedDepth - condition { - value - } - conditionDescription { - details - } - } - attributionClass - editionNumber - editionSize - height - width - depth - dimensionsMetric - provenance - userId - userEmail - userName - userPhone - source - state - sourceArtworkID - assets { - id - imageUrls - geminiToken - size - filename - } - externalId - addtionalAssets: assets(assetType: [ADDITIONAL_FILE]) { - id - size - filename - documentPath - s3Path - s3Bucket - } - } - me { - addressConnection { - edges { - node { - addressLine1 - addressLine2 - city - country - isDefault - postalCode - region - } - } - } - } - } -` diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/constants.ts b/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/constants.ts deleted file mode 100644 index eadf8c9c7bf..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/constants.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { SubmitArtworkStackNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" - -export type SubmitArtworkScreen = keyof SubmitArtworkStackNavigation - -export const ARTWORK_FORM_TIER_1_FINAL_STEP = "AddPhoneNumber" -export const ARTWORK_FORM_TIER_2_FINAL_STEP = "Condition" - -const TIER_1_STEPS: SubmitArtworkScreen[] = [ - "SubmitArtworkFromMyCollection", - "SelectArtist", - "AddTitle", - "AddPhotos", - "AddDetails", - "PurchaseHistory", - "AddDimensions", - "AddPhoneNumber", -] - -export const SUBMIT_ARTWORK_DRAFT_SUBMISSION_STEPS: SubmitArtworkScreen[] = [ - "StartFlow", - ...TIER_1_STEPS, - "CompleteYourSubmission", - "ArtistRejected", -] - -const TIER_2_STEPS: SubmitArtworkScreen[] = [ - "ShippingLocation", - "FrameInformation", - "AdditionalDocuments", - "Condition", -] - -export const SUBMIT_ARTWORK_APPROVED_SUBMISSION_STEPS: SubmitArtworkScreen[] = [ - "StartFlow", - ...TIER_1_STEPS, - ...TIER_2_STEPS, - "CompleteYourSubmission", - "ArtistRejected", -] - -export const TIER_1_STATES = ["DRAFT", "SUBMITTED"] diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/fetchArtworkInformation.ts b/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/fetchArtworkInformation.ts deleted file mode 100644 index 907eae9bb92..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/fetchArtworkInformation.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { fetchArtworkInformationQuery } from "__generated__/fetchArtworkInformationQuery.graphql" -import { getRelayEnvironment } from "app/system/relay/defaultEnvironment" -import { fetchQuery, graphql } from "react-relay" - -export const fetchArtworkInformation = async (artworkID: string) => { - const result = await fetchQuery( - getRelayEnvironment(), - graphql` - query fetchArtworkInformationQuery($artworkID: String!) { - artwork(id: $artworkID) { - internalID - artist { - displayLabel - imageUrl - href - internalID - } - medium - category - date - depth - editionSize - editionNumber - height - width - images { - height - isDefault - imageURL - width - } - attributionClass { - name - } - isEdition - metric - title - signature - provenance - date - location { - city - state - country - postalCode - address - address2 - } - isFramed - framedHeight - framedWidth - framedMetric - framedDepth - condition { - value - } - conditionDescription { - details - } - } - } - `, - { artworkID } - ).toPromise() - - return result?.artwork -} - -export type FetchArtworkInformationResult = Awaited> diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialNavigationState.ts b/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialNavigationState.ts deleted file mode 100644 index 59aba1bdf23..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialNavigationState.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { SubmitArtworkScreen } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/constants" - -export const getInitialNavigationState = ({ - initialStep, - skippedSteps, - steps, -}: { - initialStep: SubmitArtworkScreen - skippedSteps: SubmitArtworkScreen[] - steps: SubmitArtworkScreen[] -}) => { - const availableSteps = steps.filter((step) => !skippedSteps.includes(step)) - - if (availableSteps.includes(initialStep)) { - return { - routes: availableSteps.slice(0, availableSteps.indexOf(initialStep) + 1).map((routeName) => ({ - name: routeName, - })), - } - } - - return undefined -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialSubmissionValues.ts b/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialSubmissionValues.ts deleted file mode 100644 index 3819efb7a81..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialSubmissionValues.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { - ConsignmentAttributionClass, - SubmitArtworkFormEditQuery$data, -} from "__generated__/SubmitArtworkFormEditQuery.graphql" -import { ArtworkConditionEnumType } from "__generated__/myCollectionCreateArtworkMutation.graphql" -import { COUNTRY_SELECT_OPTIONS } from "app/Components/CountrySelect" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { acceptableCategoriesForSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/acceptableCategoriesForSubmission" -import { extractNodes } from "app/utils/extractNodes" -import { NormalizedDocument } from "app/utils/normalizeUploadedDocument" -import { compact } from "lodash" - -export const getInitialSubmissionValues = ( - values: NonNullable, - me: SubmitArtworkFormEditQuery$data["me"] -): SubmissionModel => { - const photos = - values.assets?.map((asset) => { - const path = (Object.values(asset?.imageUrls || {})?.[0] as string) ?? "" - - return { - path, - id: asset?.id ?? "", - geminiToken: asset?.geminiToken ?? "", - } - }) ?? [] - - const categories = acceptableCategoriesForSubmission() - - const addresses = extractNodes(me?.addressConnection) - const defaultAddress = addresses.find((address) => address.isDefault) ?? addresses?.[0] - - return { - artist: values.artist?.name ?? "", - artistId: values.artist?.internalID ?? "", - category: categories.find((category) => category.label === values.category)?.value as any, - year: values.year ?? "", - title: values.title ?? "", - medium: values.medium ?? "", - attributionClass: - (values.attributionClass?.replace("_", " ").toLowerCase() as ConsignmentAttributionClass) ?? - null, - editionNumber: values.editionNumber ?? "", - editionSizeFormatted: values.editionSize ?? "", - height: values.height ?? "", - width: values.width ?? "", - depth: values.depth ?? "", - dimensionsMetric: values.dimensionsMetric ?? "in", - provenance: values.provenance ?? "", - location: { - city: values.locationCity ?? defaultAddress?.city ?? "", - country: values.locationCountry ?? defaultAddress?.country ?? "", - state: values.locationState ?? defaultAddress?.region ?? "", - countryCode: - values.locationCountryCode ?? - COUNTRY_SELECT_OPTIONS.find(({ label }) => label === defaultAddress?.country)?.value ?? - "", - zipCode: values.locationPostalCode ?? defaultAddress?.postalCode ?? "", - address: values.locationAddress ?? defaultAddress?.addressLine1 ?? "", - address2: values.locationAddress2 ?? defaultAddress?.addressLine2 ?? "", - }, - signature: values.signature ?? null, - userEmail: values.userEmail ?? "", - userName: values.userId ?? "", - userPhone: values.userPhone ?? "", - submissionId: values.id, - artistSearchResult: null, - source: values.source ?? null, - state: values.state ?? null, - myCollectionArtworkID: values.sourceArtworkID ?? null, - photos: compact(photos), - artwork: { - internalID: values.myCollectionArtwork?.internalID ?? null, - isFramed: values.myCollectionArtwork?.isFramed ?? null, - framedMetric: values.myCollectionArtwork?.framedMetric ?? null, - framedWidth: values.myCollectionArtwork?.framedWidth ?? null, - framedHeight: values.myCollectionArtwork?.framedHeight ?? null, - framedDepth: values.myCollectionArtwork?.framedDepth ?? null, - condition: - (values.myCollectionArtwork?.condition?.value as ArtworkConditionEnumType) ?? undefined, - conditionDescription: values.myCollectionArtwork?.conditionDescription?.details ?? undefined, - }, - - externalId: values.externalId, - additionalDocuments: getInitialAdditionalDocuments(values.addtionalAssets), - } -} - -const getInitialAdditionalDocuments = ( - values: NonNullable["addtionalAssets"] -): NormalizedDocument[] => { - if (!values) return [] - - return compact( - values.map((document) => { - if (!document || !document.id) { - return null - } - - return { - abortUploading: undefined, - assetId: document?.id, - bucket: document?.s3Bucket, - errorMessage: null, - externalUrl: document?.documentPath, - geminiToken: null, - id: document?.id as string, - item: null, - loading: false, - name: document?.filename, - progress: null, - removed: false, - size: document?.size, - sourceKey: document?.s3Path, - } as NormalizedDocument - }) - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialSubmissionValuesFromArtwork.ts b/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialSubmissionValuesFromArtwork.ts deleted file mode 100644 index 5001d30526d..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/getInitialSubmissionValuesFromArtwork.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { ConsignmentAttributionClass } from "__generated__/createConsignSubmissionMutation.graphql" -import { ArtworkConditionEnumType } from "__generated__/myCollectionCreateArtworkMutation.graphql" -import { FetchArtworkInformationResult } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/fetchArtworkInformation" -import { SubmissionModel } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { acceptableCategoriesForSubmission } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/utils/acceptableCategoriesForSubmission" -import { getAttributionClassValueByName } from "app/utils/artworkRarityClassifications" -import { compact } from "lodash" - -/** - * Helper method used to get the initial form values for the submission form - * from the artwork information - */ -export const getInitialSubmissionFormValuesFromArtwork = ( - artwork: NonNullable -) => { - // By setting the path for each image we make sure the image will be uploaded to S3 - // and processed by Gemini. - const initialPhotos = - compact( - artwork.images?.map((image) => { - const imageURL = image?.imageURL - if (!imageURL) { - return null - } - - return { - height: image?.height || undefined, - isDefault: image?.isDefault || undefined, - imageURL: imageURL, - path: imageURL.replace(":version", "large"), - width: image?.width || undefined, - automaticallyAdded: true, - } - }) - ) || [] - - // Although ideally we would set the type as a partial here, - // that will make us quickly forget to update the type when we add new fields/screens - // This is a tradeoff between type safety and ease of development - const formValues: SubmissionModel = { - submissionId: null, - externalId: null, - artist: artwork.artist?.displayLabel || "", - artistId: artwork.artist?.internalID || "", - artistSearchResult: { - imageUrl: artwork.artist?.imageUrl || "", - href: artwork.artist?.href || "", - internalID: artwork.artist?.internalID || "", - displayLabel: artwork.artist?.displayLabel || "", - __typename: "Artist", - }, - attributionClass: - (getAttributionClassValueByName( - artwork.attributionClass?.name - ) as ConsignmentAttributionClass) || undefined, - category: acceptableCategoriesForSubmission().find( - (category) => category.label === artwork.category - )?.value as any, - depth: artwork.depth || "", - dimensionsMetric: artwork.metric || "", - editionNumber: artwork.editionNumber || "", - editionSizeFormatted: artwork.editionSize || "", - height: artwork.height || "", - location: { - city: artwork?.location?.city || "", - state: artwork?.location?.state || "", - country: artwork?.location?.country || "", - zipCode: artwork?.location?.postalCode || "", - countryCode: "", - address: artwork?.location?.address || "", - address2: artwork?.location?.address2 || "", - }, - medium: artwork.medium || "", - myCollectionArtworkID: artwork.internalID, - provenance: artwork.provenance || "", - // If there is a signature, set it to true, otherwise null - // This is because the signature field is a boolean - // Anyway, the user can change it later during the flow - signature: artwork.signature ? true : null, - source: "MY_COLLECTION", - state: "DRAFT", - utmMedium: "", - utmSource: "", - utmTerm: "", - width: artwork.width || "", - title: artwork.title || "", - year: artwork.date || "", - - // Photos - photos: [], - initialPhotos, - - // Contact information - userName: "", - userEmail: "", - userPhone: "", - - artwork: { - internalID: artwork.internalID, - isFramed: artwork.isFramed, - framedMetric: artwork.framedMetric, - framedWidth: artwork.framedWidth, - framedHeight: artwork.framedHeight, - framedDepth: artwork.framedDepth, - condition: artwork.condition?.value as ArtworkConditionEnumType | null | undefined, - conditionDescription: artwork.conditionDescription?.details, - }, - - additionalDocuments: [], - } - - return formValues -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers.tsx b/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers.tsx deleted file mode 100644 index 12021f2dbd8..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/testWrappers.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { SubmitArtworkBottomNavigation } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkBottomNavigation" -import { - SubmitArtworkFormStore, - SubmitArtworkFormStoreModelState, - SubmitArtworkFormStoreProvider, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { - SubmissionModel, - submissionModelInitialValues, - getCurrentValidationSchema, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" -import { setupTestWrapper } from "app/utils/tests/setupTestWrapper" -import { FormikProvider, useFormik } from "formik" - -const FormikWrapper: React.FC<{ - injectedProps?: Partial -}> = ({ children, injectedProps }) => { - const initialValues = { - ...submissionModelInitialValues, - ...injectedProps, - } as any - - const { currentStep } = SubmitArtworkFormStore.useStoreState((state) => state) - - const handleSubmit = () => { - // Implement when needed - } - const validationSchema = getCurrentValidationSchema(currentStep) - - const formik = useFormik({ - enableReinitialize: true, - initialValues: initialValues, - onSubmit: handleSubmit, - validationSchema, - }) - - return {children} -} - -export const renderWithSubmitArtworkWrapper = ({ - component, - props, - injectedFormikProps, - includeBottomNavigation = true, -}: { - component: React.ReactElement - props?: Partial - injectedFormikProps?: Partial - includeBottomNavigation?: boolean -}) => { - return renderWithWrappers( - - - {component} - {!!includeBottomNavigation && } - - - ) -} - -export const setupWithSubmitArtworkTestWrappers = ({ - Component, - props, - injectedFormikProps, -}: { - Component: React.ReactElement - props?: Partial - injectedFormikProps?: Partial -}) => { - return setupTestWrapper({ - Component: () => ( - - {Component} - - ), - }) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners.ts b/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners.ts deleted file mode 100644 index 0fa78012156..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/useNavigationListeners.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { useIsFocused } from "@react-navigation/native" -import { - NAVIGATE_TO_NEXT_STEP_EVENT, - NAVIGATE_TO_PREVIOUS_STEP_EVENT, - SubmitArtworkFormEvents, - useSubmissionContext, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext" -import { ArtworkDetailsFormModel } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/validation" -import { useFormikContext } from "formik" -import { useEffect } from "react" - -export const useNavigationListeners = ({ - onNextStep, - onPreviousStep, -}: { - onNextStep: () => void - onPreviousStep?: () => void -}) => { - const { values } = useFormikContext() - const { currentStep } = useSubmissionContext() - const isFocused = useIsFocused() - - useEffect(() => { - if (!isFocused) { - return - } - SubmitArtworkFormEvents.on(NAVIGATE_TO_NEXT_STEP_EVENT, onNextStep) - - return () => { - SubmitArtworkFormEvents.removeAllListeners(NAVIGATE_TO_NEXT_STEP_EVENT) - } - }, [isFocused, currentStep, values]) - - useEffect(() => { - if (!isFocused) { - return - } - - if (onPreviousStep) { - SubmitArtworkFormEvents.on(NAVIGATE_TO_PREVIOUS_STEP_EVENT, () => { - onPreviousStep() - }) - } - - return () => { - SubmitArtworkFormEvents.removeAllListeners(NAVIGATE_TO_PREVIOUS_STEP_EVENT) - } - }, [isFocused, currentStep, values]) -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext.ts b/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext.ts deleted file mode 100644 index 3364f4e24af..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/useSubmissionContext.ts +++ /dev/null @@ -1,114 +0,0 @@ -import EventEmitter from "events" -import { NavigationProp, useNavigation } from "@react-navigation/native" -import { SubmitArtworkFormStore } from "app/Scenes/SellWithArtsy/ArtworkForm/Components/SubmitArtworkFormStore" -import { - SubmitArtworkStackNavigation, - __unsafe__SubmissionArtworkFormNavigationRef, - getCurrentRoute, -} from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { - ARTWORK_FORM_TIER_1_FINAL_STEP, - ARTWORK_FORM_TIER_2_FINAL_STEP, - TIER_1_STATES, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/constants" -import { - SubmissionModel, - getCurrentValidationSchema, -} from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation" -import { useSubmitArtworkTracking } from "app/Scenes/SellWithArtsy/Hooks/useSubmitArtworkTracking" -import { goBack } from "app/system/navigation/navigate" -import { useBackHandler } from "app/utils/hooks/useBackHandler" -import { useFormikContext } from "formik" -import { useEffect, useMemo } from "react" -import { Alert } from "react-native" - -export const SubmitArtworkFormEvents = new EventEmitter() -SubmitArtworkFormEvents.setMaxListeners(20) - -export const NAVIGATE_TO_NEXT_STEP_EVENT = "NAVIGATE_TO_NEXT_STEP_EVENT" -export const NAVIGATE_TO_PREVIOUS_STEP_EVENT = "NAVIGATE_TO_PREVIOUS_STEP_EVENT" - -export const useSubmissionContext = () => { - const setCurrentStep = SubmitArtworkFormStore.useStoreActions((actions) => actions.setCurrentStep) - const { currentStep, isLoading } = SubmitArtworkFormStore.useStoreState((state) => state) - const navigation = useNavigation>() - - const { values } = useFormikContext() - - const validationSchema = useMemo(() => { - return getCurrentValidationSchema(currentStep) - }, [currentStep]) - - const isValid = useMemo(() => { - return validationSchema.isValidSync(values) - }, [currentStep, values]) - - const isFinalStep = - values.state && TIER_1_STATES.includes(values.state) - ? currentStep === ARTWORK_FORM_TIER_1_FINAL_STEP - : currentStep === ARTWORK_FORM_TIER_2_FINAL_STEP - - const navigateToNextStep = async () => { - SubmitArtworkFormEvents.emit(NAVIGATE_TO_NEXT_STEP_EVENT) - } - - const navigateToPreviousStep = () => { - SubmitArtworkFormEvents.emit(NAVIGATE_TO_PREVIOUS_STEP_EVENT) - - // TODO: Fix this with proper mocking of the ref - if (!__unsafe__SubmissionArtworkFormNavigationRef.current?.canGoBack() && !__TEST__) { - Alert.alert( - "Are you sure you want to go back?", - "You will lose any unsaved changes.", - [ - { - text: "Cancel", - style: "cancel", - isPreferred: true, - }, - { - text: "Exit", - onPress: () => { - goBack() - }, - style: "destructive", - }, - ], - { cancelable: true } - ) - return - } - // Order is important here to make sure getCurrentRoute returns the correct value - navigation.goBack?.() - const previousStepId = getCurrentRoute() - - if (previousStepId) { - setCurrentStep(previousStepId) - } - } - - const { trackSubmissionStepScreen } = useSubmitArtworkTracking() - - const useSubmitArtworkScreenTracking = (step: keyof SubmitArtworkStackNavigation) => { - useEffect(() => { - if (currentStep === step) { - trackSubmissionStepScreen(currentStep, values.submissionId || undefined) - } - }, [currentStep]) - } - - useBackHandler(() => { - navigateToPreviousStep() - return true - }) - - return { - isValid, - isLoading, - currentStep, - isFinalStep, - navigateToNextStep, - navigateToPreviousStep, - useSubmitArtworkScreenTracking, - } -} diff --git a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation.ts b/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation.ts deleted file mode 100644 index c557529eb38..00000000000 --- a/src/app/Scenes/SellWithArtsy/ArtworkForm/Utils/validation.ts +++ /dev/null @@ -1,236 +0,0 @@ -import { - ConsignmentSubmissionCategoryAggregation, - ConsignmentSubmissionSource, -} from "__generated__/createConsignSubmissionMutation.graphql" -import { ArtworkConditionEnumType } from "__generated__/myCollectionCreateArtworkMutation.graphql" -import { - ConsignmentAttributionClass, - ConsignmentSubmissionStateAggregation, -} from "__generated__/updateConsignSubmissionMutation.graphql" -import { AutosuggestResult } from "app/Components/AutosuggestResults/AutosuggestResults" -import { - SubmitArtworkStackNavigation, - getCurrentRoute, -} from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { Location } from "app/Scenes/SellWithArtsy/SubmitArtwork/ArtworkDetails/validation" -import { Photo } from "app/Scenes/SellWithArtsy/SubmitArtwork/UploadPhotos/validation" -import { unsafe_getFeatureFlag } from "app/store/GlobalStore" -import { NormalizedDocument } from "app/utils/normalizeUploadedDocument" -import * as Yup from "yup" - -export const getCurrentValidationSchema = (_injectedStep?: keyof SubmitArtworkStackNavigation) => { - const currentStep = _injectedStep || getCurrentRoute() - - switch (currentStep) { - case "SelectArtist": - return artistFormSchema - case "AddTitle": - return artworkFormTitleSchema - case "AddPhotos": - return artworkFormPhotosSchema - case "AddDetails": - return artworkDetailsValidationSchema - case "PurchaseHistory": - return provenanceSchema - case "AddDimensions": - return dimensionsSchema - case "ShippingLocation": - return shippingLocationSchema - case "FrameInformation": - return frameInformationSchema - case "Condition": - return conditionSchema - case "AdditionalDocuments": - return additionalDocumentsSchema - default: - return Yup.object() - } -} - -const additionalDocumentsSchema = Yup.object().shape({ - additionalDocuments: Yup.array().min(0), -}) - -const conditionSchema = Yup.object().shape({ - condition: Yup.string() - .oneOf( - ["EXCELLENT", "FAIR", "GOOD", "VERY_GOOD"], - "Condition must be one of EXCELLENT, FAIR, GOOD, VERY_GOOD" - ) - .nullable(), - conditionDescription: Yup.string().trim(), -}) - -const frameInformationSchema = Yup.object().shape({ - isFramed: Yup.boolean().nullable(), - framedMetric: Yup.string().trim(), - framedWidth: Yup.string().trim(), - framedHeight: Yup.string().trim(), - framedDepth: Yup.string().trim(), -}) - -const shippingLocationSchema = Yup.object().shape({ - location: Yup.object().shape({ - city: Yup.string().required().trim(), - state: Yup.string().required().trim(), - country: Yup.string().required().trim(), - countryCode: Yup.string().trim(), - zipCode: Yup.string().required().trim(), - address: Yup.string().required().trim(), - address2: Yup.string().trim(), - }), -}) - -const artistFormSchema = Yup.object().shape({ - artist: Yup.string().required().trim(), -}) - -const artworkFormTitleSchema = Yup.object().shape({ - title: Yup.string().required().trim(), -}) - -const artworkFormPhotosSchema = Yup.object().shape({ - photos: Yup.array() - .min(__TEST__ ? 0 : 1) - .of( - Yup.object().shape({ - id: Yup.string().required(), - geminiToken: Yup.string().required(), - path: Yup.string(), - }) - ), -}) - -const dimensionsSchema = Yup.object().shape({ - depth: unsafe_getFeatureFlag("ARSWAMakeAllDimensionsOptional") - ? Yup.string().trim() - : Yup.string().required().trim(), - height: unsafe_getFeatureFlag("ARSWAMakeAllDimensionsOptional") - ? Yup.string().trim() - : Yup.string().required().trim(), - width: unsafe_getFeatureFlag("ARSWAMakeAllDimensionsOptional") - ? Yup.string().trim() - : Yup.string().required().trim(), - dimensionsMetric: unsafe_getFeatureFlag("ARSWAMakeAllDimensionsOptional") - ? Yup.string().trim() - : Yup.string().required().trim(), -}) - -const provenanceSchema = Yup.object().shape({ - provenance: Yup.string().trim(), - signature: Yup.boolean().nullable(), -}) - -const artworkDetailsValidationSchema = Yup.object().shape({ - category: Yup.string().required(), - medium: Yup.string(), - year: Yup.string(), -}) - -export interface SubmissionModel { - submissionId: string | null - artist: string - artistId: string - artistSearchResult: AutosuggestResult | null - attributionClass: ConsignmentAttributionClass | null - category: Exclude | null - depth: string - dimensionsMetric: string - editionNumber: string - editionSizeFormatted: string - height: string - location: Location | null - medium: string - myCollectionArtworkID: string | null - provenance: string - signature?: boolean | null | undefined - source: ConsignmentSubmissionSource | null - state?: ConsignmentSubmissionStateAggregation | null - utmMedium?: string - utmSource?: string - utmTerm?: string - width: string - title: string - year: string - - // Photos - photos: Photo[] - initialPhotos?: Photo[] - - // Contact information - userName: string - userEmail: string - userPhone: string - - // Artwork - artwork: { - internalID: string | null | undefined - isFramed: boolean | null | undefined - framedMetric: string | null | undefined - framedWidth: string | null | undefined - framedHeight: string | null | undefined - framedDepth: string | null | undefined - condition: ArtworkConditionEnumType | null | undefined - conditionDescription: string | null | undefined - } - - externalId: string | null - additionalDocuments: NormalizedDocument[] -} - -export const submissionModelInitialValues: SubmissionModel = { - submissionId: null, - artist: "", - artistId: "", - artistSearchResult: null, - attributionClass: null, - category: null, - depth: "", - dimensionsMetric: "in", - editionNumber: "", - editionSizeFormatted: "", - height: "", - location: { - city: "", - state: "", - country: "", - countryCode: "", - zipCode: "", - }, - medium: "", - myCollectionArtworkID: null, - provenance: "", - signature: null, - source: null, - state: "DRAFT", - utmMedium: "", - utmSource: "", - utmTerm: "", - width: "", - title: "", - year: "", - - // Photos - photos: [], - initialPhotos: [], - - // Contact information - userName: "", - userEmail: "", - userPhone: "", - - // Artwork - artwork: { - internalID: null, - isFramed: null, - framedMetric: "in", - framedWidth: null, - framedHeight: null, - framedDepth: null, - condition: null, - conditionDescription: null, - }, - - externalId: null, - additionalDocuments: [], -} diff --git a/src/app/Scenes/SellWithArtsy/Components/CollectorsNetwork.tsx b/src/app/Scenes/SellWithArtsy/Components/CollectorsNetwork.tsx deleted file mode 100644 index 4dda5d5b749..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/CollectorsNetwork.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { Flex, Spacer, Text } from "@artsy/palette-mobile" -import { Image } from "react-native" -import { isTablet } from "react-native-device-info" - -export const CollectorsNetwork: React.FC = () => { - if (isTablet()) { - return ( - - - Reach a global network of collectors - - - - - 3M+ - registered buyers worldwide - - - 3,000 - miles average transaction distance - - - 190 - countries - - - - - - ) - } - return ( - - - Reach a global network of collectors - - - 3M+ - registered buyers worldwide - - - - - 3,000 - miles average transaction distance - - - - 190 - countries - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/Components/FAQSWA.tsx b/src/app/Scenes/SellWithArtsy/Components/FAQSWA.tsx deleted file mode 100644 index 6bcdeba6595..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/FAQSWA.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { Flex, Text, Button } from "@artsy/palette-mobile" -import { navigate } from "app/system/navigation/navigate" -import { useScreenDimensions } from "app/utils/hooks" -import { Image } from "react-native" -import { isTablet } from "react-native-device-info" - -export const FAQSWA: React.FC = () => { - const supportUrl = "https://support.artsy.net/s/topic/0TO3b000000UesxGAC/sell" - - const { width: deviceWidth } = useScreenDimensions() - return ( - - - - No upfront fees, clear pricing estimates, and competitive commission structures. - - - Have more questions? - - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/Components/Footer.tsx b/src/app/Scenes/SellWithArtsy/Components/Footer.tsx deleted file mode 100644 index 8e73db9a327..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/Footer.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Flex, Text, Separator } from "@artsy/palette-mobile" -import { navigate } from "app/system/navigation/navigate" -import { isTablet } from "react-native-device-info" - -export const Footer: React.FC = () => { - return ( - - - - - Gallerist or Art Dealer? - - - navigate("https://partners.artsy.net/")} - style={{ textDecorationLine: "underline" }} - > - Become a partner - {" "} - to access the world’s largest online art marketplace. - - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/Components/Header.tsx b/src/app/Scenes/SellWithArtsy/Components/Header.tsx deleted file mode 100644 index 692dafd6fb5..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/Header.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import { - ArrowRightIcon, - Box, - EntityHeader, - Flex, - Spacer, - Text, - Touchable, -} from "@artsy/palette-mobile" -import { Header_submission$key } from "__generated__/Header_submission.graphql" -import { - INITIAL_EDIT_STEP, - SubmitArtworkStackNavigation, -} from "app/Scenes/SellWithArtsy/ArtworkForm/SubmitArtworkForm" -import { useSubmitArtworkTracking } from "app/Scenes/SellWithArtsy/Hooks/useSubmitArtworkTracking" -import { GlobalStore } from "app/store/GlobalStore" -import { navigate } from "app/system/navigation/navigate" -import { useScreenDimensions } from "app/utils/hooks" -import { Alert, Image } from "react-native" -import { isTablet } from "react-native-device-info" -import { graphql, useFragment } from "react-relay" - -interface HeaderProps { - submission: Header_submission$key | null -} - -export const Header: React.FC = (props) => { - const { trackTappedContinueSubmission } = useSubmitArtworkTracking() - const { draft } = GlobalStore.useAppState((state) => state.artworkSubmission) - const { width } = useScreenDimensions() - - const submission = useFragment(FRAGMENT, props.submission) - - const artist = submission?.artist - - const previousStep: keyof SubmitArtworkStackNavigation = draft?.currentStep || INITIAL_EDIT_STEP - - return ( - - - - - - - {!!draft && !!submission && ( - - { - const id = draft.submissionID - trackTappedContinueSubmission(id, previousStep) - navigate(`/sell/submissions/${id}/edit?initialStep=${previousStep}`) - }} - onLongPress={() => { - Alert.alert( - "Are you sure you want to delete this draft?", - "This action cannot be undone.", - [ - { - text: "Cancel", - style: "cancel", - }, - { - text: "Delete", - onPress: () => { - GlobalStore.actions.artworkSubmission.setDraft(null) - }, - style: "destructive", - }, - ] - ) - }} - > - - - Finish previous submission: - - - } - px={2} - py={1} - borderWidth={1} - borderColor="black10" - borderRadius={5} - /> - - - - )} - - - Sell art from your collection - - - - With our global reach and art market expertise, our specialists will find the best sales - option for your work. - - - - ) -} - -const FRAGMENT = graphql` - fragment Header_submission on ConsignmentSubmission { - title - artist { - name - imageUrl - } - } -` diff --git a/src/app/Scenes/SellWithArtsy/Components/Highlights.tsx b/src/app/Scenes/SellWithArtsy/Components/Highlights.tsx deleted file mode 100644 index 9b5cbf581f8..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/Highlights.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Flex, Join, Spacer, Text } from "@artsy/palette-mobile" -import { - LightStarIcon, - MoneyCircleIcon, - WorldGlobeCircleIcon, -} from "app/Scenes/SellWithArtsy/Components/icons/Icons" - -const reasons = [ - { - icon: , - title: "Earn more from your sale", - text: "With lower fees than traditional auction houses and dealers, you take home more of the final sale price.", - }, - { - icon: , - title: "Tap into our expertise", - text: "Our team has a wealth of experience in the secondary art market. A dedicated specialist will be with you every step of the way.", - }, - { - icon: , - title: "Reach a global network", - text: "With the world’s largest network of collectors, we match your work with the most interested buyers in over 190 countries.", - }, -] - -export const Highlights: React.FC = () => { - return ( - - }> - {reasons.map(({ icon, title, text }) => ( - - {icon} - - {title} - - {text} - - ))} - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/Components/HowItWorks.tsx b/src/app/Scenes/SellWithArtsy/Components/HowItWorks.tsx deleted file mode 100644 index 84167fe1a70..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/HowItWorks.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { Spacer, Flex, Text, Join } from "@artsy/palette-mobile" - -const STEPS = [ - { - title: "Submit your artwork", - text: "Enter the artist’s name on the submission page. If the artist is in our database, you’ll be able to upload images and artwork details.", - }, - { - title: "Meet your expert", - text: "One of our specialists will review your submission and determine the best sales option.", - }, - { - title: "Get a sales option", - text: "Review your tailored sales strategy and price estimate. We’ll select the best way to sell your work—either at auction, through private sale, or a direct listing on Artsy.", - }, - { - title: "Sell your work", - text: "Keep your work until it sells, then let our team handle the logistics. No costly presale insurance, shipping, or handling fees.", - }, -] - -export const HowItWorks: React.FC = () => { - return ( - - How it works - - - }> - {STEPS.map((step, index) => ( - - {`0${index + 1}`} - {step.title} - {step.text} - - ))} - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/Components/MeetTheSpecialists.tsx b/src/app/Scenes/SellWithArtsy/Components/MeetTheSpecialists.tsx deleted file mode 100644 index c1fac7387b3..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/MeetTheSpecialists.tsx +++ /dev/null @@ -1,194 +0,0 @@ -import { ActionType, ContextModule, OwnerType, TappedConsignmentInquiry } from "@artsy/cohesion" -import { Flex, Spacer, Text, useColor, useSpace, Button } from "@artsy/palette-mobile" -import { MeetTheSpecialists_staticContent$key } from "__generated__/MeetTheSpecialists_staticContent.graphql" -import { useExtraLargeWidth } from "app/Components/ArtworkRail/useExtraLargeWidth" -import { ReadMore } from "app/Components/ReadMore" -import { AnimateHeight } from "app/utils/animations/AnimateHeight" -import { MotiView } from "moti" -import { useState } from "react" -import { FlatList, ImageBackground } from "react-native" -import { isTablet } from "react-native-device-info" -import LinearGradient from "react-native-linear-gradient" -import { Easing } from "react-native-reanimated" -import { graphql, useFragment } from "react-relay" - -const IMG_HEIGHT_TO_WIDTH_RATIO = 1.511 // based on designs - -type InqueryPress = ( - trackingargs?: TappedConsignmentInquiry, - recipientEmail?: string, - recipientName?: string -) => void - -export const MeetTheSpecialists: React.FC<{ - onInquiryPress: InqueryPress - staticContent: MeetTheSpecialists_staticContent$key -}> = ({ onInquiryPress, staticContent }) => { - const staticContentData = useFragment(specialistFragment, staticContent) - - const space = useSpace() - - const specialistBios = staticContentData?.specialistBios - - if (!specialistBios) { - return null - } - - return ( - - - Meet the specialists - - - Our specialists span today’s most popular collecting categories. - - - { - return - }} - keyExtractor={(item) => item.name} - ListFooterComponent={() => } - /> - - - Not sure who’s the right fit for your collection? Get in touch and we’ll connect you. - - - - - - ) -} - -interface SpecialistProps { - specialist: { - image: { imageURL: string | undefined | null } - firstName: string - name: string - jobTitle: string - bio: string - email: string - } - onInquiryPress: InqueryPress -} -const Specialist: React.FC = ({ specialist, onInquiryPress }) => { - const [isBioExpanded, setIsBioExpanded] = useState(false) - - const color = useColor() - const space = useSpace() - - const imgWidth = useExtraLargeWidth() - const imgHeight = imgWidth * IMG_HEIGHT_TO_WIDTH_RATIO - - const buttonText = `Contact ${specialist.firstName}` - - const bioTextLimit = isTablet() ? 160 : 88 - - return ( - - - - - - - - {specialist.name} - - - {specialist.jobTitle} - - - setIsBioExpanded(isExpanded)} - /> - - - - - - - ) -} - -const tracks = { - consignmentInquiryTapped: (subject: string): TappedConsignmentInquiry => ({ - action: ActionType.tappedConsignmentInquiry, - context_module: ContextModule.sellMeetTheSpecialists, - context_screen: OwnerType.sell, - context_screen_owner_type: OwnerType.sell, - subject, - }), -} - -const specialistFragment = graphql` - fragment MeetTheSpecialists_staticContent on StaticContent { - specialistBios { - name - firstName - jobTitle - bio - email - image { - imageURL - } - } - } -` diff --git a/src/app/Scenes/SellWithArtsy/Components/SellWithArtsyRecentlySold.tsx b/src/app/Scenes/SellWithArtsy/Components/SellWithArtsyRecentlySold.tsx deleted file mode 100644 index e596f5b0cf3..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/SellWithArtsyRecentlySold.tsx +++ /dev/null @@ -1,200 +0,0 @@ -import { ContextModule, OwnerType, tappedEntityGroup, TappedEntityGroupArgs } from "@artsy/cohesion" -import { Flex, Spacer, Text } from "@artsy/palette-mobile" -import { ListRenderItem } from "@shopify/flash-list" -import { - SellWithArtsyRecentlySold_recentlySoldArtworkTypeConnection$data, - SellWithArtsyRecentlySold_recentlySoldArtworkTypeConnection$key, -} from "__generated__/SellWithArtsyRecentlySold_recentlySoldArtworkTypeConnection.graphql" -import { ArtworkRailProps } from "app/Components/ArtworkRail/ArtworkRail" -import { ArtworkRailCard } from "app/Components/ArtworkRail/ArtworkRailCard" -import { - ARTWORK_RAIL_CARD_IMAGE_HEIGHT, - ARTWORK_RAIL_CARD_MIN_WIDTH, -} from "app/Components/ArtworkRail/ArtworkRailCardImage" -import { PrefetchFlashList } from "app/Components/PrefetchFlashList" -import { extractNodes } from "app/utils/extractNodes" -import { ExtractNodeType } from "app/utils/relayHelpers" -import { compact } from "lodash" -import { useCallback } from "react" -import { PixelRatio } from "react-native" -import { graphql, useFragment } from "react-relay" -import { useTracking } from "react-tracking" - -const MAX_NUMBER_OF_ARTWORKS = 30 -const fontScale = PixelRatio.getFontScale() - -interface SellWithArtsyRecentlySoldProps { - recentlySoldArtworks: SellWithArtsyRecentlySold_recentlySoldArtworkTypeConnection$key -} - -const trackingArgs: TappedEntityGroupArgs = { - contextModule: ContextModule.artworkRecentlySoldGrid, - contextScreenOwnerType: OwnerType.sell, - destinationScreenOwnerType: OwnerType.artwork, - type: "thumbnail", -} - -export const SellWithArtsyRecentlySold: React.FC = ({ - recentlySoldArtworks, -}) => { - const tracking = useTracking() - const recentlySoldArtworksData = useFragment( - customRecentlySoldArtworksFragment, - recentlySoldArtworks - ) - - const recentlySoldArtworksNodes = extractNodes(recentlySoldArtworksData) - - return ( - - - Previously sold on Artsy - - - - - { - tracking.trackEvent( - tappedEntityGroup({ - ...trackingArgs, - destinationScreenOwnerId: recentlySoldArtwork?.artwork?.internalID, - destinationScreenOwnerSlug: recentlySoldArtwork?.artwork?.slug, - }) - ) - }} - showPartnerName={false} - /> - - ) -} - -type RecentlySoldArtwork = - ExtractNodeType - -export interface RecentlySoldArtworksRailProps - extends Omit { - recentlySoldArtworks: RecentlySoldArtwork[] - onPress?: (recentlySoldArtwork: RecentlySoldArtwork, index: number) => void -} - -const RecentlySoldArtworksRail: React.FC = ({ - listRef, - onPress, - onEndReached, - onEndReachedThreshold, - ListHeaderComponent = , - ListFooterComponent = , - hideArtistName = false, - recentlySoldArtworks, - showPartnerName = true, -}) => { - const renderItem: ListRenderItem = useCallback( - ({ item, index }) => { - if (!item?.artwork) { - return null - } - - return ( - { - onPress?.(item, index) - }} - // 102 = 92px (text container height) + 10px (padding) - // 20px is the height of a second line of the Estimate price when displayed in two lines - containerHeight={ARTWORK_RAIL_CARD_IMAGE_HEIGHT + fontScale * (102 + 20)} - showPartnerName={showPartnerName} - SalePriceComponent={ - - } - hideArtistName={hideArtistName} - /> - ) - }, - [hideArtistName, onPress, showPartnerName] - ) - return ( - String(item?.artwork?.slug || index)} - ListFooterComponent={ListFooterComponent} - ListHeaderComponent={ListHeaderComponent} - listRef={listRef} - onEndReached={onEndReached} - onEndReachedThreshold={onEndReachedThreshold} - renderItem={renderItem} - showsHorizontalScrollIndicator={false} - /> - ) -} - -interface RecentlySoldCardSectionProps { - priceRealizedDisplay: string - lowEstimateDisplay: string - highEstimateDisplay: string - performanceDisplay?: string -} - -const RecentlySoldCardSection: React.FC = ({ - priceRealizedDisplay, - lowEstimateDisplay, - highEstimateDisplay, - performanceDisplay, -}) => { - const priceFontSize = fontScale > 1 ? "sm" : "md" - - return ( - - - - {priceRealizedDisplay} - - {!!performanceDisplay && ( - - {`+${performanceDisplay}`} - - )} - - - Estimate {compact([lowEstimateDisplay, highEstimateDisplay]).join("—")} - - - ) -} - -const customRecentlySoldArtworksFragment = graphql` - fragment SellWithArtsyRecentlySold_recentlySoldArtworkTypeConnection on RecentlySoldArtworkTypeConnection { - edges { - node { - artwork { - ...ArtworkRailCard_artwork - internalID - href - slug - } - lowEstimate { - display - } - highEstimate { - display - } - priceRealized { - display - } - performance { - mid - } - } - } - } -` diff --git a/src/app/Scenes/SellWithArtsy/Components/SpeakToTheTeam.tsx b/src/app/Scenes/SellWithArtsy/Components/SpeakToTheTeam.tsx deleted file mode 100644 index 8040462f5f6..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/SpeakToTheTeam.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { ActionType, ContextModule, OwnerType, TappedConsignmentInquiry } from "@artsy/cohesion" -import { Flex, Spacer, Text, useColor, Button } from "@artsy/palette-mobile" -import { Image } from "react-native" -import { isTablet } from "react-native-device-info" - -export const SpeakToTheTeam: React.FC<{ - onInquiryPress: (inquiryArgs?: TappedConsignmentInquiry) => void -}> = ({ onInquiryPress }) => { - const color = useColor() - return ( - - - - - Interested in selling multiple artworks? {"\n"} - Speak with our team. - - - - - - - - - ) -} - -const tracks = { - consignmentInquiryTapped: (): TappedConsignmentInquiry => ({ - action: ActionType.tappedConsignmentInquiry, - context_module: ContextModule.sellSpeakToTheTeam, - context_screen: OwnerType.sell, - context_screen_owner_type: OwnerType.sell, - subject: "Get in Touch", - }), -} diff --git a/src/app/Scenes/SellWithArtsy/Components/StickySWAHeader.tsx b/src/app/Scenes/SellWithArtsy/Components/StickySWAHeader.tsx deleted file mode 100644 index 6d84aa8fb9c..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/StickySWAHeader.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { - ActionType, - ContextModule, - OwnerType, - TappedConsignArgs, - TappedConsignmentInquiry, -} from "@artsy/cohesion" -import { Button, Flex, LinkText, Spacer, Text } from "@artsy/palette-mobile" - -interface StickySWAHeaderProps { - onConsignPress: (tappedConsignArgs: TappedConsignArgs) => void - onInquiryPress: (inquiryTrackingArgs?: TappedConsignmentInquiry) => void -} - -export const StickySWAHeader: React.FC = ({ - onConsignPress, - onInquiryPress, -}) => { - const handleSubmitPress = (subject: string) => { - onConsignPress(tracks.consignArgs(subject)) - } - - const handleInquiryPress = () => { - onInquiryPress(tracks.consignmentInquiryTapped()) - } - - return ( - - - - - - - Not sure what you’re looking for?{" "} - - Speak to an advisor - - - - ) -} - -const tracks = { - consignArgs: (subject: string): TappedConsignArgs => ({ - contextModule: ContextModule.sellHeader, - contextScreenOwnerType: OwnerType.sell, - subject, - }), - consignmentInquiryTapped: (): TappedConsignmentInquiry => ({ - action: ActionType.tappedConsignmentInquiry, - context_module: ContextModule.sellHeader, - context_screen: OwnerType.sell, - context_screen_owner_type: OwnerType.sell, - subject: "Get in Touch", - }), -} diff --git a/src/app/Scenes/SellWithArtsy/Components/WaysWeSell.tsx b/src/app/Scenes/SellWithArtsy/Components/WaysWeSell.tsx deleted file mode 100644 index b8e1daa8fac..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/WaysWeSell.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { Flex, Spacer, Text, useTheme } from "@artsy/palette-mobile" -import { useExtraLargeWidth } from "app/Components/ArtworkRail/useExtraLargeWidth" -import { Image, ImageSourcePropType } from "react-native" -import { FlatList } from "react-native-gesture-handler" - -const IMAGE_WIDTH = 600 - -const data: Array<{ - title: string - text: string - imageSource: ImageSourcePropType - height: number - width: number -}> = [ - { - title: "Auctions", - text: "Our curated auctions provide you with multiple opportunities to reach the widest audience and successfully achieve your artwork’s full potential.", - imageSource: require("images/ways-we-sell-auction.webp"), - width: IMAGE_WIDTH, - height: 415, - }, - { - title: "Private Sales", - text: "We offer tailored and discreet sales arrangements for our collectors’ highest value and most sensitive artworks.", - imageSource: require("images/ways-we-sell-private-sales.webp"), - width: IMAGE_WIDTH, - height: 597, - }, - { - title: "Online storefront", - text: "When your work is listed directly on Artsy.net—the world’s largest online art marketplace—it reaches over 3 million art lovers.", - imageSource: require("images/ways-we-sell-online-storefront.webp"), - width: IMAGE_WIDTH, - height: 344, - }, -] - -export const WaysWeSell: React.FC = () => { - const { color, space } = useTheme() - - const maxImageWidth = useExtraLargeWidth() - - const maxImageContainerHeight = - (maxImageWidth * Math.max(...data.map((i) => i.height))) / IMAGE_WIDTH - - return ( - - - - A sales strategy tailored to your artwork - - - - A dedicated specialist works with you to select the best sales option for your artwork. - - - - { - const imageAspectRatio = item.height / item.width - - const imageHeight = maxImageWidth * imageAspectRatio - return ( - - - - - - - - {item.title} - - - {item.text} - - - - ) - }} - ItemSeparatorComponent={() => } - keyExtractor={(item) => item.title} - /> - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/Components/icons/Icons.tsx b/src/app/Scenes/SellWithArtsy/Components/icons/Icons.tsx deleted file mode 100644 index 30c0b579b89..00000000000 --- a/src/app/Scenes/SellWithArtsy/Components/icons/Icons.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import { Icon, IconProps, Path, useColor } from "@artsy/palette-mobile" - -// TODO: - Remove these icons when palette-Mobile is stable as they have already been added there in newer unstable versions - -export const MoneyCircleIcon = ({ fill, ...restProps }: IconProps) => { - const color = useColor() - return ( - - - - - - - - ) -} - -export const LightStarIcon = ({ fill, ...restProps }: IconProps) => { - const color = useColor() - return ( - - - - - - - - ) -} - -export const WorldGlobeCircleIcon = ({ fill, ...restProps }: IconProps) => { - const color = useColor() - return ( - - - - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryConfirmation.tests.tsx b/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryConfirmation.tests.tsx deleted file mode 100644 index 999c9925a1a..00000000000 --- a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryConfirmation.tests.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { fireEvent } from "@testing-library/react-native" -import { popToRoot } from "app/system/navigation/navigate" -import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" -import { ConsignmentInquiryConfirmation } from "./ConsignmentInquiryConfirmation" - -describe("ConsignmentInquiryConfirmation", () => { - it('"Back to Sell with Artsy" Button pops to root screen', () => { - const { getByTestId } = renderWithWrappers() - const button = getByTestId("back-to-swa-button") - fireEvent.press(button) - expect(popToRoot).toHaveBeenCalled() - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryConfirmation.tsx b/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryConfirmation.tsx deleted file mode 100644 index 8571d35b1a6..00000000000 --- a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryConfirmation.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { ArtsyLogoBlackIcon, Flex, Box, Text, Button } from "@artsy/palette-mobile" -import { popToRoot } from "app/system/navigation/navigate" - -export const ConsignmentInquiryConfirmation: React.FC<{}> = () => { - return ( - - - - - - Your message has been sent - - - An Artsy specialist will be in touch to find out more about how we can assist you. - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryForm.tests.tsx b/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryForm.tests.tsx deleted file mode 100644 index d81bb341afc..00000000000 --- a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryForm.tests.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" -import { ConsignmentInquiryForm } from "./ConsignmentInquiryForm" - -const initialValues = { - name: "tester name", - email: "email@hq.com", - phoneNumber: "+4912345", - message: "", -} - -jest.mock("formik", () => ({ - useFormikContext: () => { - return { - values: initialValues, - handleChange: jest.fn(() => jest.fn()), - errors: {}, - isValid: true, - } - }, -})) - -describe("ConsignmentInquiryForm", () => { - const getWrapper = () => - renderWithWrappers() - it("renders with fields prepopulated", () => { - const tree = getWrapper() - const nameInput = tree.getByTestId("swa-inquiry-name-input") - const emailInput = tree.getByTestId("swa-inquiry-email-input") - const phoneInput = tree.getByTestId("swa-inquiry-phone-input") - expect(nameInput.props.value).toBe(initialValues.name) - expect(emailInput.props.value).toBe(initialValues.email) - expect(phoneInput.props.value).toBe("12 345") // excluding area code and spaced - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryForm.tsx b/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryForm.tsx deleted file mode 100644 index f9976f4f38b..00000000000 --- a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryForm.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import { Box, Button, Input, LinkText, Spacer, Text } from "@artsy/palette-mobile" -import { useNavigation } from "@react-navigation/native" -import { PhoneInput } from "app/Components/Input/PhoneInput" -import { navigate } from "app/system/navigation/navigate" -import { useFormikContext } from "formik" -import { useEffect, useRef } from "react" -import { Platform, ScrollView } from "react-native" -import { InquiryFormikSchema } from "./ConsignmentInquiryScreen" - -export const ConsignmentInquiryForm: React.FC<{ - confirmLeaveEdit: (v: boolean) => void - canPopScreen: boolean - recipientName?: string -}> = ({ confirmLeaveEdit, canPopScreen, recipientName }) => { - const { values, handleChange, errors, handleSubmit, isValid, dirty, validateField } = - useFormikContext() - - const navigation = useNavigation() - - useEffect(() => { - const backListener = navigation.addListener("beforeRemove", (e) => { - e.preventDefault() - if (canPopScreen) { - navigation.dispatch(e.data.action) - } - if (dirty) { - confirmLeaveEdit(true) - return - } - navigation.dispatch(e.data.action) - }) - return backListener - }, [canPopScreen, dirty, navigation]) - - const scrollViewRef = useRef(null) - const nameInputRef = useRef(null) - const emailInputRef = useRef(null) - const phoneInputRef = useRef(null) - const messageInputRef = useRef(null) - - const jumpToNextField = (currentField: "name" | "email" | "phone" | "message") => { - switch (currentField) { - case "name": - emailInputRef.current?.focus() - break - case "email": - phoneInputRef.current?.focus() - break - case "phone": - messageInputRef.current?.focus() - break - default: - return - } - } - - // We cannot rely on the KeyboardAvoidingView to fully expose the - // multiline input and the send button at the same time, hence the need - // for this function - const showMessageInputFully = () => { - requestAnimationFrame(() => { - scrollViewRef.current?.scrollToEnd() - }) - } - - const handleOnChangeText = (field: keyof InquiryFormikSchema, text: string) => { - if (errors[field]) { - validateField(field) - } - handleChange(field)(text) - } - - return ( - - - - - {!!recipientName ? `Contact ${recipientName}` : "Contact a specialist"} - - validateField("name")} - onChangeText={(text) => handleOnChangeText("name", text)} - onSubmitEditing={() => jumpToNextField("name")} - placeholder="First and last name" - ref={nameInputRef} - returnKeyType="next" - testID="swa-inquiry-name-input" - title="Name" - value={values.name} - /> - - validateField("email")} - onChangeText={(text) => handleOnChangeText("email", text.trim())} - onSubmitEditing={() => jumpToNextField("email")} - placeholder="Email address" - ref={emailInputRef} - returnKeyType="next" - spellCheck={false} - testID="swa-inquiry-email-input" - textContentType={Platform.OS === "ios" ? "username" : "emailAddress"} - title="Email" - value={values.email} - /> - - handleOnChangeText("phoneNumber", text.trim())} - onSubmitEditing={() => jumpToNextField("phone")} - placeholder="(000) 000-0000" - ref={phoneInputRef} - shouldDisplayLocalError={false} - style={{ flex: 1 }} - optional - testID="swa-inquiry-phone-input" - title="Phone number" - value={values.phoneNumber} - /> - - validateField("message")} - onChangeText={(text) => handleOnChangeText("message", text.trimStart())} - onFocus={showMessageInputFully} - onSubmitEditing={() => jumpToNextField("message")} - placeholder="Questions about selling multiple works or an entire collection? Tell us more about how we can assist you. " - ref={messageInputRef} - required - returnKeyType="default" - testID="swa-inquiry-message-input" - title="Your Message" - value={values.message} - /> - - - By continuing, you agree to{" "} - navigate("/privacy")}> - Artsy’s Privacy Policy. - {" "} - - - - - - ) -} diff --git a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryScreen.tests.tsx b/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryScreen.tests.tsx deleted file mode 100644 index 8495401b3c5..00000000000 --- a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryScreen.tests.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { act } from "@testing-library/react-native" -import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" -import { createMockEnvironment, MockPayloadGenerator } from "relay-test-utils" -import { ConsignmentInquiryScreen, createConsignmentInquiry } from "./ConsignmentInquiryScreen" - -describe("ConsignmentInquiryScreen", () => { - const props = { - userId: "user-id", - name: "Tester HQ", - email: "tester@hq.com", - phone: "+49123456898", - } - - it("renders without errors", () => { - renderWithWrappers() - }) - - describe("createConsignmentInquiry", () => { - const { phone, ...otherProps } = props - const input = { - ...otherProps, - phoneNumber: phone, - message: "Message to You", - } - - const inputWithRecipientEmail = { - ...otherProps, - phoneNumber: phone, - message: "Message to You", - recipientEmail: "test@artsymail.com", - } - - const environment = createMockEnvironment() - - const onCompleted = jest.fn() - - it("sends Consignment Inquiries", () => { - createConsignmentInquiry(environment, onCompleted, jest.fn(), input) - const operation = environment.mock.getMostRecentOperation() - act(() => { - environment.mock.resolve(operation, MockPayloadGenerator.generate(operation)) - }) - expect(onCompleted).toBeCalled() - }) - - it("sends Consignment Inquiries with recipientEmail ", () => { - createConsignmentInquiry(environment, onCompleted, jest.fn(), inputWithRecipientEmail) - const operation = environment.mock.getMostRecentOperation() - act(() => { - environment.mock.resolve(operation, MockPayloadGenerator.generate(operation)) - }) - expect(onCompleted).toBeCalled() - }) - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryScreen.tsx b/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryScreen.tsx deleted file mode 100644 index a0aa8c4b5ae..00000000000 --- a/src/app/Scenes/SellWithArtsy/ConsignmentInquiry/ConsignmentInquiryScreen.tsx +++ /dev/null @@ -1,172 +0,0 @@ -import { ActionType, ContextModule, OwnerType } from "@artsy/cohesion" -import { SentConsignmentInquiry } from "@artsy/cohesion/dist/Schema/Events/Consignments" -import { ConsignmentInquiryScreenMutation } from "__generated__/ConsignmentInquiryScreenMutation.graphql" -import { AbandonFlowModal } from "app/Components/AbandonFlowModal" -import { useToast } from "app/Components/Toast/toastHook" -import { goBack } from "app/system/navigation/navigate" -import { getRelayEnvironment } from "app/system/relay/defaultEnvironment" -import { FormikProvider, useFormik } from "formik" -import { useState } from "react" -import { KeyboardAvoidingView, Modal } from "react-native" -import { Screen } from "react-native-screens" -import { commitMutation, Environment, graphql } from "react-relay" -import { useTracking } from "react-tracking" -import * as Yup from "yup" -import { ConsignmentInquiryConfirmation } from "./ConsignmentInquiryConfirmation" -import { ConsignmentInquiryForm } from "./ConsignmentInquiryForm" - -interface InquiryScreenProps { - name: string - email: string - phone: string - userId?: string - recipientEmail?: string - recipientName?: string -} - -export interface InquiryFormikSchema { - name: string - email: string - phoneNumber: string - message: string -} - -const ValidationSchema = Yup.object().shape({ - name: Yup.string().trim().required("Name field is required").min(1, "Name field is required"), - email: Yup.string() - .required("Email field is required") - .email("Please provide a valid email address"), - message: Yup.string().required("An inquiry message is required"), -}) - -export const createConsignmentInquiry = ( - environment: Environment, - onCompleted: (response: ConsignmentInquiryScreenMutation["response"]) => void, - onError: () => void, - input: InquiryFormikSchema & { userId?: string; recipientEmail?: string } -) => { - commitMutation(environment, { - mutation: graphql` - mutation ConsignmentInquiryScreenMutation($input: CreateConsignmentInquiryMutationInput!) { - createConsignmentInquiry(input: $input) { - consignmentInquiryOrError { - ... on ConsignmentInquiryMutationSuccess { - consignmentInquiry { - internalID - } - } - ... on ConsignmentInquiryMutationFailure { - mutationError { - error - message - statusCode - } - } - } - } - } - `, - variables: { input }, - onCompleted, - onError, - }) -} - -export const ConsignmentInquiryScreen: React.FC = ({ - email, - name, - phone, - userId, - recipientEmail, - recipientName, -}) => { - const [showAbandonModal, setShowAbandonModal] = useState(false) - const [showConfirmedModal, setShowConfirmedModal] = useState(false) - const { trackEvent } = useTracking() - const toast = useToast() - - const formik = useFormik({ - validateOnChange: false, - validateOnBlur: true, - initialValues: { - email, - name, - phoneNumber: phone, - message: "", - }, - - onSubmit: async ({ email, name, phoneNumber, message }) => { - const formattedNameValue = name.trim() - - const input = !!recipientEmail - ? { email, name: formattedNameValue, phoneNumber, message, userId, recipientEmail } - : { email, name: formattedNameValue, phoneNumber, message, userId } - const onCompleted = (response: ConsignmentInquiryScreenMutation["response"]) => { - const consignmentInquiryId = - response.createConsignmentInquiry?.consignmentInquiryOrError?.consignmentInquiry - ?.internalID - const error = - response.createConsignmentInquiry?.consignmentInquiryOrError?.mutationError?.message - - if (error) { - toast.show(`Error: ${error}`, "top", { backgroundColor: "red100" }) - return - } - if (consignmentInquiryId) { - trackEvent(tracks.sentConsignmentInquiry(consignmentInquiryId)) - setShowConfirmedModal(true) - } - } - const onError = () => { - toast.show("Error: Failed to send inquiry.", "top", { - backgroundColor: "red100", - }) - } - - createConsignmentInquiry(getRelayEnvironment(), onCompleted, onError, input) - }, - validationSchema: ValidationSchema, - }) - - const canPopScreen = showAbandonModal || showConfirmedModal - - return ( - - <> - - setShowAbandonModal(v)} - canPopScreen={canPopScreen} - recipientName={recipientName} - /> - - - setShowAbandonModal(false)} - onLeave={goBack} - /> - - - - - - - - - ) -} - -const tracks = { - sentConsignmentInquiry: (consignmentInquiryId: number): SentConsignmentInquiry => ({ - action: ActionType.sentConsignmentInquiry, - context_module: ContextModule.consignmentInquiryForm, - context_screen_owner_type: OwnerType.consignmentInquiry, - context_screen: OwnerType.consignmentInquiry, - consignment_inquiry_id: consignmentInquiryId, - }), -} diff --git a/src/app/Scenes/SellWithArtsy/Hooks/useSubmitArtworkTracking.ts b/src/app/Scenes/SellWithArtsy/Hooks/useSubmitArtworkTracking.ts deleted file mode 100644 index 39989c225c0..00000000000 --- a/src/app/Scenes/SellWithArtsy/Hooks/useSubmitArtworkTracking.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { ActionType, ContextModule, OwnerType } from "@artsy/cohesion" -import { SubmitArtworkScreen } from "app/Scenes/SellWithArtsy/ArtworkForm/Utils/constants" -import { useTracking } from "react-tracking" - -export const useSubmitArtworkTracking = () => { - const { trackEvent } = useTracking() - - const trackTappedContinueSubmission = (submission_id: string, destination_step: string) => { - trackEvent({ - action: "tappedContinueSubmission", - context_module: ContextModule.sell, - context_owner_type: OwnerType.sell, - submission_id, - destination_step, - }) - } - - const trackTappedNewSubmission = () => { - trackEvent({ - action: "tappedNewSubmission", - context_module: ContextModule.sell, - context_owner_type: getOwnerType("StartFlow"), - }) - } - - const trackTappedStartMyCollection = () => { - trackEvent({ - action: "tappedStartMyCollection", - context_module: ContextModule.sell, - context_owner_type: getOwnerType("StartFlow"), - }) - } - - const trackTappedSubmissionSaveExit = ( - submission_id: string | null, - currentStep: SubmitArtworkScreen - ) => { - trackEvent({ - action: "tappedSubmissionSaveExit", - context_module: ContextModule.sell, - context_owner_type: getOwnerType(currentStep), - submission_id, - submission_step: currentStep, - }) - } - - const trackTappedSubmissionBack = ( - submission_id: string | null, - currentStep: SubmitArtworkScreen - ) => { - trackEvent({ - action: "tappedSubmissionBack", - context_module: ContextModule.sell, - context_owner_type: getOwnerType(currentStep), - submission_id, - submission_step: currentStep, - }) - } - - const trackConsignmentSubmitted = (submission_id: string | null) => { - trackEvent({ - action: "consignmentSubmitted", - context_module: ContextModule.sell, - context_owner_type: getOwnerType("CompleteYourSubmission"), - submission_id, - fieldsProvided: [], - }) - } - - const trackTappedSubmitAnotherWork = (submission_id: string | null) => { - trackEvent({ - action: "tappedSubmitAnotherWork", - context_module: ContextModule.sell, - context_owner_type: getOwnerType("CompleteYourSubmission"), - submission_id, - }) - } - - const trackTappedViewArtworkInMyCollection = (submission_id: string | null) => { - trackEvent({ - action: "tappedViewArtworkInMyCollection", - context_module: ContextModule.sell, - context_owner_type: getOwnerType("CompleteYourSubmission"), - submission_id, - }) - } - - const trackTappedContactAdvisor = (userId: string | undefined, userEmail: string | undefined) => { - trackEvent({ - action: ActionType.tappedConsignmentInquiry, - context_module: ContextModule.sell, - context_owner_type: getOwnerType("ArtistRejected"), - label: "contact an advisor", - user_id: userId, - user_email: userEmail, - }) - } - - const trackTappedEditSubmission = ( - submission_id: string, - buttonLabel: string | null | undefined, - submission_state: string - ) => { - trackEvent({ - action: "tappedEditSubmission", - context_module: ContextModule.sell, - context_owner_type: OwnerType.myCollectionArtwork, - submission_id, - submission_state, - subject: buttonLabel, - }) - } - - const trackSubmissionStepScreen = ( - currentStep: SubmitArtworkScreen, - submission_id: string | undefined - ) => { - trackEvent({ - action: "screen", - context_screen_owner_type: getOwnerType(currentStep), - context_screen_owner_id: submission_id, - }) - } - - return { - trackTappedContinueSubmission, - trackTappedNewSubmission, - trackTappedStartMyCollection, - trackTappedSubmissionSaveExit, - trackTappedSubmissionBack, - trackConsignmentSubmitted, - trackTappedSubmitAnotherWork, - trackTappedViewArtworkInMyCollection, - trackTappedContactAdvisor, - trackTappedEditSubmission, - trackSubmissionStepScreen, - } -} - -const getOwnerType = (currentStep: SubmitArtworkScreen): OwnerType => { - switch (currentStep) { - case "StartFlow": - return OwnerType.submitArtworkStepStart - case "SelectArtist": - return OwnerType.submitArtworkStepSelectArtist - case "AddTitle": - return OwnerType.submitArtworkStepAddTitle - case "AddPhotos": - return OwnerType.submitArtworkStepAddPhotos - case "AddDetails": - return OwnerType.submitArtworkStepAddDetails - case "PurchaseHistory": - return OwnerType.submitArtworkStepPurchaseHistory - case "AddDimensions": - return OwnerType.submitArtworkStepAddDimensions - case "AddPhoneNumber": - return OwnerType.submitArtworkStepAddPhoneNumber - case "CompleteYourSubmission": - return OwnerType.submitArtworkStepCompleteYourSubmission - case "CompleteYourSubmissionPostApproval": - return OwnerType.submitArtworkStepCompleteYourSubmissionPostApproval - case "ArtistRejected": - return OwnerType.submitArtworkStepArtistRejected - case "ShippingLocation": - return OwnerType.submitArtworkStepShippingLocation - case "FrameInformation": - return OwnerType.submitArtworkStepFrameInformation - case "AdditionalDocuments": - return OwnerType.submitArtworkStepAddtionalDocuments - case "Condition": - return OwnerType.submitArtworkStepCondition - case "SubmitArtworkFromMyCollection": - return OwnerType.submitArtworkStepSelectArtworkMyCollectionArtwork - } -} diff --git a/src/app/Scenes/SellWithArtsy/SellWithArtsyHome.tests.tsx b/src/app/Scenes/SellWithArtsy/SellWithArtsyHome.tests.tsx deleted file mode 100644 index 721d42abbe5..00000000000 --- a/src/app/Scenes/SellWithArtsy/SellWithArtsyHome.tests.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import { fireEvent, screen } from "@testing-library/react-native" -import { SellWithArtsyHomeTestQuery } from "__generated__/SellWithArtsyHomeTestQuery.graphql" -import { mockTrackEvent } from "app/utils/tests/globallyMockedStuff" -import { setupTestWrapper } from "app/utils/tests/setupTestWrapper" -import { graphql } from "react-relay" -import { SellWithArtsyHome } from "./SellWithArtsyHome" - -jest.mock("../../utils/useStatusBarStyle", () => { - return { - useLightStatusBarStyle: jest.fn(), - useSwitchStatusBarStyle: jest.fn(), - } -}) - -describe("SellWithArtsyHome", () => { - const { renderWithRelay } = setupTestWrapper({ - Component: (props) => { - if (props?.me) { - return - } - - return null - }, - variables: { submissionID: "1234", includeSubmission: false }, - query: graphql` - query SellWithArtsyHomeTestQuery($submissionID: ID, $includeSubmission: Boolean = false) - @relay_test_operation { - recentlySoldArtworks { - ...SellWithArtsyRecentlySold_recentlySoldArtworkTypeConnection - } - me { - internalID - name - email - phone - } - submission(id: $submissionID) @include(if: $includeSubmission) { - ...Header_submission - } - staticContent { - ...MeetTheSpecialists_staticContent - } - } - `, - }) - - describe("Tracking", () => { - // HEADER - describe("Header Events", () => { - it("tracks Consign Events", async () => { - renderWithRelay({}) - const headerConsignButton = screen.getByTestId("header-consign-CTA") - - fireEvent(headerConsignButton, "onPress") - expect(mockTrackEvent).toHaveBeenCalledTimes(1) - expect(mockTrackEvent).toHaveBeenLastCalledWith( - expect.objectContaining({ - action: "tappedConsign", - context_module: "sellHeader", - context_screen_owner_type: "sell", - destination_screen_owner_type: "consignmentSubmission", - subject: "Start Selling", - }) - ) - }) - - it("tracks Inquiry Events", () => { - renderWithRelay({ - StaticContent: () => ({ - specialistBios: [ - { - specialty: "collectorServices", - name: "Dana Rodriguez", - firstName: "Dana", - jobTitle: "Associate, Collector Services", - bio: "20-year veteran as the VP of Artsy's commercial and benefit auctions businesses.", - image: "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2", - email: "dana.rodriguez@artsy.net", - }, - ], - }), - }) - const headerInquiryButton = screen.getByTestId("MeetTheSpecialists-contact-CTA") - - fireEvent(headerInquiryButton, "onPress") - expect(mockTrackEvent).toHaveBeenCalledTimes(1) - expect(mockTrackEvent).toHaveBeenLastCalledWith( - expect.objectContaining({ - action: "tappedConsignmentInquiry", - context_module: "sellMeetTheSpecialists", - context_screen: "sell", - context_screen_owner_type: "sell", - subject: "Contact Dana", - }) - ) - }) - }) - - // MEETTHESPECIALISTS - describe("MeetTheSpecialists Events", () => { - it("tracks Inquiry Events", () => { - renderWithRelay({}) - const headerConsignButton = screen.getByTestId("MeetTheSpecialists-inquiry-CTA") - - fireEvent(headerConsignButton, "onPress") - expect(mockTrackEvent).toHaveBeenCalledTimes(1) - expect(mockTrackEvent).toHaveBeenLastCalledWith( - expect.objectContaining({ - action: "tappedConsignmentInquiry", - context_module: "sellMeetTheSpecialists", - context_screen: "sell", - context_screen_owner_type: "sell", - subject: "Get in Touch", - }) - ) - }) - }) - - // SPEAKTOTHETEAM - describe("SpeakToTheTeam Events", () => { - it("tracks Inquiry Events", () => { - renderWithRelay({}) - const headerConsignButton = screen.getByTestId("SpeakToTheTeam-inquiry-CTA") - - fireEvent(headerConsignButton, "onPress") - expect(mockTrackEvent).toHaveBeenCalledTimes(1) - expect(mockTrackEvent).toHaveBeenLastCalledWith( - expect.objectContaining({ - action: "tappedConsignmentInquiry", - context_module: "sellSpeakToTheTeam", - context_screen: "sell", - context_screen_owner_type: "sell", - subject: "Get in Touch", - }) - ) - }) - }) - }) -}) diff --git a/src/app/Scenes/SellWithArtsy/SellWithArtsyHome.tsx b/src/app/Scenes/SellWithArtsy/SellWithArtsyHome.tsx deleted file mode 100644 index cbe51460c19..00000000000 --- a/src/app/Scenes/SellWithArtsy/SellWithArtsyHome.tsx +++ /dev/null @@ -1,207 +0,0 @@ -import { tappedConsign, TappedConsignArgs, TappedConsignmentInquiry } from "@artsy/cohesion" -import { Flex, Screen, Skeleton, SkeletonBox, SkeletonText, Spacer } from "@artsy/palette-mobile" -import * as Sentry from "@sentry/react-native" -import { SellWithArtsyHomeQuery } from "__generated__/SellWithArtsyHomeQuery.graphql" -import { CollectorsNetwork } from "app/Scenes/SellWithArtsy/Components/CollectorsNetwork" -import { FAQSWA } from "app/Scenes/SellWithArtsy/Components/FAQSWA" -import { Highlights } from "app/Scenes/SellWithArtsy/Components/Highlights" -import { MeetTheSpecialists } from "app/Scenes/SellWithArtsy/Components/MeetTheSpecialists" -import { SpeakToTheTeam } from "app/Scenes/SellWithArtsy/Components/SpeakToTheTeam" -import { StickySWAHeader } from "app/Scenes/SellWithArtsy/Components/StickySWAHeader" -import { WaysWeSell } from "app/Scenes/SellWithArtsy/Components/WaysWeSell" -import { GlobalStore } from "app/store/GlobalStore" -import { navigate } from "app/system/navigation/navigate" -import { useBottomTabsScrollToTop } from "app/utils/bottomTabsHelper" -import { RefreshEvents, SELL_SCREEN_REFRESH_KEY } from "app/utils/refreshHelpers" -import { useSwitchStatusBarStyle } from "app/utils/useStatusBarStyle" -import { compact } from "lodash" -import { RefObject, Suspense, useEffect, useReducer } from "react" -import { StatusBarStyle } from "react-native" -import { FlatList } from "react-native-gesture-handler" -import { graphql, useLazyLoadQuery } from "react-relay" -import { useTracking } from "react-tracking" -import { Footer } from "./Components/Footer" -import { Header } from "./Components/Header" -import { HowItWorks } from "./Components/HowItWorks" -import { SellWithArtsyRecentlySold } from "./Components/SellWithArtsyRecentlySold" - -export const SellWithArtsyHome: React.FC = () => { - const { draft } = GlobalStore.useAppState((state) => state.artworkSubmission) - - const id = draft?.submissionID - - const [fetchKey, increaseFetchKey] = useReducer((state) => state + 1, 0) - - useEffect(() => { - RefreshEvents.addListener(SELL_SCREEN_REFRESH_KEY, handleRefreshEvent) - return () => { - RefreshEvents.removeListener(SELL_SCREEN_REFRESH_KEY, handleRefreshEvent) - } - }, []) - - const handleRefreshEvent = () => { - increaseFetchKey() - } - - const { recentlySoldArtworks, me, submission, staticContent } = - useLazyLoadQuery( - SellWithArtsyHomeScreenQuery, - { submissionID: id, includeSubmission: !!id }, - { - fetchPolicy: "store-and-network", - fetchKey: fetchKey ?? 0, - } - ) - - const onFocusStatusBarStyle: StatusBarStyle = "dark-content" - const onBlurStatusBarStyle: StatusBarStyle = "dark-content" - - const scrollViewRef = useBottomTabsScrollToTop() - - useSwitchStatusBarStyle(onFocusStatusBarStyle, onBlurStatusBarStyle) - - const tracking = useTracking() - - const handleConsignPress = (tappedConsignArgs: TappedConsignArgs) => { - tracking.trackEvent(tappedConsign(tappedConsignArgs)) - - navigate("/sell/submissions/new") - return - } - - const handleInquiryPress = ( - inquiryTrackingArgs?: TappedConsignmentInquiry, - recipientEmail?: string, - recipientName?: string - ) => { - if (inquiryTrackingArgs) { - tracking.trackEvent(inquiryTrackingArgs) - } - navigate("/sell/inquiry", { - passProps: { - email: me?.email ?? "", - name: me?.name ?? "", - phone: me?.phone ?? "", - userId: me?.internalID ?? undefined, - recipientEmail: recipientEmail ?? null, - recipientName: recipientName ?? null, - }, - }) - } - - const data = compact([ - { - key: "header", - content:
, - }, - { - key: "highlights", - content: , - }, - { - key: "ways-we-sell", - content: , - }, - { - key: "how-it-works", - content: , - }, - { - key: "faq-swa", - content: , - }, - staticContent && { - key: "meet-the-specialists", - content: ( - - ), - }, - { - key: "collectors-network", - content: , - }, - !!recentlySoldArtworks && { - key: "recently-sold-artworks", - content: , - }, - { - key: "speak-to-the-team", - content: , - }, - { - key: "footer", - content: