Skip to content

Commit

Permalink
lib-user: Add group create modal (#6009)
Browse files Browse the repository at this point in the history
* Add CreateButton

* Refactor Modal with bodyBackground prop

* Init GroupModal component

* Add GroupModal accessibility

* Add init GroupForm

* Refactor create user_group

* Refactor GroupFormContainer create group

* Refactor MyGroups create group

* Init MyGroups grid refactor for small screens

* Refactor text color for dark theme in GroupCard group displayName and TitledStat

* Fix hover effect and spacing issue

* Refactor GroupForm fields per design

* Refactor GroupForm submit button

* Add GroupForm tests

* Add FormFields help

* Fix GroupCardContainer import

* Update CreateButton dark color
  • Loading branch information
mcbouslog authored Apr 5, 2024
1 parent d65f474 commit 72a4e32
Show file tree
Hide file tree
Showing 23 changed files with 586 additions and 117 deletions.
5 changes: 4 additions & 1 deletion packages/lib-react-components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## Unrealeased 2024-03-19
## [Unreleased] 2024

### Added
Added a `bodyBackground` prop to Modal to allow for custom background colors.

### Fixed
Added `d3` as peer dependency and grab available d3 methods from `@visx`.
Expand Down
11 changes: 11 additions & 0 deletions packages/lib-react-components/src/Modal/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import withLayer from '../helpers/withLayer'
import ModalBody from './components/ModalBody'
import ModalHeading from './components/ModalHeading'

const DEFAULT_BACKGROUND = {
dark: 'dark-5',
light: 'neutral-6'
}

const Modal = forwardRef(function ({
bodyBackground = DEFAULT_BACKGROUND,
children,
className = '',
closeFn,
Expand Down Expand Up @@ -37,6 +43,7 @@ ref) {
title={title}
/>
<ModalBody
background={bodyBackground}
className={className}
overflow={overflow}
pad={pad}
Expand All @@ -52,6 +59,10 @@ Modal.propTypes = {
Determines whether the modal is visible or not.
*/
active: PropTypes.bool,
/**
The background color for the modal body. It can be set to any CSS color value or color string value from the Zooniverse Grommet theme or an object setting the color for the light and dark theme.
*/
bodyBackground: PropTypes.oneOfType([ PropTypes.object, PropTypes.string ]),
children: PropTypes.node.isRequired,
/**
Optional CSS class applied to the modal content.
Expand Down
1 change: 1 addition & 0 deletions packages/lib-react-components/src/Modal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
A generic modal component. Accepts the following props:

- `active` (boolean) - determines whether the modal is visible or not
- `bodyBackground` (object or string) - Defaults to `{ dark: 'dark-5', light: 'neutral-6' }`. The background color for the modal body. It can be set to any CSS color value or color string value from the Zooniverse Grommet theme or an object setting the color for the light and dark theme.
- `closeFn` (function) - Optional function called when clicking outside the modal, or when the Esc button is pressed. If this is not present, then the close button is not shown and the modal cannot be closed except by taking action in the content eg. pressing a button to continue.
- `headingBackground` (object or string) - Defaults to `'brand'`. The background color for the modal header. It can be set to any CSS color value or color string value from the Zooniverse Grommet theme or an object setting the color for the light and dark theme.
- `pad` (string or object) - Defaults to `medium`. Determines Box padding of the modal body.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ import { Box } from 'grommet'
import PropTypes from 'prop-types'

function ModalBody ({
background = {
dark: 'dark-5',
light: 'neutral-6'
},
children,
className,
overflow,
pad
className = '',
overflow = 'auto',
pad = {
bottom: 'medium',
horizontal: 'medium',
top: 'small'
}
}) {
return (
<Box
background={{
dark: 'dark-5',
light: 'neutral-6'
}}
background={background}
className={className}
overflow={overflow}
pad={pad}
Expand All @@ -23,18 +28,9 @@ function ModalBody ({
}

ModalBody.propTypes = {
background: PropTypes.oneOfType([ PropTypes.object, PropTypes.string ]),
className: PropTypes.string,
children: PropTypes.node.isRequired,
}

ModalBody.defaultProps = {
className: '',
overflow: 'auto',
pad: {
bottom: 'medium',
horizontal: 'medium',
top: 'small'
}
}

export default ModalBody
3 changes: 2 additions & 1 deletion packages/lib-user/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"dependencies": {
"@zooniverse/panoptes-js": "~0.4.0",
"panoptes-client": "~5.6.0",
"swr": "~2.2.4"
"swr": "~2.2.4",
"uuid": "~9.0.1"
},
"peerDependencies": {
"@zooniverse/grommet-theme": "3.x.x",
Expand Down
35 changes: 0 additions & 35 deletions packages/lib-user/src/components/MyGroups/CreateGroup.js

This file was deleted.

47 changes: 14 additions & 33 deletions packages/lib-user/src/components/MyGroups/MyGroups.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,30 @@
import { Grid, ResponsiveContext } from 'grommet'
import { func, node } from 'prop-types'
import { node } from 'prop-types'
import { useContext } from 'react'

import { ContentBox, Layout } from '@components/shared'
import CreateGroup from './CreateGroup'

const DEFAULT_HANDLER = () => true

function MyGroups({
children,
handleGroupCreate = DEFAULT_HANDLER
children
}) {
const size = useContext(ResponsiveContext)
const columnCount = size === 'small' ? 1 : 2

return (
<Layout>
<ContentBox
linkLabel='Learn more about Groups'
linkProps={{ href: '/groups' }}
title='My Groups'
pad={{ horizontal: '60px', vertical: '30px' }}
>
<Grid
as='ul'
columns={{
count: columnCount,
size: 'auto'
}}
gap={{ row: '20px', column: '40px' }}
pad='none'
>
{children}
</Grid>
<CreateGroup
handleGroupCreate={handleGroupCreate}
/>
</ContentBox>
</Layout>
<Grid
as='ul'
columns={{
count: columnCount,
size: 'auto'
}}
gap={{ row: '20px', column: '40px' }}
pad='none'
>
{children}
</Grid>
)
}

MyGroups.propTypes = {
children: node,
handleGroupCreate: func
children: node
}

export default MyGroups
27 changes: 23 additions & 4 deletions packages/lib-user/src/components/MyGroups/MyGroups.stories.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import MyGroups from './MyGroups'
import { Box } from 'grommet'

import MyGroups from './MyGroups'
import GroupCard from './components/GroupCard/GroupCard'

import { getActiveGroupsWithRoles } from './helpers/getActiveGroupsWithRoles'

import { MEMBERSHIPS, USER_GROUPS } from '../../../test/mocks/panoptes'

export default {
title: 'Components/MyGroups',
component: MyGroups,
decorators: [ComponentDecorator]
}

const MEMBERSHIPS_WITH_GROUPS = {
linked: {
user_groups: USER_GROUPS
Expand All @@ -13,9 +21,20 @@ const MEMBERSHIPS_WITH_GROUPS = {
}
const groups = getActiveGroupsWithRoles(MEMBERSHIPS_WITH_GROUPS)

export default {
title: 'Components/MyGroups',
component: MyGroups
function ComponentDecorator(Story) {
return (
<Box
background={{
dark: 'dark-3',
light: 'neutral-6'
}}
fill
pad='30px'
>
<Story />
</Box>
)

}

export const Default = {
Expand Down
63 changes: 39 additions & 24 deletions packages/lib-user/src/components/MyGroups/MyGroupsContainer.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
'use client'

import { object, string } from 'prop-types'
import { useState } from 'react'

import {
usePanoptesAuthUser,
usePanoptesMemberships,
usePanoptesUser
} from '@hooks'

import {
createPanoptesUserGroup,
getBearerToken
} from '@utils'
import { ContentBox, Layout } from '@components/shared'

import { getActiveGroupsWithRoles } from './helpers/getActiveGroupsWithRoles'

import MyGroups from './MyGroups'
import CreateButton from './components/CreateButton'
import GroupCardList from './components/GroupCardList'
import GroupForm from './components/GroupForm'
import GroupModal from './components/GroupModal'

function MyGroupsContainer({
authClient,
login
}) {
const [groupModalActive, setGroupModalActive] = useState(false)

const {
data: authUser
} = usePanoptesAuthUser(authClient)
Expand Down Expand Up @@ -50,29 +53,41 @@ function MyGroupsContainer({
}
})

async function handleGroupCreate(data) {
try {
const authorization = await getBearerToken(authClient)
const newGroup = await createPanoptesUserGroup({ data, authorization })
console.log('newGroup', newGroup)
window.location.reload()
} catch (error) {
console.error(error)
}
}

const activeGroupsWithRoles = getActiveGroupsWithRoles(membershipsWithGroups)

return (
<MyGroups
handleGroupCreate={handleGroupCreate}
>
<GroupCardList
authClient={authClient}
authUserId={authUser?.id}
groups={activeGroupsWithRoles}
/>
</MyGroups>
<>
<GroupModal
active={groupModalActive}
handleClose={() => setGroupModalActive(false)}
title='create new group'
titleColor='black'
>
<GroupForm
authClient={authClient}
authUserId={authUser?.id}
/>
</GroupModal>
<Layout>
<ContentBox
linkLabel='Learn more about Groups'
linkProps={{ href: '/groups' }}
title='My Groups'
pad={{ horizontal: '60px', vertical: '30px' }}
>
<MyGroups>
<GroupCardList
authClient={authClient}
authUserId={authUser?.id}
groups={activeGroupsWithRoles}
/>
</MyGroups>
<CreateButton
onClick={() => setGroupModalActive(true)}
/>
</ContentBox>
</Layout>
</>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Blank } from 'grommet-icons'

function AddIcon(props) {
return (
<Blank
viewBox='0 0 15 15'
{...props}
>
<path d="M13.9286 9.07143H8.57143V14.4286C8.57143 15.0179 8.08929 15.5 7.5 15.5C6.91071 15.5 6.42857 15.0179 6.42857 14.4286V9.07143H1.07143C0.482143 9.07143 0 8.58929 0 8C0 7.41071 0.482143 6.92857 1.07143 6.92857H6.42857V1.57143C6.42857 0.982143 6.91071 0.5 7.5 0.5C8.08929 0.5 8.57143 0.982143 8.57143 1.57143V6.92857H13.9286C14.5179 6.92857 15 7.41071 15 8C15 8.58929 14.5179 9.07143 13.9286 9.07143Z" fill="#5C5C5C" />
</Blank>
)
}

export default AddIcon
Loading

0 comments on commit 72a4e32

Please sign in to comment.