Skip to content

Commit

Permalink
Core 4513 update forms (#993) (#1016)
Browse files Browse the repository at this point in the history
* CORE-4513: update forms

* add additional fields to form

* temp textarea

* render view by type

* CORE-4513 add description textaerea

* update dataset date

* update small issues

* CORE-4513: add dataset access

* minor issues

* update success message

* update on forms

* update core

* update checkbox

* add whats included
  • Loading branch information
ekachxaidze98 authored Oct 26, 2023
1 parent 095fb95 commit a6eb331
Show file tree
Hide file tree
Showing 19 changed files with 826 additions and 104 deletions.
19 changes: 16 additions & 3 deletions components/checkbox/animated.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@ import { classNames } from '@oacore/design/lib/utils'

import styles from './styles.module.scss'

const Checkbox = ({ id, labelText, setCheckbox, className }) => {
const [isChecked, setIsChecked] = useState(false)
const Checkbox = ({
id,
labelText,
setCheckbox,
className,
value = false,
isDisabled = false,
}) => {
const [isChecked, setIsChecked] = useState(value)
const checkboxAnimationRef = useSpringRef()
const checkboxAnimationStyle = useSpring({
backgroundColor: isChecked ? '#b75400' : '#fff',
Expand All @@ -20,6 +27,11 @@ const Checkbox = ({ id, labelText, setCheckbox, className }) => {
ref: checkboxAnimationRef,
})

const checkedboxtyle = useSpring({
backgroundColor: '#757575',
borderColor: '#757575',
})

const [checkmarkLength, setCheckmarkLength] = useState(null)

const checkmarkAnimationRef = useSpringRef()
Expand All @@ -42,14 +54,15 @@ const Checkbox = ({ id, labelText, setCheckbox, className }) => {
<input
id={id}
type="checkbox"
disabled={isDisabled}
onChange={() => {
setIsChecked(!isChecked)
setCheckbox(!isChecked)
}}
className={styles.disabled}
/>
<animated.svg
style={checkboxAnimationStyle}
style={isDisabled ? checkedboxtyle : checkboxAnimationStyle}
className={styles.checkbox}
aria-hidden="true"
viewBox="0 0 15 11"
Expand Down
19 changes: 17 additions & 2 deletions components/modal/hooks/use-input.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
import { useState } from 'react'
import { useState, useEffect } from 'react'

const useInput = (element) => {
const useInput = (element, fetchSuggestions = false) => {
const [value, setValue] = useState('')
const [suggestions, setSuggestions] = useState([])

useEffect(() => {
if (fetchSuggestions) {
fetch(`https://api.ror.org/organizations?query=${value}`)
.then((response) => response.json())
.then((data) => {
setSuggestions(data.items)
})
.catch((error) => {
console.error('Error fetching suggestions:', error)
})
}
}, [fetchSuggestions, value])

return {
value,
element,
suggestions,
reset: () => setValue(''),
bind: {
value,
Expand Down
34 changes: 25 additions & 9 deletions components/modal/registration/conditions.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import React, { useState } from 'react'
import { Modal, Button, Link } from '@oacore/design/lib'
import { Modal, Button } from '@oacore/design/lib'
import { useRouter } from 'next/router'

import text from '../../../data/registration.yml'
import styles from './styles.module.scss'
import Markdown from '../../markdown'

import { Checkbox } from 'components/checkbox'
import { observe, useStore } from 'store'

const ModalConditions = observe(() => {
const [isAgreeNewsletter, setIsAgreeNewsletter] = useState(false)
const { registration } = useStore()
const router = useRouter()

const onSubmit = () => {
registration.setData({ agreeNewsletter: isAgreeNewsletter })
Expand All @@ -24,16 +28,28 @@ const ModalConditions = observe(() => {
return (
<Modal hideManually aria-label="conditions-modal">
<h6>Just one more thing!</h6>
<main>
Please read and agree to the CORE
<Link href="/index">Terms and Conditions</Link> and
<Link href="/privacy"> privacy notice</Link>. The T&Cs and privacy
notice are designed to inform you of your rights and obligations when
using the CORE service.
</main>
<Markdown>{text.terms}</Markdown>
{registration.data.accountType !== 'personal' && (
<Checkbox
value
isDisabled
id="agreeNewsletter"
labelText={
router.pathname.includes('api')
? ` I authorise CORE to send me information about the CORE API
(required).`
: ` I authorise CORE to send me information about the CORE Dataset (required).`
}
setCheckbox={setIsAgreeNewsletter}
/>
)}
<Checkbox
id="agreeNewsletter"
labelText="I want to receive information about the CORE API and related CORE products and services. You may unsubscribe at any time."
labelText={
router.pathname.includes('api')
? ` I want to receive information about the CORE API and related CORE products and services. You may unsubscribe at any time.`
: ` I want to receive information about the CORE Dataset and related CORE products and services. You may unsubscribe at any time.`
}
setCheckbox={setIsAgreeNewsletter}
/>
<footer className={styles.buttonGroup}>
Expand Down
205 changes: 184 additions & 21 deletions components/modal/registration/form.jsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,95 @@
import React from 'react'
import { Modal, Form, TextField, Button } from '@oacore/design/lib'
import React, { useEffect, useState } from 'react'
import { Modal, Form, TextField, Button, Popover } from '@oacore/design/lib'
import { useRouter } from 'next/router'

import questionInfo from '../../../public/images/logos/questionInfo.svg'
import styles from './styles.module.scss'
import ProfileSelect from './profile-select'
import CountrySelect from './country-select'
import useSelect from '../../../hooks/use-select'
import useInput from '../hooks/use-input'
import Markdown from '../../markdown'
import findText from './helpers/findText'
import text from '../../../data/registration.yml'
import DropdownInput from './institution-select'
import CustomRadio from '../../radio-button'

import { useStore, observe } from 'store'

const ModalForm = observe(() => {
const ModalForm = observe((emailFill) => {
const router = useRouter()
const {
value: firstName,
bind: bindFirstName,
element: elemFirstName,
} = useInput('firstName')

const {
value: lastName,
bind: bindLastName,
element: elemLastName,
} = useInput('lastName')

const {
value: description,
bind: bindDescription,
element: elemLastDescription,
} = useInput('description')

const {
value: organisationName,
suggestions: organisationNameSuggestions,
bind: bindOrganisationName,
element: elemOrganisationName,
} = useInput('organisationName')
const { value: countryName, onChange: countryOnChange } =
useSelect('countryName')
} = useInput('organisationName', true)

const {
value: libraryEmail,
element: elemLibraryEmail,
bind: bindLibraryEmail,
} = useInput('libraryEmail')

const [email, setEmail] = useState(emailFill.emailFill)
const { registration } = useStore()

const [selectedOption, setSelectedOption] = useState('')
const handleRadioSelect = (id) => {
setSelectedOption(id)
}

const { value: countryName, onChange: countryOnChange } =
useSelect('countryName')

const onCloseModal = () => {
registration.reset()
}

useEffect(() => {
setSelectedOption(
registration.data.accountType === 'enterprise' ? 'all' : 'few'
)
}, [registration.data.accountType])

const onHandleSubmit = (evt) => {
evt.preventDefault()

if (description.trim().split(/\s+/).length > 150) return

if (organisationName)
registration.setData({ organisation: organisationName })

if (firstName && lastName && countryName.id) {
registration.setData({ firstName, lastName, country: countryName.id })
if (libraryEmail) registration.setData({ libraryEmail })

if (description) registration.setData({ description })

if (firstName && lastName && countryName.id && email) {
registration.setData({
firstName,
lastName,
country: countryName.id,
email,
paidAccess: selectedOption === 'all',
})
registration.setIsModalFormActive(false)
registration.setIsModalConditionsActive(true)
}
Expand All @@ -64,6 +110,70 @@ const ModalForm = observe(() => {
<Markdown>{findText('box')}</Markdown>
</div>
<Form onSubmit={onHandleSubmit}>
{router.pathname.includes('dataset') && (
<div className={styles.radioItemsWrapper}>
<h6 className={styles.radioItemsTitle}>
Choose the datasets you wish to get access to
</h6>
<div className={styles.radioItemsInnerWrapper}>
<div className={styles.radioItem}>
<div className={styles.radioTitleWrapper}>
<CustomRadio
id={text.options.only.id}
label={text.options.only.label}
checked={selectedOption === text.options.only.id}
onChange={() => handleRadioSelect(text.options.only.id)}
/>
<Popover
className={styles.popover}
placement="top"
content={text.options.only.info}
>
<Button>
<img src={questionInfo} alt="questionInfo" />
</Button>
</Popover>
</div>
<Markdown className={styles.radioDescription}>
{text.options.only.description}
</Markdown>
</div>
{registration.data.accountType === 'personal' && (
<div className={styles.none}>{text.options.none}</div>
)}
{registration.data.accountType !== 'personal' && (
<div className={styles.radioItem}>
<div className={styles.radioTitleWrapper}>
<CustomRadio
id={text.options.all.id}
label={text.options.all.label}
checked={selectedOption === text.options.all.id}
onChange={() => handleRadioSelect(text.options.all.id)}
/>
<Popover
className={styles.popover}
placement="top"
content={
<Markdown>
{registration.data.accountType === 'enterprise'
? text.options.all.info
: text.options.all.susInfo}
</Markdown>
}
>
<Button>
<img src={questionInfo} alt="questionInfo" />
</Button>
</Popover>
</div>
<Markdown className={styles.radioDescription}>
{text.options.all.description}
</Markdown>
</div>
)}
</div>
</div>
)}
<div className={styles.inputGroup}>
<TextField
id={elemFirstName}
Expand All @@ -84,24 +194,77 @@ const ModalForm = observe(() => {
{...bindLastName}
/>
</div>
{registration.data.accountType !== 'personal' && (
<>
<TextField
id={elemOrganisationName}
name={elemOrganisationName}
label={
registration.data.accountType === 'enterprise'
? 'Organization name'
: 'Institution name'
}
placeholder="Full name of your institution, e.g ‘The Open University’"
className={styles.modalFormInputOrg}
{...bindOrganisationName}
id={emailFill.emailFill}
name={emailFill.emailFill}
label="Email"
placeholder="[email protected]"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<div className={styles.institutionSubtitle}>
{registration.data.accountType === 'enterprise'
? 'The supplied email address must correspond to the organization that you select.'
: 'The supplied email address must correspond to the institution that you select.'}
</div>
</>
{registration.data.accountType !== 'personal' && (
<DropdownInput
elemOrganisationName={elemOrganisationName}
bindOrganisationName={bindOrganisationName}
registration={registration}
organisationNameSuggestions={organisationNameSuggestions}
/>
)}

<CountrySelect onChange={countryOnChange} />

{registration.data.accountType === 'institution' && (
<div className={styles.typeMainWrapper}>
<div className={styles.typeWrapper}>
<div className={styles.titleWrapper}>
<span className={styles.title}>
{text.membershipType.title}
</span>
</div>
<Markdown className={styles.typeText}>
{router.pathname.includes('api')
? text.membershipType.typeText
: text.membershipType.typeTextChecked}
</Markdown>
</div>
</div>
)}
{registration.data.accountType === 'institution' && (
<TextField
id={elemLibraryEmail}
name={elemLibraryEmail}
label="Could you please provide us with the email for your library contact?"
placeholder="[email protected]"
defaultValue={emailFill.emailFill}
type="email"
{...bindLibraryEmail}
/>
)}
<div>
<TextField
className={styles.description}
id={elemLastDescription}
name={elemLastDescription}
label="Describe the use case in which you would like to use CORE data"
placeholder="Text..."
type="textarea"
value={description}
required
{...bindDescription}
/>
{description.trim().split(/\s+/).length > 150 && (
<div style={{ color: 'red' }}>
Word count exceeds the limit (150 words)
</div>
)}
<span className={styles.wordCount}>Max 150 words.</span>
</div>
<div className={styles.buttonGroup}>
<Button variant="text" onClick={onCloseModal}>
cancel
Expand Down
Loading

0 comments on commit a6eb331

Please sign in to comment.