donetick-fe/src/views/Settings/APITokenSettings.jsx
2024-12-11 20:46:33 -05:00

165 lines
4.6 KiB
JavaScript

import { CopyAll } from '@mui/icons-material'
import {
Box,
Button,
Card,
Chip,
Divider,
IconButton,
Input,
Typography,
} from '@mui/joy'
import moment from 'moment'
import { useContext, useEffect, useState } from 'react'
import { UserContext } from '../../contexts/UserContext'
import {
CreateLongLiveToken,
DeleteLongLiveToken,
GetLongLiveTokens,
} from '../../utils/Fetcher'
import { isPlusAccount } from '../../utils/Helpers'
import TextModal from '../Modals/Inputs/TextModal'
const APITokenSettings = () => {
const [tokens, setTokens] = useState([])
const [isGetTokenNameModalOpen, setIsGetTokenNameModalOpen] = useState(false)
const [showTokenId, setShowTokenId] = useState(null)
const { userProfile, setUserProfile } = useContext(UserContext)
useEffect(() => {
GetLongLiveTokens().then(resp => {
resp.json().then(data => {
setTokens(data.res)
})
})
}, [])
const handleSaveToken = name => {
CreateLongLiveToken(name).then(resp => {
if (resp.ok) {
resp.json().then(data => {
// add the token to the list:
console.log(data)
const newTokens = [...tokens]
newTokens.push(data.res)
setTokens(newTokens)
})
}
})
}
return (
<div className='grid gap-4 py-4' id='apitokens'>
<Typography level='h3'>Access Token</Typography>
<Divider />
<Typography level='body-sm'>
Create token to use with the API to update things that trigger task or
chores
</Typography>
{!isPlusAccount(userProfile) && (
<Chip variant='soft' color='warning'>
Not available in Basic Plan
</Chip>
)}
{tokens.map(token => (
<Card key={token.token} className='p-4'>
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
<Box>
<Typography level='body-md'>{token.name}</Typography>
<Typography level='body-xs'>
{moment(token.createdAt).fromNow()}(
{moment(token.createdAt).format('lll')})
</Typography>
</Box>
<Box>
<Button
variant='outlined'
color='primary'
sx={{ mr: 1 }}
onClick={() => {
if (showTokenId === token.id) {
setShowTokenId(null)
return
}
setShowTokenId(token.id)
}}
>
{showTokenId === token?.id ? 'Hide' : 'Show'} Token
</Button>
<Button
variant='outlined'
color='danger'
onClick={() => {
const confirmed = confirm(
`Are you sure you want to remove ${token.name} ?`,
)
if (confirmed) {
DeleteLongLiveToken(token.id).then(resp => {
if (resp.ok) {
alert('Token removed')
const newTokens = tokens.filter(t => t.id !== token.id)
setTokens(newTokens)
}
})
}
}}
>
Remove
</Button>
</Box>
</Box>
{showTokenId === token?.id && (
<Box>
<Input
value={token.token}
sx={{ width: '100%', mt: 2 }}
readOnly
endDecorator={
<IconButton
variant='outlined'
color='primary'
onClick={() => {
navigator.clipboard.writeText(token.token)
alert('Token copied to clipboard')
setShowTokenId(null)
}}
>
<CopyAll />
</IconButton>
}
/>
</Box>
)}
</Card>
))}
<Button
variant='soft'
color='primary'
disabled={!isPlusAccount(userProfile)}
sx={{
width: '210px',
mb: 1,
}}
onClick={() => {
setIsGetTokenNameModalOpen(true)
}}
>
Generate New Token
</Button>
<TextModal
isOpen={isGetTokenNameModalOpen}
title='Give a name for your new token, something to remember it by.'
onClose={() => {
setIsGetTokenNameModalOpen(false)
}}
okText={'Generate Token'}
onSave={handleSaveToken}
/>
</div>
)
}
export default APITokenSettings