-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unlock Membership Tiers for Kickback #220
base: dev
Are you sure you want to change the base?
Changes from 3 commits
536ec70
292b7b0
682d830
a60f5f7
eda6bd5
595316b
c1f1908
a1166a7
ca62713
2170033
dbc56b9
f53d6be
393de51
0c05ba2
b76de81
54149f1
2eee09a
c0eaed3
173d5c3
c62e1e5
e5f3a30
ee72b5d
7e1fa4b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,70 @@ | |
Learn how to configure a non-root public URL by running `npm run build`. | ||
--> | ||
<title>Kickback</title> | ||
|
||
<!-- | ||
Unlock snippet scripts modified from | ||
https://github.com/unlock-protocol/react-example/blob/master/public/index.html | ||
--> | ||
<script> (function (d, s) { | ||
// if production, set network to Mainnet, else set to Rinkeby for paywall | ||
const environment = "%NODE_ENV%"; | ||
const networkId = environment === "production" ? 1 : 4; | ||
|
||
// if Rinkeby set, use Rinkeby paywall, else use Mainnet | ||
let testnetUrl = networkId === 4 ? 'staging-' : ''; | ||
let js = d.createElement(s); | ||
let sc = d.getElementsByTagName(s)[0]; | ||
js.src = `https://${testnetUrl}paywall.unlock-protocol.com/static/unlock.1.0.min.js`; | ||
sc.parentNode.insertBefore(js, sc); | ||
}(document, "script")); | ||
</script> | ||
|
||
<script> | ||
// if production, set network to Mainnet, else set to Rinkeby for paywall | ||
const environment = "%NODE_ENV%"; | ||
const networkId = environment === "production" ? 1 : 4; | ||
|
||
// Kovan is included, but currently only Rinkeby and Mainnet is unsupported with paywall | ||
// tokens entered first to last are displayed right to left in paywall modal | ||
// NOTE: Replace Mainnet keys with keys Kickback owns | ||
const locks = { | ||
1: { | ||
"enter-key-address-here": { | ||
name: "Kickback Gold Supporter" | ||
}, | ||
"enter-key-address-here": { | ||
name: "Kickback Bronze Supporter" | ||
} | ||
}, | ||
4: { | ||
"0xb452A1BfE64036718aCeFC8B5F718E0c9d233cB8": { | ||
name: "Kickback Gold Supporter" | ||
}, | ||
"0x70456ebD53E19eaE05932C482FeF1b24251ABb18": { | ||
name: "Kickback Bronze Supporter" | ||
} | ||
}, | ||
42: { | ||
"0x2eD8aD6AA973BEA5D60FA70Eead10F113fb4Dc99": { | ||
name: "Kickback Gold Supporter" | ||
}, | ||
"0xe61607898287220586abE01b536714d8429f675C": { | ||
name: "Kickback Bronze Supporter" | ||
} | ||
} | ||
}[networkId] | ||
|
||
// unlock config must use var | ||
var unlockProtocolConfig = { | ||
locks, | ||
icon: 'https://unlock-protocol.com/static/images/svg/unlock-word-mark.svg', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be changed to a Kickback logo ;) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea. Changed in a60f5f7. It looks like only public urls are compatible with Unlock, so I used https://kickback.events/card.png. |
||
callToAction: { | ||
default: | ||
'Select a membership to access page', | ||
}, | ||
} | ||
</script> | ||
</head> | ||
|
||
<body> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
import React, { Component } from 'react' | ||
import React, { useState, useEffect } from 'react' | ||
import styled from 'react-emotion' | ||
import { withRouter } from 'react-router-dom' | ||
import { useHistory } from 'react-router-dom' | ||
import DefaultTextInput from '../components/Forms/TextInput' | ||
import Label from '../components/Forms/Label' | ||
import DefaultButton from '../components/Forms/Button' | ||
import Loader from '../components/Loader' | ||
|
||
import PartyForm from '../components/SingleEvent/Admin/PartyForm' | ||
import { CREATE_PENDING_PARTY } from '../graphql/mutations' | ||
|
@@ -13,42 +15,117 @@ const CreateContainer = styled('div')` | |
flex-direction: column; | ||
` | ||
|
||
const LockedContainer = styled('div')` | ||
display: flex; | ||
flex-direction: column; | ||
` | ||
|
||
const TextInput = styled(DefaultTextInput)` | ||
margin-bottom: 20px; | ||
` | ||
|
||
class Create extends Component { | ||
state = { | ||
password: '' | ||
} | ||
const Button = styled(DefaultButton)` | ||
margin: 60px auto 0px auto; | ||
` | ||
|
||
render() { | ||
const { password } = this.state | ||
|
||
return ( | ||
<CreateContainer> | ||
<PartyForm | ||
onCompleted={this._onCreated} | ||
mutation={CREATE_PENDING_PARTY} | ||
variables={{ password }} | ||
type="create" | ||
> | ||
<Label>SECRET PASSWORD:</Label> | ||
<TextInput | ||
value={password} | ||
onChangeText={val => this.setState({ password: val })} | ||
type="password" | ||
/> | ||
</PartyForm> | ||
</CreateContainer> | ||
) | ||
} | ||
const UnlockCredit = styled('div')` | ||
margin: 40px auto 140px auto; | ||
font-size: 14px; | ||
` | ||
|
||
_onCreated = ({ id }, deposit, limitOfParticipants, coolingPeriod) => { | ||
this.props.history.push( | ||
const UnlockedLogo = styled('a')` | ||
color: #ff6771; | ||
font-weight: 800; | ||
` | ||
|
||
function Create() { | ||
const [password, setPassword] = useState('') | ||
const [locked, setLocked] = useState('pending') | ||
let history = useHistory() | ||
|
||
const _onCreated = ({ id }, deposit, limitOfParticipants, coolingPeriod) => { | ||
history.push( | ||
`/deploy?id=${id}&deposit=${deposit}&limitOfParticipants=${limitOfParticipants}&coolingPeriod=${coolingPeriod}` | ||
) | ||
} | ||
|
||
const unlockHandler = e => { | ||
setLocked(e.detail) | ||
/* | ||
Status can either be 'unlocked' or 'locked'... | ||
If state is 'unlocked': implement code here which will be triggered when | ||
the current visitor has a valid lock key | ||
If state is 'locked': implement code here which will be | ||
triggered when the current visitor does not have a valid lock key | ||
*/ | ||
} | ||
|
||
const checkout = () => { | ||
window.ethereum.enable() | ||
window.unlockProtocol && window.unlockProtocol.loadCheckoutModal() | ||
} | ||
|
||
useEffect(() => { | ||
window.addEventListener('unlockProtocol', unlockHandler) | ||
}, []) | ||
|
||
useEffect(() => { | ||
return () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this not be bundled with the other useEffect's return statement? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right. dbc56b9 |
||
window.removeEventListener('unlockProtocol', unlockHandler) | ||
} | ||
}, []) | ||
|
||
return ( | ||
<CreateContainer> | ||
{ | ||
{ | ||
unlocked: ( | ||
<PartyForm | ||
onCompleted={_onCreated} | ||
mutation={CREATE_PENDING_PARTY} | ||
variables={{ password }} | ||
type="create" | ||
> | ||
<Label>SECRET PASSWORD:</Label> | ||
<TextInput | ||
value={password} | ||
onChangeText={val => setPassword(val)} | ||
type="password" | ||
/> | ||
</PartyForm> | ||
), | ||
locked: ( | ||
<LockedContainer> | ||
<h1>Deploy your Kickback contract with us</h1> | ||
<p> | ||
Kickback offers paid benefits for event organizers publishing | ||
their own kickback contract. Membership comes in two tiers. | ||
</p> | ||
<Button | ||
data-testid="unlock-button" | ||
analyticsId="Unlock Membership" | ||
onClick={checkout} | ||
> | ||
Unlock Membership | ||
</Button> | ||
<UnlockCredit> | ||
Powered by{' '} | ||
<UnlockedLogo href="https://unlock-protocol.com/"> | ||
Unlock | ||
</UnlockedLogo> | ||
</UnlockCredit> | ||
</LockedContainer> | ||
), | ||
pending: ( | ||
<div> | ||
<Loader /> | ||
</div> | ||
), | ||
default: <div>Please enable Javascript</div> | ||
}[locked || locked['default']] | ||
} | ||
</CreateContainer> | ||
) | ||
} | ||
|
||
export default withRouter(Create) | ||
export default Create |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any way to abstract these into the main
src
directory. It's not very visible having the locks in the index.html.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. I looked through Unlock's documentation, and looked at the React example in Unlock's Github. They had this config in
public/index.html
. I also don't think there's a way to import a file fromsrc
topublic
, else I'd be usingenv.json
instead of passing environment variables throughpackage.json
. Unless @julien51 has any suggestions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually... I think this just adds a variable to
window
. Let me test somethingThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Locks moved to
config/env.json
insrc
. Readme updated as well with instructions. 393de51