Save uploaded avatar to team
This commit is contained in:
1 parent
ac5e253d02
commit
ecc538648e
14 files changed
+255
-184
No files matched your search
@@ -41,6 +41,7 @@ type TeamProfile {
|
||||
description: String
|
||||
motto: String
|
||||
avatar: String
|
||||
banner: String
|
||||
updatedAt: DateTime!
|
||||
createdAt: DateTime!
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# source: http://localhost:4466
|
||||
# timestamp: Wed Sep 12 2018 08:41:57 GMT-0700 (Pacific Daylight Time)
|
||||
# timestamp: Thu Sep 20 2018 16:52:44 GMT-0700 (Pacific Daylight Time)
|
||||
|
||||
type AggregateFBStatus {
|
||||
count: Int!
|
||||
@@ -1400,7 +1400,9 @@ type TeamProfile {
|
||||
description: String
|
||||
motto: String
|
||||
avatar: String
|
||||
banner: String
|
||||
updatedAt: DateTime!
|
||||
createdAt: DateTime!
|
||||
}
|
||||
|
||||
"""A connection to a list of items."""
|
||||
@@ -1417,6 +1419,7 @@ input TeamProfileCreateInput {
|
||||
description: String
|
||||
motto: String
|
||||
avatar: String
|
||||
banner: String
|
||||
}
|
||||
|
||||
input TeamProfileCreateOneInput {
|
||||
@@ -1439,19 +1442,23 @@ enum TeamProfileOrderByInput {
|
||||
motto_DESC
|
||||
avatar_ASC
|
||||
avatar_DESC
|
||||
banner_ASC
|
||||
banner_DESC
|
||||
updatedAt_ASC
|
||||
updatedAt_DESC
|
||||
id_ASC
|
||||
id_DESC
|
||||
createdAt_ASC
|
||||
createdAt_DESC
|
||||
id_ASC
|
||||
id_DESC
|
||||
}
|
||||
|
||||
type TeamProfilePreviousValues {
|
||||
description: String
|
||||
motto: String
|
||||
avatar: String
|
||||
banner: String
|
||||
updatedAt: DateTime!
|
||||
createdAt: DateTime!
|
||||
}
|
||||
|
||||
type TeamProfileSubscriptionPayload {
|
||||
@@ -1497,12 +1504,14 @@ input TeamProfileUpdateDataInput {
|
||||
description: String
|
||||
motto: String
|
||||
avatar: String
|
||||
banner: String
|
||||
}
|
||||
|
||||
input TeamProfileUpdateInput {
|
||||
description: String
|
||||
motto: String
|
||||
avatar: String
|
||||
banner: String
|
||||
}
|
||||
|
||||
input TeamProfileUpdateOneInput {
|
||||
@@ -1647,6 +1656,46 @@ input TeamProfileWhereInput {
|
||||
|
||||
"""All values not ending with the given string."""
|
||||
avatar_not_ends_with: String
|
||||
banner: String
|
||||
|
||||
"""All values that are not equal to given value."""
|
||||
banner_not: String
|
||||
|
||||
"""All values that are contained in given list."""
|
||||
banner_in: [String!]
|
||||
|
||||
"""All values that are not contained in given list."""
|
||||
banner_not_in: [String!]
|
||||
|
||||
"""All values less than the given value."""
|
||||
banner_lt: String
|
||||
|
||||
"""All values less than or equal the given value."""
|
||||
banner_lte: String
|
||||
|
||||
"""All values greater than the given value."""
|
||||
banner_gt: String
|
||||
|
||||
"""All values greater than or equal the given value."""
|
||||
banner_gte: String
|
||||
|
||||
"""All values containing the given string."""
|
||||
banner_contains: String
|
||||
|
||||
"""All values not containing the given string."""
|
||||
banner_not_contains: String
|
||||
|
||||
"""All values starting with the given string."""
|
||||
banner_starts_with: String
|
||||
|
||||
"""All values not starting with the given string."""
|
||||
banner_not_starts_with: String
|
||||
|
||||
"""All values ending with the given string."""
|
||||
banner_ends_with: String
|
||||
|
||||
"""All values not ending with the given string."""
|
||||
banner_not_ends_with: String
|
||||
updatedAt: DateTime
|
||||
|
||||
"""All values that are not equal to given value."""
|
||||
@@ -1669,6 +1718,28 @@ input TeamProfileWhereInput {
|
||||
|
||||
"""All values greater than or equal the given value."""
|
||||
updatedAt_gte: DateTime
|
||||
createdAt: DateTime
|
||||
|
||||
"""All values that are not equal to given value."""
|
||||
createdAt_not: DateTime
|
||||
|
||||
"""All values that are contained in given list."""
|
||||
createdAt_in: [DateTime!]
|
||||
|
||||
"""All values that are not contained in given list."""
|
||||
createdAt_not_in: [DateTime!]
|
||||
|
||||
"""All values less than the given value."""
|
||||
createdAt_lt: DateTime
|
||||
|
||||
"""All values less than or equal the given value."""
|
||||
createdAt_lte: DateTime
|
||||
|
||||
"""All values greater than the given value."""
|
||||
createdAt_gt: DateTime
|
||||
|
||||
"""All values greater than or equal the given value."""
|
||||
createdAt_gte: DateTime
|
||||
}
|
||||
|
||||
type TeamStatus {
|
||||
|
||||
@@ -13,6 +13,7 @@ const TEAMS_FRAGMENT = gql`{
|
||||
createdAt
|
||||
profile {
|
||||
avatar
|
||||
banner
|
||||
description
|
||||
motto
|
||||
updatedAt
|
||||
|
||||
+7
-6
@@ -121,8 +121,8 @@ const resolvers = {
|
||||
return err
|
||||
})
|
||||
},
|
||||
async updateTeamProfile(parent, { slug, owner, description, motto, avatar }, ctx, info) {
|
||||
return ctx.db.mutation.updateTeam({data:{profile: {update: {description: description, motto: motto, avatar: avatar}}}, where:{slug: slug}}, TEAMS_FRAGMENT)
|
||||
async updateTeamProfile(parent, { slug, owner, description, motto, avatar, banner }, ctx, info) {
|
||||
return ctx.db.mutation.updateTeam({data:{profile: {update: {description: description, motto: motto, avatar: avatar, banner: banner}}}, where:{slug: slug}}, TEAMS_FRAGMENT)
|
||||
.catch((err) => {
|
||||
console.log('createTeam error: ', err)
|
||||
return err
|
||||
@@ -140,8 +140,8 @@ const resolvers = {
|
||||
async getAzureSAS(parent, { teamSlug }, ctx, info) {
|
||||
// Create start and expiry times
|
||||
let today = new Date()
|
||||
let tomorrow = new Date()
|
||||
tomorrow.setDate(today.getDate() + 7)
|
||||
let week = new Date()
|
||||
week.setDate(today.getDate() + 7)
|
||||
// Create SharedKeyCredential and attach to pipline
|
||||
const SKC = new Azure.SharedKeyCredential(azureAccount, azureKey)
|
||||
const pipeline = Azure.StorageURL.newPipeline(SKC)
|
||||
@@ -179,10 +179,11 @@ const resolvers = {
|
||||
// Generate SAS url
|
||||
const SASQueryParameters = Azure.generateAccountSASQueryParameters(
|
||||
{
|
||||
containerName,
|
||||
version: '2017-11-09',
|
||||
permissions: SASContainerPerms,
|
||||
startTime: today,
|
||||
expiryTime: tomorrow,
|
||||
expiryTime: week,
|
||||
protocol: 'https',
|
||||
services: SASServicePerms,
|
||||
resourceTypes: SASResourceTypes
|
||||
}, SKC )
|
||||
|
||||
@@ -19,16 +19,11 @@ type Query {
|
||||
type Mutation {
|
||||
authenticate(idToken: String!): Member
|
||||
createTeam(name: String!, slug: String!, owner: String!): Team @isAuthenticated
|
||||
updateTeamProfile(slug: String!, owner: String!, description: String, motto: String, avatar: String): Team @isAuthenticated
|
||||
updateTeamProfile(slug: String!, owner: String!, description: String, motto: String, avatar: String, banner: String): Team @isAuthenticated
|
||||
deleteTeam(slug: String!): Team @isAuthenticated @isOwner(type: "Team")
|
||||
getAzureSAS(teamSlug: String!):String
|
||||
}
|
||||
|
||||
input MemberProfileInput {
|
||||
authId: String!
|
||||
alias: String!
|
||||
}
|
||||
|
||||
fragment MemberInfo on Member {
|
||||
id
|
||||
authId
|
||||
|
||||
Generated
+5
@@ -4847,6 +4847,11 @@
|
||||
"integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
|
||||
"dev": true
|
||||
},
|
||||
"browser-image-resizer": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/browser-image-resizer/-/browser-image-resizer-1.2.0.tgz",
|
||||
"integrity": "sha512-xMiB6BnRsD6RWmkD6Av90qXY7uaAOXJPaS5D8cSazyao/bx6ENCm67XGl6BIhn1ETjK52yEs8A/atmMPp74M4A=="
|
||||
},
|
||||
"browserify-aes": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
"azure-storage": "^2.10.1",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"blob-util": "^2.0.2",
|
||||
"browser-image-resizer": "^1.2.0",
|
||||
"classnames": "^2.2.6",
|
||||
"cross-fetch": "^2.2.2",
|
||||
"dotenv-webpack": "^1.5.7",
|
||||
|
||||
@@ -18,6 +18,7 @@ export const GET_ALL_TEAMS_QUERY = gql`
|
||||
createdAt
|
||||
profile {
|
||||
avatar
|
||||
banner
|
||||
description
|
||||
motto
|
||||
updatedAt
|
||||
|
||||
@@ -16,6 +16,7 @@ export const GET_TEAMS_BY_OWNER = gql`
|
||||
createdAt
|
||||
profile {
|
||||
avatar
|
||||
banner
|
||||
description
|
||||
motto
|
||||
updatedAt
|
||||
|
||||
@@ -15,6 +15,7 @@ export const TEAMS_FRAGMENT = gql`
|
||||
createdAt
|
||||
profile {
|
||||
avatar
|
||||
banner
|
||||
description
|
||||
motto
|
||||
updatedAt
|
||||
|
||||
@@ -3,16 +3,20 @@ import gql from 'graphql-tag'
|
||||
|
||||
const UPDATE_TEAM_PROFILE = gql`
|
||||
mutation UpdateTeamProfileMutation(
|
||||
$slug: String!
|
||||
$owner: String!
|
||||
$description: String
|
||||
$motto: String
|
||||
$slug: String!,
|
||||
$owner: String!,
|
||||
$description: String,
|
||||
$motto: String,
|
||||
$avatar: String,
|
||||
$banner: String
|
||||
) {
|
||||
updateTeamProfile(
|
||||
slug: $slug
|
||||
owner: $owner
|
||||
description: $description
|
||||
slug: $slug,
|
||||
owner: $owner,
|
||||
description: $description,
|
||||
motto: $motto
|
||||
avatar: $avatar,
|
||||
banner: $banner
|
||||
) {
|
||||
id
|
||||
name
|
||||
@@ -26,6 +30,7 @@ const UPDATE_TEAM_PROFILE = gql`
|
||||
createdAt
|
||||
profile {
|
||||
avatar
|
||||
banner
|
||||
description
|
||||
motto
|
||||
updatedAt
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Mutation } from 'react-apollo'
|
||||
import Dropzone from 'react-dropzone'
|
||||
import { Cropper } from 'react-image-cropper'
|
||||
import * as Azure from '@azure/storage-blob'
|
||||
import readAndCompressImage from 'browser-image-resizer'
|
||||
import { imgSrcToBlob } from 'blob-util'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
|
||||
@@ -12,6 +13,8 @@ import DialogActions from '@material-ui/core/DialogActions'
|
||||
import DialogContent from '@material-ui/core/DialogContent'
|
||||
import Button from '@material-ui/core/Button'
|
||||
|
||||
import MessageCard from './MessageCard'
|
||||
|
||||
import GET_AZURE_SAS from '../../graphql/teams/GetAzureSASMutation'
|
||||
|
||||
const styles = theme => ({
|
||||
@@ -45,16 +48,21 @@ const styles = theme => ({
|
||||
}
|
||||
})
|
||||
|
||||
const imageConfig = {
|
||||
quality: 0.5,
|
||||
maxWidth: 200,
|
||||
maxHeight: 200,
|
||||
autoRotate: true,
|
||||
debug: true,
|
||||
mimeType: 'image/jpeg'
|
||||
}
|
||||
|
||||
class UploadImage extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
// this.saveToStorage = this.saveToStorage.bind(this)
|
||||
this.onDrop = this.onDrop.bind(this)
|
||||
this.handleCrop = this.handleCrop.bind(this)
|
||||
this.onCropComplete = this.onCropComplete.bind(this)
|
||||
this.onCropChange = this.onCropChange.bind(this)
|
||||
this.getCroppedImg = this.getCroppedImg.bind(this)
|
||||
this.handleClickOpen = this.handleClickOpen.bind(this)
|
||||
this.handleClose = this.handleClose.bind(this)
|
||||
this.handleSubmit = this.handleSubmit.bind(this)
|
||||
@@ -70,17 +78,27 @@ class UploadImage extends Component {
|
||||
width: 200,
|
||||
height: 200
|
||||
},
|
||||
cropping: false,
|
||||
cropped: null,
|
||||
rejected: null
|
||||
rejected: null,
|
||||
uploaded: false,
|
||||
image: ''
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { classes, team, authId } = this.props
|
||||
console.log('UploadImage', team, authId, this.state)
|
||||
const { classes, team, authId, handleAvatar } = this.props
|
||||
let avatar = null
|
||||
if (team.profile !== null && team.profile.avatar !== undefined && team.profile.avatar !== null && team.profile.avatar !== 'a') {
|
||||
avatar = team.profile.avatar
|
||||
} else {
|
||||
if (this.state.image !== '') avatar = this.state.image
|
||||
}
|
||||
|
||||
console.log('UploadImage', team, avatar, authId, this.state)
|
||||
return (
|
||||
<div className={classes.dropzoneContainer}>
|
||||
{this.state.src === null && (
|
||||
{avatar === null && this.state.src === null && (
|
||||
<Dropzone
|
||||
accept='image/jpeg, image/png'
|
||||
onDrop={this.onDrop}
|
||||
@@ -90,55 +108,64 @@ class UploadImage extends Component {
|
||||
<p>Drag-and-drop team avater here or click to select files. <br /> Only *.jpeg and *.png images</p>
|
||||
</Dropzone>
|
||||
)}
|
||||
{this.state.cropped !== null && (
|
||||
{(avatar !== null || this.state.src !== null) && (
|
||||
<Mutation mutation={GET_AZURE_SAS} >
|
||||
{(getAzureSAS, { loading, error, data }) => {
|
||||
console.log('getAzureSAS: ', error, data)
|
||||
console.log('getAzureSAS keys: ', process.env.AZURE_STORAGE_URL, process.env.AZURE_SAS)
|
||||
if (data !== undefined && data.getAzureSAS !== null) {
|
||||
this.saveAvatar(data.getAzureSAS, team.slug)
|
||||
if (!this.state.uploaded) {
|
||||
if (data !== undefined && data.getAzureSAS !== null) {
|
||||
this.saveAvatar(data.getAzureSAS, team.slug, handleAvatar)
|
||||
}
|
||||
// this.handleSubmit(getAzureSAS, team.slug)
|
||||
}
|
||||
if (this.state.cropping) {
|
||||
return (
|
||||
<div>
|
||||
<MessageCard message='Cropping...' />
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<img src={avatar} className={classes.cropPreview} alt='Crop Preview' />
|
||||
</div>
|
||||
<Dialog
|
||||
open={this.state.open}
|
||||
onClose={this.handleClose}
|
||||
aria-labelledby='form-dialog-title'
|
||||
>
|
||||
<div classes={classes.dialogContainer}>
|
||||
<DialogContent>
|
||||
<div className={classes.cropBox}>
|
||||
<Cropper
|
||||
src={this.state.src}
|
||||
originX={100}
|
||||
originY={100}
|
||||
ref={ref => { this.cropper = ref }}
|
||||
onImgLoad={this.onImageLoaded}
|
||||
/>
|
||||
</div>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={this.handleClose} color='primary'>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={(e) => this.handleCrop(e, getAzureSAS, team.slug, handleAvatar)}
|
||||
color='primary'
|
||||
>
|
||||
Crop Image
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</div>
|
||||
</Dialog>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<img src={this.state.cropped} className={classes.cropPreview} alt='Crop Preview' />
|
||||
<Button onClick={(e) => this.handleSubmit(e, getAzureSAS, team.slug)}>Save</Button>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</Mutation>
|
||||
)}
|
||||
{this.state.src !== null && (
|
||||
<Dialog
|
||||
open={this.state.open}
|
||||
onClose={this.handleClose}
|
||||
aria-labelledby='form-dialog-title'
|
||||
>
|
||||
<div classes={classes.dialogContainer}>
|
||||
<DialogContent>
|
||||
<div className={classes.cropBox}>
|
||||
<Cropper
|
||||
src={this.state.src}
|
||||
originX={100}
|
||||
originY={100}
|
||||
ref={ref => { this.cropper = ref }}
|
||||
onImgLoad={this.onImageLoaded}
|
||||
/>
|
||||
</div>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={this.handleClose} color='primary'>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={this.handleCrop}
|
||||
color='primary'
|
||||
>
|
||||
Crop Image
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</div>
|
||||
</Dialog>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -167,29 +194,30 @@ class UploadImage extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleCrop () {
|
||||
console.log('handleCrop', this.cropper)
|
||||
this.setState({ cropped: this.cropper.crop(), open: false })
|
||||
async handleCrop (e, getAzureSAS, teamSlug, handleAvatar) {
|
||||
e.preventDefault()
|
||||
const data = await getAzureSAS({ variables: { teamSlug } })
|
||||
console.log('handleCrop', this.cropper, data)
|
||||
const cropped = this.cropper.crop()
|
||||
const croppedBlob = await imgSrcToBlob(cropped, 'image/png', 'Anonymous')
|
||||
let resizedBlob = await readAndCompressImage(croppedBlob, imageConfig)
|
||||
|
||||
return this.setState({ cropped: resizedBlob, cropping: true, open: false }, () => {
|
||||
this.saveAvatar(data.getAzureSAS, teamSlug, handleAvatar)
|
||||
})
|
||||
}
|
||||
|
||||
async handleSubmit (e, getAzureSAS, teamSlug) {
|
||||
e.preventDefault()
|
||||
|
||||
await getAzureSAS({ variables: { teamSlug } })
|
||||
}
|
||||
|
||||
async saveAvatar (SASQueryParameters, teamSlug) {
|
||||
const blob = await imgSrcToBlob(this.state.cropped, 'image/png', 'Anonymous')
|
||||
console.log('handleSubmit0:', await blob, await blob.type)
|
||||
const type = blob.type
|
||||
let ext
|
||||
if (type === 'image/jpeg') ext = 'jpg'
|
||||
if (type === 'image/png') ext = 'png'
|
||||
const fileName = `${teamSlug}-avatar.${ext}`
|
||||
async saveAvatar (SASQueryParameters, teamSlug, handleAvatar) {
|
||||
const fileName = `${teamSlug}-avatar.jpg`
|
||||
console.log('saveAvatar SASurl', process.env.AZURE_SAS_URL)
|
||||
// const SASurl = `${process.env.AZURE_STORAGE_URL}?${SASQueryParameters}`
|
||||
const SASurl2 = `${process.env.AZURE_STORAGE_URL}?${SASQueryParameters}`
|
||||
const SASurl = process.env.AZURE_SAS_URL
|
||||
|
||||
console.log('getAzureSAS2 SASurl: ', SASurl2, SASurl)
|
||||
const pipeline = Azure.StorageURL.newPipeline(new Azure.AnonymousCredential())
|
||||
const serviceURL = new Azure.ServiceURL(SASurl, pipeline)
|
||||
console.log('getAzureSAS2: ', serviceURL)
|
||||
@@ -198,54 +226,15 @@ class UploadImage extends Component {
|
||||
console.log('getAzureSAS3: ', containerURL)
|
||||
const blockBlobURL = Azure.BlockBlobURL.fromContainerURL(containerURL, fileName)
|
||||
|
||||
console.log(Azure.Aborter.None, await blob, blockBlobURL)
|
||||
const avatar = await Azure.uploadBrowserDataToBlockBlob(Azure.Aborter.None, blob, blockBlobURL)
|
||||
console.log('getAzureSAS34: ', blockBlobURL)
|
||||
const avatar = await Azure.uploadBrowserDataToBlockBlob(Azure.Aborter.None, this.state.cropped, blockBlobURL)
|
||||
console.log('saveAvatar: ', avatar)
|
||||
const image = `${process.env.AZURE_STORAGE_URL}${teamSlug}/${fileName}`
|
||||
handleAvatar(image)
|
||||
this.setState({ cropping: false, uploaded: true, image: image })
|
||||
return avatar
|
||||
}
|
||||
|
||||
onCropComplete (crop, pixelCrop) {
|
||||
console.log('onCropComplete', crop, pixelCrop, this.state)
|
||||
const cropped = this.getCroppedImg(crop, pixelCrop, this.state.src)
|
||||
this.setState({ cropped })
|
||||
}
|
||||
|
||||
onCropChange (crop) {
|
||||
this.setState({ crop })
|
||||
}
|
||||
|
||||
getCroppedImg (image, pixelCrop, fileName) {
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = pixelCrop.width
|
||||
canvas.height = pixelCrop.height
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
ctx.drawImage(
|
||||
image,
|
||||
pixelCrop.x,
|
||||
pixelCrop.y,
|
||||
pixelCrop.width,
|
||||
pixelCrop.height,
|
||||
0,
|
||||
0,
|
||||
pixelCrop.width,
|
||||
pixelCrop.height
|
||||
)
|
||||
|
||||
// As Base64 string
|
||||
return canvas.toDataURL('image/jpeg')
|
||||
|
||||
// As a blob
|
||||
/*
|
||||
return new Promise((resolve, reject) => {
|
||||
canvas.toBlob(file => {
|
||||
file.name = fileName
|
||||
resolve(file)
|
||||
}, 'image/jpeg')
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
handleClickOpen () {
|
||||
this.setState({ open: true })
|
||||
}
|
||||
@@ -253,36 +242,13 @@ class UploadImage extends Component {
|
||||
handleClose () {
|
||||
this.setState({ open: false, src: null })
|
||||
}
|
||||
/*
|
||||
async saveToStorage (file) {
|
||||
const blobService = Azure.createBlobService()
|
||||
const container = ''
|
||||
|
||||
await uploadBrowserDataToBlockBlob(Aborter.None, file, blockBlobURL, {
|
||||
blockSize: 4 * 1024 * 1024, // 4MB block size
|
||||
parallelism: 20, // 20 concurrency
|
||||
progress: ev => console.log(ev)
|
||||
});
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
UploadImage.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
team: PropTypes.object,
|
||||
authId: PropTypes.string.isRequired
|
||||
authId: PropTypes.string.isRequired,
|
||||
handleAvatar: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
export default withStyles(styles)(UploadImage)
|
||||
|
||||
/*
|
||||
<ReactCrop
|
||||
src={this.state.src}
|
||||
crop={this.state.crop}
|
||||
onImageLoaded={this.onImageLoaded}
|
||||
onComplete={this.onCropComplete}
|
||||
onChange={this.onCropChange}
|
||||
className={classes.reactCrop}
|
||||
imageStyle={{ display: 'block', maxWidth: '100%', maxHeight: 'stretch' }}
|
||||
/>
|
||||
*/
|
||||
@@ -41,13 +41,18 @@ export class ManageTeamEdit extends Component {
|
||||
this.handleClose = this.handleClose.bind(this)
|
||||
this.handleChange = this.handleChange.bind(this)
|
||||
this.handleSubmit = this.handleSubmit.bind(this)
|
||||
this.handleAvatar = this.handleAvatar.bind(this)
|
||||
console.log('ManageTeamEdit', props.team)
|
||||
const motto = props.team.profile.motto || ''
|
||||
const description = props.team.profile.description || ''
|
||||
const avatar = props.team.profile.avatar || ''
|
||||
const banner = props.team.profile.banner || ''
|
||||
this.state = {
|
||||
open: false,
|
||||
motto: motto,
|
||||
description: description
|
||||
description: description,
|
||||
avatar: avatar,
|
||||
banner: banner
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +108,7 @@ export class ManageTeamEdit extends Component {
|
||||
Edit Team Details
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<UploadImage team={team} authId={authId} />
|
||||
<UploadImage team={team} authId={authId} handleAvatar={this.handleAvatar} />
|
||||
<TextField
|
||||
autoFocus
|
||||
margin='dense'
|
||||
@@ -181,7 +186,13 @@ export class ManageTeamEdit extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleAvatar (avatarUrl) {
|
||||
console.log('handleAvatar: ', avatarUrl)
|
||||
this.setState({ avatar: avatarUrl })
|
||||
}
|
||||
|
||||
async handleSubmit (e, updateTeamProfile, slug) {
|
||||
console.log('handleSubmit: ', this.state)
|
||||
e.preventDefault()
|
||||
const currentUser = await getItem('user')
|
||||
let authId = JSON.parse(currentUser)
|
||||
@@ -191,7 +202,9 @@ export class ManageTeamEdit extends Component {
|
||||
slug,
|
||||
owner: authId,
|
||||
description: this.state.description,
|
||||
motto: this.state.motto
|
||||
motto: this.state.motto,
|
||||
avatar: this.state.avatar,
|
||||
banner: this.state.banner
|
||||
}
|
||||
})
|
||||
this.setState({ description: '', motto: '', open: false })
|
||||
|
||||
@@ -12,32 +12,41 @@ import ManageTeamDetails from './ManageTeamDetails'
|
||||
import ManageTeamDelete from './ManageTeamDelete'
|
||||
import ManageTeamEdit from './ManageTeamEdit'
|
||||
|
||||
export const ManageTeamsItem = ({ classes, team, authId }) => (
|
||||
<Grid item xs={12}>
|
||||
<Card className={classes.card}>
|
||||
<div className={classes.cardDetails}>
|
||||
<CardMedia
|
||||
className={classes.cardMedia}
|
||||
image='data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22288%22%20height%3D%22225%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20288%20225%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_164edaf95ee%22%3E%3Crect%20width%3D%22288%22%20height%3D%22225%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2296.32500076293945%22%20y%3D%22118.8%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' // eslint-disable-line max-len
|
||||
title='Image title'
|
||||
/>
|
||||
<CardContent className={classes.cardContent}>
|
||||
<Typography gutterBottom variant='headline' component='h2'>
|
||||
{team.name}
|
||||
</Typography>
|
||||
<Typography variant='caption' color='textSecondary'>
|
||||
{team.createdAt} | Members: {team.members.length}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<ManageTeamDetails team={team} />
|
||||
<ManageTeamEdit slug={team.slug} authId={authId} team={team} />
|
||||
<ManageTeamDelete slug={team.slug} authId={authId} />
|
||||
</CardActions>
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
)
|
||||
export const ManageTeamsItem = ({ classes, team, authId }) => {
|
||||
console.log('ManageTeamsItem', team, team.profile, team.profile.avatar)
|
||||
let avatar
|
||||
if (team.profile.avatar !== undefined && team.profile.avatar !== 'a') {
|
||||
avatar = team.profile.avatar
|
||||
} else {
|
||||
avatar = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22288%22%20height%3D%22225%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20288%20225%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_164edaf95ee%22%3E%3Crect%20width%3D%22288%22%20height%3D%22225%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2296.32500076293945%22%20y%3D%22118.8%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E'
|
||||
}
|
||||
return (
|
||||
<Grid item xs={12}>
|
||||
<Card className={classes.card}>
|
||||
<div className={classes.cardDetails}>
|
||||
<CardMedia
|
||||
className={classes.cardMedia}
|
||||
image={avatar}
|
||||
title={team.name}
|
||||
/>
|
||||
<CardContent className={classes.cardContent}>
|
||||
<Typography gutterBottom variant='headline' component='h2'>
|
||||
{team.name}
|
||||
</Typography>
|
||||
<Typography variant='caption' color='textSecondary'>
|
||||
{team.createdAt} | Members: {team.members.length}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<ManageTeamDetails team={team} />
|
||||
<ManageTeamEdit slug={team.slug} authId={authId} team={team} />
|
||||
<ManageTeamDelete slug={team.slug} authId={authId} />
|
||||
</CardActions>
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
ManageTeamsItem.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
|
||||
Reference in new issue
Block a user