diff --git a/components/FileUploader/DropZone/DropZone.module.css b/components/FileUploader/DropZone/DropZone.module.css new file mode 100644 index 0000000..bdeab14 --- /dev/null +++ b/components/FileUploader/DropZone/DropZone.module.css @@ -0,0 +1,8 @@ +.container, .textContainer { + width: var(--sizes-100); + height: var(--sizes-100); + display: flex; + align-items: center; + justify-content: center; +} + diff --git a/components/FileUploader/DropZone/DropZone.tsx b/components/FileUploader/DropZone/DropZone.tsx new file mode 100644 index 0000000..de9e6b4 --- /dev/null +++ b/components/FileUploader/DropZone/DropZone.tsx @@ -0,0 +1,40 @@ +import React from "react"; +import { + DropEvent, + useDropzone, + FileRejection, + DropzoneOptions, + DropzoneState, +} from "react-dropzone"; +import styles from "./DropZone.module.css"; +import clsx from "clsx"; + +export type OnUpload = ( + acceptedFiles: T[], + fileRejections: FileRejection[], + event: DropEvent +) => void; + +type Props = { + children: (state: DropzoneState) => string | React.ReactElement; + options?: DropzoneOptions; + className?: string; +}; + +export const DropZone: React.VFC = ({ + options, + children, + className, +}) => { + const dropZoneState = useDropzone({ + ...options, + }); + const { getRootProps, getInputProps } = dropZoneState; + + return ( +
+ +
{children(dropZoneState)}
+
+ ); +}; diff --git a/components/FileUploader/DropZone/index.ts b/components/FileUploader/DropZone/index.ts new file mode 100644 index 0000000..7afb31b --- /dev/null +++ b/components/FileUploader/DropZone/index.ts @@ -0,0 +1 @@ +export * from "./DropZone"; diff --git a/components/FileUploader/FileUploader.module.css b/components/FileUploader/FileUploader.module.css index bdeab14..8104fa6 100644 --- a/components/FileUploader/FileUploader.module.css +++ b/components/FileUploader/FileUploader.module.css @@ -1,8 +1,32 @@ -.container, .textContainer { +.container { width: var(--sizes-100); - height: var(--sizes-100); + height: 150px; + cursor: copy; + padding: var(--spacings-s); + border: var(--borders-strong); display: flex; align-items: center; + font-weight: var(--font-weights-bold); + border-radius: var(--radii-s); justify-content: center; + border-color: var(--colors-gray-lightest); + transition: var(--transitions-fast); } +.container.loading { + cursor: unset; +} + +.container.loading:hover { + box-shadow: unset; +} + +.container:hover { + box-shadow: var(--shadows-medium); +} + +@media screen and (max-width: 768px) { + .container { + padding: var(--spacings-s); + } +} \ No newline at end of file diff --git a/components/FileUploader/FileUploader.tsx b/components/FileUploader/FileUploader.tsx index f2138d5..438bb59 100644 --- a/components/FileUploader/FileUploader.tsx +++ b/components/FileUploader/FileUploader.tsx @@ -1,40 +1,79 @@ -import React from "react"; -import { - DropEvent, - useDropzone, - FileRejection, - DropzoneOptions, - DropzoneState, -} from "react-dropzone"; -import styles from "./FileUploader.module.css"; +import React, { useCallback } from "react"; +import Loader from "react-spinners/PacmanLoader"; import clsx from "clsx"; - -export type OnUpload = ( - acceptedFiles: T[], - fileRejections: FileRejection[], - event: DropEvent -) => void; +import { ProjectInfo } from "../../types/projects"; +import { acceptedFileConfigs } from "../../utils/config"; +import { DropZone, OnUpload } from "./DropZone"; +import styles from "./FileUploader.module.css"; type Props = { - children: (state: DropzoneState) => string | React.ReactElement; - options?: DropzoneOptions; - className?: string; + onUpload: (fundingLinks?: ProjectInfo[]) => void; + isLoading?: boolean; + setIsLoading: (isLoading: boolean) => void; }; +function getAcceptedFileExtensions() { + return acceptedFileConfigs.map(({ extension }) => extension); +} + export const FileUploader: React.VFC = ({ - options, - children, - className, + onUpload, + isLoading, + setIsLoading, }) => { - const dropZoneState = useDropzone({ - ...options, - }); - const { getRootProps, getInputProps } = dropZoneState; + const onDrop: OnUpload = useCallback( + async (acceptedFiles) => { + setIsLoading(true); + try { + const formData = new FormData(); + + acceptedFiles.forEach((file) => { + formData.append("file", file); + }); + + const response = await fetch("/api/get-grouped-funding-links", { + method: "POST", + body: formData, + }); + + const groupedFundingLinks = await response.json(); + + onUpload(groupedFundingLinks || []); + } catch (e) { + onUpload([]); + } finally { + setIsLoading(false); + } + }, + [onUpload, setIsLoading] + ); + + const renderText = useCallback( + ({ isDragActive }) => { + if (isLoading) { + return ; + } + + if (isDragActive) { + return "Drop your package.json here ..."; + } + + return "Drag 'n' drop your package.json, or click to select it from your computer"; + }, + [isLoading] + ); return ( -
- -
{children(dropZoneState)}
-
+ + {renderText} + ); }; diff --git a/components/Home/Home.tsx b/components/Home/Home.tsx index 7da9e2f..246eaa8 100644 --- a/components/Home/Home.tsx +++ b/components/Home/Home.tsx @@ -2,7 +2,7 @@ import React from "react"; import { useProjects } from "../../contexts/ProjectsContext"; import { FundingGroup } from "../FundingGroup"; -import { PackageJsonUploader } from "../PackageJsonUploader"; +import { FileUploader } from "../FileUploader"; import styles from "./Home.module.css"; import Bleed from "nextra-theme-docs/bleed"; @@ -15,7 +15,7 @@ export const Home: React.VFC = () => {

Sponsorhello

- void; - isLoading?: boolean; - setIsLoading: (isLoading: boolean) => void; -}; - -function getAcceptedFileExtensions() { - return acceptedFileConfigs.map((config) => { - const parts = config.name.split("."); - - return `.${parts[parts.length - 1]}`; - }); -} - -export const PackageJsonUploader: React.VFC = ({ - onUpload, - isLoading, - setIsLoading, -}) => { - const onDrop: OnUpload = useCallback( - async (acceptedFiles) => { - setIsLoading(true); - try { - const formData = new FormData(); - - acceptedFiles.forEach((file) => { - formData.append("file", file); - }); - - const response = await fetch("/api/get-grouped-funding-links", { - method: "POST", - body: formData, - }); - - const groupedFundingLinks = await response.json(); - - onUpload(groupedFundingLinks || []); - } catch (e) { - onUpload([]); - } finally { - setIsLoading(false); - } - }, - [onUpload, setIsLoading] - ); - - const renderText = useCallback( - ({ isDragActive }: DropzoneState) => { - if (isLoading) { - return ; - } - - if (isDragActive) { - return "Drop your package.json here ..."; - } - - return "Drag 'n' drop your package.json, or click to select it from your computer"; - }, - [isLoading] - ); - - return ( - - {renderText} - - ); -}; diff --git a/components/PackageJsonUploader/index.ts b/components/PackageJsonUploader/index.ts deleted file mode 100644 index f4977f5..0000000 --- a/components/PackageJsonUploader/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./PackageJsonUploader"; diff --git a/middlewares/fileParser/fileParser.ts b/middlewares/fileParser/fileParser.ts index 4c5bb7b..2b79e3e 100644 --- a/middlewares/fileParser/fileParser.ts +++ b/middlewares/fileParser/fileParser.ts @@ -14,7 +14,9 @@ function getFileConfig( return acceptedFileConfigs.find( (config) => - config.name === file.originalFilename && config.mimetype === file.mimetype + file.originalFilename && + config.name.test(file.originalFilename) && + config.mimetype === file.mimetype ); } diff --git a/pages/api/get-grouped-funding-links.ts b/pages/api/get-grouped-funding-links.ts index 2a79ee2..0b7afe5 100644 --- a/pages/api/get-grouped-funding-links.ts +++ b/pages/api/get-grouped-funding-links.ts @@ -20,6 +20,7 @@ const handler = nc({ }) .use(fileParser) .post(async (req, res) => { + console.log(req.body.platform, req.body.content); platformsClient.parseFileContent(req.body.platform, req.body.content); const groupedFundingLinks = await platformsClient.getFunding( diff --git a/types/dependencies.ts b/types/dependencies.ts index 7db7e71..d50b2aa 100644 --- a/types/dependencies.ts +++ b/types/dependencies.ts @@ -1,5 +1,6 @@ export type DependenciesFileConfig = { - name: string; + name: RegExp; + extension: string; mimetype: string; platform: string; }; diff --git a/utils/config.ts b/utils/config.ts index 70a3d76..1fc10da 100644 --- a/utils/config.ts +++ b/utils/config.ts @@ -2,8 +2,15 @@ import { DependenciesFileConfig } from "../types/dependencies"; export const acceptedFileConfigs: DependenciesFileConfig[] = [ { - name: "package.json", - mimetype: "application/json", + name: /package.json/g, platform: "npm", + mimetype: "application/json", + extension: ".json", + }, + { + name: /\w*.csproj/g, + platform: "nuget", + mimetype: "application/octet-stream", + extension: ".csproj", }, ];