diff --git a/src/features/Projects/pages/ExplorePage/Header/Header.tsx b/src/features/Projects/pages/ExplorePage/Header/Header.tsx index 0c2891c..12654a0 100644 --- a/src/features/Projects/pages/ExplorePage/Header/Header.tsx +++ b/src/features/Projects/pages/ExplorePage/Header/Header.tsx @@ -5,6 +5,7 @@ import { MEDIA_QUERIES } from "src/utils/theme/media_queries"; import CustomDot from "./CustomDot/CustomDot"; import useEmblaCarousel from 'embla-carousel-react' import { useCallback, useEffect, useState } from "react"; +import { createRoute } from "src/utils/routing"; const headerLinks = [ { @@ -12,7 +13,8 @@ const headerLinks = [ img: Assets.Images_ExploreHeader1, link: { content: "Submit project", - url: "https://form.jotform.com/220301236112030", + url: createRoute({ type: "edit-project" }), + newTab: false, }, }, { @@ -25,6 +27,7 @@ const headerLinks = [ link: { content: "Register Now", url: "https://bolt.fun/hackathons/shock-the-web-2/", + newTab: true, }, }, ]; @@ -72,7 +75,7 @@ export default function Header() { {headerLinks[0].title} - @@ -86,7 +89,7 @@ export default function Header() {
{headerLinks[1].title}
- diff --git a/src/features/Projects/pages/ListProjectPage/Components/ExtrasTab/ExtrasTab.tsx b/src/features/Projects/pages/ListProjectPage/Components/ExtrasTab/ExtrasTab.tsx index 7ae502d..178ac90 100644 --- a/src/features/Projects/pages/ListProjectPage/Components/ExtrasTab/ExtrasTab.tsx +++ b/src/features/Projects/pages/ListProjectPage/Components/ExtrasTab/ExtrasTab.tsx @@ -1,143 +1,70 @@ -import { Controller, NestedValue, Resolver, SubmitHandler, useForm } from "react-hook-form" -import { NotificationsService } from "src/services/notifications.service"; -import * as yup from "yup"; -import { yupResolver } from "@hookform/resolvers/yup"; -import { usePrompt } from "src/utils/hooks"; -import { toast } from "react-toastify"; +import { Controller, useFormContext } from "react-hook-form" import Card from "src/Components/Card/Card"; -import TeamMembersInput from "../TeamMembersInput/TeamMembersInput"; -import { Team_Member_Role } from "src/graphql"; -import RecruitRolesInput from "../RecruitRolesInput/RecruitRolesInput"; import TournamentsInput from "../TournamentsInput/TournamentsInput"; +import { IListProjectForm } from "../FormContainer/FormContainer"; +interface Props { } -export interface IExtrasForm { - launch_status: "wip" | "launched" - tournaments: NestedValue -} +export default function ExtrasTab(props: Props) { -interface Props { - data?: IExtrasForm, -} - -// type IFormInputs = Props['data']; - -const schema: yup.SchemaOf = yup.object({ - launch_status: yup.mixed().oneOf(['wip', 'launched']).required(), - tournaments: yup.array().required().default([]) -}).required(); - -export default function ExtrasTab({ data }: Props) { - - const { register, formState: { errors, isDirty, }, handleSubmit, reset, control } = useForm({ - defaultValues: { - ...data, - launch_status: 'wip', - tournaments: [] - }, - resolver: yupResolver(schema) as Resolver, - // mode: 'onBlur', - }); + const { register, formState: { errors, isDirty, }, control } = useFormContext(); - usePrompt('You may have some unsaved changes. You still want to leave?', isDirty) + // usePrompt('You may have some unsaved changes. You still want to leave?', isDirty) - const onSubmit: SubmitHandler = data => { - - const toastId = toast.loading("Saving changes...", NotificationsService.defaultOptions) - const mutate: any = null; - mutate({ - // variables: { - // data: { - // // name: data.name, - // // avatar: data.avatar, - // // jobTitle: data.jobTitle, - // // bio: data.bio, - // // email: data.email, - // // github: data.github, - // // linkedin: data.linkedin, - // // lightning_address: data.lightning_address, - // // location: data.location, - // // twitter: data.twitter, - // // website: data.website, - // } - // }, - onCompleted: () => { - reset(data); - toast.update(toastId, { render: "Saved changes successfully", type: "success", ...NotificationsService.defaultOptions, isLoading: false }); - } - }) - .catch(() => { - toast.update(toastId, { render: "A network error happened", type: "error", ...NotificationsService.defaultOptions, isLoading: false }); - // mutationStatus.reset() - }) - }; - return ( -
-
- - - -

🚀 Launch status

-

Has this product been launched already, or is it still a work in progress?

-
-
- -
-

WIP 🛠️

-

It’s still a Work In Progress.

-
-
-
- -
-

Launched 🚀

-

The product is ready for launch, or has been launched already.

-
-
- {errors.launch_status &&

{errors.launch_status?.message}

} -
-
- - -

⚔️️ Tournaments

-

Is your application part of a tournament? If so, select the tournament(s) that apply and it will automatically be listed for you.

-
- ( - - )} +
+ +

🚀 Launch status

+

Has this product been launched already, or is it still a work in progress?

+
+
+ - {errors.tournaments &&

{errors.tournaments?.message}

} +
+

WIP 🛠️

+

It’s still a Work In Progress.

+
- -
-
- {/* reset()} - /> */} -
+
+ +
+

Launched 🚀

+

The product is ready for launch, or has been launched already.

+
+
+ {errors.launch_status &&

{errors.launch_status?.message}

} +
+ + + +

⚔️️ Tournaments

+

Is your application part of a tournament? If so, select the tournament(s) that apply and it will automatically be listed for you.

+
+ ( + + )} + /> + {errors.tournaments &&

{errors.tournaments?.message}

} +
+
) } diff --git a/src/features/Projects/pages/ListProjectPage/Components/FormContainer/FormContainer.tsx b/src/features/Projects/pages/ListProjectPage/Components/FormContainer/FormContainer.tsx index 11c7d5d..7630da3 100644 --- a/src/features/Projects/pages/ListProjectPage/Components/FormContainer/FormContainer.tsx +++ b/src/features/Projects/pages/ListProjectPage/Components/FormContainer/FormContainer.tsx @@ -1,12 +1,91 @@ +import { FormProvider, NestedValue, Resolver, SubmitHandler, useForm } from "react-hook-form" +import * as yup from "yup"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { Team_Member_Role } from "src/graphql"; +import { PropsWithChildren } from "react"; +import { useSearchParams } from "react-router-dom"; + interface Props { } -export default function FormContainer() { - return ( -
-
+export interface IListProjectForm { + id?: number + name: string + website: string + tagline: string + description: string + thumbnail_image?: string + cover_image?: string + twitter?: string + discord?: string + github?: string + category_id: number + capabilities: NestedValue + screenshots: NestedValue + + members: NestedValue<{ + id: number, + name: string, + jobTitle: string | null, + avatar: string, + role: Team_Member_Role, + }[]> + recruit_roles: NestedValue + + + launch_status: "wip" | "launched" + tournaments: NestedValue +} + +const schema: yup.SchemaOf = yup.object({ + id: yup.number().optional(), + name: yup.string().trim().required().min(2), + website: yup.string().trim().url().required(), + tagline: yup.string().trim().required().min(10), + description: yup.string().trim().required().min(50, 'Write at least 10 words descriping your project'), + thumbnail_image: yup.string().url().ensure(), + cover_image: yup.string().url().ensure(), + twitter: yup.string().url().ensure(), + discord: yup.string().url().ensure(), + github: yup.string().url().ensure(), + category_id: yup.number().required("Please choose a category"), + capabilities: yup.array().of(yup.string().required()).default([]), + screenshots: yup.array().of(yup.string().required()).default([]), + members: yup.array().of(yup.object() as any).default([]), + recruit_roles: yup.array().default([]), + launch_status: yup.mixed().oneOf(['wip', 'launched']).default('wip'), + tournaments: yup.array().default([]) +}).required(); + +export default function FormContainer(props: PropsWithChildren) { + + const [params] = useSearchParams(); + + const methods = useForm({ + defaultValues: { + id: !!params.get('id') ? Number(params.get('id')) : undefined, + capabilities: [], + screenshots: [], + members: [], + recruit_roles: [], + launch_status: 'wip', + tournaments: [], + }, + resolver: yupResolver(schema) as Resolver, + }); + + + const onSubmit: SubmitHandler = data => console.log(data); + + + return ( + +
+ {props.children} +
+
) } diff --git a/src/features/Projects/pages/ListProjectPage/Components/ProjectDetailsTab/ProjectDetailsTab.tsx b/src/features/Projects/pages/ListProjectPage/Components/ProjectDetailsTab/ProjectDetailsTab.tsx index 0a7bb04..6fe02f0 100644 --- a/src/features/Projects/pages/ListProjectPage/Components/ProjectDetailsTab/ProjectDetailsTab.tsx +++ b/src/features/Projects/pages/ListProjectPage/Components/ProjectDetailsTab/ProjectDetailsTab.tsx @@ -1,290 +1,188 @@ -import { Controller, NestedValue, Resolver, SubmitHandler, useForm } from "react-hook-form" -import Button from "src/Components/Button/Button"; -import { Project, User, useUpdateProfileAboutMutation } from "src/graphql"; -import { NotificationsService } from "src/services/notifications.service"; -import * as yup from "yup"; -import { yupResolver } from "@hookform/resolvers/yup"; -import Avatar from "src/features/Profiles/Components/Avatar/Avatar"; -import { usePrompt } from "src/utils/hooks"; -import { toast } from "react-toastify"; +import { Controller, useFormContext } from "react-hook-form" import Card from "src/Components/Card/Card"; -import { FaDiscord, FaTwitter } from "react-icons/fa"; +import { FaDiscord } from "react-icons/fa"; import { FiCamera, FiGithub, FiTwitter } from "react-icons/fi"; import CategoriesInput from "../CategoriesInput/CategoriesInput"; import CapabilitiesInput from "../CapabilitiesInput/CapabilitiesInput"; +import { IListProjectForm } from "../FormContainer/FormContainer"; + +interface Props { } + +export default function ProjectDetailsTab(props: Props) { + + const { register, formState: { errors, }, control } = useFormContext(); -interface IProjectDetails { - name: string - website: string - tagline: string - description: string - thumbnail_image: string - cover_image: string - - twitter: string - discord: string - github: string - - category_id: number - - capabilities: NestedValue - - screenshots: NestedValue - -} - -interface Props { - data?: IProjectDetails, - onClose?: () => void; -} - -// type IFormInputs = Props['data']; - -const schema: yup.SchemaOf = yup.object({ - name: yup.string().trim().required().min(2), - website: yup.string().trim().url().required(), - tagline: yup.string().trim().required().min(10), - description: yup.string().trim().required().min(50, 'Write at least 10 words descriping your project'), - thumbnail_image: yup.string().url().required(), - cover_image: yup.string().url().required(), - - twitter: yup.string().ensure(), - discord: yup.string().ensure(), - github: yup.string().ensure(), - - category_id: yup.number().required(), - - capabilities: yup.array().of(yup.string().required()), - - screenshots: yup.array().of(yup.string().required()), -}).required(); - -export default function ProjectDetailsTab({ data, onClose }: Props) { - - const { register, formState: { errors, isDirty, }, handleSubmit, reset, control } = useForm({ - defaultValues: { - ...data, - capabilities: data?.capabilities ?? [] - }, - resolver: yupResolver(schema) as Resolver, - // mode: 'onBlur', - }); - - const [mutate, mutationStatus] = useUpdateProfileAboutMutation(); + // usePrompt('You may have some unsaved changes. You still want to leave?', isDirty) - usePrompt('You may have some unsaved changes. You still want to leave?', isDirty) - - - const onSubmit: SubmitHandler = data => { - - const toastId = toast.loading("Saving changes...", NotificationsService.defaultOptions) - - mutate({ - // variables: { - // data: { - // // name: data.name, - // // avatar: data.avatar, - // // jobTitle: data.jobTitle, - // // bio: data.bio, - // // email: data.email, - // // github: data.github, - // // linkedin: data.linkedin, - // // lightning_address: data.lightning_address, - // // location: data.location, - // // twitter: data.twitter, - // // website: data.website, - // } - // }, - onCompleted: () => { - reset(data); - toast.update(toastId, { render: "Saved changes successfully", type: "success", ...NotificationsService.defaultOptions, isLoading: false }); - } - }) - .catch(() => { - toast.update(toastId, { render: "A network error happened", type: "error", ...NotificationsService.defaultOptions, isLoading: false }); - mutationStatus.reset() - }) - }; - return ( -
-
- -
-
- {/* */} -
- - Add image -
+
+ +
+
+ {/* */} +
+ + Add image
-
-

- Project name* -

-
- -
- {errors.name &&

- {errors.name.message} -

} -

- Project link* -

-
- -
- {errors.website &&

- {errors.website.message} -

} -

- Tagline* -

-
- -
- {errors.tagline &&

- {errors.tagline.message} -

} -

- Description* -

-
-