@selfcommunity/react-ui 0.10.5-payments.178 → 0.10.5-payments.180

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,7 +41,7 @@ function Checkout(inProps) {
41
41
  props: inProps,
42
42
  name: constants_1.PREFIX
43
43
  });
44
- const { className, contentType, contentId, content, priceId, returnUrl, successUrl, uiMode, onComplete } = props, rest = tslib_1.__rest(props, ["className", "contentType", "contentId", "content", "priceId", "returnUrl", "successUrl", "uiMode", "onComplete"]);
44
+ const { className, clientSecret, contentType, contentId, content, priceId, returnUrl, successUrl, uiMode, onComplete } = props, rest = tslib_1.__rest(props, ["className", "clientSecret", "contentType", "contentId", "content", "priceId", "returnUrl", "successUrl", "uiMode", "onComplete"]);
45
45
  const [loading, setLoading] = (0, react_1.useState)(false);
46
46
  const [initialized, setInitialized] = (0, react_1.useState)(false);
47
47
  // CONTEXT
@@ -53,7 +53,7 @@ function Checkout(inProps) {
53
53
  ? (0, stripe_js_1.loadStripe)(stripePublicKey, { stripeAccount: stripeConnectedAccountId, locale: (0, payment_1.getDefaultLocale)(intl).locale })
54
54
  : null;
55
55
  // STATE
56
- const [clientSecret, setClientSecret] = (0, react_1.useState)(props.clientSecret);
56
+ const [clientSecretKey, setClientSecretKey] = (0, react_1.useState)(clientSecret);
57
57
  const isContentObject = (0, react_1.useMemo)(() => contentType && contentId !== undefined, [contentType, contentId]);
58
58
  const fetchClientSecret = (0, react_1.useCallback)(() => {
59
59
  // Create a Checkout Session
@@ -62,7 +62,7 @@ function Checkout(inProps) {
62
62
  setLoading(true);
63
63
  api_services_1.PaymentApiClient.checkoutCreateSession(Object.assign(Object.assign(Object.assign({ content_type: contentType, content_id: content ? content.id : contentId, payment_price_id: priceId }, (returnUrl && { return_url: returnUrl })), (successUrl && { success_url: successUrl })), (uiMode && { ui_mode: uiMode })))
64
64
  .then((r) => {
65
- setClientSecret(r.client_secret);
65
+ setClientSecretKey(r.client_secret);
66
66
  setLoading(false);
67
67
  })
68
68
  .catch((error) => {
@@ -73,22 +73,22 @@ function Checkout(inProps) {
73
73
  // EFFECTS
74
74
  (0, react_1.useEffect)(() => {
75
75
  let _t;
76
- if (scUserContext.user && contentType && (contentId || content) && priceId && !clientSecret && Boolean(stripePromise) && !initialized) {
76
+ if (scUserContext.user && contentType && (contentId || content) && priceId && !clientSecretKey && Boolean(stripePromise) && !initialized) {
77
77
  _t = setTimeout(fetchClientSecret);
78
78
  return () => {
79
79
  _t && clearTimeout(_t);
80
80
  };
81
81
  }
82
- }, [scUserContext.user, clientSecret, stripePromise, contentType, contentId, content, priceId, loading, initialized]);
82
+ }, [scUserContext.user, clientSecretKey, stripePromise, contentType, contentId, content, priceId, loading, initialized]);
83
83
  // Payment provider options
84
- const providerOptions = (0, react_1.useMemo)(() => (Object.assign({ clientSecret }, (onComplete && { onComplete })
84
+ const providerOptions = (0, react_1.useMemo)(() => (Object.assign({ clientSecret: clientSecretKey }, (onComplete && { onComplete })
85
85
  // ...(onShippingDetailsChange && {onShippingDetailsChange})
86
- )), [clientSecret, onComplete]);
86
+ )), [clientSecretKey, onComplete]);
87
87
  if (!isPaymentsEnabled) {
88
88
  return null;
89
89
  }
90
90
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
91
- if (!stripePromise || !clientSecret || !scUserContext.user) {
91
+ if (!stripePromise || !clientSecretKey || !scUserContext.user) {
92
92
  return (0, jsx_runtime_1.jsx)(Skeleton_1.default, {});
93
93
  }
94
94
  const renderContentObject = () => {
@@ -64,6 +64,6 @@ function CommunityPaywalls(inProps) {
64
64
  if (loading) {
65
65
  return (0, jsx_runtime_1.jsx)(Skeleton_1.default, {});
66
66
  }
67
- return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className), container: true, spacing: 4 }, rest, { children: scCommunity.paywalls.map((p, i) => ((0, jsx_runtime_1.jsx)(Unstable_Grid2_1.default, Object.assign({ xs: 12, sm: 6, md: 4 }, { children: (0, jsx_runtime_1.jsx)(PaymentProduct_1.default, Object.assign({ expanded: true, paymentProduct: p, contentType: types_1.SCContentType.COMMUNITY, contentId: scCommunity.id }, (scCommunity.payment_order && { paymentOrder: scCommunity.payment_order, onUpdatePaymentOrder }), (scCommunity.payment_order && { paymentOrder: scCommunity.payment_order, onUpdatePaymentOrder }), (callbackUrl && { PaymentProductPriceComponentProps: { returnUrlParams: { callbackUrl } } }))) }), i))) })));
67
+ return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className), container: true, spacing: 4 }, rest, { children: scCommunity.paywalls.map((p, i) => ((0, jsx_runtime_1.jsx)(Unstable_Grid2_1.default, Object.assign({ xs: 12, sm: 12, md: 4 }, { children: (0, jsx_runtime_1.jsx)(PaymentProduct_1.default, Object.assign({ expanded: true, paymentProduct: p, contentType: types_1.SCContentType.COMMUNITY, contentId: scCommunity.id }, (scCommunity.payment_order && { paymentOrder: scCommunity.payment_order, onUpdatePaymentOrder }), (scCommunity.payment_order && { paymentOrder: scCommunity.payment_order, onUpdatePaymentOrder }), (callbackUrl && { PaymentProductPriceComponentProps: { returnUrlParams: { callbackUrl } } }))) }), i))) })));
68
68
  }
69
69
  exports.default = CommunityPaywalls;
@@ -19,6 +19,7 @@ const Errors_1 = require("../../constants/Errors");
19
19
  const notistack_1 = require("notistack");
20
20
  const Skeleton_1 = tslib_1.__importDefault(require("./Student/Skeleton"));
21
21
  const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
22
+ const BuyButton_1 = tslib_1.__importDefault(require("../BuyButton"));
22
23
  const BUTTON_MESSAGES = {
23
24
  dashboard: 'ui.course.dashboard.student.button.dashboard',
24
25
  request: 'ui.course.dashboard.student.button.request',
@@ -167,7 +168,7 @@ function Student(inProps) {
167
168
  }, [scContext.settings.handleAnonymousAction]);
168
169
  // MEMOS
