Skip to content

Commit

Permalink
Hooks ahhh
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Bendel authored and Chris Bendel committed Nov 7, 2023
1 parent 1b195b6 commit 6729ee6
Show file tree
Hide file tree
Showing 15 changed files with 66 additions and 62 deletions.
1 change: 1 addition & 0 deletions frontend/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = {
parser: '@typescript-eslint/parser',
'extends': [
'eslint:recommended',
'plugin:react-hooks/recommended',
// "plugin:react/recommended", // TODO: enable once
],
'ignorePatterns': ['**/api/**/*.js'],
Expand Down
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"@faker-js/faker": "^6.1.2",
"@playwright/test": "^1.36.2",
"@vitejs/plugin-react-refresh": "^1.3.6",
"eslint-plugin-react-hooks": "^4.6.0",
"expect-playwright": "^0.8.0",
"npm-run-all": "^4.1.5",
"typescript": "^4.7.4",
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/components/incorrect-user.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { React } from '@common'
import { OXColoredStripe } from '@components'
import { loginURL } from '@lib'
import { loginURL, useEnvironment } from '@lib'

export interface IncorrectUserProps {
desiredRole?: string
}
export const IncorrectUser:React.FC<IncorrectUserProps> = ({ desiredRole }) => {
const env = useEnvironment()

return (
<div className="incorrect-user" data-testid="incorrect-user-panel">
<OXColoredStripe />
<div className="container mt-4">
<h1>Looks like you‘re not logged in{desiredRole ? ` as a ${desiredRole}` : ''}.</h1>
<p>Please <a data-testid="login-link" href={loginURL()}>log in</a> before using this site</p>
<p>Please <a data-testid="login-link" href={loginURL(env)}>log in</a> before using this site</p>
</div>
</div>
)
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/multi-session-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export const MultiSessionBar: FC<{ study: ParticipantStudy }> = ({ study }) => {

const [first, last] = study.stages
const perc = (filter(study.stages, 'isCompleted').length / study.stages.length) * 100

// TODO Come back to this
// eslint-disable-next-line react-hooks/rules-of-hooks
const duration = useMemo(() => {
const d = last.availableAfterDays || 0
if (d === 0) return 'immediately'
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/navbar/account-links.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function AccountLinks() {
</Menu.Item>
</StyledLink>
{!env.isImpersonating &&
<StyledLink to={logoutURL()} onClick={() => {
<StyledLink to={logoutURL(env)} onClick={() => {
logout().then(() => refetch())
}}>
<Menu.Item>
Expand Down
33 changes: 14 additions & 19 deletions frontend/src/lib/environment-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { React } from '@common'
import { UserInfo } from '@models'
import { ErrorPage, IncorrectUser, LoadingAnimation } from '@components'

import { ENV } from './env'
import { useApi } from './api-config'
import { useQuery } from 'react-query';
Expand Down Expand Up @@ -57,10 +56,9 @@ export const useCurrentResearcher = () => {
}

export const useUserInfo = () => {
console.log('inside useUserInfo')
const env = useEnvironment()
return useQuery('fetchUserInfo', () => {
console.log('inside use query')
return fetchUserInfo()
return fetchUserInfo(env)
})
}

Expand All @@ -72,40 +70,37 @@ export const useUserPreferences = () => {
})
}

export const locationOrigin = () => {
const env = useEnvironment()
console.log(env)
export const locationOrigin = (env: Environment) => {
if (env.accountsEnvName === 'production') {
return `https://openstax.org`;
}
return `https://${env.accountsEnvName}.openstax.org`;
}

export const loginURL = () => {
const url = accountsUrl()
export const loginURL = (env: Environment) => {
const url = accountsUrl(env)
if (ENV.IS_DEV_MODE) return url

return `${url}/login/?r=${encodeURIComponent(window.location.href)}`
}

export const logoutURL = () => {
export const logoutURL = (env: Environment) => {
if (ENV.IS_DEV_MODE) return '/dev/user';
const homepage = encodeURIComponent(`${locationOrigin()}/kinetic`);
return `${accountsUrl()}/signout?r=${homepage}`;
const homepage = encodeURIComponent(`${locationOrigin(env)}/kinetic`);
return `${accountsUrl(env)}/signout?r=${homepage}`;
}

export const accountsUrl = (): string => {
export const accountsUrl = (env: Environment): string => {
if (ENV.IS_DEV_MODE) return '/dev/user'
return `${locationOrigin()}/accounts`;
return `${locationOrigin(env)}/accounts`;
}

export const accountsApiUrl = (): string => {
export const accountsApiUrl = (env: Environment): string => {
if (ENV.IS_DEV_MODE) return `${ENV.API_ADDRESS}/development/user/api/user`
return `${accountsUrl()}/api/user`
return `${accountsUrl(env)}/api/user`
}

export const fetchUserInfo = async (): Promise<UserInfo> => {
console.log('fetching user info')
const resp = await fetch(`${accountsApiUrl()}`, { credentials: 'include' })
export const fetchUserInfo = async (env: Environment): Promise<UserInfo> => {
const resp = await fetch(`${accountsApiUrl(env)}`, { credentials: 'include' })
return await resp.json()
}
3 changes: 2 additions & 1 deletion frontend/src/screens/analysis/runs-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ const StatusIcon = styled(Icon)({
})

const useRunsTable = (analysis: Analysis) => {
const api = useApi()

const [sorting, setSorting] = React.useState<SortingState>([{
id: 'startedAt',
desc: true,
Expand Down Expand Up @@ -181,7 +183,6 @@ const useRunsTable = (analysis: Analysis) => {
size: 375,
enableSorting: false,
cell: ({ row: { original: run } }: { row: { original: AnalysisRun } }) => {
const api = useApi()
const canDownload = hasRunSucceeded(run)
const cancelRun = () => {
api.updateAnalysisRun({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,18 @@ const StyledForm = styled(Form<Researcher>)(({ readOnly }) => ({
export const ResearcherAccountForm: React.FC<{className?: string}> = ({ className }) => {
const api = useApi()
const [researcher, setResearcher] = useState(useCurrentResearcher())
const [institution, setInstitution] = useState(researcher?.institution)
const { refetch: refetchEnv } = useFetchEnvironment()
const { data: userInfo, refetch: refetchUser } = useUserInfo()

if (!researcher) {
return null
}

// Default to OpenStax accounts first/last name if blank
researcher.firstName = researcher.firstName || userInfo?.first_name
researcher.lastName = researcher.lastName || userInfo?.last_name

const [institution, setInstitution] = useState(researcher.institution)

const saveResearcher = async (researcher: Researcher) => {
try {
if (!researcher.id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Box, Col, Footer, Form, HelpLink, Icon, Modal, ResourceLinks, Tooltip, TopNavBar } from '@components';
import { React, styled, useState } from '@common';
import { accountsUrl, useApi, useCurrentResearcher } from '@lib';
import { accountsUrl, useApi, useCurrentResearcher, useEnvironment } from '@lib';
import { colors } from '@theme';
import { Researcher } from '@api';
import CustomerSupportImage from '../../../components/customer-support-image';
Expand All @@ -11,6 +11,7 @@ import { ResearcherAccountForm } from './researcher-account-form';

export default function ResearcherAccountPage() {
const researcher = useCurrentResearcher()
const env = useEnvironment()

if (!researcher) {
return null
Expand All @@ -23,7 +24,7 @@ export default function ResearcherAccountPage() {
<Col sm={9} css={{ paddingRight: '2rem' }} direction='column'>
<Box justify='between' height='40px'>
<h3>My Account</h3>
<a href={`${accountsUrl()}`} target='_blank'>
<a href={`${accountsUrl(env)}`} target='_blank'>
<span>Update Email & Password</span>
<Icon icon="chevronRight" />
</a>
Expand Down Expand Up @@ -122,6 +123,9 @@ export const IRB = () => {
const Avatar: React.FC = () => {
const api = useApi()
const [researcher, setResearcher] = useState(useCurrentResearcher())
const [avatar, setAvatar] = useState<Blob>()
const [isShowingModal, setShowingModal] = useState(false)

if (!researcher) {
return null
}
Expand All @@ -133,8 +137,7 @@ const Avatar: React.FC = () => {
height: 125,
width: 125,
})
const [avatar, setAvatar] = useState<Blob>()
const [isShowingModal, setShowingModal] = useState(false)

const onHide = () => setShowingModal(false)

const saveResearcher = async (researcher: Researcher) => {
Expand All @@ -149,7 +152,6 @@ const Avatar: React.FC = () => {
onHide()
}


return (
<Box className='col-2' justify='start' direction='column'>
<Box onClick={() => setShowingModal(true)} direction='column' align='center' gap='large' css={{ cursor: 'pointer' }} >
Expand Down
9 changes: 3 additions & 6 deletions frontend/src/screens/researcher/studies/create/edit-study.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, React, useEffect, useMemo, useNavigate, useParams, useState, Yup } from '@common'
import { Box, React, useMemo, useNavigate, useParams, useState, Yup } from '@common'
import { useApi, useQueryParam } from '@lib';
import { isDraft, useFetchStudy } from '@models';
import {
Expand All @@ -24,6 +24,7 @@ import { colors } from '@theme';
import { ReviewStudy, SubmitStudyModal } from './forms/review-study';
import { noop } from 'lodash-es';
import { useLocalstorageState } from 'rooks';
import { Navigate } from 'react-router-dom';

const buildValidationSchema = (allOtherStudies: Study[]) => {
return Yup.object().shape({
Expand All @@ -46,7 +47,6 @@ const getFormDefaults = (study: Study, step: StudyStep) => {
}

export default function EditStudy() {
const nav = useNavigate()
const id = useParams<{ id: string }>().id
const { loading, study, setStudy, allStudies } = useFetchStudy(id || 'new')

Expand All @@ -55,10 +55,7 @@ export default function EditStudy() {
}

if (!study) {
useEffect(() => {
nav('/studies')
}, [])
return <></>
return <Navigate to={'/studies'} />
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ const AdditionalSession: FC<{
onDelete: (index: number) => void,
session: Stage | NewStage
}> = ({ index, onDelete, session }) => {
const { register, getValues } = useFormContext()

// don't show the first session
if (index === 0) return null
const { register, getValues } = useFormContext()
const prevStagePoints = getValues(`stages.${index - 1}.points`)

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,11 +277,12 @@ const ShareStudy: FC<{study: Study}> = () => {
}

const ClosingCriteria: FC<{study: Study}> = ({ study }) => {
const { watch, setValue, getValues, trigger } = useFormContext()

const firstStage = getFirstStage(study)
if (!firstStage) {
return null
}
const { watch, setValue, getValues, trigger } = useFormContext()

return (
<Box gap='xlarge'>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, React, useEffect, useNavigate, useParams } from '@common';
import { Box, React, useNavigate, useParams } from '@common';
import { Study } from '@api';
import { Col, CollapsibleSection, ExitButton, LoadingAnimation, Page, ResearcherButton } from '@components';
import { getStudyLead, getStudyPi, isReadyForLaunch, isWaiting, useFetchStudy } from '@models';
Expand All @@ -8,33 +8,24 @@ import { FinalizeStudy } from './finalize-study';
import Waiting from '@images/study-creation/waiting.svg'
import { EditSubmittedStudy } from './edit-submitted-study';
import { useQueryParam } from '@lib';
import { Link } from 'react-router-dom';
import { Link, Navigate } from 'react-router-dom';

export default function StudyOverview() {
const nav = useNavigate()
const id = useParams<{ id: string }>().id
const { loading, study } = useFetchStudy(id!)

if (!id) {
useEffect(() => {
nav('/studies')
}, [])
return <></>
return <Navigate to='/studies' />
}

const { loading, study } = useFetchStudy(id)

if (loading) {
return <LoadingAnimation />
}

if (!study) {
useEffect(() => {
nav('/studies')
}, [])
return <></>
return <Navigate to='/studies' />
}


return (
<Page hideFooter backgroundColor={colors.white}>
<StudyOverviewContent study={study} />
Expand Down
23 changes: 13 additions & 10 deletions frontend/src/screens/study-landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,7 @@ export default function UsersStudies() {
const abort = useQueryParam('abort') == 'true'

const md = useQueryParam('md') || {}
if (!user) {
return <IncorrectUser />
}

const onNav = () => {
if (isIframed()) {
sendMessageToParent({ closeStudyModal: true })
} else {
nav('/studies')
}
}
useEffect(() => {
let isPreview = false
try {
Expand All @@ -141,6 +131,19 @@ export default function UsersStudies() {
.catch(setError)
}, [])

if (!user) {
return <IncorrectUser />
}

const onNav = () => {
if (isIframed()) {
sendMessageToParent({ closeStudyModal: true })
} else {
nav('/studies')
}
}


if (error) {
return <ErrorPage error={error} />
}
Expand Down
5 changes: 5 additions & 0 deletions frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2076,6 +2076,11 @@ escodegen@^2.0.0:
optionalDependencies:
source-map "~0.6.1"

eslint-plugin-react-hooks@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3"
integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==

eslint-plugin-react@^7.29.4:
version "7.33.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.0.tgz#6c356fb0862fec2cd1b04426c669ea746e9b6eb3"
Expand Down

0 comments on commit 6729ee6

Please sign in to comment.