Skip to content

Commit

Permalink
Add UploadPackageForm
Browse files Browse the repository at this point in the history
  • Loading branch information
Oksamies committed Nov 27, 2023
1 parent c06563a commit ef39227
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 71 deletions.
15 changes: 15 additions & 0 deletions packages/cyberstorm-forms/src/forms/UploadPackageForm.module.css
Original file line number Diff line number Diff line change
@@ -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);
}
170 changes: 170 additions & 0 deletions packages/cyberstorm-forms/src/forms/UploadPackageForm.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<ApiForm
{...toaster}
schema={uploadPackageFormSchema}
endpoint={packageUpload}
formProps={{ className: styles.root }}
>
<div className={styles.root}>
<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={
<FormSelectSearch
name="team"
schema={uploadPackageFormSchema}
options={props.teams.map((t) => t.name)}
placeholder="Choose a team..."
/>
}
/>
<SettingItem
title="Communities"
description="Select communities you want your package to be listed under. Current community is selected by default."
content={
<FormMultiSelectSearch
name="communities"
schema={uploadPackageFormSchema}
options={options}
placeholder="Choose community..."
onChangeParse={communitiesParse}
/>
}
/>
<SettingItem
title="Categories"
description="Select descriptive categories to help people discover your package."
content={
<FormMultiSelectSearch
name="community_categories"
schema={uploadPackageFormSchema}
options={options}
placeholder="Choose categories..."
onChangeParse={communityCategoriesParse}
/>
}
/>
<div className={styles.line} />
<SettingItem
title="Contains NSFW content"
description='A "NSFW" -tag will be applied to your package.'
content={
<FormSwitch
schema={uploadPackageFormSchema}
name="has_nsfw_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>
<FormSubmitButton text="Submit" />
</div>
}
/>
</div>
</ApiForm>
);
}

UploadPackageForm.displayName = "UploadPackageForm";
1 change: 1 addition & 0 deletions packages/cyberstorm-forms/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Original file line number Diff line number Diff line change
@@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<BaseLayout
breadCrumb={
Expand All @@ -24,67 +25,7 @@ export function PackageUploadLayout() {
</BreadCrumbs>
}
header={<Title text="Upload Package" />}
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} />}
/>
);
}
Expand Down
28 changes: 28 additions & 0 deletions packages/thunderstore-api/src/fetch/packageUpload.ts
Original file line number Diff line number Diff line change
@@ -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),
});
}
1 change: 1 addition & 0 deletions packages/thunderstore-api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
2 changes: 1 addition & 1 deletion packages/ts-api-react-forms/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
10 changes: 10 additions & 0 deletions packages/ts-api-react-forms/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
});

0 comments on commit ef39227

Please sign in to comment.