Skip to content

Commit

Permalink
Merge pull request #8 from thunderstore-io/feature/package-upload
Browse files Browse the repository at this point in the history
Add PackageUpload component and set some foundations
  • Loading branch information
nihaals authored Apr 2, 2021
2 parents 6694729 + 1539c5b commit 742759c
Show file tree
Hide file tree
Showing 24 changed files with 1,517 additions and 54 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"plugin:prettier/recommended"
],
"rules": {
"react/react-in-jsx-scope": "off"
"react/react-in-jsx-scope": "off",
"react/prop-types": "off"
}
}
1 change: 1 addition & 0 deletions nextjs/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NEXT_PUBLIC_API_URL=http://localhost/api/
2 changes: 2 additions & 0 deletions nextjs/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/node_modules/
/.next/
/out/
/.env.local
25 changes: 1 addition & 24 deletions nextjs/README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,11 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
# nextjs

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.

[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.

The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
13 changes: 8 additions & 5 deletions nextjs/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { ChakraProvider, CSSReset } from "@chakra-ui/react";
import { AppProps } from "next/dist/next-server/lib/router/router";
import { theme } from "thunderstore-components";
import { RootWrapper, theme } from "thunderstore-components";

function MyApp({ Component, pageProps }: AppProps): JSX.Element {
return (
<ChakraProvider theme={theme}>
<CSSReset />
<RootWrapper
theme={theme}
thunderstoreProviderValue={{
apiUrl: process.env.NEXT_PUBLIC_API_URL || "https://thunderstore.io/api/",
}}
>
<Component {...pageProps} />
</ChakraProvider>
</RootWrapper>
);
}

Expand Down
42 changes: 42 additions & 0 deletions nextjs/pages/community-picker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Community, MultiCommunityPicker } from "thunderstore-components";
import React, { useState } from "react";
import { Box, Button, List, ListItem } from "@chakra-ui/react";

const CommunityPickerPage: React.FC<Record<string, never>> = () => {
const [disabled, setDisabled] = useState(false);
const [disabling, setDisabling] = useState(false);
const [communities, setCommunities] = useState<Community[]>([]);

return (
<Box p={2}>
<Button
mb={2}
onClick={() => {
setDisabling(true);
setTimeout(() => {
setDisabled(!disabled);
setDisabling(false);
}, 1000);
}}
disabled={disabling}
>
{disabled ? "Enable" : "Disable"}
</Button>
{communities && (
<List mb={2}>
{communities.map((community) => (
<ListItem key={community.identifier}>{community.identifier}</ListItem>
))}
</List>
)}
<MultiCommunityPicker
disabled={disabled}
onChange={(options) => {
setCommunities(options.map((option) => option.community));
}}
/>
</Box>
);
};

export default CommunityPickerPage;
2 changes: 1 addition & 1 deletion nextjs/pages/package-upload.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PackageUpload } from "thunderstore-components";
import React from "react";

