Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: beaches demo #300

Merged
merged 1 commit into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added packages/interface/public/logo-muqa.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/interface/public/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 0 additions & 9 deletions packages/interface/public/round-logo.svg

This file was deleted.

2 changes: 1 addition & 1 deletion packages/interface/src/components/ImageUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface IImageUploadProps extends ComponentProps<"img"> {

export const ImageUpload = ({
name = "",
maxSize = 1024 * 1024, // 1 MB
maxSize = 2048 * 2048, // 2 MB
className,
}: IImageUploadProps): JSX.Element => {
const ref = useRef<HTMLInputElement>(null);
Expand Down
1 change: 0 additions & 1 deletion packages/interface/src/components/JoinButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export const JoinButton = (): JSX.Element => {

const onError = useCallback(() => toast.error("Signup error"), []);
const handleSignup = useCallback(() => onSignup(onError), [onSignup, onError]);

return (
<div>
{appState === EAppState.VOTING && !isEligibleToVote && (
Expand Down
9 changes: 2 additions & 7 deletions packages/interface/src/components/RoundInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import Image from "next/image";

import { Heading } from "~/components/ui/Heading";
import { config } from "~/config";

export const RoundInfo = (): JSX.Element => (
<div className="w-full border-b border-gray-200 pb-2">
<h4>Round</h4>
<h4>MUQA</h4>

<div className="flex items-center gap-2">
{config.roundLogo && <Image alt="round logo" height="20" src={`/${config.roundLogo}`} width="20" />}

<Heading as="h3" size="3xl">
{config.roundId}
Beach Contest
</Heading>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions packages/interface/src/components/ui/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const Avatar = createComponent(
sm: "w-12 h-12 rounded-md",
md: "w-16 h-16 rounded-md",
lg: "w-40 h-40 rounded-3xl",
xl: "w-80 h-80 rounded-4xl",
},
rounded: {
full: "rounded-full",
Expand Down
2 changes: 1 addition & 1 deletion packages/interface/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const getRPCURL = (): string | undefined => {
};

export const config = {
logoUrl: "/Logo.svg",
logoUrl: "/logo.svg",
pageSize: 3 * 4,
// TODO: temp solution until we come up with solid one
// https://github.com/privacy-scaling-explorations/maci-platform/issues/31
Expand Down
7 changes: 4 additions & 3 deletions packages/interface/src/contexts/Maci.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ export const MaciProvider: React.FC<MaciProviderProps> = ({ children }: MaciProv
// for Semaphore it will be a proof being part of the group
useEffect(() => {
setIsLoading(true);

// add custom logic for other gatekeepers here
switch (gatekeeperTrait) {
case GatekeeperTrait.Semaphore:
Expand Down Expand Up @@ -145,6 +144,9 @@ export const MaciProvider: React.FC<MaciProviderProps> = ({ children }: MaciProv
});
setIsLoading(false);
break;
case GatekeeperTrait.FreeForAll:
setIsLoading(false);
break;
default:
break;
}
Expand All @@ -157,7 +159,7 @@ export const MaciProvider: React.FC<MaciProviderProps> = ({ children }: MaciProv
// for instance with semaphore
const isEligibleToVote = useMemo(
() => gatekeeperTrait && (gatekeeperTrait === GatekeeperTrait.FreeForAll || Boolean(sgData)) && Boolean(address),
[sgData, address],
[sgData, address, gatekeeperTrait],
);

// on load get the key pair from local storage and set the signature message
Expand Down Expand Up @@ -192,7 +194,6 @@ export const MaciProvider: React.FC<MaciProviderProps> = ({ children }: MaciProv
if (!address) {
return;
}

const signature = await signMessageAsync({ message: signatureMessage });
const newSemaphoreIdentity = new Identity(signature);
const userKeyPair = genKeyPair({ seed: BigInt(signature) });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { Spinner } from "~/components/ui/Spinner";
import { useIsCorrectNetwork } from "~/hooks/useIsCorrectNetwork";

import type { Application } from "../types";
import type { ImpactMetrix, ContributionLink, FundingSource } from "~/features/projects/types";

export enum EApplicationStep {
PROFILE,
Expand Down Expand Up @@ -39,62 +38,19 @@ export const ApplicationButtons = ({

const form = useFormContext<Application>();

const [
name,
bio,
payoutAddress,
websiteUrl,
profileImageUrl,
bannerImageUrl,
contributionDescription,
impactDescription,
impactCategory,
contributionLinks,
fundingSources,
] = useMemo(
() =>
form.watch([
"name",
"bio",
"payoutAddress",
"websiteUrl",
"profileImageUrl",
"bannerImageUrl",
"contributionDescription",
"impactDescription",
"impactCategory",
"contributionLinks",
"fundingSources",
]),
const [name, bio, profileImageUrl, bannerImageUrl, activitiesDescription] = useMemo(
() => form.watch(["name", "bio", "websiteUrl", "profileImageUrl", "bannerImageUrl", "activitiesDescription"]),
[form],
);

const checkLinks = (
links: Pick<ContributionLink | ImpactMetrix | FundingSource, "description">[] | undefined,
): boolean =>
links === undefined || links.every((link) => link.description !== undefined && link.description.length > 0);

const checkStepComplete = (): boolean => {
if (step === EApplicationStep.PROFILE) {
return (
bannerImageUrl !== undefined &&
profileImageUrl !== undefined &&
bio.length > 0 &&
name.length > 0 &&
payoutAddress.length > 0 &&
websiteUrl.length > 0
);
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
return bannerImageUrl !== undefined && profileImageUrl !== undefined && bio.length > 0 && name.length > 0;
}

if (step === EApplicationStep.ADVANCED) {
return (
impactCategory !== undefined &&
impactCategory.length > 0 &&
contributionDescription.length > 0 &&
impactDescription.length > 0 &&
checkLinks(contributionLinks) &&
checkLinks(fundingSources)
);
return (activitiesDescription ?? "").length > 0;
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@ import { toast } from "sonner";
import { useAccount } from "wagmi";

import { ImageUpload } from "~/components/ImageUpload";
import { FieldArray, Form, FormControl, FormSection, Select, Textarea } from "~/components/ui/Form";
import { Form, FormControl, FormSection, Textarea } from "~/components/ui/Form";
import { Input } from "~/components/ui/Input";
import { useIsCorrectNetwork } from "~/hooks/useIsCorrectNetwork";

import { useCreateApplication } from "../hooks/useCreateApplication";
import { ApplicationSchema, contributionTypes, fundingSourceTypes } from "../types";
import { ApplicationSchema } from "../types";

import { ApplicationButtons, EApplicationStep } from "./ApplicationButtons";
import { ApplicationSteps } from "./ApplicationSteps";
import { ImpactTags } from "./ImpactTags";
import { ReviewApplicationDetails } from "./ReviewApplicationDetails";

export const ApplicationForm = (): JSX.Element => {
Expand All @@ -29,7 +28,7 @@ export const ApplicationForm = (): JSX.Element => {

/**
* There are 3 steps for creating an application.
* The first step is to set the project introduction (profile);
* The first step is to set the beach introduction (profile);
* the second step is to set the contributions, impacts, and funding sources (advanced);
* the last step is to review the input values, allow editing by going back to previous steps (review).
*/
Expand Down Expand Up @@ -69,58 +68,39 @@ export const ApplicationForm = (): JSX.Element => {
<ApplicationSteps step={step} />

<Form
defaultValues={{
payoutAddress: address,
}}
schema={ApplicationSchema}
onSubmit={(application) => {
create.mutate(application);
}}
>
<FormSection
className={step === EApplicationStep.PROFILE ? "block" : "hidden"}
description="Please provide information about your project."
title="Project Profile"
description="Please provide information about your beach."
title="Beach Profile"
>
<FormControl required hint="This is the name of your project" label="Project name" name="name">
<Input placeholder="Type your project name" />
<FormControl required hint="This is the name of your beach" label="beach name" name="name">
<Input placeholder="Type your beach name" />
</FormControl>

<FormControl required label="Description" name="bio">
<Textarea placeholder="Type project description" rows={4} />
<Textarea placeholder="Type beach description" rows={4} />
</FormControl>

<div className="gap-4 md:flex">
<FormControl required className="flex-1" label="Website" name="websiteUrl">
<FormControl className="flex-1" label="Website" name="websiteUrl" required={false}>
<Input placeholder="https://" />
</FormControl>

<FormControl required className="flex-1" label="Payout address" name="payoutAddress">
<Input placeholder="0x..." />
</FormControl>
</div>

<div className="gap-4 md:flex">
<FormControl className="flex-1" label="X(Twitter)" name="twitter" required={false}>
<Input placeholder="Type your twitter username" />
</FormControl>

<FormControl
className="flex-1"
hint="Provide your github of this project"
label="Github"
name="github"
required={false}
>
<Input placeholder="Type your github username" />
</FormControl>
</div>

<div className="mb-4 gap-4 md:flex">
<FormControl
required
hint="The size should be smaller than 1MB."
label="Project avatar"
label="beach avatar"
name="profileImageUrl"
>
<ImageUpload className="h-48 w-48 " />
Expand All @@ -130,7 +110,7 @@ export const ApplicationForm = (): JSX.Element => {
required
className="flex-1"
hint="The size should be smaller than 1MB."
label="Project background image"
label="beach background image"
name="bannerImageUrl"
>
<ImageUpload className="h-48 " />
Expand All @@ -140,76 +120,12 @@ export const ApplicationForm = (): JSX.Element => {

<FormSection
className={step === EApplicationStep.ADVANCED ? "block" : "hidden"}
description="Describe the contribution and impact of your project."
title="Contribution & Impact"
description="Describe the activities of your beach."
title="Activities"
>
<FormControl required label="Contribution description" name="contributionDescription">
<Textarea placeholder="What have your project contributed to?" rows={4} />
</FormControl>

<FormControl required label="Impact description" name="impactDescription">
<Textarea placeholder="What impact has your project had?" rows={4} />
<FormControl required label="Activities description" name="activitiesDescription">
<Textarea placeholder="What can you do in your beach?" rows={4} />
</FormControl>

<ImpactTags />

<FieldArray
description="Where can we find your contributions?"
name="contributionLinks"
renderField={(field, i) => (
<div className="mb-4 flex flex-wrap gap-2">
<FormControl required className="min-w-96" name={`contributionLinks.${i}.description`}>
<Input placeholder="Type the description of your contribution" />
</FormControl>

<FormControl required className="min-w-72" name={`contributionLinks.${i}.url`}>
<Input placeholder="https://" />
</FormControl>

<FormControl required name={`contributionLinks.${i}.type`}>
<Select>
{Object.entries(contributionTypes).map(([value, label]) => (
<option key={value} value={value}>
{label}
</option>
))}
</Select>
</FormControl>
</div>
)}
title="Contribution links"
/>

<FieldArray
description="From what sources have you received funding?"
name="fundingSources"
renderField={(field, i) => (
<div className="mb-4 flex flex-wrap gap-2">
<FormControl required className="min-w-96" name={`fundingSources.${i}.description`}>
<Input placeholder="Type the name of your funding source" />
</FormControl>

<FormControl required valueAsNumber className="w-32" name={`fundingSources.${i}.amount`}>
<Input placeholder="Amount" type="number" />
</FormControl>

<FormControl required className="w-32" name={`fundingSources.${i}.currency`}>
<Input placeholder="e.g. USD" />
</FormControl>

<FormControl required name={`fundingSources.${i}.type`}>
<Select>
{Object.entries(fundingSourceTypes).map(([value, label]) => (
<option key={value} value={value}>
{label}
</option>
))}
</Select>
</FormControl>
</div>
)}
title="Funding sources"
/>
</FormSection>

{step === EApplicationStep.REVIEW && <ReviewApplicationDetails />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const ApplicationItem = ({

const form = useFormContext();

const { fundingSources = [], profileImageUrl } = metadata.data ?? {};
const { activitiesDescription, profileImageUrl } = metadata.data ?? {};

return (
<Link href={`/projects/${id}`} target="_blank">
Expand All @@ -48,7 +48,7 @@ export const ApplicationItem = ({
</Skeleton>

<div className="text-sm text-gray-400">
<div>{fundingSources.length} funding sources</div>
<div>{activitiesDescription} </div>
</div>
</div>
</div>
Expand Down
Loading
Loading