add labels testing page

This commit is contained in:
Hongbo Wu
2022-02-22 18:33:39 +08:00
parent d33b213092
commit 4d770399bd
4 changed files with 253 additions and 0 deletions

View File

@ -0,0 +1,42 @@
import { gql } from 'graphql-request'
import { gqlFetcher } from '../networkHelpers'
export async function createLabelMutation(
name: string,
color: string,
description?: string
): Promise<any | undefined> {
const mutation = gql`
mutation {
createLabel(
input: {
color: "${color}"
name: "${name}"
description: "${description}"
}
) {
... on CreateLabelSuccess {
label {
id
name
color
description
createdAt
}
}
... on CreateLabelError {
errorCodes
}
}
}
`
try {
const data = await gqlFetcher(mutation)
console.log('created label', data)
return data
} catch (error) {
console.log('createLabelMutation error', error)
return undefined
}
}

View File

@ -0,0 +1,34 @@
import { gql } from 'graphql-request'
import { gqlFetcher } from '../networkHelpers'
export async function deleteLabelMutation(
labelId: string
): Promise<any | undefined> {
const mutation = gql`
mutation {
deleteLabel(id: "${labelId}") {
... on DeleteLabelSuccess {
label {
id
name
color
description
createdAt
}
}
... on DeleteLabelError {
errorCodes
}
}
}
`
try {
const data = await gqlFetcher(mutation)
console.log('deleted label', data)
return data
} catch (error) {
console.log('deleteLabelMutation error', error)
return undefined
}
}

View File

@ -0,0 +1,70 @@
import { gql } from 'graphql-request'
import useSWR from 'swr'
import { publicGqlFetcher } from '../networkHelpers'
type LabelsQueryResponse = {
isValidating: boolean
labels: Label[]
revalidate: () => void
}
type LabelsResponseData = {
labels?: LabelsData
}
type LabelsData = {
labels?: unknown
}
export type Label = {
id: string
name: string
color: string
description?: string
createdAt: Date
}
export function useGetLabelsQuery(): LabelsQueryResponse {
const query = gql`
query GetLabels {
labels {
... on LabelsSuccess {
labels {
id
name
color
description
createdAt
}
}
... on LabelsError {
errorCodes
}
}
}
`
const { data, mutate, error, isValidating } = useSWR(query, publicGqlFetcher)
try {
if (data) {
const result = data as LabelsResponseData
const labels = result.labels?.labels as Label[]
return {
isValidating,
labels,
revalidate: () => {
mutate()
},
}
}
} catch (error) {
console.log('error', error)
}
return {
isValidating: false,
labels: [],
// eslint-disable-next-line @typescript-eslint/no-empty-function
revalidate: () => {},
}
}

View File

@ -0,0 +1,107 @@
import { PrimaryLayout } from '../../components/templates/PrimaryLayout'
import { Button } from '../../components/elements/Button'
import { Box, VStack } from '../../components/elements/LayoutPrimitives'
import { toast, Toaster } from 'react-hot-toast'
import { useGetLabelsQuery } from '../../lib/networking/queries/useGetLabelsQuery'
import { createLabelMutation } from '../../lib/networking/mutations/createLabelMutation'
import { deleteLabelMutation } from '../../lib/networking/mutations/deleteLabelMutation'
import { useState } from 'react'
export default function LabelsPage(): JSX.Element {
const { labels, revalidate, isValidating } = useGetLabelsQuery()
const [name, setName] = useState('')
const [color, setColor] = useState('')
const [description, setDescription] = useState('')
async function createLabel(): Promise<void> {
const res = await createLabelMutation(name, color, description)
if (res) {
if (res.createLabel.errorCodes && res.createLabel.errorCodes.length > 0) {
toast.error(res.createLabel.errorCodes[0])
} else {
toast.success('Label created')
setName('')
setColor('')
setDescription('')
revalidate()
}
} else {
toast.error('Failed to create label')
}
}
async function deleteLabel(id: string): Promise<void> {
await deleteLabelMutation(id)
revalidate()
}
return (
<PrimaryLayout pageTestId="settings-labels-tag">
<Toaster />
<VStack css={{ mx: '42px' }}>
<h2>Create a new label</h2>
<form
onSubmit={async (e): Promise<void> => {
e.preventDefault()
await createLabel()
}}
>
<input
type="text"
name="name"
placeholder="Name"
required
value={name}
onChange={(event) => {
setName(event.target.value)
}}
/>
<input
type="text"
name="color"
placeholder="Color"
required
value={color}
onChange={(event) => {
setColor(event.target.value)
}}
/>
<input
type="text"
name="description"
placeholder="Description"
value={description}
onChange={(event) => {
setDescription(event.target.value)
}}
/>
<Button type="submit" disabled={isValidating}>
Create
</Button>
</form>
<h2>Labels</h2>
{labels &&
labels.map((label) => {
return (
<Box key={label.id}>
<form
onSubmit={async (e): Promise<void> => {
e.preventDefault()
await deleteLabel(label.id)
}}
>
<input type="text" value={label.name} disabled />
<input type="text" value={label.color} disabled />
<input type="text" value={label.description} disabled />
<Button type="submit" disabled={isValidating}>
Delete
</Button>
</form>
</Box>
)
})}
</VStack>
</PrimaryLayout>
)
}