const PackageUploadPage: React.FC<never> = () => {
const PackageUploadPage: React.FC<Record<string, never>> = () => {
return <PackageUpload />;
};

Expand Down
34 changes: 34 additions & 0 deletions nextjs/pages/team-picker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { TeamPicker } from "thunderstore-components";
import React, { useState } from "react";
import { Box, Button, Text } from "@chakra-ui/react";

const CommunityPickerPage: React.FC<Record<string, never>> = () => {
const [disabled, setDisabled] = useState(false);
const [disabling, setDisabling] = useState(false);
const [teamName, setTeamName] = useState<string | null>(null);

return (
<Box p={2}>
<Button
mb={2}
onClick={() => {
setDisabling(true);
setTimeout(() => {
setDisabled(!disabled);
setDisabling(false);
}, 1000);
}}
disabled={disabling}
>
{disabled ? "Enable" : "Disable"}
</Button>
<Text>Team name: {teamName}</Text>
<TeamPicker
disabled={disabled}
onChange={(option) => setTeamName(option?.teamName || null)}
/>
</Box>
);
};

export default CommunityPickerPage;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"private": true,
"repository": "https://github.com/thunderstore-io/thunderstore-ui",
"workspaces": [
"nextjs",
"thunderstore-components"
],
"repository": "https://github.com/thunderstore-io/thunderstore-ui",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
Expand Down
20 changes: 16 additions & 4 deletions thunderstore-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,30 @@
"version": "0.1.0",
"description": "Shared components for Thunderstore",
"repository": "https://github.com/thunderstore-io/thunderstore-ui/tree/master/thunderstore-components",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"build": "tsc",
"dev": "tsc --watch"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"dependencies": {
"@chakra-ui/react": "^1.4.1",
"@emotion/react": "^11.1.5",
"@emotion/styled": "^11.1.5",
"adm-zip": "^0.5.3",
"chakra-ui-markdown-renderer": "^1.1.0",
"downshift": "^6.1.1",
"framer-motion": "^4.0.3",
"react-hook-form": "^6.15.5"
"js-cookie": "^2.2.1",
"jszip": "^3.6.0",
"react-dropzone": "^11.3.1",
"react-hook-form": "^6.15.5",
"react-markdown": "^5.0.3",
"react-query": "^3.12.1",
"remark-gfm": "^1.0.0"
},
"devDependencies": {}
"devDependencies": {
"@types/adm-zip": "^0.4.33",
"@types/js-cookie": "^2.2.6"
}
}
49 changes: 49 additions & 0 deletions thunderstore-components/src/components/CommunityPicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Text } from "@chakra-ui/layout";
import React, { useContext } from "react";
import { useQuery } from "react-query";
import { apiFetch } from "../fetch";
import { MultiSelect, MultiSelectProps, SelectOption } from "./Select";
import { ThunderstoreContext } from "./ThunderstoreProvider";

export interface Community {
identifier: string;
name: string;
discord_url: string | null;
wiki_url: string | null;
}

type CommunitySelectOption = SelectOption & {
community: Community;
};

type MultiCommunityPickerProps = Pick<
MultiSelectProps<CommunitySelectOption>,
"disabled" | "onChange"
>;

export const MultiCommunityPicker: React.FC<MultiCommunityPickerProps> = ({
disabled = false,
onChange,
}) => {
const context = useContext(ThunderstoreContext);
const { isLoading, data } = useQuery("communityList", async () => {
const r = await apiFetch(context, "/experimental/community/");
return await r.json();
});

if (isLoading) {
return <Text>Loading...</Text>;
}

if (!data) {
return <Text>Failed to fetch</Text>;
}

const options: CommunitySelectOption[] = data.results.map((community: Community) => ({
label: community.name,
value: community.identifier,
community: community,
}));

return <MultiSelect options={options} disabled={disabled} onChange={onChange} />;
};
34 changes: 34 additions & 0 deletions thunderstore-components/src/components/FileUpload.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Box, Center, chakra, Text, useColorModeValue } from "@chakra-ui/react";
import React, { useCallback } from "react";
import { DropEvent, FileRejection, useDropzone } from "react-dropzone";

interface FileUploadProps {
onUpload: (
acceptedFiles: File[],
fileRejections: FileRejection[],
event: DropEvent
) => void;
accept?: string | string[];
}

export const FileUpload: React.FC<FileUploadProps> = ({ onUpload, accept }) => {
const bg = useColorModeValue("gray", "gray");
const onDrop = useCallback(onUpload, []);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: accept,
});

return (
<Box {...getRootProps()} background={bg}>
<Center>
<chakra.input {...getInputProps()} />
{isDragActive ? (
<Text>Drop the file here</Text>
) : (
<Text>Drop the file here, or click to select files</Text>
)}
</Center>
</Box>
);
};
16 changes: 16 additions & 0 deletions thunderstore-components/src/components/Markdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";
import ReactMarkdown from "react-markdown";
import gfm from "remark-gfm";
import ChakraUIRenderer from "chakra-ui-markdown-renderer";

interface MarkdownProps {
children: string;
}

export const Markdown: React.FC<MarkdownProps> = ({ children }) => {
return (
<ReactMarkdown plugins={[gfm]} renderers={ChakraUIRenderer()}>
{children}
</ReactMarkdown>
);
};
Loading

0 comments on commit 742759c

Please sign in to comment.