Skip to content

Commit

Permalink
v2.0.0 - Refactor to use hook & support new Evenbrite widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdshepard committed Sep 12, 2022
1 parent 3184285 commit 7af1b78
Show file tree
Hide file tree
Showing 11 changed files with 1,945 additions and 3,625 deletions.
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
src
images
webpack.config.js
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16.17
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 Vancouver Startup Society
Copyright (c) 2022 Enceladus Consulting Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
100 changes: 63 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# React Eventbrite Popup Checkout
A React component that bootstraps Eventbrite's popup checkout widget.

**Note:** Popup will only trigger if your app is served with **HTTPS**. Otherwise a new window is opened that links to your Eventbrite event page.
# React Eventbrite Checkout
A React component that loads Eventbrite's checkout widgets.

## Install
If using NPM:
Expand All @@ -15,43 +13,71 @@ $ yarn add react-eventbrite-popup-checkout
```

## Usage
**Note:** In-app checkout will only trigger when your app is served with **HTTPS**. Otherwise, the component directs the user to Eventbrite's website to complete the purchase.

### Modal Example
![plot](./images/modal.gif)

Create a button that triggers a checkout modal.

### Example
```js
```jsx
import React from 'react';
import EventbriteButton from 'react-eventbrite-popup-checkout';

class MyApp extends React.Component {
render() {
return (
<div>
<EventbriteButton ebEventId='12555555'>Checkout</EventbriteButton>
</div>
);
}
}
```
### Required Props
```
ebEventId: <string>
```
import useEventbrite from 'react-eventbrite-popup-checkout';

### Optional Props
```
className: <string>
ebScriptPath: <string>
isModal: <boolean>
onOrderComplete: <function>
onClick: <function>
component: <node>
componentProps: <shape>
const App = () => {
const handleOrderCompleted = React.useCallback(() => {
console.log('Order was completed successfully');
}, []);
const modalButtonCheckout = useEventbrite({
eventId: 'YOUR-EB-EVENT-ID',
modal: true,
onOrderComplete: handleOrderCompleted,
});

return (
<div id="my-app">
{/* guard for null - resolves when Eventbrite loads */}
{modalButtonCheckout && (
<button id={modalButtonCheckout.id} type="button">
Modal Checkout
</button>
)}
</div>
)
};
```

#### `onClick`
Pass an optional `onClick` function to process the click event before the Eventbrite widget gets fired (e.g., for analytics).
### Embedded iFrame Example
![plot](./images/iframe.gif)

Embed an iFrame checkout.

#### `component`
Specify what component to use (e.g., a custom `<Button />`). Defaults to plain HTML button. Note: if using a custom component, it must accept an `id` prop.
```jsx
import React from 'react';
import useEventbrite from 'react-eventbrite-popup-checkout';

const App = () => {
const handleOrderCompleted = React.useCallback(() => {
console.log('Order was completed successfully');
}, []);
const iframeCheckout = useEventbrite({
eventId: 'YOUR-EB-EVENT-ID',
modal: false,
onOrderComplete: handleOrderCompleted,
iFrameHeight: 500, // optional
iFrameAutoAdapt: 100, // optional - The widget's viewport percentage (between 75-100)
});

return (
<div id="my-app">
{/* guard for null - resolves when Eventbrite loads */}
{iframeCheckout && (
<div id={iframeCheckout.id} />
)}
</div>
)
};
```

#### `componentProps`
Props to pass to your custom component.
### Auto Apply Promo Code
You can pass `promoCode` to the `useEventbrite` hook to automatically apply a promo code during checkout.
Binary file added images/iframe.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/modal.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 14 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-eventbrite-popup-checkout",
"version": "1.0.5",
"description": "A React component for the Eventbrite checkout widget",
"version": "2.0.0",
"description": "A React component for the Eventbrite checkout widgets",
"main": "dist/main.js",
"repository": {
"type": "git",
Expand All @@ -22,20 +22,21 @@
"prepublish": "npx webpack --config webpack.config.js"
},
"peerDependencies": {
"react": "^16.0.0"
"react": ">= 16.8.0",
"react-dom": ">= 16.8.0"
},
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.6",
"babel-plugin-transform-class-properties": "^6.24.1",
"react": "^16.8.6",
"webpack": "^4.33.0",
"webpack-cli": "^3.3.4"
"@babel/core": "^7.19.0",
"@babel/preset-env": "^7.19.0",
"@babel/preset-react": "^7.18.6",
"babel-loader": "^8.2.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
},
"dependencies": {
"prop-types": "^15.7.2",
"uuid": "^3.4.0"
"prop-types": "^15.8.1",
"uuid": "^9.0.0"
}
}
118 changes: 0 additions & 118 deletions src/index.jsx

This file was deleted.

89 changes: 89 additions & 0 deletions src/useEventbrite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React from 'react';
import { v4 as uuid } from 'uuid';

const TAG_ID = `EB_SCRIPT_${uuid()}`;
const SCRIPT_URL = 'https://www.eventbrite.com/static/widgets/eb_widgets.js';

const useEventbrite = ({
eventId,
modal,
onOrderComplete,
iFrameHeight,
iFrameAutoAdapt,
promoCode,
}) => {
const id = `EB_${uuid()}`;
const [isLoaded, setLoaded] = React.useState(false);
const onLoad = React.useCallback(() => setLoaded(true), [setLoaded]);
const onErr = React.useCallback(e => {
console.error(`Failed to load Eventbrite script from ${scriptUrl}`);
console.error(e);

setLoaded(false);
}, [setLoaded]);

React.useEffect(() => {
if (window?.EBWidgets) {
setLoaded(true);
return;
}

const existing = document.getElementById(TAG_ID);

if (existing) {
existing.remove();
}

const script = document.createElement('script');
script.id = TAG_ID;
script.async = true;
script.src = SCRIPT_URL;
script.addEventListener('load', onLoad);
script.addEventListener('error', onErr);
script.addEventListener('abort', onErr);
document.head.appendChild(script);

return () => {
script.removeEventListener('load', onLoad);
script.removeEventListener('error', onErr);
script.removeEventListener('abort', onErr);
script.remove();
setLoaded(false);
};
}, [
setLoaded,
onLoad,
onErr,
]);

React.useEffect(() => {
if (!isLoaded) {
return;
}

const config = {
widgetType: 'checkout',
eventId,
onOrderComplete,
modal,
};

if (modal) {
config.modalTriggerElementId = id;
} else {
config.iFrameContainerId = id;
config.iFrameContainerHeight = iFrameHeight || 425;
config.iFrameAutoAdapt = iFrameAutoAdapt || 100;
}

if (promoCode) {
config.promoCode = promoCode;
}

window.EBWidgets.createWidget(config);
}, [isLoaded]);

return isLoaded ? { id } : null;
};

export default useEventbrite;
Loading

0 comments on commit 7af1b78

Please sign in to comment.