From ef392271c6395c2fc2ac412b4dd435b84c208928 Mon Sep 17 00:00:00 2001 From: Oksamies Date: Fri, 24 Nov 2023 22:34:34 +0200 Subject: [PATCH] Add UploadPackageForm --- .../src/forms/UploadPackageForm.module.css | 15 ++ .../src/forms/UploadPackageForm.tsx | 170 ++++++++++++++++++ packages/cyberstorm-forms/src/index.ts | 1 + .../PackageUploadLayout.module.css | 7 +- .../PackageUpload/PackageUploadLayout.tsx | 79 ++------ .../src/fetch/packageUpload.ts | 28 +++ packages/thunderstore-api/src/index.ts | 1 + packages/ts-api-react-forms/src/index.ts | 2 +- packages/ts-api-react-forms/src/schema.ts | 10 ++ 9 files changed, 242 insertions(+), 71 deletions(-) create mode 100644 packages/cyberstorm-forms/src/forms/UploadPackageForm.module.css create mode 100644 packages/cyberstorm-forms/src/forms/UploadPackageForm.tsx create mode 100644 packages/thunderstore-api/src/fetch/packageUpload.ts diff --git a/packages/cyberstorm-forms/src/forms/UploadPackageForm.module.css b/packages/cyberstorm-forms/src/forms/UploadPackageForm.module.css new file mode 100644 index 000000000..2a8fdc30b --- /dev/null +++ b/packages/cyberstorm-forms/src/forms/UploadPackageForm.module.css @@ -0,0 +1,15 @@ +.root { + display: flex; + flex-direction: column; + gap: var(--gap--48); +} + +.line { + border-bottom: var(--border-width--px) solid var(--color-surface--4); +} + +.submit { + display: flex; + flex-direction: row; + gap: var(--gap--16); +} diff --git a/packages/cyberstorm-forms/src/forms/UploadPackageForm.tsx b/packages/cyberstorm-forms/src/forms/UploadPackageForm.tsx new file mode 100644 index 000000000..6d9389c63 --- /dev/null +++ b/packages/cyberstorm-forms/src/forms/UploadPackageForm.tsx @@ -0,0 +1,170 @@ +"use client"; + +import styles from "./UploadPackageForm.module.css"; +import { + ApiForm, + uploadPackageFormSchema, +} from "@thunderstore/ts-api-react-forms"; +import { + FormSubmitButton, + FormMultiSelectSearch, + FormSelectSearch, + useFormToaster, + CreateTeamForm, + FormSwitch, +} from "@thunderstore/cyberstorm-forms"; +import { TextInput, Dialog, Button } from "@thunderstore/cyberstorm"; +import { SettingItem } from "@thunderstore/cyberstorm/src/components/SettingItem/SettingItem"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faPlus } from "@fortawesome/free-solid-svg-icons"; +import { packageUpload } from "@thunderstore/thunderstore-api"; + +const options = [ + { label: "Asd", value: "asd" }, + { label: "Asd2", value: "asd2" }, + { label: "Asd3", value: "asd3" }, + { label: "Asd4", value: "asd4" }, + { label: "Asd5", value: "asd5" }, + { label: "Asd6", value: "asd6" }, + { label: "Asd7", value: "asd7" }, + { label: "Asd8", value: "asd8" }, + { label: "Asd9", value: "asd9" }, + { label: "Asd10", value: "asd10" }, + { label: "Asd11", value: "asd11" }, + { label: "Asd12", value: "asd12" }, + { label: "Asd13", value: "asd13" }, + { label: "Asd14", value: "asd14" }, +]; + +interface UploadPackageFormProps { + teams: { + name: string; + }[]; +} + +export function UploadPackageForm(props: UploadPackageFormProps) { + const toaster = useFormToaster({ + successMessage: "Package submitted", + }); + + // Parse categories to the right format for form + function communityCategoriesParse( + selected: { + label: string; + value: string; + }[], + onChange: (selected: { [key: string]: string[] }) => void + ) { + const communityCategories: { [key: string]: string[] } = {}; + selected.map((x) => (communityCategories[x.value] = [x.value])); + onChange(communityCategories); + } + + // Parse communities to the right format for form + function communitiesParse( + selected: { + label: string; + value: string; + }[], + onChange: (selected: string[]) => void + ) { + onChange(selected.map((x) => x.value)); + } + + return ( + +
+ } + /> +
+ + Create team + + + + + } + > + + + } + content={ + t.name)} + placeholder="Choose a team..." + /> + } + /> + + } + /> + + } + /> +
+ + } + /> +
+ + + Reset + + +
+ } + /> +
+ + ); +} + +UploadPackageForm.displayName = "UploadPackageForm"; diff --git a/packages/cyberstorm-forms/src/index.ts b/packages/cyberstorm-forms/src/index.ts index a3a9912fb..d80c50ab7 100644 --- a/packages/cyberstorm-forms/src/index.ts +++ b/packages/cyberstorm-forms/src/index.ts @@ -5,3 +5,4 @@ export { FormMultiSelectSearch } from "./components/FormMultiSelectSearch"; export { FormSwitch } from "./components/FormSwitch"; export { FormTextInput } from "./components/FormTextInput"; export { CreateTeamForm } from "./forms/CreateTeamForm"; +export { UploadPackageForm } from "./forms/UploadPackageForm"; diff --git a/packages/cyberstorm/src/components/Layout/Developers/PackageUpload/PackageUploadLayout.module.css b/packages/cyberstorm/src/components/Layout/Developers/PackageUpload/PackageUploadLayout.module.css index acab2ff80..2a8fdc30b 100644 --- a/packages/cyberstorm/src/components/Layout/Developers/PackageUpload/PackageUploadLayout.module.css +++ b/packages/cyberstorm/src/components/Layout/Developers/PackageUpload/PackageUploadLayout.module.css @@ -1,5 +1,10 @@ +.root { + display: flex; + flex-direction: column; + gap: var(--gap--48); +} + .line { - margin: var(--space--24) 0; border-bottom: var(--border-width--px) solid var(--color-surface--4); } diff --git a/packages/cyberstorm/src/components/Layout/Developers/PackageUpload/PackageUploadLayout.tsx b/packages/cyberstorm/src/components/Layout/Developers/PackageUpload/PackageUploadLayout.tsx index ccff568f2..5a58d53ea 100644 --- a/packages/cyberstorm/src/components/Layout/Developers/PackageUpload/PackageUploadLayout.tsx +++ b/packages/cyberstorm/src/components/Layout/Developers/PackageUpload/PackageUploadLayout.tsx @@ -1,21 +1,22 @@ "use client"; -import styles from "./PackageUploadLayout.module.css"; import { Title } from "../../../Title/Title"; import { BreadCrumbs } from "../../../BreadCrumbs/BreadCrumbs"; import { PackageUploadLink } from "../../../Links/Links"; -import { SettingItem } from "../../../SettingItem/SettingItem"; -import { TextInput } from "../../../TextInput/TextInput"; -import * as Button from "../../../Button/"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faPlus } from "@fortawesome/free-solid-svg-icons"; import { BaseLayout } from "../../BaseLayout/BaseLayout"; -import { CreateTeamForm } from "@thunderstore/cyberstorm-forms"; -import { Dialog } from "../../../.."; +import { UploadPackageForm } from "@thunderstore/cyberstorm-forms"; +import { useDapper } from "@thunderstore/dapper"; +import { usePromise } from "@thunderstore/use-promise"; /** * Cyberstorm PackageUpload Layout */ + export function PackageUploadLayout() { + const dapper = useDapper(); + const user = usePromise(dapper.getCurrentUser, []); + // TODO: Somehow grab categories from all the selected communities and pass them on + // const communities = usePromise(dapper.getCommunities, []); + // const filters = usePromise(dapper.getCommunityFilters, [communityId]) return ( } header={} - mainContent={ - <> - <SettingItem - title="Upload file" - description="Upload your package as a ZIP file." - content={<TextInput />} - /> - <div className={styles.line} /> - <SettingItem - title="Team" - description="No teams available?" - additionalLeftColumnContent={ - <Dialog.Root - title="Create Team" - trigger={ - <Button.Root colorScheme="primary" paddingSize="large"> - <Button.ButtonLabel>Create team</Button.ButtonLabel> - <Button.ButtonIcon> - <FontAwesomeIcon icon={faPlus} /> - </Button.ButtonIcon> - </Button.Root> - } - > - <CreateTeamForm /> - </Dialog.Root> - } - content={<TextInput />} - /> - <SettingItem - title="Communities" - description="Select communities you want your package to be listed under. Current community is selected by default." - content={<TextInput />} - /> - <SettingItem - title="Categories" - description="Select descriptive categories to help people discover your package." - content={<TextInput />} - /> - <div className={styles.line} /> - <SettingItem - title="Contains NSFW content" - description='A "NSFW" -tag will be applied to your package.' - content="" - /> - <div className={styles.line} /> - <SettingItem - title="Submit" - description='Double-check your selections and hit "Submit" when you are ready!' - content={ - <div className={styles.submit}> - <Button.Root colorScheme="danger"> - <Button.ButtonLabel>Reset</Button.ButtonLabel> - </Button.Root> - <Button.Root colorScheme="accent"> - <Button.ButtonLabel>Submit</Button.ButtonLabel> - </Button.Root> - </div> - } - /> - </> - } + mainContent={<UploadPackageForm teams={user.teams} />} /> ); } diff --git a/packages/thunderstore-api/src/fetch/packageUpload.ts b/packages/thunderstore-api/src/fetch/packageUpload.ts new file mode 100644 index 000000000..5dac66fa5 --- /dev/null +++ b/packages/thunderstore-api/src/fetch/packageUpload.ts @@ -0,0 +1,28 @@ +import { RequestConfig } from "../index"; +import { apiFetch2 } from "../apiFetch"; + +export type PackageUploadApiArgs = { + // author_name: string; + // upload_uuid: string; + team: string; + community_categories: { [key: string]: string[] }; + communities: string[]; + has_nsfw_content: boolean; +}; + +export function packageUpload( + config: RequestConfig, + data: PackageUploadApiArgs +) { + const path = "api/experimental/submission/submit/"; + + // TODO: Add these datas in form + const todoData = { ...data, upload_uuid: "123", author_name: "root" }; + + return apiFetch2({ + config, + path, + method: "POST", + body: JSON.stringify(todoData), + }); +} diff --git a/packages/thunderstore-api/src/index.ts b/packages/thunderstore-api/src/index.ts index 57b7a635d..cef0b6d1f 100644 --- a/packages/thunderstore-api/src/index.ts +++ b/packages/thunderstore-api/src/index.ts @@ -17,4 +17,5 @@ export * from "./fetch/teamDetails"; export * from "./fetch/teamMembers"; export * from "./fetch/teamServiceAccounts"; export * from "./fetch/teamCreate"; +export * from "./fetch/packageUpload"; export * from "./errors"; diff --git a/packages/ts-api-react-forms/src/index.ts b/packages/ts-api-react-forms/src/index.ts index d19267261..66f7b1da7 100644 --- a/packages/ts-api-react-forms/src/index.ts +++ b/packages/ts-api-react-forms/src/index.ts @@ -2,4 +2,4 @@ export { ApiForm } from "./ApiForm"; export { getErrorFormKey, handleFormApiErrors } from "./errors"; export { useApiForm } from "./useApiForm"; export type { UseApiFormReturn, UseApiFormArgs } from "./useApiForm"; -export { createTeamFormSchema } from "./schema"; +export { createTeamFormSchema, uploadPackageFormSchema } from "./schema"; diff --git a/packages/ts-api-react-forms/src/schema.ts b/packages/ts-api-react-forms/src/schema.ts index 251c266f7..245dc12c4 100644 --- a/packages/ts-api-react-forms/src/schema.ts +++ b/packages/ts-api-react-forms/src/schema.ts @@ -5,3 +5,13 @@ export const createTeamFormSchema = z.object({ .string({ required_error: "Team name is required" }) .min(1, { message: "Team name is required" }), }); + +// TODO: Add these manually at the form +// author_name: z.string(), +// upload_uuid: z.string(), +export const uploadPackageFormSchema = z.object({ + team: z.string(), + community_categories: z.record(z.array(z.string())), + communities: z.array(z.string()).nonempty(), + has_nsfw_content: z.boolean(), +});