169
170
  const actionButton = (0, react_1.useMemo)(() => {
170
- var _a, _b;
171
+ var _a, _b, _c;
171
172
  if (!scCourse) {
172
173
  return (0, jsx_runtime_1.jsx)(material_1.Skeleton, { animation: "wave", variant: "rectangular", width: "130px", height: "20px" });
173
174
  }
@@ -180,7 +181,7 @@ function Student(inProps) {
180
181
  ? BUTTON_MESSAGES.start
181
182
  : scCourse.user_completion_rate === 100
182
183
  ? BUTTON_MESSAGES.review
183
- : BUTTON_MESSAGES.continue, to: scCourse.join_status !== null ? scRoutingContext.url(react_core_1.SCRoutes.COURSE_LESSON_ROUTE_NAME, getUrlNextLesson(scCourse)) : undefined, disabled: scCourse.join_status !== null ? getIsNextLessonLocked(scCourse) : undefined, color: scCourse.user_completion_rate === 100 ? 'inherit' : undefined, variant: scCourse.user_completion_rate === 100 ? 'outlined' : undefined, loading: scCourse.join_status === null ? loadingRequest : undefined, onClick: !scUserContext.user ? handleAnonymousAction : scCourse.join_status === null ? handleRequest : undefined })), scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
184
+ : BUTTON_MESSAGES.continue, to: scCourse.join_status !== null ? scRoutingContext.url(react_core_1.SCRoutes.COURSE_LESSON_ROUTE_NAME, getUrlNextLesson(scCourse)) : undefined, disabled: scCourse.join_status !== null ? getIsNextLessonLocked(scCourse) : undefined, color: scCourse.user_completion_rate === 100 ? 'inherit' : undefined, variant: scCourse.user_completion_rate === 100 ? 'outlined' : undefined, loading: scCourse.join_status === null ? loadingRequest : undefined, onClick: !scUserContext.user ? handleAnonymousAction : scCourse.join_status === null ? handleRequest : undefined })), isPaymentsEnabled && ((_c = scCourse.paywalls) === null || _c === void 0 ? void 0 : _c.length) > 0 && !scCourse.join_status && ((0, jsx_runtime_1.jsx)(BuyButton_1.default, { contentType: types_1.SCContentType.COURSE, content: scCourse })), scCourse.privacy === types_1.SCCoursePrivacyType.PRIVATE &&
184
185
  (scCourse.join_status === null || scCourse.join_status === types_1.SCCourseJoinStatusType.REQUESTED) && ((0, jsx_runtime_1.jsx)(ActionButton_1.default, { labelId: sentRequest ? BUTTON_MESSAGES.cancel : BUTTON_MESSAGES.request, color: "inherit", variant: "outlined", loading: loadingRequest, onClick: handleRequest }))] })));
185
186
  }, [scCourse, sentRequest, loadingRequest, handleRequest]);
186
187
  if (!scCourse) {
@@ -111,7 +111,6 @@ function EventHeader(inProps) {
111
111
  const _backgroundCover = Object.assign({}, (scEvent.image_bigger
112
112
  ? { background: `url('${scEvent.image_bigger}') center / cover` }
113
113
  : { background: `url('${preferences.preferences[react_core_1.SCPreferences.IMAGES_USER_DEFAULT_COVER].value}') center / cover` }));
114
- console.log('*** event *** ', scEvent);
115
114
  return (
116
115
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
117
116
  // @ts-ignore
@@ -147,6 +146,10 @@ function EventHeader(inProps) {
147
146
  month: 'long'
148
147
  }),
149
148
  hour: intl.formatDate(scEvent.start_date, { hour: 'numeric', minute: 'numeric' })
150
- } })) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5", className: classes.name }, { children: scEvent.name })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.visibility }, { children: [(0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: scEvent.privacy === types_1.SCEventPrivacyType.PUBLIC ? ((0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: classes.visibilityItem }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "public" }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventHeader.visibility.public", defaultMessage: "ui.eventHeader.visibility.public" })] }))) : ((0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: classes.visibilityItem }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "private" }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventHeader.visibility.private", defaultMessage: "ui.eventHeader.visibility.private" })] }))) }), (0, jsx_runtime_1.jsx)(Bullet_1.default, {}), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.visibilityItem }, { children: scEvent.location === types_1.SCEventLocationType.PERSON ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventHeader.location.live", defaultMessage: "ui.eventHeader.location.live" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventHeader.location.online", defaultMessage: "ui.eventHeader.location.online" })) }))] })), (0, jsx_runtime_1.jsx)(User_1.default, { className: classes.planner, userId: scEvent.managed_by.id, secondary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventHeader.user.manager", defaultMessage: "ui.eventHeader.user.manager" }), elevation: 0, actions: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: isEventAdmin ? ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.multiActions }, { children: [(0, jsx_runtime_1.jsx)(EventInviteButton_1.default, { size: isMobile ? 'small' : 'medium', event: scEvent, disabled: isEventFinished }), (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [!isMobile && ((0, jsx_runtime_1.jsx)(EditEventButton_1.default, { size: isMobile ? 'small' : 'medium', event: scEvent, onEditSuccess: setSCEvent, disabled: isEventFinished })), (0, jsx_runtime_1.jsx)(EventActionsMenu_1.default, Object.assign({ event: scEvent, onEditSuccess: (data) => setSCEvent(data) }, EventActionsProps))] })] }))) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isPaymentsEnabled && ((_a = scEvent.paywalls) === null || _a === void 0 ? void 0 : _a.length) > 0 && scEvent.subscription_status !== types_1.SCEventSubscriptionStatusType.REQUESTED ? ((0, jsx_runtime_1.jsx)(BuyButton_1.default, { contentType: types_1.SCContentType.EVENT, content: scEvent })) : ((0, jsx_runtime_1.jsx)(EventSubscribeButton_1.default, Object.assign({ event: scEvent, onSubscribe: handleSubscribe }, EventSubscribeButtonProps, { disabled: isEventFinished }))), (0, jsx_runtime_1.jsx)(EventActionsMenu_1.default, Object.assign({ event: scEvent, onEditSuccess: setSCEvent }, EventActionsProps))] })) }) })] }))] })));
149
+ } })) })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5", className: classes.name }, { children: scEvent.name })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.visibility }, { children: [(0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: scEvent.privacy === types_1.SCEventPrivacyType.PUBLIC ? ((0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: classes.visibilityItem }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "public" }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventHeader.visibility.public", defaultMessage: "ui.eventHeader.visibility.public" })] }))) : ((0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: classes.visibilityItem }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "private" }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventHeader.visibility.private", defaultMessage: "ui.eventHeader.visibility.private" })] }))) }), (0, jsx_runtime_1.jsx)(Bullet_1.default, {}), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.visibilityItem }, { children: scEvent.location === types_1.SCEventLocationType.PERSON ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventHeader.location.live", defaultMessage: "ui.eventHeader.location.live" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventHeader.location.online", defaultMessage: "ui.eventHeader.location.online" })) }))] })), (0, jsx_runtime_1.jsx)(User_1.default, { className: classes.planner, userId: scEvent.managed_by.id, secondary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventHeader.user.manager", defaultMessage: "ui.eventHeader.user.manager" }), elevation: 0, actions: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: isEventAdmin ? ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.multiActions }, { children: [(0, jsx_runtime_1.jsx)(EventInviteButton_1.default, { size: isMobile ? 'small' : 'medium', event: scEvent, disabled: isEventFinished }), (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [!isMobile && ((0, jsx_runtime_1.jsx)(EditEventButton_1.default, { size: isMobile ? 'small' : 'medium', event: scEvent, onEditSuccess: setSCEvent, disabled: isEventFinished })), (0, jsx_runtime_1.jsx)(EventActionsMenu_1.default, Object.assign({ event: scEvent, onEditSuccess: (data) => setSCEvent(data) }, EventActionsProps))] })] }))) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isPaymentsEnabled &&
150
+ ((_a = scEvent.paywalls) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
151
+ (scEvent.privacy === types_1.SCEventPrivacyType.PUBLIC ||
152
+ (scEvent.privacy === types_1.SCEventPrivacyType.PRIVATE &&
153
+ (!scEvent.subscription_status || scEvent.subscription_status !== types_1.SCEventSubscriptionStatusType.REQUESTED))) ? ((0, jsx_runtime_1.jsx)(BuyButton_1.default, { contentType: types_1.SCContentType.EVENT, content: scEvent })) : ((0, jsx_runtime_1.jsx)(EventSubscribeButton_1.default, Object.assign({ event: scEvent, onSubscribe: handleSubscribe }, EventSubscribeButtonProps, { disabled: isEventFinished }))), (0, jsx_runtime_1.jsx)(EventActionsMenu_1.default, Object.assign({ event: scEvent, onEditSuccess: setSCEvent }, EventActionsProps))] })) }) })] }))] })));
151
154
  }
