diff --git a/packages/components/src/DonationRequest/DonationRequest.test.tsx b/packages/components/src/DonationRequest/DonationRequest.test.tsx
index b8ddcc7761..51dbbc0a73 100644
--- a/packages/components/src/DonationRequest/DonationRequest.test.tsx
+++ b/packages/components/src/DonationRequest/DonationRequest.test.tsx
@@ -4,7 +4,7 @@ import { fireEvent } from '@testing-library/react'
import { describe, expect, it, vi } from 'vitest'
import { render } from '../test/utils'
-import { BUTTON_LABEL,DonationRequest } from './DonationRequest'
+import { BUTTON_LABEL, DonationRequest } from './DonationRequest'
describe('DonationRequest', () => {
it('shows the expected content', async () => {
diff --git a/packages/components/src/DonationRequest/DonationRequest.tsx b/packages/components/src/DonationRequest/DonationRequest.tsx
index c4981f130c..6663ee9cd7 100644
--- a/packages/components/src/DonationRequest/DonationRequest.tsx
+++ b/packages/components/src/DonationRequest/DonationRequest.tsx
@@ -99,6 +99,7 @@ export const DonationRequest = (props: IProps) => {
href={link}
onClick={callback}
data-cy="DonationRequestSkip"
+ data-testid="DonationRequestSkip"
>
diff --git a/packages/components/src/DownloadButton/DownloadButton.stories.tsx b/packages/components/src/DownloadButton/DownloadButton.stories.tsx
index 5966326cc0..95984d6be6 100644
--- a/packages/components/src/DownloadButton/DownloadButton.stories.tsx
+++ b/packages/components/src/DownloadButton/DownloadButton.stories.tsx
@@ -7,4 +7,14 @@ export default {
component: DownloadButton,
} as Meta
-export const Default: StoryFn = () =>
+export const Default: StoryFn = () => (
+ {}} />
+)
+
+export const CustomDetails: StoryFn = () => (
+ {}}
+ glyph="download-cloud"
+ label="Hello there"
+ />
+)
diff --git a/packages/components/src/DownloadButton/DownloadButton.test.tsx b/packages/components/src/DownloadButton/DownloadButton.test.tsx
index 6d626be9aa..930ed05509 100644
--- a/packages/components/src/DownloadButton/DownloadButton.test.tsx
+++ b/packages/components/src/DownloadButton/DownloadButton.test.tsx
@@ -3,14 +3,22 @@ import '@testing-library/jest-dom/vitest'
import { describe, expect, it } from 'vitest'
import { render } from '../test/utils'
-import { Default } from './DownloadButton.stories'
+import { CustomDetails, Default } from './DownloadButton.stories'
import type { IProps } from './DownloadButton'
describe('DownloadButton', () => {
- it('validates the component behaviour', () => {
+ it('renders the default state', () => {
const { getByText } = render()
expect(getByText('Download files')).toBeInTheDocument()
})
+
+ it('renders the custom options', () => {
+ const { getByText } = render(
+ ,
+ )
+
+ expect(getByText('Hello there')).toBeInTheDocument()
+ })
})
diff --git a/packages/components/src/DownloadButton/DownloadButton.tsx b/packages/components/src/DownloadButton/DownloadButton.tsx
index ea663ee146..b16c29e12f 100644
--- a/packages/components/src/DownloadButton/DownloadButton.tsx
+++ b/packages/components/src/DownloadButton/DownloadButton.tsx
@@ -3,12 +3,21 @@ import { Flex, Text } from 'theme-ui'
import { Icon } from '../Icon/Icon'
import { Tooltip } from '../Tooltip/Tooltip'
+import type { IGlyphs } from '../Icon/types'
+
export interface IProps {
- onClick?: () => void
+ onClick: () => void
isLoggedIn?: boolean
+ label?: string
+ glyph?: keyof IGlyphs
}
-export const DownloadButton = ({ onClick, isLoggedIn }: IProps) => {
+export const DownloadButton = ({
+ glyph,
+ isLoggedIn,
+ label,
+ onClick,
+}: IProps) => {
return (
<>
{
data-testid="downloadButton"
data-tip={!isLoggedIn ? 'Login to download' : ''}
>
-
+
- Download files
+ {label ? label : 'Download files'}
diff --git a/packages/components/src/DownloadFileFromLink/DownloadFileFromLink.tsx b/packages/components/src/DownloadFileFromLink/DownloadFileFromLink.tsx
index fe435f71c6..1649e4d6e0 100644
--- a/packages/components/src/DownloadFileFromLink/DownloadFileFromLink.tsx
+++ b/packages/components/src/DownloadFileFromLink/DownloadFileFromLink.tsx
@@ -15,7 +15,7 @@ export const DownloadFileFromLink = (props: DownloadFileFromLinkProps) => {
href={props.link}
onClick={() => props.handleClick && props.handleClick()}
>
-
+ {}} />
) : (
Promise
+ handleClick?: () => void
redirectToSignIn?: () => Promise
}
@@ -72,6 +75,8 @@ export const DownloadStaticFile = ({
allowDownload,
handleClick,
redirectToSignIn,
+ forDonationRequest,
+ isLoggedIn,
}: IProps) => {
const size = bytesToSize(file.size || 0)
@@ -79,9 +84,11 @@ export const DownloadStaticFile = ({
return null
}
+ const forDownload = allowDownload && file.downloadUrl && !redirectToSignIn
+
return (
<>
- {allowDownload && file.downloadUrl && !redirectToSignIn ? (
+ {forDownload && (
handleClick && handleClick()}
@@ -91,7 +98,18 @@ export const DownloadStaticFile = ({
>
- ) : (
+ )}
+
+ {forDonationRequest && (
+ handleClick && handleClick()}
+ isLoggedIn={isLoggedIn}
+ label={`${file.name} (${size})`}
+ glyph="download-cloud"
+ />
+ )}
+
+ {!forDownload && !forDonationRequest && (
({
__esModule: true,
useCommonStores: vi.fn(),
}))
-const userToMock = (user) => {
+const userToMock = (user?: IUserPPDB) => {
return (useCommonStores as Mock).mockImplementation(() => ({
- stores: { userStore: { user } },
+ stores: {
+ userStore: { user: user ?? undefined },
+ themeStore: {
+ currentTheme: {
+ donations: {
+ body: '',
+ iframeSrc: '',
+ imageURL: '',
+ },
+ },
+ },
+ },
}))
}
describe('DownloadFileFromLink', () => {
it('when logged out, requires users to login', () => {
+ userToMock()
const { getAllByTestId } = render(
,
)
@@ -41,7 +57,7 @@ describe('DownloadFileFromLink', () => {
expect(mockedUsedNavigate).toHaveBeenCalledWith('/sign-in')
})
- it('when logged in, opens the link via handleClick', () => {
+ it('when logged in, opens via handleClick', () => {
const user = FactoryUser()
userToMock(user)
@@ -50,7 +66,9 @@ describe('DownloadFileFromLink', () => {
,
)
@@ -60,23 +78,64 @@ describe('DownloadFileFromLink', () => {
expect(handleClick).toHaveBeenCalled()
})
- it('when a beta-tester, opens the donation modal', () => {
+ it('when a beta-tester, opens the donation modal for fileLink', () => {
const user = FactoryUser({ userRoles: [UserRole.BETA_TESTER] })
userToMock(user)
const handleClick = vi.fn()
+ const fileLink = 'http://youtube.com/'
const { getAllByTestId } = render(
,
)
const downloadButton = getAllByTestId('downloadButton')[0]
fireEvent.click(downloadButton)
+ expect(getAllByTestId('DonationRequestSkip')[0]).toHaveAttribute(
+ 'href',
+ fileLink,
+ )
+ expect(getAllByTestId('DonationRequest')[0]).toBeInTheDocument()
+ expect(handleClick).not.toHaveBeenCalled()
+ })
+
+ it('when a beta-tester, opens the donation modal for files', () => {
+ const user = FactoryUser({ userRoles: [UserRole.BETA_TESTER] })
+ userToMock(user)
+
+ const downloadUrl = 'http://great-url.com/'
+ const handleClick = vi.fn()
+
+ const { getAllByTestId } = render(
+ ,
+ )
+
+ const downloadButton = getAllByTestId('downloadButton')[0]
+ fireEvent.click(downloadButton)
+
+ expect(getAllByTestId('DonationRequestSkip')[0]).toHaveAttribute(
+ 'href',
+ downloadUrl,
+ )
expect(getAllByTestId('DonationRequest')[0]).toBeInTheDocument()
expect(handleClick).not.toHaveBeenCalled()
})
diff --git a/src/common/DownloadWithDonationAsk.tsx b/src/common/DownloadWithDonationAsk.tsx
index c7431ccf87..90360b0e41 100644
--- a/src/common/DownloadWithDonationAsk.tsx
+++ b/src/common/DownloadWithDonationAsk.tsx
@@ -3,18 +3,23 @@ import { useNavigate } from 'react-router-dom'
import {
DonationRequestModal,
DownloadButton,
+ DownloadCounter,
DownloadFileFromLink,
+ DownloadStaticFile,
} from 'oa-components'
import { useCommonStores } from './hooks/useCommonStores'
import { AuthWrapper } from './AuthWrapper'
import type { UserRole } from 'src/models'
+import type { IUploadedFileMeta } from 'src/stores/storage'
export interface IProps {
handleClick: () => Promise
isLoggedIn: boolean
- link: string
+ fileDownloadCount: number
+ fileLink: string | undefined
+ files: (IUploadedFileMeta | File | null)[] | undefined
}
/*
@@ -23,8 +28,9 @@ export interface IProps {
can/should move to the component library.
*/
export const DownloadWithDonationAsk = (props: IProps) => {
- const { handleClick, isLoggedIn, link } = props
+ const { handleClick, isLoggedIn, fileDownloadCount, fileLink, files } = props
const [isModalOpen, setIsModalOpen] = useState(false)
+ const [link, setLink] = useState('')
const navigate = useNavigate()
const { themeStore } = useCommonStores().stores
@@ -35,14 +41,9 @@ export const DownloadWithDonationAsk = (props: IProps) => {
toggleIsModalOpen()
}
- if (!isLoggedIn) {
- return (
- navigate('/sign-in')}
- isLoggedIn={false}
- />
- )
- }
+ const filteredFiles: IUploadedFileMeta[] | undefined = files?.filter(
+ (file): file is IUploadedFileMeta => file !== null && 'downloadUrl' in file,
+ )
return (
<>
@@ -59,11 +60,57 @@ export const DownloadWithDonationAsk = (props: IProps) => {
+ <>
+ {!isLoggedIn && (
+ navigate('/sign-in')}
+ isLoggedIn={false}
+ />
+ )}
+
+ {isLoggedIn && fileLink && (
+
+ )}
+ {isLoggedIn &&
+ filteredFiles &&
+ filteredFiles.map((file, index) => (
+
+ ))}
+ >
}
>
-
+ <>
+ {fileLink && (
+ {
+ setLink(fileLink)
+ toggleIsModalOpen()
+ }}
+ isLoggedIn
+ />
+ )}
+ {filteredFiles &&
+ filteredFiles.map((file, index) => (
+ {
+ setLink(file.downloadUrl)
+ toggleIsModalOpen()
+ }}
+ forDonationRequest
+ isLoggedIn
+ />
+ ))}
+ >
+
>
)
}
diff --git a/src/pages/Howto/Content/Howto/HowtoDownloads/HowtoDownloads.tsx b/src/pages/Howto/Content/Howto/HowtoDownloads/HowtoDownloads.tsx
index af80baa456..5f01e09c35 100644
--- a/src/pages/Howto/Content/Howto/HowtoDownloads/HowtoDownloads.tsx
+++ b/src/pages/Howto/Content/Howto/HowtoDownloads/HowtoDownloads.tsx
@@ -1,6 +1,4 @@
import { useState } from 'react'
-import { useNavigate } from 'react-router-dom'
-import { DownloadCounter, DownloadStaticFile } from 'oa-components'
import { DownloadWithDonationAsk } from 'src/common/DownloadWithDonationAsk'
import { useCommonStores } from 'src/common/hooks/useCommonStores'
import { Flex } from 'theme-ui'
@@ -23,13 +21,8 @@ export const HowtoDownloads = ({ howto, loggedInUser }: IProps) => {
const { _id, files, fileLink, total_downloads } = howto
const [fileDownloadCount, setFileDownloadCount] = useState(total_downloads)
- const navigate = useNavigate()
const { howtoStore } = useCommonStores().stores
- const redirectToSignIn = async () => {
- navigate('/sign-in')
- }
-
const incrementDownloadCount = async () => {
const updatedDownloadCount = await howtoStore.incrementDownloadCount(_id)
setFileDownloadCount(updatedDownloadCount!)
@@ -54,31 +47,13 @@ export const HowtoDownloads = ({ howto, loggedInUser }: IProps) => {
return (
- {fileLink && (
-
- )}
- {files &&
- files
- .filter(Boolean)
- .map(
- (file, index) =>
- file && (
-
- ),
- )}
-
+
)
}