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

added new contract task type in the admin dashboard #843

Merged
merged 11 commits into from
Oct 6, 2024
14 changes: 14 additions & 0 deletions app/admin/quests/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,20 @@ export default function Page() {
} catch (error) {
console.error("Error while creating balance task:", error);
}
} else if (step.type === "Contract"){
try {
await AdminService.createContract({
quest_id: questId,
name: step.data.contract_name,
desc: step.data.contract_desc,
href: step.data.contract_href,
cta: step.data.contract_cta,
calls: step.data.contract_calls,
PoulavBhowmick03 marked this conversation as resolved.
Show resolved Hide resolved
});
} catch (error) {
console.error("Error while creating contract task:", error);
PoulavBhowmick03 marked this conversation as resolved.
Show resolved Hide resolved
showNotification(`Error adding ${step.type} task: ${error}`, "error");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add JSON parsing and error handling for 'calls' field in 'Contract' task type

The 'calls' field in the 'Contract' task type should accept JSON input. Before passing step.data.contract_calls to AdminService.createContract, parse it using JSON.parse to ensure it is valid JSON. If parsing fails, display an error message using showNotification, similar to how it's handled in other task types.

Apply this diff to implement JSON parsing and error handling:

} else if (step.type === "Contract"){
+   try {
+     const calls = JSON.parse(step.data.contract_calls);
+   } catch (e) {
+     showNotification("Invalid JSON in 'calls' field for Contract", "error");
+     return;
+   }
    try {
      await AdminService.createContract({
        quest_id: questId,
        name: step.data.contract_name,
        desc: step.data.contract_desc,
        href: step.data.contract_href,
        cta: step.data.contract_cta,
-       calls: step.data.contract_calls,
+       calls: calls,
      });
    } catch (error) {
      console.error("Error while creating contract task:", error);
      showNotification(`Error adding ${step.type} task: ${error}`, "error");
    }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} else if (step.type === "Contract"){
try {
await AdminService.createContract({
quest_id: questId,
name: step.data.contract_name,
desc: step.data.contract_desc,
href: step.data.contract_href,
cta: step.data.contract_cta,
calls: step.data.contract_calls,
});
} catch (error) {
console.error("Error while creating contract task:", error);
showNotification(`Error adding ${step.type} task: ${error}`, "error");
}
} else if (step.type === "Contract"){
try {
const calls = JSON.parse(step.data.contract_calls);
} catch (e) {
showNotification("Invalid JSON in 'calls' field for Contract", "error");
return;
}
try {
await AdminService.createContract({
quest_id: questId,
name: step.data.contract_name,
desc: step.data.contract_desc,
href: step.data.contract_href,
cta: step.data.contract_cta,
calls: calls,
});
} catch (error) {
console.error("Error while creating contract task:", error);
showNotification(`Error adding ${step.type} task: ${error}`, "error");
}

}
});
setButtonLoading(false);
Expand Down
39 changes: 37 additions & 2 deletions app/admin/quests/dashboard/[questId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type StepMap =
| { type: "Custom"; data: WithNewField<CustomInputType, "id", number> }
| { type: "Domain"; data: WithNewField<DomainInputType, "id", number> }
| { type: "Balance"; data: WithNewField<BalanceInputType, "id", number> }
| { type: "Contract"; data: WithNewField<ContractInputType, "id", number> }
| { type: "CustomApi"; data: WithNewField<CustomApiInputType, "id", number> }
| { type: "None"; data: object };

Expand Down Expand Up @@ -216,6 +217,18 @@ export default function Page({ params }: QuestIdProps) {
balance_href: task.href,
},
};
} else if (task.task_type === "contract") {
return {
type: "Contract",
data: {
id: task.id,
contract_name: task.name,
contract_desc: task.desc,
contract_href: task.href,
contract_cta: task.cta,
contract_calls: task.calls,
},
};
} else if(task.task_type === "custom_api"){
return {
type: "CustomApi",
Expand Down Expand Up @@ -524,6 +537,15 @@ export default function Page({ params }: QuestIdProps) {
cta: step.data.balance_cta,
href: step.data.balance_href,
});
} else if (step.type === "Contract") {
await AdminService.createContract({
quest_id: questId.current,
name: step.data.contract_name,
desc: step.data.contract_desc,
href: step.data.contract_href,
cta: step.data.contract_cta,
calls: JSON.parse(step.data.contract_calls),
});
Marchand-Nicolas marked this conversation as resolved.
Show resolved Hide resolved
}
else if(step.type === "CustomApi"){
await AdminService.createCustomApi({
Expand All @@ -537,7 +559,7 @@ export default function Page({ params }: QuestIdProps) {
})
}
} catch (error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this catch, you can add

showNotification(`Error adding ${step.type} task: ${error}`, "error");

So that if there is any issue while parsing the JSON, the user is instantly informed

console.error(`Error adding task of type ${step.type}:`, error);
showNotification(`Error adding ${step.type} task: ${error}`, "error");
}
}
}, []);
Expand Down Expand Up @@ -633,6 +655,19 @@ export default function Page({ params }: QuestIdProps) {
cta: step.data.balance_cta,
href: step.data.balance_href,
});
} else if (step.type === "Contract") {
try {
await AdminService.updateContract({
id: step.data.id,
name: step.data.contract_name,
desc: step.data.contract_desc,
href: step.data.contract_href,
cta: step.data.contract_cta,
calls: JSON.parse(step.data.contract_calls),
});
} catch (error) {
showNotification(`Error updating ${step.type} task: ${error}`, "error");
}
} else if (step.type === "CustomApi") {
await AdminService.updateCustomApi({
id: step.data.id,
Expand Down Expand Up @@ -782,7 +817,7 @@ export default function Page({ params }: QuestIdProps) {
<AdminQuestDetails
quest={questData}
// eslint-disable-next-line @typescript-eslint/no-empty-function
setShowDomainPopup={() => {}}
setShowDomainPopup={() => { }}
hasRootDomain={false}
rewardButtonTitle={questData.disabled ? "Enable" : "Disable"}
onRewardButtonClick={async () => {
Expand Down
4 changes: 4 additions & 0 deletions components/admin/formSteps/TaskDetailsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import DomainStep from "../taskSteps/domainStep";
import Typography from "@components/UI/typography/typography";
import { TEXT_TYPE } from "@constants/typography";
import BalanceStep from "../taskSteps/balanceStep";
import ContractStep from "../taskSteps/contractStep";
import CustomApiStep from "../taskSteps/customApiStep"

type TaskDetailsFormProps = {
Expand Down Expand Up @@ -105,6 +106,9 @@ const TaskDetailsForm: FunctionComponent<TaskDetailsFormProps> = ({
step={step}
/>
);
} else if (step?.type === "Contract") {
return (
<ContractStep
Comment on lines +109 to +111
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing closing parenthesis

} else if(step?.type === "CustomApi"){
return(
<CustomApiStep
Expand Down
61 changes: 61 additions & 0 deletions components/admin/taskSteps/contractStep.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { FunctionComponent } from "react";
import TextInput from "../textInput";

type ContractStepProps = {
handleTasksInputChange: (
e: React.ChangeEvent<HTMLInputElement>,
index: number
) => void;
step: StepMap;
index: number;
};
Marchand-Nicolas marked this conversation as resolved.
Show resolved Hide resolved

const ContractStep: FunctionComponent<ContractStepProps> = ({
handleTasksInputChange,
step,
index,
}) => {
return (
<div className="flex flex-col gap-4 pt-2">
<TextInput
onChange={(e) => handleTasksInputChange(e, index)}
value={step.data.contract_name || ""}
name="contract_name"
label="Name"
placeholder="Name"
/>
<TextInput
onChange={(e) => handleTasksInputChange(e, index)}
value={step.data.contract_desc || ""}
name="contract_desc"
label="Description"
placeholder="Description"
multiline={4}
/>
<TextInput
onChange={(e) => handleTasksInputChange(e, index)}
value={step.data.contract_href || ""}
name="contract_href"
label="URL"
placeholder="URL"
/>
<TextInput
onChange={(e) => handleTasksInputChange(e, index)}
value={step.data.contract_cta || ""}
name="contract_cta"
label="CTA"
placeholder="CTA"
/>
<TextInput
onChange={(e) => handleTasksInputChange(e, index)}
value={step.data.calls || ""}
PoulavBhowmick03 marked this conversation as resolved.
Show resolved Hide resolved
name="calls"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not working, because here it should be contract_calls instead of calls

label="Calls (JSON)"
placeholder='e.g.: [{ "contract": "0x...", "entry_point": "transfer", "call_data": ["0x..."], "regex": "..." }]'
multiline={4}
/>
</div>
);
};

export default ContractStep;
10 changes: 10 additions & 0 deletions constants/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const TASK_OPTIONS = [
"Custom",
"Domain",
"Balance",
"Contract",
"CustomApi"
];

Expand Down Expand Up @@ -116,6 +117,13 @@ export const BalanceInput = {
balance_href: "",
};

export const ContractInput = {
contract_name: "",
contract_desc: "",
contract_href: "",
contract_cta: "",
calls: "",
PoulavBhowmick03 marked this conversation as resolved.
Show resolved Hide resolved
};
Marchand-Nicolas marked this conversation as resolved.
Show resolved Hide resolved
export const CustomApiInput = {
api_name: "",
api_desc: "",
Expand All @@ -132,6 +140,8 @@ export const getDefaultValues = (type: TaskType) => {
if (type === "Discord") return DiscordInput;
if (type === "Custom") return CustomInput;
if (type === "Domain") return DomainInput;
if (type === "Balance") return BalanceInput;
if (type === "Contract") return ContractInput;
if (type === "CustomApi") return CustomApiInput;
if (type === "None") return {};

Expand Down
19 changes: 19 additions & 0 deletions services/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
AddUser,
CreateBalance,
UpdateBalance,
CreateContract,
UpdateContract,
CreateCustomApi,
UpdateCustomApi,
} from "../types/backTypes";
Expand Down Expand Up @@ -356,6 +358,9 @@ const updateBalance = async (params: UpdateBalance) => {
}
};

const createContract = async (params: CreateContract) => {
try {
const response = await fetch(`${baseurl}/admin/tasks/contract/create`, {
const createCustomApi = async (params: CreateCustomApi) => {
try{
const response = await fetch(`${baseurl}/admin/tasks/custom_api/create`, {
Expand All @@ -368,6 +373,14 @@ const createCustomApi = async (params: CreateCustomApi) => {
});
return await response.json();
} catch (err) {
console.log("Error creating contract task", err);
}
};

const updateContract = async (params: UpdateContract) => {
try {
const response = await fetch(`${baseurl}/admin/tasks/contract/update`, {
=======
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected merge markers

console.log("Error while creating custom API task", err);
}
}
Expand All @@ -383,6 +396,10 @@ const updateCustomApi = async (params: UpdateCustomApi) => {
body: JSON.stringify(params),
});
return await response.json();
} catch (error) {
console.log("Error updating contract task", error);
}
};
} catch (err) {
console.log("Error while updating custom API task", err);
}
Expand Down Expand Up @@ -549,6 +566,8 @@ export const AdminService = {
createCustom,
createBalance,
updateBalance,
createContract,
updateContract,
createQuiz,
createQuizQuestion,
deleteTask,
Expand Down
19 changes: 19 additions & 0 deletions types/backTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type UserTask = {
task_type: string | null;
discord_guild_id: string | null;
contracts: string[] | null;
calls: object | null;
};

type UserDocument = {
Expand Down Expand Up @@ -404,6 +405,24 @@ export type UpdateBalance = {
href?: string;
};

export type CreateContract = {
quest_id: number;
name: string;
desc: string;
href: string;
cta: string;
calls: object;
};

export type UpdateContract = {
id: number;
name?: string;
desc?: string;
href?: string;
cta?: string;
calls?: object;
};

export type UpdateCustom = {
id: number;
name?: string;
Expand Down
3 changes: 3 additions & 0 deletions types/frontTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ type StepMap =
| { type: "None"; data: object }
| { type: "Domain"; data: DomainInputType }
| { type: "Balance"; data: BalanceInputType }
| { type: "Contract"; data: ContractInputType };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the ";" at the end of this line

| { type: "CustomApi"; data: CustomApiInputType };

type CustomInputType = typeof CustomInput;
Expand All @@ -325,6 +326,7 @@ type QuizInputType = typeof QuizDefaultInput;
type TwitterFwInputType = typeof TwitterFwInput;
type TwitterRwInputType = typeof TwitterRwInput;
type BalanceInputType = typeof BalanceInput;
type ContractInputType = typeof ContractInput;
type CustomApiInputType = typeof CustomApiInput;
type TaskType =
| "Quiz"
Expand All @@ -334,6 +336,7 @@ type TaskType =
| "TwitterRw"
| "Domain"
| "Balance"
| "Contract"
| "CustomApi"
| "None";

Expand Down