152
155
  exports.default = EventHeader;
@@ -55,7 +55,7 @@ function PaymentProductPrice(inProps) {
55
55
  return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ disableTypography: true, className: classes.root, image: (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.image }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, Object.assign({ variant: "square", alt: 'price.name', className: classes.image }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "card_giftcard" }) })) })), primary: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)("b", { children: (0, payment_1.getConvertedAmount)(price) }) })), secondary: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!isMobile && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "p", variant: "body2", className: classes.secondary }, { children: price.description }))), (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: !isMobile && paymentOrder && paymentOrder.payment_price.id === price.id && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "p", variant: "body2", className: (0, classnames_1.default)(classes.secondary, classes.purchasedAt) }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.paymentProduct.action.purchasedAt", id: "ui.paymentProduct.action.purchasedAt", values: {
56
56
  purchasedAt: intl.formatDate(new Date(paymentOrder.created_at), { day: 'numeric', year: 'numeric', month: 'long' })
57
57
  } }) }))) })] }), actions: actions !== null && actions !== void 0 ? actions : ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.action }, { children: (0, jsx_runtime_1.jsx)(material_1.Zoom, Object.assign({ in: true, style: { transitionDelay: '200ms' } }, { children: (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", color: paymentOrder && paymentOrder.payment_price.id === price.id ? 'secondary' : 'error', className: (0, classnames_1.default)(classes.button, { [classes.buttonPurchased]: paymentOrder && paymentOrder.payment_price.id === price.id }) }, (paymentOrder && { disabled: true }), { variant: "contained", component: react_core_1.Link, startIcon: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "card_giftcard" }) }, (onHandleActionBuy && { onClick: handleActionBuy }), { to: `${scRoutingContext.url(react_core_1.SCRoutes.CHECKOUT_PAYMENT, {
58
- content_type: contentType.toLowerCase(),
58
+ content_type: contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase(),
59
59
  content_id: content ? content.id : contentId,
60
60
  price_id: price.id
61
61
  })}?${returnUrlParams ? new URLSearchParams(returnUrlParams) : ''}` }, { children: paymentOrder && paymentOrder.payment_price.id === price.id ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.paymentProduct.action.purchased", id: "ui.paymentProduct.action.purchased" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.paymentProduct.action.buy", id: "ui.paymentProduct.action.buy" })) })) })) }))) }, rest)));
@@ -1,7 +1,6 @@
1
1
  import { SCPaymentProduct, SCContentType, SCPurchasableContent, SCPaymentOrder, SCPaymentPrice } from '@selfcommunity/types';
2
2
  export interface PaymentProductsProps {
3
3
  className?: string;
4
- id?: number | string;
5
4
  contentType?: SCContentType;
6
5
  contentId?: number | string;
7
6
  content?: SCPurchasableContent;
@@ -14,6 +14,7 @@ const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton"));
14
14
  const PaymentProduct_1 = tslib_1.__importDefault(require("../PaymentProduct"));
15
15
  const utils_1 = require("@selfcommunity/utils");
16
16
  const Errors_1 = require("../../constants/Errors");
17
+ const use_deep_compare_effect_1 = tslib_1.__importDefault(require("use-deep-compare-effect"));
17
18
  const classes = {
18
19
  root: `${constants_1.PREFIX}-root`
19
20
  };
@@ -27,7 +28,9 @@ function PaymentProducts(inProps) {
27
28
  props: inProps,
28
29
  name: constants_1.PREFIX
29
30
  });
30
- const { className, id, contentId, contentType, content, prefetchedProducts = [], paymentOrder, onUpdatePaymentOrder } = props, rest = tslib_1.__rest(props, ["className", "id", "contentId", "contentType", "content", "prefetchedProducts", "paymentOrder", "onUpdatePaymentOrder"]);
31
+ const { className, contentId, contentType, content, prefetchedProducts = [], paymentOrder, onUpdatePaymentOrder } = props, rest = tslib_1.__rest(props, ["className", "contentId", "contentType", "content", "prefetchedProducts", "paymentOrder", "onUpdatePaymentOrder"]);
32
+ // CONST
33
+ const prefetchedProductsIds = prefetchedProducts.map((product) => product.id);
31
34
  // STATE
32
35
  const [products, setProducts] = (0, react_1.useState)([]);
33
36
  const [loading, setLoading] = (0, react_1.useState)(true);
@@ -37,21 +40,19 @@ function PaymentProducts(inProps) {
37
40
  /**
38
41
  * Fetches products list
39
42
  */
40
- const fetchProducts = (next = api_services_1.Endpoints.GetPaymentProducts.url({})) => tslib_1.__awaiter(this, void 0, void 0, function* () {
41
- const data = yield api_services_1.PaymentApiClient.getPaymentProducts(id !== undefined ? { id } : { content_id: contentId, content_type: contentType }, {
42
- url: next
43
- });
43
+ const fetchProducts = (next) => tslib_1.__awaiter(this, void 0, void 0, function* () {
44
+ const data = yield api_services_1.PaymentService.getPaymentProducts({ content_id: contentId, content_type: contentType }, Object.assign({}, (next && { url: next })));
44
45
  return data.next ? data.results.concat(yield fetchProducts(data.next)) : data.results;
45
46
  });
46
47
  /**
47
48
  * On mount, fetches products/prices list
48
49
  */
49
- (0, react_1.useEffect)(() => {
50
+ (0, use_deep_compare_effect_1.default)(() => {
50
51
  if (prefetchedProducts.length) {
51
52
  setProducts(prefetchedProducts);
52
53
  setLoading(false);
53
54
  }
54
- else if (id !== undefined || (contentId !== undefined && contentType)) {
55
+ else if (contentId !== undefined && contentType) {
55
56
  fetchProducts()
56
57
  .then((data) => {
57
58
  if (isMountedRef.current) {
@@ -67,7 +68,7 @@ function PaymentProducts(inProps) {
67
68
  setProducts(content.paywalls || []);
68
69
  setLoading(false);
69
70
  }
70
- }, [prefetchedProducts.length]);
71
+ }, [prefetchedProductsIds, contentId, contentType]);
71
72
  if (!isPaymentsEnabled) {
72
73
  return null;
73
74
  }
@@ -74,7 +74,7 @@ function Paywalls(inProps) {
74
74
  api_services_1.PaymentApiClient.getPaymentContentStatus({ content_id: contentId, content_type: contentType })
75
75
  .then((data) => {
76
76
  if (isMountedRef.current) {
77
- setProducts(data.paywalls);
77
+ setProducts(data.paywalls.map((p) => p.payment_product));
78
78
  setPaymentOrder(data.payment_order);
79
79
  setLoading(false);
80
80
  }
@@ -83,7 +83,7 @@ function Paywalls(inProps) {
83
83
  utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error);
84
84
  });
85
85
  }
86
- }, [prefetchedPaymentContentStatus]);
86
+ }, [prefetchedPaymentContentStatus, contentId, contentType]);
87
87
  if (!isPaymentsEnabled) {
88
88
  return null;
89
89
  }
@@ -26,6 +26,7 @@ const NoTransition = react_1.default.forwardRef(function NoTransition(props, ref
26
26
  return (0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [" ", props.children, " "] });
27
27
  });
28
28
  function PaywallsDialog(inProps) {
29
+ var _a;
29
30
  // PROPS
30
31
  const props = (0, system_1.useThemeProps)({
31
32
  props: inProps,
@@ -37,7 +38,7 @@ function PaywallsDialog(inProps) {
37
38
  if (!isPaymentsEnabled) {
38
39
  return null;
39
40
  }
40
- return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ maxWidth: 'sm', fullWidth: true, title: (PaywallsComponentProps && PaywallsComponentProps.prefetchedPaymentContentStatus.payment_order) ||
41
+ return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ maxWidth: 'sm', fullWidth: true, title: (PaywallsComponentProps && ((_a = PaywallsComponentProps.prefetchedPaymentContentStatus) === null || _a === void 0 ? void 0 : _a.payment_order)) ||
41
42
  (PaywallsComponentProps.content && PaywallsComponentProps.content.payment_order) ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.paywallsDialog.title.purchased", defaultMessage: "ui.paywallsDialog.title.purchased" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.paywallsDialog.title", defaultMessage: "ui.paywallsDialog.title" })), scroll: 'paper', open: true }, (disableInitialTransition ? { TransitionComponent: NoTransition } : { TransitionComponent: Transition }), { className: (0, classnames_1.default)(classes.root, className), TransitionComponent: Transition }, rest, { children: (0, jsx_runtime_1.jsx)(Paywalls_1.default, Object.assign({}, PaywallsComponentProps)) })));
42
43
  }
43
44
  exports.default = PaywallsDialog;
@@ -59,7 +59,7 @@ function EventInfoDetails(inProps) {
59
59
  month: 'long'
60
60
  }),
61
61
  start: intl.formatDate(scEvent.running ? scEvent.running_start_date : scEvent.next_start_date ? scEvent.next_start_date : scEvent.start_date, { hour: 'numeric', minute: 'numeric' })
62
- } }) })) })), hasInProgress && scEvent.active && scEvent.running && ((0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventInfoDetails.inProgress", defaultMessage: "ui.eventInfoDetails.inProgress" }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Box, { className: classes.inProgress }) })))] }))), beforeRecurringInfo, hasRecurringInfo && scEvent.recurring !== types_1.SCEventRecurrenceType.NEVER && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hideRecurringIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: "frequency" })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder`, defaultMessage: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder` }) }))] }))), beforePrivacyInfo, hasPrivacyInfo && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hidePrivacyIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: scEvent.privacy === types_1.SCEventPrivacyType.PUBLIC ? 'public' : 'private' })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: privacy, defaultMessage: privacy }) })), "-", (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: location, defaultMessage: location }) }))] }))), beforeLocationInfo, hasLocationInfo && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hideLocationIcon && ((0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: scEvent.location === types_1.SCEventLocationType.ONLINE ? 'play_circle_outline' : 'add_location_alt' }))), scEvent.location === types_1.SCEventLocationType.ONLINE ? (scEvent.live_stream ? ((0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", variant: "contained", color: "secondary", component: react_core_1.Link, disabled: disableJoinEvent, to: scRoutingContext.url(react_core_1.SCRoutes.LIVESTREAM_ROUTE_NAME, scEvent.live_stream), className: classes.joinLive }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.eventInfoDetails.live.join", id: "ui.eventInfoDetails.live.join" }) }))) : ((0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scEvent.link, target: "_blank", className: classes.link }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", className: classes.url }, { children: scEvent.link })) })))) : ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", className: classes.url }, { children: scEvent.geolocation })))] }))), beforeCreatedInfo, hasCreatedInfo && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.creationWrapper }, { children: [!hideCreatedIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: "create" })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventInfoDetails.date.create", defaultMessage: "ui.eventInfoDetails.date.create", values: {
62
+ } }) })) })), hasInProgress && scEvent.active && scEvent.running && ((0, jsx_runtime_1.jsx)(material_1.Tooltip, Object.assign({ title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventInfoDetails.inProgress", defaultMessage: "ui.eventInfoDetails.inProgress" }) }, { children: (0, jsx_runtime_1.jsx)(material_1.Box, { className: classes.inProgress }) })))] }))), beforeRecurringInfo, hasRecurringInfo && scEvent.recurring !== types_1.SCEventRecurrenceType.NEVER && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hideRecurringIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: "frequency" })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder`, defaultMessage: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder` }) }))] }))), beforePrivacyInfo, hasPrivacyInfo && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hidePrivacyIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: scEvent.privacy === types_1.SCEventPrivacyType.PUBLIC ? 'public' : 'private' })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: privacy, defaultMessage: privacy }) })), "-", (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: location, defaultMessage: location }) }))] }))), beforeLocationInfo, hasLocationInfo && ((0, jsx_runtime_1.jsx)(material_1.Stack, Object.assign({ className: classes.iconTextWrapper }, { children: scEvent.location === types_1.SCEventLocationType.PERSON ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!hideLocationIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: "add_location_alt" })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", className: classes.url }, { children: scEvent.geolocation }))] })) : scEvent.paywalls.length && scEvent.subscription_status !== types_1.SCEventSubscriptionStatusType.GOING ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {})) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!hideLocationIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: "play_circle_outline" })), scEvent.live_stream ? ((0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", variant: "contained", color: "secondary", component: react_core_1.Link, disabled: disableJoinEvent, to: scRoutingContext.url(react_core_1.SCRoutes.LIVESTREAM_ROUTE_NAME, scEvent.live_stream), className: classes.joinLive }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { defaultMessage: "ui.eventInfoDetails.live.join", id: "ui.eventInfoDetails.live.join" }) }))) : ((0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scEvent.link, target: "_blank", className: classes.link }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", className: classes.url }, { children: scEvent.link })) })))] })) }))), beforeCreatedInfo, hasCreatedInfo && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ className: classes.creationWrapper }, { children: [!hideCreatedIcon && (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ fontSize: "small" }, { children: "create" })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.eventInfoDetails.date.create", defaultMessage: "ui.eventInfoDetails.date.create", values: {
63
63
  date: intl.formatDate(scEvent.created_at, {
64
64
  weekday: 'long',
65
65
  day: 'numeric',
@@ -39,7 +39,7 @@ export default function Checkout(inProps) {
39
39
  props: inProps,
40
40
  name: PREFIX
41
41
  });
42
- const { className, contentType, contentId, content, priceId, returnUrl, successUrl, uiMode, onComplete } = props, rest = __rest(props, ["className", "contentType", "contentId", "content", "priceId", "returnUrl", "successUrl", "uiMode", "onComplete"]);
42
+ const { className, clientSecret, contentType, contentId, content, priceId, returnUrl, successUrl, uiMode, onComplete } = props, rest = __rest(props, ["className", "clientSecret", "contentType", "contentId", "content", "priceId", "returnUrl", "successUrl", "uiMode", "onComplete"]);
43
43
  const [loading, setLoading] = useState(false);
44
44
  const [initialized, setInitialized] = useState(false);
45
45
  // CONTEXT
@@ -51,7 +51,7 @@ export default function Checkout(inProps) {
51
51
  ? loadStripe(stripePublicKey, { stripeAccount: stripeConnectedAccountId, locale: getDefaultLocale(intl).locale })
52
52
  : null;
53
53
  // STATE
54
- const [clientSecret, setClientSecret] = useState(props.clientSecret);
54
+ const [clientSecretKey, setClientSecretKey] = useState(clientSecret);
55
55
  const isContentObject = useMemo(() => contentType && contentId !== undefined, [contentType, contentId]);
56
56
  const fetchClientSecret = useCallback(() => {
57
57
  // Create a Checkout Session
@@ -60,7 +60,7 @@ export default function Checkout(inProps) {
60
60
  setLoading(true);
61
61
  PaymentApiClient.checkoutCreateSession(Object.assign(Object.assign(Object.assign({ content_type: contentType, content_id: content ? content.id : contentId, payment_price_id: priceId }, (returnUrl && { return_url: returnUrl })), (successUrl && { success_url: successUrl })), (uiMode && { ui_mode: uiMode })))
62
62
  .then((r) => {
63
- setClientSecret(r.client_secret);
63
+ setClientSecretKey(r.client_secret);
64
64
  setLoading(false);
65
65
  })
66
66
  .catch((error) => {
@@ -71,22 +71,22 @@ export default function Checkout(inProps) {
71
71
  // EFFECTS
72
72
  useEffect(() => {
73
73
  let _t;
74
- if (scUserContext.user && contentType && (contentId || content) && priceId && !clientSecret && Boolean(stripePromise) && !initialized) {
74
+ if (scUserContext.user && contentType && (contentId || content) && priceId && !clientSecretKey && Boolean(stripePromise) && !initialized) {
75
75
  _t = setTimeout(fetchClientSecret);
76
76
  return () => {
77
77
  _t && clearTimeout(_t);
78
78
  };
79
79
  }
80
- }, [scUserContext.user, clientSecret, stripePromise, contentType, contentId, content, priceId, loading, initialized]);
80
+ }, [scUserContext.user, clientSecretKey, stripePromise, contentType, contentId, content, priceId, loading, initialized]);
81
81
  // Payment provider options
82
- const providerOptions = useMemo(() => (Object.assign({ clientSecret }, (onComplete && { onComplete })
82
+ const providerOptions = useMemo(() => (Object.assign({ clientSecret: clientSecretKey }, (onComplete && { onComplete })
83
83
  // ...(onShippingDetailsChange && {onShippingDetailsChange})
84
- )), [clientSecret, onComplete]);
84
+ )), [clientSecretKey, onComplete]);
85
85
  if (!isPaymentsEnabled) {
86
86
  return null;
87
87
  }
88
88
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
89
- if (!stripePromise || !clientSecret || !scUserContext.user) {
89
+ if (!stripePromise || !clientSecretKey || !scUserContext.user) {
90
90
  return _jsx(CheckoutSkeleton, {});
91
91
  }
92
92
  const renderContentObject = () => {
@@ -62,5 +62,5 @@ export default function CommunityPaywalls(inProps) {
62
62
  if (loading) {
63
63
  return _jsx(CommunityPaywallSkeleton, {});
64
64
  }
65
- return (_jsx(Root, Object.assign({ className: classNames(classes.root, className), container: true, spacing: 4 }, rest, { children: scCommunity.paywalls.map((p, i) => (_jsx(Grid, Object.assign({ xs: 12, sm: 6, md: 4 }, { children: _jsx(PaymentProduct, Object.assign({ expanded: true, paymentProduct: p, contentType: SCContentType.COMMUNITY, contentId: scCommunity.id }, (scCommunity.payment_order && { paymentOrder: scCommunity.payment_order, onUpdatePaymentOrder }), (scCommunity.payment_order && { paymentOrder: scCommunity.payment_order, onUpdatePaymentOrder }), (callbackUrl && { PaymentProductPriceComponentProps: { returnUrlParams: { callbackUrl } } }))) }), i))) })));
65
+ return (_jsx(Root, Object.assign({ className: classNames(classes.root, className), container: true, spacing: 4 }, rest, { children: scCommunity.paywalls.map((p, i) => (_jsx(Grid, Object.assign({ xs: 12, sm: 12, md: 4 }, { children: _jsx(PaymentProduct, Object.assign({ expanded: true, paymentProduct: p, contentType: SCContentType.COMMUNITY, contentId: scCommunity.id }, (scCommunity.payment_order && { paymentOrder: scCommunity.payment_order, onUpdatePaymentOrder }), (scCommunity.payment_order && { paymentOrder: scCommunity.payment_order, onUpdatePaymentOrder }), (callbackUrl && { PaymentProductPriceComponentProps: { returnUrlParams: { callbackUrl } } }))) }), i))) })));
66
66
  }
@@ -5,7 +5,7 @@ import { PREFIX } from './constants';
5
5
  import { Avatar, Box, Divider, LinearProgress, Skeleton, Stack, styled, Typography, useThemeProps } from '@mui/material';
6
6
  import classNames from 'classnames';
7
7
  import HeaderCourseDashboard from './Header';
8
- import { SCCourseJoinStatusType, SCCourseLessonCompletionStatusType, SCCoursePrivacyType } from '@selfcommunity/types';
8
+ import { SCContentType, SCCourseJoinStatusType, SCCourseLessonCompletionStatusType, SCCoursePrivacyType } from '@selfcommunity/types';
9
9
  import { FormattedMessage, useIntl } from 'react-intl';
10
10
  import ActionButton from './Student/ActionButton';
11
11
  import { CLAPPING } from '../../assets/courses/clapping';
@@ -17,6 +17,7 @@ import { SCOPE_SC_UI } from '../../constants/Errors';
17
17
  import { useSnackbar } from 'notistack';
18
18
  import StudentSkeleton from './Student/Skeleton';
19
19
  import UserAvatar from '../../shared/UserAvatar';
20
+ import BuyButton from '../BuyButton';
20
21
  const BUTTON_MESSAGES = {
21
22
  dashboard: 'ui.course.dashboard.student.button.dashboard',
22
23
  request: 'ui.course.dashboard.student.button.request',
@@ -165,7 +166,7 @@ function Student(inProps) {
165
166
  }, [scContext.settings.handleAnonymousAction]);
166
167
  // MEMOS
167
168
  const actionButton = useMemo(() => {
168
- var _a, _b;
169
+ var _a, _b, _c;
169
170
  if (!scCourse) {
170
171
  return _jsx(Skeleton, { animation: "wave", variant: "rectangular", width: "130px", height: "20px" });
171
172
  }
@@ -178,7 +179,7 @@ function Student(inProps) {
178
179
  ? BUTTON_MESSAGES.start
179
180
  : scCourse.user_completion_rate === 100
180
181
  ? BUTTON_MESSAGES.review
181
- : BUTTON_MESSAGES.continue, to: scCourse.join_status !== null ? scRoutingContext.url(SCRoutes.COURSE_LESSON_ROUTE_NAME, getUrlNextLesson(scCourse)) : undefined, disabled: scCourse.join_status !== null ? getIsNextLessonLocked(scCourse) : undefined, color: scCourse.user_completion_rate === 100 ? 'inherit' : undefined, variant: scCourse.user_completion_rate === 100 ? 'outlined' : undefined, loading: scCourse.join_status === null ? loadingRequest : undefined, onClick: !scUserContext.user ? handleAnonymousAction : scCourse.join_status === null ? handleRequest : undefined })), scCourse.privacy === SCCoursePrivacyType.PRIVATE &&
182
+ : BUTTON_MESSAGES.continue, to: scCourse.join_status !== null ? scRoutingContext.url(SCRoutes.COURSE_LESSON_ROUTE_NAME, getUrlNextLesson(scCourse)) : undefined, disabled: scCourse.join_status !== null ? getIsNextLessonLocked(scCourse) : undefined, color: scCourse.user_completion_rate === 100 ? 'inherit' : undefined, variant: scCourse.user_completion_rate === 100 ? 'outlined' : undefined, loading: scCourse.join_status === null ? loadingRequest : undefined, onClick: !scUserContext.user ? handleAnonymousAction : scCourse.join_status === null ? handleRequest : undefined })), isPaymentsEnabled && ((_c = scCourse.paywalls) === null || _c === void 0 ? void 0 : _c.length) > 0 && !scCourse.join_status && (_jsx(BuyButton, { contentType: SCContentType.COURSE, content: scCourse })), scCourse.privacy === SCCoursePrivacyType.PRIVATE &&
182
183
  (scCourse.join_status === null || scCourse.join_status === SCCourseJoinStatusType.REQUESTED) && (_jsx(ActionButton, { labelId: sentRequest ? BUTTON_MESSAGES.cancel : BUTTON_MESSAGES.request, color: "inherit", variant: "outlined", loading: loadingRequest, onClick: handleRequest }))] })));
183
184
  }, [scCourse, sentRequest, loadingRequest, handleRequest]);
184
185
  if (!scCourse) {
@@ -109,7 +109,6 @@ export default function EventHeader(inProps) {
109
109
  const _backgroundCover = Object.assign({}, (scEvent.image_bigger
110
110
  ? { background: `url('${scEvent.image_bigger}') center / cover` }
111
111
  : { background: `url('${preferences.preferences[SCPreferences.IMAGES_USER_DEFAULT_COVER].value}') center / cover` }));
112
- console.log('*** event *** ', scEvent);
113
112
  return (
114
113
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
115
114
  // @ts-ignore
@@ -145,5 +144,9 @@ export default function EventHeader(inProps) {
145
144
  month: 'long'
146
145
  }),
147
146
  hour: intl.formatDate(scEvent.start_date, { hour: 'numeric', minute: 'numeric' })
148
- } })) })), _jsx(Typography, Object.assign({ variant: "h5", className: classes.name }, { children: scEvent.name })), _jsxs(Box, Object.assign({ className: classes.visibility }, { children: [_jsx(_Fragment, { children: scEvent.privacy === SCEventPrivacyType.PUBLIC ? (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "public" }), _jsx(FormattedMessage, { id: "ui.eventHeader.visibility.public", defaultMessage: "ui.eventHeader.visibility.public" })] }))) : (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "private" }), _jsx(FormattedMessage, { id: "ui.eventHeader.visibility.private", defaultMessage: "ui.eventHeader.visibility.private" })] }))) }), _jsx(Bullet, {}), _jsx(Typography, Object.assign({ className: classes.visibilityItem }, { children: scEvent.location === SCEventLocationType.PERSON ? (_jsx(FormattedMessage, { id: "ui.eventHeader.location.live", defaultMessage: "ui.eventHeader.location.live" })) : (_jsx(FormattedMessage, { id: "ui.eventHeader.location.online", defaultMessage: "ui.eventHeader.location.online" })) }))] })), _jsx(User, { className: classes.planner, userId: scEvent.managed_by.id, secondary: _jsx(FormattedMessage, { id: "ui.eventHeader.user.manager", defaultMessage: "ui.eventHeader.user.manager" }), elevation: 0, actions: _jsx(_Fragment, { children: isEventAdmin ? (_jsxs(Box, Object.assign({ className: classes.multiActions }, { children: [_jsx(EventInviteButton, { size: isMobile ? 'small' : 'medium', event: scEvent, disabled: isEventFinished }), _jsxs(Box, { children: [!isMobile && (_jsx(EditEventButton, { size: isMobile ? 'small' : 'medium', event: scEvent, onEditSuccess: setSCEvent, disabled: isEventFinished })), _jsx(EventActionsMenu, Object.assign({ event: scEvent, onEditSuccess: (data) => setSCEvent(data) }, EventActionsProps))] })] }))) : (_jsxs(_Fragment, { children: [isPaymentsEnabled && ((_a = scEvent.paywalls) === null || _a === void 0 ? void 0 : _a.length) > 0 && scEvent.subscription_status !== SCEventSubscriptionStatusType.REQUESTED ? (_jsx(BuyButton, { contentType: SCContentType.EVENT, content: scEvent })) : (_jsx(EventSubscribeButton, Object.assign({ event: scEvent, onSubscribe: handleSubscribe }, EventSubscribeButtonProps, { disabled: isEventFinished }))), _jsx(EventActionsMenu, Object.assign({ event: scEvent, onEditSuccess: setSCEvent }, EventActionsProps))] })) }) })] }))] })));
147
+ } })) })), _jsx(Typography, Object.assign({ variant: "h5", className: classes.name }, { children: scEvent.name })), _jsxs(Box, Object.assign({ className: classes.visibility }, { children: [_jsx(_Fragment, { children: scEvent.privacy === SCEventPrivacyType.PUBLIC ? (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "public" }), _jsx(FormattedMessage, { id: "ui.eventHeader.visibility.public", defaultMessage: "ui.eventHeader.visibility.public" })] }))) : (_jsxs(Typography, Object.assign({ className: classes.visibilityItem }, { children: [_jsx(Icon, { children: "private" }), _jsx(FormattedMessage, { id: "ui.eventHeader.visibility.private", defaultMessage: "ui.eventHeader.visibility.private" })] }))) }), _jsx(Bullet, {}), _jsx(Typography, Object.assign({ className: classes.visibilityItem }, { children: scEvent.location === SCEventLocationType.PERSON ? (_jsx(FormattedMessage, { id: "ui.eventHeader.location.live", defaultMessage: "ui.eventHeader.location.live" })) : (_jsx(FormattedMessage, { id: "ui.eventHeader.location.online", defaultMessage: "ui.eventHeader.location.online" })) }))] })), _jsx(User, { className: classes.planner, userId: scEvent.managed_by.id, secondary: _jsx(FormattedMessage, { id: "ui.eventHeader.user.manager", defaultMessage: "ui.eventHeader.user.manager" }), elevation: 0, actions: _jsx(_Fragment, { children: isEventAdmin ? (_jsxs(Box, Object.assign({ className: classes.multiActions }, { children: [_jsx(EventInviteButton, { size: isMobile ? 'small' : 'medium', event: scEvent, disabled: isEventFinished }), _jsxs(Box, { children: [!isMobile && (_jsx(EditEventButton, { size: isMobile ? 'small' : 'medium', event: scEvent, onEditSuccess: setSCEvent, disabled: isEventFinished })), _jsx(EventActionsMenu, Object.assign({ event: scEvent, onEditSuccess: (data) => setSCEvent(data) }, EventActionsProps))] })] }))) : (_jsxs(_Fragment, { children: [isPaymentsEnabled &&
148
+ ((_a = scEvent.paywalls) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
149
+ (scEvent.privacy === SCEventPrivacyType.PUBLIC ||
150
+ (scEvent.privacy === SCEventPrivacyType.PRIVATE &&
151
+ (!scEvent.subscription_status || scEvent.subscription_status !== SCEventSubscriptionStatusType.REQUESTED))) ? (_jsx(BuyButton, { contentType: SCContentType.EVENT, content: scEvent })) : (_jsx(EventSubscribeButton, Object.assign({ event: scEvent, onSubscribe: handleSubscribe }, EventSubscribeButtonProps, { disabled: isEventFinished }))), _jsx(EventActionsMenu, Object.assign({ event: scEvent, onEditSuccess: setSCEvent }, EventActionsProps))] })) }) })] }))] })));
149
152
  }
@@ -53,7 +53,7 @@ export default function PaymentProductPrice(inProps) {
53
53
  return (_jsx(Root, Object.assign({ disableTypography: true, className: classes.root, image: _jsx(Box, Object.assign({ className: classes.image }, { children: _jsx(Avatar, Object.assign({ variant: "square", alt: 'price.name', className: classes.image }, { children: _jsx(Icon, { children: "card_giftcard" }) })) })), primary: _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx("b", { children: getConvertedAmount(price) }) })), secondary: _jsxs(_Fragment, { children: [!isMobile && (_jsx(Typography, Object.assign({ component: "p", variant: "body2", className: classes.secondary }, { children: price.description }))), _jsx(_Fragment, { children: !isMobile && paymentOrder && paymentOrder.payment_price.id === price.id && (_jsx(Typography, Object.assign({ component: "p", variant: "body2", className: classNames(classes.secondary, classes.purchasedAt) }, { children: _jsx(FormattedMessage, { defaultMessage: "ui.paymentProduct.action.purchasedAt", id: "ui.paymentProduct.action.purchasedAt", values: {
54
54
  purchasedAt: intl.formatDate(new Date(paymentOrder.created_at), { day: 'numeric', year: 'numeric', month: 'long' })
55
55
  } }) }))) })] }), actions: actions !== null && actions !== void 0 ? actions : (_jsx(Box, Object.assign({ className: classes.action }, { children: _jsx(Zoom, Object.assign({ in: true, style: { transitionDelay: '200ms' } }, { children: _jsx(Button, Object.assign({ size: "small", color: paymentOrder && paymentOrder.payment_price.id === price.id ? 'secondary' : 'error', className: classNames(classes.button, { [classes.buttonPurchased]: paymentOrder && paymentOrder.payment_price.id === price.id }) }, (paymentOrder && { disabled: true }), { variant: "contained", component: Link, startIcon: _jsx(Icon, { children: "card_giftcard" }) }, (onHandleActionBuy && { onClick: handleActionBuy }), { to: `${scRoutingContext.url(SCRoutes.CHECKOUT_PAYMENT, {
56
- content_type: contentType.toLowerCase(),
56
+ content_type: contentType === null || contentType === void 0 ? void 0 : contentType.toLowerCase(),
57
57
  content_id: content ? content.id : contentId,
58
58
  price_id: price.id
59
59
  })}?${returnUrlParams ? new URLSearchParams(returnUrlParams) : ''}` }, { children: paymentOrder && paymentOrder.payment_price.id === price.id ? (_jsx(FormattedMessage, { defaultMessage: "ui.paymentProduct.action.purchased", id: "ui.paymentProduct.action.purchased" })) : (_jsx(FormattedMessage, { defaultMessage: "ui.paymentProduct.action.buy", id: "ui.paymentProduct.action.buy" })) })) })) }))) }, rest)));
@@ -1,7 +1,6 @@
1
1
  import { SCPaymentProduct, SCContentType, SCPurchasableContent, SCPaymentOrder, SCPaymentPrice } from '@selfcommunity/types';
2
2
  export interface PaymentProductsProps {
3
3
  className?: string;
4
- id?: number | string;
5
4
  contentType?: SCContentType;
6
5
  contentId?: number | string;
7
6
  content?: SCPurchasableContent;
@@ -1,17 +1,18 @@
1
1
  import { __awaiter, __rest } from "tslib";
2
2
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useEffect, useState } from 'react';
3
+ import { useState } from 'react';
4
4
  import { Box } from '@mui/material';
5
5
  import { styled } from '@mui/material/styles';
6
6
  import { useThemeProps } from '@mui/system';
7
7
  import classNames from 'classnames';
8
- import { Endpoints, PaymentApiClient } from '@selfcommunity/api-services';
8
+ import { PaymentService } from '@selfcommunity/api-services';
9
9
  import { useIsComponentMountedRef, useSCPaymentsEnabled } from '@selfcommunity/react-core';
10
10
  import { PREFIX } from './constants';
11
11
  import PaymentProductsSkeleton from './Skeleton';
12
12
  import PaymentProduct from '../PaymentProduct';
13
13
  import { Logger } from '@selfcommunity/utils';
14
14
  import { SCOPE_SC_UI } from '../../constants/Errors';
15
+ import useDeepCompareEffect from 'use-deep-compare-effect';
15
16
  const classes = {
16
17
  root: `${PREFIX}-root`
17
18
  };
@@ -25,7 +26,9 @@ export default function PaymentProducts(inProps) {
25
26
  props: inProps,
26
27
  name: PREFIX
27
28
  });
28
- const { className, id, contentId, contentType, content, prefetchedProducts = [], paymentOrder, onUpdatePaymentOrder } = props, rest = __rest(props, ["className", "id", "contentId", "contentType", "content", "prefetchedProducts", "paymentOrder", "onUpdatePaymentOrder"]);
29
+ const { className, contentId, contentType, content, prefetchedProducts = [], paymentOrder, onUpdatePaymentOrder } = props, rest = __rest(props, ["className", "contentId", "contentType", "content", "prefetchedProducts", "paymentOrder", "onUpdatePaymentOrder"]);
30
+ // CONST
31
+ const prefetchedProductsIds = prefetchedProducts.map((product) => product.id);
29
32
  // STATE
30
33
  const [products, setProducts] = useState([]);
31
34
  const [loading, setLoading] = useState(true);
@@ -35,21 +38,19 @@ export default function PaymentProducts(inProps) {
35
38
  /**
36
39
  * Fetches products list
37
40
  */
38
- const fetchProducts = (next = Endpoints.GetPaymentProducts.url({})) => __awaiter(this, void 0, void 0, function* () {
39
- const data = yield PaymentApiClient.getPaymentProducts(id !== undefined ? { id } : { content_id: contentId, content_type: contentType }, {
40
- url: next
41
- });
41
+ const fetchProducts = (next) => __awaiter(this, void 0, void 0, function* () {
42
+ const data = yield PaymentService.getPaymentProducts({ content_id: contentId, content_type: contentType }, Object.assign({}, (next && { url: next })));
42
43
  return data.next ? data.results.concat(yield fetchProducts(data.next)) : data.results;
43
44
  });
44
45
  /**
45
46
  * On mount, fetches products/prices list
46
47
  */
47
- useEffect(() => {
48
+ useDeepCompareEffect(() => {
48
49
  if (prefetchedProducts.length) {
49
50
  setProducts(prefetchedProducts);
50
51
  setLoading(false);
51
52
  }
52
- else if (id !== undefined || (contentId !== undefined && contentType)) {
53
+ else if (contentId !== undefined && contentType) {
53
54
  fetchProducts()
54
55
  .then((data) => {
55
56
  if (isMountedRef.current) {
@@ -65,7 +66,7 @@ export default function PaymentProducts(inProps) {
65
66
  setProducts(content.paywalls || []);
66
67
  setLoading(false);
67
68
  }
68
- }, [prefetchedProducts.length]);
69
+ }, [prefetchedProductsIds, contentId, contentType]);
69
70
  if (!isPaymentsEnabled) {
70
71
  return null;
71
72
  }
@@ -72,7 +72,7 @@ export default function Paywalls(inProps) {
72
72
  PaymentApiClient.getPaymentContentStatus({ content_id: contentId, content_type: contentType })
73
73
  .then((data) => {
74
74
  if (isMountedRef.current) {
75
- setProducts(data.paywalls);
75
+ setProducts(data.paywalls.map((p) => p.payment_product));
76
76
  setPaymentOrder(data.payment_order);
77
77
  setLoading(false);
78
78
  }
@@ -81,7 +81,7 @@ export default function Paywalls(inProps) {
81
81
  Logger.error(SCOPE_SC_UI, error);
82
82
  });
83
83
  }
84
- }, [prefetchedPaymentContentStatus]);
84
+ }, [prefetchedPaymentContentStatus, contentId, contentType]);
85
85
  if (!isPaymentsEnabled) {
86
86
  return null;
87
87
  }
@@ -24,6 +24,7 @@ const NoTransition = React.forwardRef(function NoTransition(props, ref) {
24
24
  return _jsxs(React.Fragment, { children: [" ", props.children, " "] });
25
25
  });
26
26
  export default function PaywallsDialog(inProps) {
27
+ var _a;
27
28
  // PROPS
28
29
  const props = useThemeProps({
29
30
  props: inProps,
@@ -35,6 +36,6 @@ export default function PaywallsDialog(inProps) {
35
36
  if (!isPaymentsEnabled) {
36
37
  return null;
37
38
  }
38
- return (_jsx(Root, Object.assign({ maxWidth: 'sm', fullWidth: true, title: (PaywallsComponentProps && PaywallsComponentProps.prefetchedPaymentContentStatus.payment_order) ||
39
+ return (_jsx(Root, Object.assign({ maxWidth: 'sm', fullWidth: true, title: (PaywallsComponentProps && ((_a = PaywallsComponentProps.prefetchedPaymentContentStatus) === null || _a === void 0 ? void 0 : _a.payment_order)) ||
39
40
  (PaywallsComponentProps.content && PaywallsComponentProps.content.payment_order) ? (_jsx(FormattedMessage, { id: "ui.paywallsDialog.title.purchased", defaultMessage: "ui.paywallsDialog.title.purchased" })) : (_jsx(FormattedMessage, { id: "ui.paywallsDialog.title", defaultMessage: "ui.paywallsDialog.title" })), scroll: 'paper', open: true }, (disableInitialTransition ? { TransitionComponent: NoTransition } : { TransitionComponent: Transition }), { className: classNames(classes.root, className), TransitionComponent: Transition }, rest, { children: _jsx(Paywalls, Object.assign({}, PaywallsComponentProps)) })));
40
41
  }
@@ -1,7 +1,7 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Box, Button, Icon, Stack, styled, Tooltip, Typography, useThemeProps } from '@mui/material';
3
3
  import { Link, SCPreferences, SCRoutes, SCUserContext, useSCFetchEvent, useSCPreferences, useSCRouting } from '@selfcommunity/react-core';
4
- import { SCEventLocationType, SCEventPrivacyType, SCEventRecurrenceType, SCFeatureName } from '@selfcommunity/types';
4
+ import { SCEventLocationType, SCEventPrivacyType, SCEventRecurrenceType, SCEventSubscriptionStatusType, SCFeatureName } from '@selfcommunity/types';
5
5
  import { useContext, useMemo } from 'react';
6
6
  import { FormattedMessage, useIntl } from 'react-intl';
7
7
  const PREFIX = 'SCEventInfoDetails';
@@ -57,7 +57,7 @@ export default function EventInfoDetails(inProps) {
57
57
  month: 'long'
58
58
  }),
59
59
  start: intl.formatDate(scEvent.running ? scEvent.running_start_date : scEvent.next_start_date ? scEvent.next_start_date : scEvent.start_date, { hour: 'numeric', minute: 'numeric' })
60
- } }) })) })), hasInProgress && scEvent.active && scEvent.running && (_jsx(Tooltip, Object.assign({ title: _jsx(FormattedMessage, { id: "ui.eventInfoDetails.inProgress", defaultMessage: "ui.eventInfoDetails.inProgress" }) }, { children: _jsx(Box, { className: classes.inProgress }) })))] }))), beforeRecurringInfo, hasRecurringInfo && scEvent.recurring !== SCEventRecurrenceType.NEVER && (_jsxs(Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hideRecurringIcon && _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "frequency" })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder`, defaultMessage: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder` }) }))] }))), beforePrivacyInfo, hasPrivacyInfo && (_jsxs(Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hidePrivacyIcon && _jsx(Icon, Object.assign({ fontSize: "small" }, { children: scEvent.privacy === SCEventPrivacyType.PUBLIC ? 'public' : 'private' })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: privacy, defaultMessage: privacy }) })), "-", _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: location, defaultMessage: location }) }))] }))), beforeLocationInfo, hasLocationInfo && (_jsxs(Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hideLocationIcon && (_jsx(Icon, Object.assign({ fontSize: "small" }, { children: scEvent.location === SCEventLocationType.ONLINE ? 'play_circle_outline' : 'add_location_alt' }))), scEvent.location === SCEventLocationType.ONLINE ? (scEvent.live_stream ? (_jsx(Button, Object.assign({ size: "small", variant: "contained", color: "secondary", component: Link, disabled: disableJoinEvent, to: scRoutingContext.url(SCRoutes.LIVESTREAM_ROUTE_NAME, scEvent.live_stream), className: classes.joinLive }, { children: _jsx(FormattedMessage, { defaultMessage: "ui.eventInfoDetails.live.join", id: "ui.eventInfoDetails.live.join" }) }))) : (_jsx(Link, Object.assign({ to: scEvent.link, target: "_blank", className: classes.link }, { children: _jsx(Typography, Object.assign({ variant: "body1", className: classes.url }, { children: scEvent.link })) })))) : (_jsx(Typography, Object.assign({ variant: "body1", className: classes.url }, { children: scEvent.geolocation })))] }))), beforeCreatedInfo, hasCreatedInfo && (_jsxs(Stack, Object.assign({ className: classes.creationWrapper }, { children: [!hideCreatedIcon && _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "create" })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.eventInfoDetails.date.create", defaultMessage: "ui.eventInfoDetails.date.create", values: {
60
+ } }) })) })), hasInProgress && scEvent.active && scEvent.running && (_jsx(Tooltip, Object.assign({ title: _jsx(FormattedMessage, { id: "ui.eventInfoDetails.inProgress", defaultMessage: "ui.eventInfoDetails.inProgress" }) }, { children: _jsx(Box, { className: classes.inProgress }) })))] }))), beforeRecurringInfo, hasRecurringInfo && scEvent.recurring !== SCEventRecurrenceType.NEVER && (_jsxs(Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hideRecurringIcon && _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "frequency" })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder`, defaultMessage: `ui.eventInfoDetails.frequency.${scEvent.recurring}.placeholder` }) }))] }))), beforePrivacyInfo, hasPrivacyInfo && (_jsxs(Stack, Object.assign({ className: classes.iconTextWrapper }, { children: [!hidePrivacyIcon && _jsx(Icon, Object.assign({ fontSize: "small" }, { children: scEvent.privacy === SCEventPrivacyType.PUBLIC ? 'public' : 'private' })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: privacy, defaultMessage: privacy }) })), "-", _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: location, defaultMessage: location }) }))] }))), beforeLocationInfo, hasLocationInfo && (_jsx(Stack, Object.assign({ className: classes.iconTextWrapper }, { children: scEvent.location === SCEventLocationType.PERSON ? (_jsxs(_Fragment, { children: [!hideLocationIcon && _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "add_location_alt" })), _jsx(Typography, Object.assign({ variant: "body1", className: classes.url }, { children: scEvent.geolocation }))] })) : scEvent.paywalls.length && scEvent.subscription_status !== SCEventSubscriptionStatusType.GOING ? (_jsx(_Fragment, {})) : (_jsxs(_Fragment, { children: [!hideLocationIcon && _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "play_circle_outline" })), scEvent.live_stream ? (_jsx(Button, Object.assign({ size: "small", variant: "contained", color: "secondary", component: Link, disabled: disableJoinEvent, to: scRoutingContext.url(SCRoutes.LIVESTREAM_ROUTE_NAME, scEvent.live_stream), className: classes.joinLive }, { children: _jsx(FormattedMessage, { defaultMessage: "ui.eventInfoDetails.live.join", id: "ui.eventInfoDetails.live.join" }) }))) : (_jsx(Link, Object.assign({ to: scEvent.link, target: "_blank", className: classes.link }, { children: _jsx(Typography, Object.assign({ variant: "body1", className: classes.url }, { children: scEvent.link })) })))] })) }))), beforeCreatedInfo, hasCreatedInfo && (_jsxs(Stack, Object.assign({ className: classes.creationWrapper }, { children: [!hideCreatedIcon && _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "create" })), _jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.eventInfoDetails.date.create", defaultMessage: "ui.eventInfoDetails.date.create", values: {
61
61
  date: intl.formatDate(scEvent.created_at, {
62
62
  weekday: 'long',
63
63
  day: 'numeric',