Skip to content

Commit

Permalink
feat: move patreon to profile settings
Browse files Browse the repository at this point in the history
  • Loading branch information
benfurber committed Jul 25, 2024
1 parent feffc0e commit de444bc
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 137 deletions.
4 changes: 4 additions & 0 deletions packages/components/assets/icons/patreon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/components/src/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export const glyphs: IGlyphs = {
menu: <MdMenu />,
'more-vert': <MdMoreVert />,
notifications: <MdNotifications />,
patreon: iconMap.patreon,
pdf: <GoFilePdf />,
plastic: iconMap.plastic,
profile: iconMap.profile,
Expand Down
2 changes: 2 additions & 0 deletions packages/components/src/Icon/svgs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import websiteSVG from '../../assets/icons/icon-website.svg'
import impactSVG from '../../assets/icons/impact.svg'
import machineSVG from '../../assets/icons/machine.svg'
import mapSVG from '../../assets/icons/map.svg'
import patreonSVG from '../../assets/icons/patreon.svg'
import plasticSVG from '../../assets/icons/plastic.svg'
import profileSVG from '../../assets/icons/profile.svg'
import revenueSVG from '../../assets/icons/revenue.svg'
Expand Down Expand Up @@ -63,6 +64,7 @@ export const iconMap = {
loading: <ImageIcon src={loadingSVG} data-cy="icon-loading" />,
machine: <ImageIcon src={machineSVG} />,
map: <ImageIcon src={mapSVG} />,
patreon: <ImageIcon src={patreonSVG} />,
plastic: <ImageIcon src={plasticSVG} />,
profile: <ImageIcon src={profileSVG} />,
revenue: <ImageIcon src={revenueSVG} />,
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/Icon/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type availableGlyphs =
| 'menu'
| 'more-vert'
| 'notifications'
| 'patreon'
| 'pdf'
| 'plastic'
| 'profile'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import React from 'react'
import { observer } from 'mobx-react'
import { ExternalLink } from 'oa-components'
import { useCommonStores } from 'src/common/hooks/useCommonStores'
import { DISCORD_INVITE_URL } from 'src/constants'
import { fields, headings } from 'src/pages/UserSettings/labels'
import { Flex, Heading, Text } from 'theme-ui'

import { ChangeEmailForm } from './ChangeEmail.form'
import { ChangePasswordForm } from './ChangePassword.form'
import { PatreonIntegration } from './PatreonIntegration'

export const AccountSettingsSection = observer(() => {
const { description, title } = fields.deleteAccount

const { userStore } = useCommonStores().stores

return (
<Flex
sx={{
Expand All @@ -25,8 +29,11 @@ export const AccountSettingsSection = observer(() => {
Here you can manage the core settings of your account.
</Text>
</Flex>

<PatreonIntegration user={userStore.activeUser} />
<ChangeEmailForm />
<ChangePasswordForm />

<Text variant="body">
{title}
<ExternalLink
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
import {
CONNECT_BUTTON_TEXT,
HEADING,
ONE_ARMY_PATREON_URL,
PatreonIntegration,
REMOVE_BUTTON_TEXT,
SUCCESS_MESSAGE,
Expand Down Expand Up @@ -89,23 +88,7 @@ describe('PatreonIntegration', () => {

it('renders correctly', () => {
expect(screen.getByText(HEADING)).toBeInTheDocument()
})

it('displays instructions on how to connect and connect button', () => {
expect(screen.getByText(CONNECT_BUTTON_TEXT)).toBeInTheDocument()
expect(
screen.getByText((t) =>
t.includes('Connect your Patreon account by clicking below'),
),
).toBeInTheDocument()
})

it('links to one army patreon page', () => {
expect(
screen.getByRole(
(t, e) => e?.getAttribute('href') === ONE_ARMY_PATREON_URL,
),
).toBeInTheDocument()
})
})

Expand All @@ -129,7 +112,6 @@ describe('PatreonIntegration', () => {
expect(mockRemovePatreonConnection).toHaveBeenCalledWith(
mockUser.userName,
)
expect(screen.getByText(CONNECT_BUTTON_TEXT)).toBeInTheDocument()
})
})

Expand All @@ -150,15 +132,5 @@ describe('PatreonIntegration', () => {
screen.queryByText(WRONG_PATREON_TIER_TITLE),
).not.toBeInTheDocument()
})

it('displays become a supporter message', () => {
expect(
screen.getByText((t) =>
t.includes(
'It looks like you are not an active supporter of this project.',
),
),
).toBeInTheDocument()
})
})
})
174 changes: 67 additions & 107 deletions src/pages/UserSettings/content/formSections/PatreonIntegration.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,26 @@
import * as React from 'react'
import { Button } from 'oa-components'
import { Button, Icon } from 'oa-components'
import { useCommonStores } from 'src/common/hooks/useCommonStores'
import { PATREON_CLIENT_ID } from 'src/config/config'
import { Box, Flex, Heading, Image, Text } from 'theme-ui'
import { Flex, Heading, Image, Text } from 'theme-ui'

import { FlexSectionContainer } from './elements'

import type { IUserPP } from 'src/models'

export const HEADING = '❤️ Become a Supporter'
const SUBHEADING =
'Support us on Patreon to get a badge here on the platform and special insights and voting rights on decisions.'
const BETA_DISCLAIMER =
'This feature is still in beta and we will continue to roll out more features for supporters.'
export const HEADING = 'Patreon'
export const SUCCESS_MESSAGE = 'Successfully linked Patreon account!'
export const SUPPORTER_MESSAGE =
'Thanks for supporting us! :) Update your data if you changed your Patreon tiers or remove the connection below.'

export const CONNECT_BUTTON_TEXT = 'Connect To Patreon'
export const UPDATE_BUTTON_TEXT = 'Update Patreon Data'
export const REMOVE_BUTTON_TEXT = 'Remove Connection'
export const CONNECT_BUTTON_TEXT = 'Connect'
export const UPDATE_BUTTON_TEXT = 'Update'
export const REMOVE_BUTTON_TEXT = 'Disconnect'

export const ONE_ARMY_PATREON_URL = 'https://www.patreon.com/one_army'

export const PatreonIntegration = (props: { user: IUserPP }) => {
export const PatreonIntegration = ({ user }) => {
const { userStore } = useCommonStores().stores
const [user, setUser] = React.useState<IUserPP>(props.user)

const removePatreonConnection = () => {
if (!user) {
return
}
userStore.removePatreonConnection(user.userName)
// Perform an optimistic update to avoid waiting for database calls to return.
setUser({
...user,
badges: {
...user.badges,
supporter: false,
},
patreon: undefined,
})
}

const patreonRedirect = () => {
Expand All @@ -60,19 +40,24 @@ export const PatreonIntegration = (props: { user: IUserPP }) => {
}

return (
<FlexSectionContainer>
<Heading as="h2" variant="small">
{HEADING}
</Heading>
<Text mt={4}>{SUBHEADING}</Text>
<Text mt={4}>{BETA_DISCLAIMER}</Text>
{user.patreon ? (
<Box mt={4} mb={4}>
<Flex
style={{
alignItems: 'center',
}}
>
<Flex
sx={{
alignItems: ['flex-start', 'flex-start', 'center'],
backgroundColor: 'offwhite',
borderRadius: 3,
flexDirection: ['column', 'column', 'row'],
justifyContent: 'space-between',
padding: 4,
gap: [2, 4],
}}
>
<Icon glyph="patreon" size={45} />
<Flex sx={{ flexDirection: 'column', flex: 1, gap: [2] }}>
<Heading as="h2" variant="small">
{HEADING}
</Heading>
{user.patreon ? (
<>
<Image
src={user.patreon.attributes.thumb_url}
sx={{
Expand All @@ -83,89 +68,64 @@ export const PatreonIntegration = (props: { user: IUserPP }) => {
}}
/>
<Text>{SUCCESS_MESSAGE}</Text>
</Flex>
{user.badges?.supporter && user.patreon.membership ? (
<Flex sx={{ flexDirection: 'column' }}>
<Text mt={4}>{SUPPORTER_MESSAGE}</Text>
{user.patreon.membership.tiers.map(({ id, attributes }) => (
<Flex
key={id}
style={{
alignItems: 'center',
}}
mt={4}
>
<div
{user.badges?.supporter && user.patreon.membership && (
<Flex sx={{ flexDirection: 'column' }}>
<Text mt={4}>{SUPPORTER_MESSAGE}</Text>
{user.patreon.membership.tiers.map(({ id, attributes }) => (
<Flex
key={id}
style={{
width: '40px',
height: '40px',
overflow: 'hidden',
marginRight: '10px',
alignItems: 'center',
}}
mt={4}
>
<Image
src={attributes.image_url}
sx={{
borderRadius: '50%',
width: 'auto',
<div
style={{
width: '40px',
height: '40px',
objectFit: 'cover',
objectPosition: 'center',
overflow: 'hidden',
marginRight: '10px',
}}
/>
</div>
<Text>{attributes.title}</Text>
</Flex>
))}
</Flex>
) : (
<Flex sx={{ flexDirection: 'column' }}>
<Text mt={4}>
Thanks for connecting your account! It looks like you are not an
active supporter of this project. You can support us{' '}
<a href={ONE_ARMY_PATREON_URL} target="_blank" rel="noreferrer">
here
</a>
. If you become a supporter in the future, click the button
below to update your data.
</Text>
</Flex>
)}
</Box>
) : (
<Text mt={4} mb={4} sx={{ display: 'block', whiteSpace: 'pre-line' }}>
How it works: <br />
1.{' '}
<a href={ONE_ARMY_PATREON_URL} target="_blank" rel="noreferrer">
Support us
</a>{' '}
on Patreon <br />
2. Connect your Patreon account by clicking below <br />
3. You are now part of the special supporters club!
</Text>
)}
<Flex>
<Button
type="button"
onClick={patreonRedirect}
mb={3}
sx={{ justifyContent: 'center', mr: 3 }}
variant="outline"
>
>
<Image
src={attributes.image_url}
sx={{
borderRadius: '50%',
width: 'auto',
height: '40px',
objectFit: 'cover',
objectPosition: 'center',
}}
/>
</div>
<Text>{attributes.title}</Text>
</Flex>
))}
</Flex>
)}
</>
) : (
<Text variant="quiet">
As a supporter you get a badge on the platform, special insights and
voting rights on decisions.
</Text>
)}
</Flex>

<Flex sx={{ flexDirection: 'column', gap: 2 }}>
<Button type="button" onClick={patreonRedirect} variant="primary">
{user.patreon ? UPDATE_BUTTON_TEXT : CONNECT_BUTTON_TEXT}
</Button>
{user.patreon && (
<Button
type="button"
onClick={removePatreonConnection}
mb={3}
sx={{ justifyContent: 'center' }}
variant="outline"
>
{REMOVE_BUTTON_TEXT}
</Button>
)}
</Flex>
</FlexSectionContainer>
</Flex>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { FlexSectionContainer } from './elements'
import { EmailNotificationsSection } from './EmailNotifications.section'
import { ExpertiseSection } from './Expertise.section'
import { FocusSection } from './Focus.section'
import { PatreonIntegration } from './PatreonIntegration'
import { PublicContactSection } from './PublicContact.section'
import { SettingsFormNotifications } from './SettingsFormNotifications'
import { UserInfosSection } from './UserInfos.section'
Expand Down Expand Up @@ -222,7 +221,6 @@ export const UserProfile = () => {
/>
</FlexSectionContainer>
)}
<PatreonIntegration user={user} />
</form>

<Button
Expand Down

0 comments on commit de444bc

Please sign in to comment.