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
19 changes: 17 additions & 2 deletions app/admin/quests/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ export default function Page() {
} catch (error) {
console.error("Error while creating balance task:", error);
}
}else if (step.type === "CustomApi") {
} else if (step.type === "CustomApi") {
try {
await AdminService.createCustomApi({
quest_id: questId,
Expand All @@ -383,6 +383,21 @@ 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: JSON.parse(step.data.contract_calls),
});
} 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");
}
}
});
setButtonLoading(false);
Expand Down Expand Up @@ -480,7 +495,7 @@ export default function Page() {
<AdminQuestDetails
quest={finalQuestData}
// eslint-disable-next-line @typescript-eslint/no-empty-function
setShowDomainPopup={() => {}}
setShowDomainPopup={() => { }}
hasRootDomain={false}
rewardButtonTitle={finalQuestData.disabled ? "Enable" : "Disable"}
onRewardButtonClick={async () => {
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
19 changes: 14 additions & 5 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,8 +106,16 @@ const TaskDetailsForm: FunctionComponent<TaskDetailsFormProps> = ({
step={step}
/>
);
} else if(step?.type === "CustomApi"){
return(
} 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

handleTasksInputChange={handleTasksInputChange}
index={currentTask}
step={step}
/>
);
} else if (step?.type === "CustomApi") {
return (
<CustomApiStep
handleTasksInputChange={handleTasksInputChange}
index={currentTask}
Expand Down Expand Up @@ -207,7 +216,7 @@ const TaskDetailsForm: FunctionComponent<TaskDetailsFormProps> = ({
] as TaskType,
data: getDefaultValues(
TWITTER_OPTIONS[
category as keyof typeof TWITTER_OPTIONS
category as keyof typeof TWITTER_OPTIONS
] as TaskType
),
};
Expand All @@ -220,12 +229,12 @@ const TaskDetailsForm: FunctionComponent<TaskDetailsFormProps> = ({
cursor: "pointer",
backgroundColor:
steps[currentTask]?.type ===
TWITTER_OPTIONS[category as keyof typeof TWITTER_OPTIONS]
TWITTER_OPTIONS[category as keyof typeof TWITTER_OPTIONS]
? "#ffffff"
: "#29282B",
color:
steps[currentTask]?.type ===
TWITTER_OPTIONS[category as keyof typeof TWITTER_OPTIONS]
TWITTER_OPTIONS[category as keyof typeof TWITTER_OPTIONS]
? "#29282B"
: "#ffffff",
}}
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.contract_calls || ""}
name="contract_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: "",
contract_calls: "",
};
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
36 changes: 36 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,38 @@ const updateBalance = async (params: UpdateBalance) => {
}
};

const createContract = async (params: CreateContract) => {
try {
const response = await fetch(`${baseurl}/admin/tasks/contract/create`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
body: JSON.stringify(params),
});
return await response.json();
} catch (err) {
console.log("Error while creating contract task", err);
}
};

const updateContract = async (params: UpdateContract) => {
try {
const response = await fetch(`${baseurl}/admin/tasks/contract/update`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
body: JSON.stringify(params),
});
return await response.json();
} catch (err) {
console.log("Error while updating contract task", err);
}
};

const createCustomApi = async (params: CreateCustomApi) => {
try{
const response = await fetch(`${baseurl}/admin/tasks/custom_api/create`, {
Expand Down Expand Up @@ -549,6 +583,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
5 changes: 4 additions & 1 deletion types/frontTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ type StepMap =
| { type: "None"; data: object }
| { type: "Domain"; data: DomainInputType }
| { type: "Balance"; data: BalanceInputType }
| { type: "CustomApi"; data: CustomApiInputType };
| { type: "Contract"; data: ContractInputType }
| { type: "CustomApi"; data: CustomApiInputType }

type CustomInputType = typeof CustomInput;
type DiscordInputType = typeof DiscordInput;
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