mirror of
https://github.com/fergalmoran/onearmy-community-platform.git
synced 2026-01-06 17:03:58 +00:00
feat: move patreon to profile settings
This commit is contained in:
4
packages/components/assets/icons/patreon.svg
Normal file
4
packages/components/assets/icons/patreon.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="40" height="43" viewBox="0 0 40 43" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M31.6764 30.6581L33.9381 29.3784L36.3686 29.3275L38.9204 32.0306L38.7281 35.9953L35.9078 39.721L33.4294 42.2894L28.3488 40.8113L24.3834 38.5909L22.8479 35.5475L24.1185 32.34L27.0444 31.2151L29.7025 32.1216L30.3762 32.6118L31.0884 31.5063L31.6764 30.6581Z" fill="#D61F30"/>
|
||||
<path d="M39.1742 13.1175C39.1668 7.7547 34.9901 3.35948 30.0897 1.77359C24.0044 -0.195741 15.9785 0.0897038 10.1677 2.83137C3.12497 6.15481 0.912581 13.4348 0.830137 20.6954C0.76247 26.6648 1.35825 42.3872 10.2265 42.4992C16.8158 42.5828 17.797 34.0922 20.8459 30.003C23.0151 27.0938 25.8081 26.272 29.2462 25.4211C35.1554 23.9585 39.1828 19.295 39.1742 13.1175Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 765 B |
@@ -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,
|
||||
|
||||
@@ -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'
|
||||
@@ -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} />,
|
||||
|
||||
@@ -44,6 +44,7 @@ export type availableGlyphs =
|
||||
| 'menu'
|
||||
| 'more-vert'
|
||||
| 'notifications'
|
||||
| 'patreon'
|
||||
| 'pdf'
|
||||
| 'plastic'
|
||||
| 'profile'
|
||||
|
||||
@@ -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={{
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
@@ -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()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -129,7 +112,6 @@ describe('PatreonIntegration', () => {
|
||||
expect(mockRemovePatreonConnection).toHaveBeenCalledWith(
|
||||
mockUser.userName,
|
||||
)
|
||||
expect(screen.getByText(CONNECT_BUTTON_TEXT)).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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 = () => {
|
||||
@@ -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={{
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
@@ -222,7 +221,6 @@ export const UserProfile = () => {
|
||||
/>
|
||||
</FlexSectionContainer>
|
||||
)}
|
||||
<PatreonIntegration user={user} />
|
||||
</form>
|
||||
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user