Skip to content

Commit

Permalink
Private notes (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
technophile-04 authored Apr 18, 2024
1 parent 9e1d0f9 commit a8e1a7b
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 11 deletions.
18 changes: 16 additions & 2 deletions packages/nextjs/app/admin/_components/EditGrantModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { ChangeEvent, forwardRef, useState } from "react";
import { useSWRConfig } from "swr";
import useSWRMutation from "swr/mutation";
import { useAccount, useNetwork, useSignTypedData } from "wagmi";
import { GrantDataWithBuilder } from "~~/services/database/schema";
import { GrantDataWithPrivateNote } from "~~/services/database/schema";
import { EIP_712_DOMAIN, EIP_712_TYPES__EDIT_GRANT } from "~~/utils/eip712";
import { getParsedError, notification } from "~~/utils/scaffold-eth";
import { patchMutationFetcher } from "~~/utils/swr";

type EditGrantModalProps = {
grant: GrantDataWithBuilder;
grant: GrantDataWithPrivateNote;
closeModal: () => void;
};

Expand All @@ -18,13 +18,15 @@ type ReqBody = {
askAmount?: number;
signature?: `0x${string}`;
signer?: string;
private_note?: string;
};

export const EditGrantModal = forwardRef<HTMLDialogElement, EditGrantModalProps>(({ grant, closeModal }, ref) => {
const [formData, setFormData] = useState({
title: grant.title,
description: grant.description,
askAmount: grant.askAmount.toString(),
private_note: grant.private_note ?? "",
});

const { address } = useAccount();
Expand Down Expand Up @@ -63,6 +65,7 @@ export const EditGrantModal = forwardRef<HTMLDialogElement, EditGrantModalProps>
// Converting this to number with parseFloat and again to string (similar to backend),
// if not it generates different signature with .23 and 0.23
askAmount: parseFloat(formData.askAmount).toString(),
private_note: formData.private_note,
},
});
notificationId = notification.loading("Updating grant");
Expand Down Expand Up @@ -132,6 +135,17 @@ export const EditGrantModal = forwardRef<HTMLDialogElement, EditGrantModalProps>
onChange={handleInputChange}
/>
</div>
<div className="w-full flex-col gap-1">
<p className="m-0 font-semibold text-base">Private Note (optional)</p>
<textarea
name="private_note"
placeholder="Notes for Admins"
value={formData.private_note}
className="textarea textarea-md textarea-bordered w-full"
rows={3}
onChange={handleInputChange}
/>
</div>
<button
className={`btn btn-md btn-success ${isLoading ? "opacity-50" : ""}`}
onClick={handleEditGrant}
Expand Down
7 changes: 5 additions & 2 deletions packages/nextjs/app/admin/_components/GrantReview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import TelegramIcon from "~~/components/assets/TelegramIcon";
import TwitterIcon from "~~/components/assets/TwitterIcon";
import { Address } from "~~/components/scaffold-eth";
import { useScaffoldContractWrite } from "~~/hooks/scaffold-eth";
import { GrantData, GrantDataWithBuilder, SocialLinks } from "~~/services/database/schema";
import { GrantData, GrantDataWithPrivateNote, SocialLinks } from "~~/services/database/schema";
import { PROPOSAL_STATUS, ProposalStatusType } from "~~/utils/grants";

