Added confirmation popup to refresh API key. Refreshing API key now requires a user to relink their Twitch account.

This commit is contained in:
Phil 2022-09-16 16:07:11 +01:00
parent a8afe80153
commit de0996acef
3 changed files with 59 additions and 15 deletions

View File

@ -71,6 +71,7 @@ export type PrivateUser = {
twitchName: string
controlToken: string
botEnabled?: boolean
needsRelinking?: boolean
}
}

View File

@ -2,9 +2,11 @@ import { RefreshIcon } from '@heroicons/react/outline'
import { PrivateUser, User } from 'common/user'
import { cleanDisplayName, cleanUsername } from 'common/util/clean-username'
import { formatMoney } from 'common/util/format'
import Link from 'next/link'
import React, { useState } from 'react'
import Textarea from 'react-expanding-textarea'
import { AddFundsButton } from 'web/components/add-funds-button'
import { ConfirmationButton } from 'web/components/confirmation-button'
import { Col } from 'web/components/layout/col'
import { Row } from 'web/components/layout/row'
import { Page } from 'web/components/page'
@ -16,7 +18,11 @@ import { generateNewApiKey } from 'web/lib/api/api-key'
import { changeUserInfo } from 'web/lib/firebase/api'
import { redirectIfLoggedOut } from 'web/lib/firebase/server-auth'
import { uploadImage } from 'web/lib/firebase/storage'
import { getUserAndPrivateUser, updateUser } from 'web/lib/firebase/users'
import {
getUserAndPrivateUser,
updatePrivateUser,
updateUser,
} from 'web/lib/firebase/users'
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
return { props: { auth: await getUserAndPrivateUser(creds.uid) } }
@ -91,10 +97,15 @@ export default function ProfilePage(props: {
}
}
const updateApiKey = async (e: React.MouseEvent) => {
const updateApiKey = async (e?: React.MouseEvent) => {
const newApiKey = await generateNewApiKey(user.id)
setApiKey(newApiKey ?? '')
e.preventDefault()
e?.preventDefault()
if (!privateUser.twitchInfo) return
await updatePrivateUser(privateUser.id, {
twitchInfo: { ...privateUser.twitchInfo, needsRelinking: true },
})
}
const fileHandler = async (event: any) => {
@ -227,12 +238,36 @@ export default function ProfilePage(props: {
value={apiKey}
readOnly
/>
<button
className="btn btn-primary btn-square p-2"
onClick={updateApiKey}
<ConfirmationButton
openModalBtn={{
className: 'btn btn-primary btn-square p-2',
label: '',
icon: <RefreshIcon />,
}}
submitBtn={{
label: 'Update key',
className: 'btn-primary',
}}
onSubmitWithSuccess={async () => {
updateApiKey()
return true
}}
>
<RefreshIcon />
</button>
<Col>
<Title text={'Are you sure?'} />
<div>
Updating your API key will break any existing applications
connected to your account, <b>including the Twitch bot</b>.
You will need to go to the{' '}
<Link href="/twitch">
<a className="underline focus:outline-none">
Twitch page
</a>
</Link>{' '}
to relink your account.
</div>
</Col>
</ConfirmationButton>
</div>
</div>
</Col>

View File

@ -40,6 +40,9 @@ function ButtonGetStarted(props: {
const { user, privateUser, buttonClass, spinnerClass } = props
const [isLoading, setLoading] = useState(false)
const needsRelink =
privateUser?.twitchInfo?.twitchName &&
privateUser?.twitchInfo?.needsRelinking
const callback =
user && privateUser
@ -77,11 +80,11 @@ function ButtonGetStarted(props: {
) : (
<Button
size="xl"
color="gradient"
color={needsRelink ? 'red' : 'gradient'}
className={clsx('my-4 self-center !px-16', buttonClass)}
onClick={getStarted}
>
Start playing
{needsRelink ? 'API key updated: relink Twitch' : 'Start playing'}
</Button>
)
}
@ -92,7 +95,8 @@ function TwitchPlaysManifoldMarkets(props: {
}) {
const { user, privateUser } = props
const twitchUser = privateUser?.twitchInfo?.twitchName
const twitchInfo = privateUser?.twitchInfo
const twitchUser = twitchInfo?.twitchName
return (
<div>
@ -120,7 +124,7 @@ function TwitchPlaysManifoldMarkets(props: {
receive their profit.
</div>
Start playing now by logging in with Google and typing commands in chat!
{twitchUser ? (
{twitchUser && !twitchInfo.needsRelinking ? (
<Button
size="xl"
color="green"
@ -280,7 +284,7 @@ function BotConnectButton(props: {
<Button
color="red"
onClick={updateBotConnected(false)}
className={clsx(loading && '!btn-disabled', '')}
className={clsx(loading && '!btn-disabled', 'border-none')}
>
{loading ? (
<LoadingIndicator spinnerClassName="!h-5 !w-5 border-white !border-2" />
@ -292,7 +296,7 @@ function BotConnectButton(props: {
<Button
color="green"
onClick={updateBotConnected(true)}
className={clsx(loading && '!btn-disabled', '')}
className={clsx(loading && '!btn-disabled', 'border-none')}
>
{loading ? (
<LoadingIndicator spinnerClassName="!h-5 !w-5 border-white !border-2" />
@ -310,7 +314,11 @@ function SetUpBot(props: {
privateUser?: PrivateUser | null
}) {
const { user, privateUser } = props
const twitchLinked = privateUser?.twitchInfo?.twitchName
const twitchLinked =
privateUser?.twitchInfo?.twitchName &&
!privateUser?.twitchInfo?.needsRelinking
? true
: undefined
const toastTheme = {
className: '!bg-primary !text-white',
icon: <LinkIcon className="mr-2 h-6 w-6" aria-hidden="true" />,