diff --git a/web/invite-links/manage-invite-links-modal.react.js b/web/invite-links/manage-invite-links-modal.react.js --- a/web/invite-links/manage-invite-links-modal.react.js +++ b/web/invite-links/manage-invite-links-modal.react.js @@ -6,6 +6,7 @@ import { primaryInviteLinksSelector } from 'lib/selectors/invite-links-selectors.js'; import type { InviteLink } from 'lib/types/link-types.js'; +import EditLinkModal from './manage/edit-link-modal.react.js'; import EmptyLinkContent from './manage/empty-link-content.react.js'; import ExistingLinkContent from './manage/existing-link-content.react.js'; import css from './manage/manage-invite-links-modal.css'; @@ -23,11 +24,26 @@ ]; const { popModal } = useModalContext(); + const [modalStage, setModalStage] = React.useState('view'); + const enterEditMode = React.useCallback(() => setModalStage('edit'), []); + const enterViewMode = React.useCallback(() => setModalStage('view'), []); + + if (modalStage === 'edit') { + return ( + <EditLinkModal inviteLink={inviteLink} enterViewMode={enterViewMode} /> + ); + } + let content; if (inviteLink) { - content = <ExistingLinkContent inviteLink={inviteLink} />; + content = ( + <ExistingLinkContent + inviteLink={inviteLink} + enterEditMode={enterEditMode} + /> + ); } else { - content = <EmptyLinkContent />; + content = <EmptyLinkContent enterEditMode={enterEditMode} />; } return ( diff --git a/web/invite-links/manage/edit-link-modal.react.js b/web/invite-links/manage/edit-link-modal.react.js new file mode 100644 --- /dev/null +++ b/web/invite-links/manage/edit-link-modal.react.js @@ -0,0 +1,67 @@ +// @flow + +import classnames from 'classnames'; +import * as React from 'react'; + +import { useModalContext } from 'lib/components/modal-provider.react.js'; +import { inviteLinkUrl } from 'lib/facts/links.js'; +import type { InviteLink } from 'lib/types/link-types.js'; + +import css from './manage-invite-links-modal.css'; +import Button from '../../components/button.react.js'; +import Input from '../../modals/input.react.js'; +import Modal from '../../modals/modal.react.js'; + +type Props = { + +inviteLink: ?InviteLink, + +enterViewMode: () => mixed, +}; + +function EditLinkModal(props: Props): React.Node { + const { inviteLink, enterViewMode } = props; + const [name, setName] = React.useState( + inviteLink?.name ?? Math.random().toString(36).slice(-9), + ); + const { popModal } = useModalContext(); + + const onChangeName = React.useCallback( + (event: SyntheticEvent<HTMLInputElement>) => { + setName(event.currentTarget.value); + }, + [], + ); + + return ( + <Modal name="Public link" onClose={popModal} size="large"> + <div className={classnames(css.container, css.editLinkContainer)}> + <div className={css.editLinkDescription}> + <p> + Invite links make it easy for your friends to join your community. + Anybody who knows your community’s invite link will be able to join + it. + </p> + <p> + Note that if you change your public link’s URL, other communities + will be able to claim the old URL. + </p> + </div> + <hr className={css.separator} /> + <div className={css.linkSection}> + Invite URL + <div className={css.linkRow}> + {inviteLinkUrl('')} + <Input type="text" value={name} onChange={onChangeName} /> + </div> + </div> + <div className={css.buttonRow}> + <Button variant="outline" onClick={enterViewMode}> + Back + </Button> + <Button variant="filled">Save & enable public link</Button> + </div> + </div> + </Modal> + ); +} + +export default EditLinkModal; diff --git a/web/invite-links/manage/empty-link-content.react.js b/web/invite-links/manage/empty-link-content.react.js --- a/web/invite-links/manage/empty-link-content.react.js +++ b/web/invite-links/manage/empty-link-content.react.js @@ -9,11 +9,16 @@ color: 'var(--purple-link)', }; -function EmptyLinkContent(): React.Node { +type Props = { + +enterEditMode: () => mixed, +}; + +function EmptyLinkContent(props: Props): React.Node { + const { enterEditMode } = props; return ( <div className={css.sectionHeaderRow}> <div className={css.sectionHeaderText}>Public link</div> - <Button variant="text" buttonColor={buttonColor}> + <Button variant="text" buttonColor={buttonColor} onClick={enterEditMode}> Enable </Button> </div> diff --git a/web/invite-links/manage/existing-link-content.react.js b/web/invite-links/manage/existing-link-content.react.js --- a/web/invite-links/manage/existing-link-content.react.js +++ b/web/invite-links/manage/existing-link-content.react.js @@ -14,9 +14,10 @@ type Props = { +inviteLink: InviteLink, + +enterEditMode: () => mixed, }; function ExistingLinkContent(props: Props): React.Node { - const { inviteLink } = props; + const { inviteLink, enterEditMode } = props; return ( <> <div className={css.sectionHeaderRow}> @@ -30,6 +31,7 @@ variant="text" buttonColor={buttonColor} className={css.inlineButton} + onClick={enterEditMode} > Edit public link </Button> diff --git a/web/invite-links/manage/manage-invite-links-modal.css b/web/invite-links/manage/manage-invite-links-modal.css --- a/web/invite-links/manage/manage-invite-links-modal.css +++ b/web/invite-links/manage/manage-invite-links-modal.css @@ -25,3 +25,47 @@ display: inline; font-size: var(--s-font-14); } + +.editLinkContainer { + display: flex; + flex-direction: column; + gap: 32px; + color: var(--modal-fg); + font-size: var(--s-font-14); +} + +.editLinkDescription { + font-weight: var(--semi-bold); + color: var(--modal-fg); + display: flex; + flex-direction: column; + gap: 12px; +} + +.editLinkDescription p { + font-size: var(--s-font-14); +} + +.separator { + border-color: var(--border-color); + margin: 0; +} + +.linkSection { + display: flex; + flex-direction: column; + gap: 16px; +} + +.linkRow { + display: flex; + font-size: var(--m-font-16); + align-items: center; + gap: 8px; +} + +.buttonRow { + display: flex; + justify-content: flex-end; + gap: 8px; +} diff --git a/web/modals/input.react.js b/web/modals/input.react.js --- a/web/modals/input.react.js +++ b/web/modals/input.react.js @@ -18,7 +18,7 @@ export type InputProps = { ...BaseInputProps, +type: string, - +placeholder: string, + +placeholder?: string, +maxLength?: number, };