const BuilderSocials = ({ socialLinks }: { socialLinks?: SocialLinks }) => {
Expand Down Expand Up @@ -44,7 +44,7 @@ const BuilderSocials = ({ socialLinks }: { socialLinks?: SocialLinks }) => {
};

type GrantReviewProps = {
grant: GrantDataWithBuilder;
grant: GrantDataWithPrivateNote;
selected: boolean;
toggleSelection: () => void;
};
Expand Down Expand Up @@ -220,6 +220,9 @@ export const GrantReview = ({ grant, selected, toggleSelection }: GrantReviewPro
</button>
</div>
</div>
{grant.private_note && grant.private_note.trim().length > 0 && (
<p className="mb-0 text-orange-500">{grant.private_note}</p>
)}
</div>
<EditGrantModal ref={editGrantModalRef} grant={grant} closeModal={() => editGrantModalRef?.current?.close()} />
<ActionModal ref={actionModalRef} grant={grant} initialTxLink={txResult?.hash} action={reviewAction} />
Expand Down
8 changes: 4 additions & 4 deletions packages/nextjs/app/api/grants/[grantId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ type ReqBody = {
askAmount?: number;
signature?: `0x${string}`;
signer?: string;
private_note?: string;
};

export async function PATCH(req: NextRequest, { params }: { params: { grantId: string } }) {
try {
const { grantId } = params;
const { title, description, signature, signer, askAmount } = (await req.json()) as ReqBody;
const { title, description, signature, signer, askAmount, private_note } = (await req.json()) as ReqBody;

if (!title || !description || !askAmount || typeof askAmount !== "number" || !signature || !signer) {
return NextResponse.json({ error: "Invalid form details submited" }, { status: 400 });
Expand All @@ -25,7 +26,7 @@ export async function PATCH(req: NextRequest, { params }: { params: { grantId: s
domain: EIP_712_DOMAIN,
types: EIP_712_TYPES__EDIT_GRANT,
primaryType: "Message",
message: { title, description, askAmount: askAmount.toString(), grantId },
message: { title, description, askAmount: askAmount.toString(), grantId, private_note: private_note ?? "" },
signature: signature,
});
if (recoveredAddress !== signer) {
Expand All @@ -37,8 +38,7 @@ export async function PATCH(req: NextRequest, { params }: { params: { grantId: s
if (signerData.data?.role !== "admin") {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}

await updateGrant(grantId, { title, description, askAmount });
await updateGrant(grantId, { title, description, askAmount }, private_note);
return NextResponse.json({ success: true });
} catch (e) {
console.error(e);
Expand Down
22 changes: 19 additions & 3 deletions packages/nextjs/services/database/grants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getFirestoreConnector } from "./firestoreDB";
import { BuilderData, GrantData, GrantDataWithBuilder } from "./schema";
import { BuilderData, GrantData, GrantDataWithPrivateNote } from "./schema";
import ecosystemGrants from "~~/services/database/ecosystemGrants.json";
import { findUserByAddress } from "~~/services/database/users";
import { PROPOSAL_STATUS, ProposalStatusType } from "~~/utils/grants";
Expand Down Expand Up @@ -60,13 +60,17 @@ export const getAllGrantsForReview = async () => {

const grantsPromises = grantsSnapshot.docs.map(async doc => {
const grantData = doc.data() as Omit<GrantData, "id">;
const privateNotes = doc.ref.collection("private_note");
const privateNotesSnapshot = await privateNotes.get();
const private_note = privateNotesSnapshot.empty ? undefined : privateNotesSnapshot.docs[0].data().note;
const builderDataResponse = await findUserByAddress(grantData.builder);

return {
id: doc.id,
...grantData,
private_note,
builderData: builderDataResponse.exists ? (builderDataResponse.data as BuilderData) : undefined,
} as GrantDataWithBuilder;
} as GrantDataWithPrivateNote;
});

return await Promise.all(grantsPromises);
Expand Down Expand Up @@ -166,9 +170,21 @@ export const reviewGrant = async ({ grantId, action, txHash, txChainId, note }:
}
};

export const updateGrant = async (grantId: string, grantData: Partial<GrantData>) => {
export const updateGrant = async (grantId: string, grantData: Partial<GrantData>, private_note?: string) => {
try {
await getGrantsDoc(grantId).update(grantData);

if (private_note === undefined) return;

const privateNoteCollection = grantsCollection.doc(grantId).collection("private_note");
const privateNoteSnapshot = await privateNoteCollection.get();
if (privateNoteSnapshot.empty) {
await privateNoteCollection.add({ note: private_note });
} else {
privateNoteSnapshot.forEach(doc => {
privateNoteCollection.doc(doc.id).update({ note: private_note });
});
}
} catch (error) {
console.error("Error updating the grant:", error);
throw error;
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/services/database/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,4 @@ export type GrantData = Simplify<
>;

export type GrantDataWithBuilder = Simplify<GrantData & { builderData?: BuilderData }>;
export type GrantDataWithPrivateNote = Simplify<GrantDataWithBuilder & { private_note?: string }>;
1 change: 1 addition & 0 deletions packages/nextjs/utils/eip712.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const EIP_712_TYPES__EDIT_GRANT = {

{ name: "grantId", type: "string" },
{ name: "askAmount", type: "string" },
{ name: "private_note", type: "string" },
],
} as const;

Expand Down

0 comments on commit a8e1a7b

Please sign in to comment.