Skip to content

Commit

Permalink
feat(campaign): add edit campaign page
Browse files Browse the repository at this point in the history
  • Loading branch information
robertu7 committed Jul 15, 2024
1 parent c5f2d9d commit 73b1d1f
Show file tree
Hide file tree
Showing 8 changed files with 610 additions and 7 deletions.
99 changes: 99 additions & 0 deletions src/components/Campaign/AddButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import * as React from 'react'
import { Button, message } from 'antd'
import gql from 'graphql-tag'
import { Mutation } from 'react-apollo'
import { withRouter, RouteComponentProps } from 'react-router-dom'

import ErrorMessage from '../../../components/ErrorMessage'
import { PATH } from '../../../constants'

const PUT_CAMPAIGN = gql`
mutation AddWritingChallenge($input: PutWritingChallengeInput!) {
putWritingChallenge(input: $input) {
id
shortHash
}
}
`

type Props = RouteComponentProps & { onSuccess: any }

type State = {
loading: boolean
warning: string | null
error: any
}

class AddButton extends React.Component<Props, State> {
state = {
loading: false,
warning: null,
error: null,
}

private action = async (putWritingChallenge: any): Promise<any> => {
const { history } = this.props

if (!putWritingChallenge) {
return
}

this.setState((prev) => ({
...prev,
loading: true,
warning: null,
error: null,
}))

try {
const result = await putWritingChallenge({
variables: {
input: {},
},
})

const shortHash = result?.data?.putWritingChallenge.shortHash
if (!shortHash) {
throw new Error('invalid shortHash')
}

this.setState(
(prev) => ({ ...prev, loading: false, error: null }),
async () => {
if (this.props.onSuccess) {
await this.props.onSuccess()
}
history.push(PATH.CAMPAIGN_EDIT.replace(':id', shortHash))
}
)
} catch (error) {
this.setState(
(prev) => ({ ...prev, loading: false, error }),
() => message.error('新增失敗')
)
}
}

public render() {
const { loading, warning, error } = this.state

if (error) {
return <ErrorMessage error={error} />
}

return (
<Mutation mutation={PUT_CAMPAIGN}>
{(putWritingChallenge: any) => (
<Button
onClick={() => this.action(putWritingChallenge)}
disabled={loading}
>
新增
</Button>
)}
</Mutation>
)
}
}

export default withRouter(AddButton)
155 changes: 155 additions & 0 deletions src/components/Campaign/Editor/Uploader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import * as React from 'react'
import { Alert, Button, Icon, Spin, Upload } from 'antd'
import gql from 'graphql-tag'
import { Mutation } from 'react-apollo'

import ErrorMessage from '../../../components/ErrorMessage'

const UPLOAD_FILE = gql`
mutation CampaignCoverUpload($input: SingleFileUploadInput!) {
singleFileUpload(input: $input) {
... on Asset {
id
path
}
}
}
`

type Props = {
campaignId: string
cover: string | null
onSuccess: ({ id, path }: { id: string; path: string }) => void
}

type State = {
cover: string | null
loading: boolean
warning: string | null
error: any
}

const spinStyle = {
marginRight: '8px',
}

const warningStyle = {
marginTop: '8px',
}

const coverContainerStyle = {
borderRadius: '50%',
marginTop: '16px',
}

class Uploader extends React.Component<Props, State> {
state = {
cover: this.props.cover,
loading: false,
warning: null,
error: null,
}

private action = async (params: any, upload: any): Promise<any> => {
const { file } = params

if (!upload) {
return
}

this.setState((prev) => ({
...prev,
error: null,
loading: true,
warning: null,
}))

try {
const result = await upload({
variables: {
input: {
file,
type: 'campaignCover',
entityType: 'campaign',
entityId: this.props.campaignId,
},
},
})

const {
data: {
singleFileUpload: { id, path },
},
} = result

this.setState((prev) => ({
...prev,
cover: path,
loading: false,
error: null,
}))
this.props.onSuccess({ id, path })
} catch (error) {
this.setState((prev) => ({ ...prev, error, loading: false }))
}
}

private _onChange = async (params: any) => {
// TODO: Catch status
}

public render() {
const { cover, error, loading, warning } = this.state

if (error) {
return <ErrorMessage error={error} />
}

return (
<Mutation mutation={UPLOAD_FILE}>
{(upload: any) => (
<>
<div>
<Upload
showUploadList={false}
customRequest={(params: any) => {
this.action(params, upload)
}}
onChange={this._onChange}
>
<Button>
{loading ? (
<Spin style={spinStyle} size="small" />
) : (
<Icon type="upload" />
)}
上傳
</Button>
</Upload>
</div>
{warning && (
<Alert
type="warning"
message={warning}
showIcon={true}
style={warningStyle}
/>
)}
{cover && (
<div style={coverContainerStyle}>
<img
style={{ borderRadius: '1rem' }}
src={cover}
width="100%"
height="100"
/>
</div>
)}
</>
)}
</Mutation>
)
}
}

export default Uploader
Loading

0 comments on commit 73b1d1f

Please sign in to comment.