Skip to content

Commit add042e

Browse files
Create a standalone page that can be used for bundles (#7861)
1 parent e174136 commit add042e

File tree

16 files changed

+266
-47
lines changed

16 files changed

+266
-47
lines changed

newIDE/app/src/AssetStore/Bundles/BundleInformationPage.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,11 @@ type Props = {|
8585
) => void,
8686
onCourseOpen: CourseListingData => void,
8787
courses: ?Array<Course>,
88-
receivedCourses: ?Array<Course>,
8988
getCourseCompletion: (courseId: string) => CourseCompletion | null,
9089
noPadding?: boolean,
90+
noActions?: boolean,
91+
simpleCheckout?: boolean,
92+
onPurchaseDone?: () => void,
9193
|};
9294

9395
const BundleInformationPage = ({
@@ -99,9 +101,11 @@ const BundleInformationPage = ({
99101
onBundleOpen,
100102
onCourseOpen,
101103
courses,
102-
receivedCourses,
103104
getCourseCompletion,
104105
noPadding,
106+
noActions,
107+
simpleCheckout,
108+
onPurchaseDone,
105109
}: Props) => {
106110
const { windowSize, isLandscape, isMobile } = useResponsiveWindowSize();
107111
const { bundleListingDatas } = React.useContext(BundleStoreContext); // If archived, should use the one passed.
@@ -175,6 +179,7 @@ const BundleInformationPage = ({
175179
onBundleOpen,
176180
onCourseOpen,
177181
discountedPrice: true,
182+
disabled: noActions,
178183
})
179184
: null,
180185
[
@@ -190,6 +195,7 @@ const BundleInformationPage = ({
190195
onGameTemplateOpen,
191196
onBundleOpen,
192197
onCourseOpen,
198+
noActions,
193199
]
194200
);
195201

@@ -311,6 +317,8 @@ const BundleInformationPage = ({
311317
bundleListingData={bundleListingData}
312318
bundle={bundle}
313319
i18n={i18n}
320+
simpleCheckout={simpleCheckout}
321+
onPurchaseDone={onPurchaseDone}
314322
/>
315323
<Line noMargin>
316324
<Text size="section-title">
@@ -339,6 +347,7 @@ const BundleInformationPage = ({
339347
onCourseOpen(courseListingData);
340348
}}
341349
discountedPrice
350+
disabled={noActions}
342351
/>
343352
</GridListTile>
344353
);

newIDE/app/src/AssetStore/Bundles/BundlePageHeader.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,17 @@ type Props = {|
6868
bundle: Bundle,
6969
simulateAppStoreProduct?: boolean,
7070
i18n: I18nType,
71+
simpleCheckout?: boolean,
72+
onPurchaseDone?: () => void,
7173
|};
7274

7375
const BundlePageHeader = ({
7476
bundle,
7577
bundleListingData,
7678
simulateAppStoreProduct,
7779
i18n,
80+
simpleCheckout,
81+
onPurchaseDone,
7882
}: Props) => {
7983
const { privateGameTemplateListingDatas } = React.useContext(
8084
PrivateGameTemplateStoreContext
@@ -467,6 +471,7 @@ const BundlePageHeader = ({
467471
isAlreadyReceived={isAlreadyReceived}
468472
onClickBuy={onClickBuy}
469473
onClickBuyWithCredits={() => {}}
474+
fullWidth
470475
customLabel={
471476
<Trans>
472477
Buy now and save{' '}
@@ -502,6 +507,8 @@ const BundlePageHeader = ({
502507
bundleListingData={purchasingBundleListingData}
503508
usageType="default"
504509
onClose={() => setPurchasingBundleListingData(null)}
510+
simpleCheckout={simpleCheckout}
511+
onPurchaseDone={onPurchaseDone}
505512
/>
506513
)}
507514
{isRedemptionCodesDialogOpen && (

newIDE/app/src/AssetStore/Bundles/BundlePurchaseDialog.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// @flow
22
import * as React from 'react';
33
import { t, Trans } from '@lingui/macro';
4-
import { type BundleListingData } from '../../Utils/GDevelopServices/Shop';
4+
import {
5+
getStripeCheckoutUrl,
6+
type BundleListingData,
7+
} from '../../Utils/GDevelopServices/Shop';
58
import Dialog, { DialogPrimaryButton } from '../../UI/Dialog';
69
import AuthenticatedUserContext from '../../Profile/AuthenticatedUserContext';
710
import CreateProfile from '../../Profile/CreateProfile';
@@ -28,13 +31,17 @@ type Props = {|
2831
usageType: string,
2932
onClose: () => void,
3033
simulateAppStoreProduct?: boolean,
34+
simpleCheckout?: boolean,
35+
onPurchaseDone?: () => void,
3136
|};
3237

3338
const BundlePurchaseDialog = ({
3439
bundleListingData,
3540
usageType,
3641
onClose,
3742
simulateAppStoreProduct,
43+
simpleCheckout,
44+
onPurchaseDone,
3845
}: Props) => {
3946
const {
4047
profile,
@@ -91,13 +98,21 @@ const BundlePurchaseDialog = ({
9198
// Purchase with web.
9299
try {
93100
setIsPurchasing(true);
94-
const checkoutUrl = getPurchaseCheckoutUrl({
95-
productId: bundleListingData.id,
96-
priceName: price.name,
97-
userId: profile.id,
98-
userEmail: profile.email,
99-
...(password ? { password } : undefined),
100-
});
101+
const checkoutUrl = simpleCheckout
102+
? getStripeCheckoutUrl({
103+
productId: bundleListingData.id,
104+
priceName: price.name,
105+
userId: profile.id,
106+
userEmail: profile.email,
107+
...(password ? { password } : undefined),
108+
})
109+
: getPurchaseCheckoutUrl({
110+
productId: bundleListingData.id,
111+
priceName: price.name,
112+
userId: profile.id,
113+
userEmail: profile.email,
114+
...(password ? { password } : undefined),
115+
});
101116
Window.openExternalURL(checkoutUrl);
102117
} catch (error) {
103118
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
@@ -155,6 +170,7 @@ const BundlePurchaseDialog = ({
155170
// We found the purchase, the user has bought the bundle.
156171
// We do not close the dialog yet, as we need to trigger a refresh of the products received.
157172
await onPurchaseSuccessful();
173+
if (onPurchaseDone) onPurchaseDone();
158174
}
159175
};
160176
checkIfPurchaseIsDone();
@@ -164,6 +180,7 @@ const BundlePurchaseDialog = ({
164180
bundlePurchases,
165181
bundleListingData,
166182
onPurchaseSuccessful,
183+
onPurchaseDone,
167184
onRefreshBundlePurchases,
168185
]
169186
);

newIDE/app/src/AssetStore/ProductPageHelper.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ export const getProductsIncludedInBundleTiles = ({
356356
onBundleOpen,
357357
onCourseOpen,
358358
discountedPrice,
359+
disabled,
359360
}: {|
360361
product: ?PrivateAssetPack | PrivateGameTemplate | Bundle | Course,
361362
productListingDatas: ?Array<
@@ -381,6 +382,7 @@ export const getProductsIncludedInBundleTiles = ({
381382
onBundleOpen?: (bundleListingData: BundleListingData) => void,
382383
onCourseOpen?: (courseListingData: CourseListingData) => void,
383384
discountedPrice?: boolean,
385+
disabled?: boolean,
384386
|}): ?Array<React.Node> => {
385387
if (!product || !productListingDatas) return null;
386388

@@ -417,6 +419,7 @@ export const getProductsIncludedInBundleTiles = ({
417419
}
418420
owned={isProductOwned}
419421
discountedPrice={discountedPrice}
422+
disabled={disabled}
420423
/>
421424
);
422425
}
@@ -435,6 +438,7 @@ export const getProductsIncludedInBundleTiles = ({
435438
onSelect={() => onPrivateAssetPackOpen(includedProductListingData)}
436439
owned={isProductOwned}
437440
discountedPrice={discountedPrice}
441+
disabled={disabled}
438442
/>
439443
);
440444
}
@@ -453,6 +457,7 @@ export const getProductsIncludedInBundleTiles = ({
453457
onSelect={() => onBundleOpen(includedProductListingData)}
454458
owned={isProductOwned}
455459
discountedPrice={discountedPrice}
460+
disabled={disabled}
456461
/>
457462
);
458463
}
@@ -471,6 +476,7 @@ export const getProductsIncludedInBundleTiles = ({
471476
onSelect={() => onCourseOpen(includedProductListingData)}
472477
owned={isProductOwned}
473478
discountedPrice={discountedPrice}
479+
disabled={disabled}
474480
/>
475481
);
476482
}
@@ -577,6 +583,7 @@ export const PurchaseProductButtons = <
577583
onClickBuy,
578584
onClickBuyWithCredits,
579585
customLabel,
586+
fullWidth,
580587
}: {|
581588
productListingData: T,
582589
selectedUsageType: string,
@@ -587,6 +594,7 @@ export const PurchaseProductButtons = <
587594
onClickBuy: () => void | Promise<void>,
588595
onClickBuyWithCredits?: () => void | Promise<void>,
589596
customLabel?: React.Node,
597+
fullWidth?: boolean,
590598
|}) => {
591599
const { authenticated } = React.useContext(AuthenticatedUserContext);
592600
const shouldUseOrSimulateAppStoreProduct =
@@ -643,6 +651,15 @@ export const PurchaseProductButtons = <
643651
</Text>
644652
)}
645653
</LineStackLayout>
654+
) : fullWidth && !creditPrice ? (
655+
<RaisedButton
656+
primary
657+
label={customLabel || <Trans>Buy for {formattedProductPriceText}</Trans>}
658+
onClick={onClickBuy}
659+
id={`buy-${productType}`}
660+
size="medium"
661+
fullWidth={fullWidth}
662+
/>
646663
) : (
647664
<LineStackLayout noMargin>
648665
{creditPrice && (

newIDE/app/src/AssetStore/index.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ type Props = {|
8080
) => void,
8181
onOpenProfile?: () => void,
8282
courses?: ?Array<Course>,
83-
receivedCourses?: ?Array<Course>,
8483
onCourseOpen?: (courseId: string) => void,
8584
getSubscriptionPlansWithPricingSystems?: () => Array<SubscriptionPlanWithPricingSystems> | null,
8685
getCourseCompletion?: (courseId: string) => CourseCompletion | null,
@@ -125,7 +124,6 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
125124
onOpenPrivateGameTemplateListingData,
126125
onOpenProfile,
127126
courses,
128-
receivedCourses,
129127
onCourseOpen,
130128
getSubscriptionPlansWithPricingSystems,
131129
getCourseCompletion,
@@ -975,7 +973,6 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
975973
getSubscriptionPlansWithPricingSystems
976974
}
977975
courses={courses}
978-
receivedCourses={receivedCourses}
979976
getCourseCompletion={getCourseCompletion}
980977
/>
981978
) : null}

newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/CourseCard.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ type Props = {|
132132
courseListingData: ?CourseListingData,
133133
onClick?: () => void,
134134
discountedPrice?: boolean,
135+
disabled?: boolean,
135136
|};
136137

137138
const CourseCard = ({
@@ -140,6 +141,7 @@ const CourseCard = ({
140141
courseListingData,
141142
onClick,
142143
discountedPrice,
144+
disabled,
143145
}: Props) => {
144146
const gdevelopTheme = React.useContext(GDevelopThemeContext);
145147
const specializationConfig = getSpecializationConfig(
@@ -148,8 +150,8 @@ const CourseCard = ({
148150
return (
149151
<I18n>
150152
{({ i18n }) => (
151-
<CardWidget onClick={onClick} size={'large'}>
152-
{course && courseListingData && onClick ? (
153+
<CardWidget onClick={disabled ? undefined : onClick} size={'large'}>
154+
{course && courseListingData ? (
153155
<Column expand noMargin noOverflowParent>
154156
<div style={styles.imageContainer}>
155157
<img

newIDE/app/src/MainFrame/EditorContainers/HomePage/LearnSection/index.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ type Props = {|
8484
) => void,
8585
onSelectExampleShortHeader: (exampleShortHeader: ExampleShortHeader) => void,
8686
getSubscriptionPlansWithPricingSystems: () => Array<SubscriptionPlanWithPricingSystems> | null,
87-
receivedCourses: ?Array<Course>,
8887
initialBundleUserFriendlySlug: ?string,
8988
initialBundleCategory: ?string,
9089
clearInitialBundleValues: () => void,
@@ -114,7 +113,6 @@ const LearnSection = ({
114113
onSelectPrivateGameTemplateListingData,
115114
onSelectExampleShortHeader,
116115
getSubscriptionPlansWithPricingSystems,
117-
receivedCourses,
118116
initialBundleUserFriendlySlug,
119117
initialBundleCategory,
120118
clearInitialBundleValues,
@@ -296,7 +294,6 @@ const LearnSection = ({
296294
onBundleOpen={onOpenBundle}
297295
onCourseOpen={onOpenCourse}
298296
courses={courses}
299-
receivedCourses={receivedCourses}
300297
getCourseCompletion={getCourseCompletion}
301298
/>
302299
);

newIDE/app/src/MainFrame/EditorContainers/HomePage/StoreSection/index.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ type Props = {|
2727
onExtensionInstalled: (extensionNames: Array<string>) => void,
2828
getSubscriptionPlansWithPricingSystems: () => Array<SubscriptionPlanWithPricingSystems> | null,
2929
onCourseOpen: (courseId: string) => void,
30-
receivedCourses?: ?Array<Course>,
3130
courses?: ?Array<Course>,
3231
getCourseCompletion: (courseId: string) => CourseCompletion | null,
3332
|};
@@ -40,7 +39,6 @@ const StoreSection = ({
4039
onExtensionInstalled,
4140
onCourseOpen,
4241
courses,
43-
receivedCourses,
4442
getSubscriptionPlansWithPricingSystems,
4543
getCourseCompletion,
4644
}: Props) => {
@@ -98,7 +96,6 @@ const StoreSection = ({
9896
displayPromotions
9997
onOpenProfile={onOpenProfile}
10098
courses={courses}
101-
receivedCourses={receivedCourses}
10299
onCourseOpen={onCourseOpen}
103100
getSubscriptionPlansWithPricingSystems={
104101
getSubscriptionPlansWithPricingSystems

0 commit comments

Comments
 (0)