|
| 1 | +import { IconButton, Typography } from '@material-ui/core' |
| 2 | + |
| 3 | +import Button from 'components/generic/Button' |
| 4 | +import React, { useMemo, useState, useEffect, useCallback } from 'react' |
| 5 | +import { useDispatch, useSelector } from 'react-redux' |
| 6 | +import { useRouteMatch, useLocation } from 'react-router' |
| 7 | + |
| 8 | +import TeamHeader from '../TeamHeader' |
| 9 | +import TeamDescription from '../TeamDescription' |
| 10 | +import TeamRoles from '../TeamRoles' |
| 11 | +import TeamMembers from '../TeamMembers' |
| 12 | +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' |
| 13 | +import junctionStyle from 'utils/styles' |
| 14 | +import { popupCenter } from 'utils/misc' |
| 15 | +import { Email } from '@material-ui/icons' |
| 16 | +import { objToArr } from 'utils/dataModifiers' |
| 17 | +import PageWrapper from 'components/layouts/PageWrapper' |
| 18 | +import { gradientRandomizer } from 'utils/stylingHelpers' |
| 19 | +import TeamsService from 'services/teams' |
| 20 | +import * as SnackbarActions from 'redux/snackbar/actions' |
| 21 | +import * as OrganiserActions from 'redux/organiser/actions' |
| 22 | +import * as DashboardActions from 'redux/dashboard/actions' |
| 23 | + |
| 24 | + |
| 25 | + |
| 26 | + |
| 27 | +// TODO add socialLinks component from Damilare (@mrprotocoll) |
| 28 | + |
| 29 | +export default ({ |
| 30 | + enableActions = true, |
| 31 | + teamData = {}, |
| 32 | + onRoleClick = () => { }, |
| 33 | + onCancel = () => { }, |
| 34 | + slug = '', |
| 35 | +}) => { |
| 36 | + const dispatch = useDispatch() |
| 37 | + const [loading, setLoading] = useState(false) |
| 38 | + const [teamMemberToRemove, setTeamMemberToRemove] = useState('') |
| 39 | + const match = useRouteMatch() |
| 40 | + console.log("match", slug) |
| 41 | + |
| 42 | + const [teamMembersArr, setTeamMembersArr] = useState([...objToArr(teamData.meta)]) |
| 43 | + const membersCount = teamData.members.length |
| 44 | + |
| 45 | + const styling = { |
| 46 | + borderStyle: 'tw-border tw-border-solid tw-border-gray-300 tw-p-4', |
| 47 | + imageSize: 'tw-w-16 tw-h-16', |
| 48 | + alignment: 'tw-items-center', |
| 49 | + userProfile: {}, |
| 50 | + } |
| 51 | + |
| 52 | + |
| 53 | + const onClickRemove = (userId) => { |
| 54 | + console.log("delete", slug, teamData.code, userId) |
| 55 | + } |
| 56 | + |
| 57 | + const onClickDelete = () => { |
| 58 | + console.log("delete") |
| 59 | + } |
| 60 | + |
| 61 | + |
| 62 | + const handleRemove = useEffect(() => { |
| 63 | + console.log("delete", slug, teamData?.code, teamMemberToRemove) |
| 64 | + setLoading(true) |
| 65 | + dispatch(DashboardActions.organiserRemoveMemberFromTeam(slug, teamData.code, teamMemberToRemove)) |
| 66 | + .then((team) => { |
| 67 | + console.log("removed succesfully.", team) |
| 68 | + dispatch(OrganiserActions.updateTeamsForEvent(slug)) |
| 69 | + }) |
| 70 | + .then(() => { |
| 71 | + console.log("teams updated", teamMembersArr.filter(t => t.profile.userId !== teamMemberToRemove)) |
| 72 | + setTeamMembersArr(teamMembersArr.filter(t => t.profile.userId !== teamMemberToRemove)) |
| 73 | + dispatch(SnackbarActions.success('removed ' + teamMemberToRemove + ' from team ' + teamData?.code)) |
| 74 | + }) |
| 75 | + .catch(() => { |
| 76 | + dispatch( |
| 77 | + SnackbarActions.error( |
| 78 | + 'Something went wrong... please try again.', |
| 79 | + ), |
| 80 | + ) |
| 81 | + }) |
| 82 | + .finally(() => { |
| 83 | + setTeamMemberToRemove('') |
| 84 | + setLoading(false) |
| 85 | + }) |
| 86 | + }, [teamMemberToRemove, slug, teamData?.code, dispatch]) |
| 87 | + |
| 88 | + |
| 89 | + |
| 90 | + const classes = junctionStyle() |
| 91 | + return ( |
| 92 | + <PageWrapper loading={loading}> |
| 93 | + <div className="tw-flex tw-flex-col tw-gap-12"> |
| 94 | + <div className="tw tw-bg-gradient-to-r tw-from-teal-400 tw-to-blue-500 tw-w-full tw-h-16 tw-rounded-lg"></div> |
| 95 | + <div className="tw-flex tw-flex-col tw-gap-8"> |
| 96 | + <TeamHeader |
| 97 | + teamName={teamData.name} |
| 98 | + teamChallenge={teamData.challenge} |
| 99 | + teamCode={enableActions ? teamData.code : null} |
| 100 | + /> |
| 101 | + <TeamDescription |
| 102 | + teamSubtitle={teamData?.subtitle} |
| 103 | + teamDescription={teamData?.description} |
| 104 | + teamIdea={teamData?.ideaTitle} |
| 105 | + teamIdeaDescription={teamData?.ideaDescription} |
| 106 | + /> |
| 107 | + </div> |
| 108 | + <TeamRoles |
| 109 | + maxRoles={10} |
| 110 | + profileView |
| 111 | + teamRoles={teamData.teamRoles} |
| 112 | + onRoleClick={onRoleClick} |
| 113 | + /> |
| 114 | + {teamMembersArr?.map(userProfile => { |
| 115 | + console.log("userProfile.profile?.avatar", userProfile.profile?.avatar) |
| 116 | + return ( |
| 117 | + <div |
| 118 | + className={`tw-flex tw-justify-between tw-rounded-lg ${styling.borderStyle} ${styling.alignment}`} |
| 119 | + > |
| 120 | + <div className="tw-flex tw-gap-4 tw-items-end"> |
| 121 | + <div |
| 122 | + className={`tw-bg-gradient-to-r ${gradientRandomizer()} tw-rounded-full ${styling.imageSize |
| 123 | + } tw-bg-cover`} |
| 124 | + style={{ backgroundImage: `url(${userProfile.profile?.avatar})` }} |
| 125 | + ></div> |
| 126 | + <div className="tw-flex tw-flex-col tw-items-start tw-gap-1"> |
| 127 | + <Typography |
| 128 | + className="tw-tracking-tight tw-font-medium" |
| 129 | + variant="h5" |
| 130 | + component="h5" |
| 131 | + > |
| 132 | + {userProfile.profile.firstName}{' '} |
| 133 | + {userProfile.profile.lastName} |
| 134 | + </Typography> |
| 135 | + |
| 136 | + |
| 137 | + </div> |
| 138 | + |
| 139 | + </div> |
| 140 | + {membersCount > 0 ? ( |
| 141 | + <Button |
| 142 | + onClick={() => setTeamMemberToRemove(userProfile.profile.userId)} |
| 143 | + color="error" |
| 144 | + variant="contained" |
| 145 | + > |
| 146 | + remove from team |
| 147 | + </Button> |
| 148 | + ) : ( |
| 149 | + <Button |
| 150 | + onClick={() => setTeamMemberToRemove(userProfile.profile.userId)} |
| 151 | + color="error" |
| 152 | + variant="contained" |
| 153 | + > |
| 154 | + Delete the team |
| 155 | + </Button> |
| 156 | + )} |
| 157 | + </div> |
| 158 | + ) |
| 159 | + } |
| 160 | + )} |
| 161 | + <div className="tw-flex tw-content-center tw-justify-start"> |
| 162 | + {teamData?.discord && ( |
| 163 | + <FontAwesomeIcon |
| 164 | + icon={['fab', 'discord']} |
| 165 | + onClick={() => |
| 166 | + popupCenter({ |
| 167 | + url: teamData.discord, |
| 168 | + title: 'Discord', |
| 169 | + }) |
| 170 | + } |
| 171 | + className={classes.socialIcon} |
| 172 | + size="2x" |
| 173 | + /> |
| 174 | + )} |
| 175 | + {teamData?.telegram && ( |
| 176 | + <FontAwesomeIcon |
| 177 | + icon={['fab', 'telegram']} |
| 178 | + onClick={() => |
| 179 | + popupCenter({ |
| 180 | + url: teamData.telegram, |
| 181 | + title: 'Telegram', |
| 182 | + }) |
| 183 | + } |
| 184 | + className={classes.socialIcon} |
| 185 | + size="2x" |
| 186 | + /> |
| 187 | + )} |
| 188 | + {teamData?.email && ( |
| 189 | + <IconButton |
| 190 | + color="primary" |
| 191 | + aria-label="Email" |
| 192 | + className="tw-p-0" |
| 193 | + onClick={() => |
| 194 | + popupCenter({ |
| 195 | + url: `mailto:${teamData.email}`, |
| 196 | + title: 'email', |
| 197 | + }) |
| 198 | + } |
| 199 | + > |
| 200 | + <Email className={classes.socialIcon} /> |
| 201 | + </IconButton> |
| 202 | + )} |
| 203 | + </div> |
| 204 | + {/* TODO add socialLinks component from Damilare (@mrprotocoll) */} |
| 205 | + <div className='tw-p-4'> |
| 206 | + <Button |
| 207 | + onClick={onCancel} |
| 208 | + color="primary" |
| 209 | + variant="contained" |
| 210 | + > |
| 211 | + cancel |
| 212 | + </Button> |
| 213 | + </div> |
| 214 | + </div> |
| 215 | + </PageWrapper> |
| 216 | + ) |
| 217 | +} |
| 218 | +//TODO fix issue that doesn't let team owners leave their own team |
0 commit comments