+
Floor Enemies
-
- {floorEnemies.map((enemy) => {
- return (
-
- {emojiToImageTag(
- enemy.emoji,
- allEmoji,
- "h-12 w-12"
- )}
-
- );
- })}
+
+ {Object.keys(groupedByEnemies).map((enemyKey) => (
+
+ {emojiToImageTag(
+ groupedByEnemies[enemyKey][0].emoji,
+ allEmoji,
+ "h-12 w-12",
+ groupedByEnemies[enemyKey].length,
+ )}
+
+ ))}
+ {floorEnemies && floorEnemies.length > 0 &&
setFloorEnemies([])}> }
diff --git a/src/ui/AddOrEditAchievementModal/AddOrEditAchievementModal.tsx b/src/ui/AddOrEditAchievementModal/AddOrEditAchievementModal.tsx
new file mode 100644
index 0000000..c5427b3
--- /dev/null
+++ b/src/ui/AddOrEditAchievementModal/AddOrEditAchievementModal.tsx
@@ -0,0 +1,134 @@
+import { useFormik } from "formik";
+import { useEffect } from "react";
+import * as Yup from "yup";
+import { useParams } from "react-router-dom";
+import { toast } from "react-toastify";
+
+import { upsertAchievement } from "../../api/achievements";
+import Button from "../Button";
+import Checkbox from "../Checkbox";
+import Modal from "../Modal";
+import TextInput from "../TextInput";
+
+interface IProps {
+ show: boolean;
+ onClose: () => void;
+ selectedAchievement?: IAchievement;
+}
+
+interface IAchievementForm {
+ id?: number;
+ description: string;
+ targetValue: number;
+ isEnabled: boolean;
+}
+
+const AddOrEditAchievementModal = ({
+ show,
+ onClose,
+ selectedAchievement,
+}: IProps) => {
+ const { gameTypeId } = useParams<{ gameTypeId: string }>();
+
+ const onSubmit = async (values: IAchievementForm) => {
+ try{
+ await upsertAchievement({
+ ...(selectedAchievement?.id && { id: selectedAchievement?.id }),
+ _gameTypeId: selectedAchievement?._gameTypeId || parseInt(gameTypeId || ""),
+ ...(selectedAchievement?.createdAt && { createdAt: selectedAchievement?.createdAt }),
+ description: values.description,
+ targetValue: values.targetValue,
+ isEnabled: values.isEnabled,
+ updatedAt: new Date().toString(),
+ });
+ onClose();
+ toast('Achievement successfully saved.',{
+ type: 'success',
+ });
+ } catch (err: any) {
+ toast(`Error : ${err.message}`, {
+ type: "error",
+ });
+ }
+ }
+
+ const validationSchema = Yup.object({
+ description: Yup.string().required().label("Desctiption"),
+ targetValue: Yup.number().min(1).required().label("Target Value"),
+ });
+
+ const initialForm: IAchievementForm = {
+ description: "",
+ targetValue: 0,
+ isEnabled: true,
+ };
+
+ const {
+ getFieldProps,
+ getFieldMeta,
+ handleSubmit,
+ isValid,
+ setValues,
+ } = useFormik({
+ initialValues: initialForm,
+ onSubmit,
+ validationSchema,
+ });
+
+ useEffect(() => {
+ setValues({
+ description: selectedAchievement?.description || "",
+ targetValue: selectedAchievement?.targetValue || 0,
+ isEnabled: selectedAchievement?.isEnabled || true,
+ });
+ }, [selectedAchievement, setValues])
+
+ return (
+
+
+
+ {selectedAchievement?.id ? 'Edit' : 'New'} Achievement
+
+
+
+
+ );
+};
+
+export default AddOrEditAchievementModal;
diff --git a/src/ui/AddOrEditAchievementModal/index.tsx b/src/ui/AddOrEditAchievementModal/index.tsx
new file mode 100644
index 0000000..10356e0
--- /dev/null
+++ b/src/ui/AddOrEditAchievementModal/index.tsx
@@ -0,0 +1,3 @@
+import AddOrEditAchievementModal from "./AddOrEditAchievementModal";
+
+export default AddOrEditAchievementModal;
diff --git a/src/ui/AddOrEditLeaderboardModal/AddOrEditLeaderboardModal.tsx b/src/ui/AddOrEditLeaderboardModal/AddOrEditLeaderboardModal.tsx
new file mode 100644
index 0000000..0268adb
--- /dev/null
+++ b/src/ui/AddOrEditLeaderboardModal/AddOrEditLeaderboardModal.tsx
@@ -0,0 +1,144 @@
+import { useFormik } from "formik";
+import { useEffect } from "react";
+import * as Yup from "yup";
+import { useParams } from "react-router-dom";
+
+import { upsertLeaderboard } from "../../api/leaderboards";
+import Button from "../Button";
+import Modal from "../Modal";
+import TextInput from "../TextInput";
+import Dropdown from "../Dropdown";
+import {
+ resetStrategies,
+ scoreStrategies,
+} from "../../utils/leaderboardStrategies";
+import { toast } from "react-toastify";
+
+interface IProps {
+ show: boolean;
+ onClose: () => void;
+ selectedLeaderboard?: ILeaderboard;
+}
+
+interface ILeaderboardForm {
+ id?: number;
+ name: string;
+ scoreStrategy: string;
+ resetStrategy: string;
+}
+
+const AddOrEditLeaderboardModal = ({
+ show,
+ onClose,
+ selectedLeaderboard,
+}: IProps) => {
+ const { gameTypeId } = useParams<{ gameTypeId: string }>();
+
+ const onSubmit = async (values: ILeaderboardForm) => {
+ try{
+ await upsertLeaderboard({
+ ...(selectedLeaderboard?.id && { id: selectedLeaderboard?.id }),
+ _gameTypeId:
+ selectedLeaderboard?._gameTypeId || parseInt(gameTypeId || ""),
+ name: values.name,
+ scoreStrategy: values.scoreStrategy.toLowerCase(),
+ resetStrategy: values.resetStrategy.toLowerCase(),
+ });
+ onClose();
+ toast('Leaderboard successfully saved.',{
+ type: 'success',
+ });
+
+ } catch (err: any) {
+ toast(`Error : ${err?.message}`, {
+ type: "error",
+ });
+ }
+ };
+
+ const validationSchema = Yup.object({
+ name: Yup.string().required().label("Desctiption"),
+ scoreStrategy: Yup.string().required().label("Score Strategy"),
+ resetStrategy: Yup.string().required().label("Reset Strategy"),
+ });
+
+ const initialForm: ILeaderboardForm = {
+ name: "",
+ scoreStrategy: "Highest",
+ resetStrategy: "Daily",
+ };
+
+ const { getFieldProps, getFieldMeta, handleSubmit, isValid, setValues } =
+ useFormik({
+ initialValues: initialForm,
+ onSubmit,
+ validationSchema,
+ });
+
+ useEffect(() => {
+ setValues({
+ name: selectedLeaderboard?.name || "",
+ scoreStrategy: selectedLeaderboard?.scoreStrategy || "Highest",
+ resetStrategy: selectedLeaderboard?.resetStrategy || "Daily",
+ });
+ }, [selectedLeaderboard, setValues]);
+
+ return (
+
+
+
+ { selectedLeaderboard?.id ? 'Edit' : 'New'} Leaderboard
+
+
+
+
+ );
+};
+
+export default AddOrEditLeaderboardModal;
diff --git a/src/ui/AddOrEditLeaderboardModal/index.tsx b/src/ui/AddOrEditLeaderboardModal/index.tsx
new file mode 100644
index 0000000..933943c
--- /dev/null
+++ b/src/ui/AddOrEditLeaderboardModal/index.tsx
@@ -0,0 +1,3 @@
+import AddOrEditLeaderboardModal from "./AddOrEditLeaderboardModal";
+
+export default AddOrEditLeaderboardModal;
diff --git a/src/ui/Button/Button.tsx b/src/ui/Button/Button.tsx
index c9bd463..e9ff503 100644
--- a/src/ui/Button/Button.tsx
+++ b/src/ui/Button/Button.tsx
@@ -3,14 +3,15 @@ interface IProps {
disabled?: boolean;
onClick?: () => void;
type?: "button" | "submit" | "reset" | undefined;
+ fullWidth?: boolean;
}
const calculateClasses = (props: IProps) => {
if (props.disabled) {
- return "bg-gray-100 text-sm text-gray-400 py-1.5 px-5 rounded-sm cursor-not-allowed";
+ return `bg-gray-100 text-sm text-gray-400 py-1.5 px-5 rounded-sm cursor-not-allowed ${props.fullWidth ? "w-full" : ""}`;
}
- return "bg-xteamaccent text-sm text-white py-1.5 px-5 rounded-sm";
+ return `bg-xteamaccent text-sm text-white py-1.5 px-5 rounded-sm ${props.fullWidth ? "w-full" : ""}`;
};
export default function Button(props: IProps) {
diff --git a/src/ui/Dropdown/Dropdown.tsx b/src/ui/Dropdown/Dropdown.tsx
index a1dc15e..15e0210 100644
--- a/src/ui/Dropdown/Dropdown.tsx
+++ b/src/ui/Dropdown/Dropdown.tsx
@@ -5,6 +5,7 @@ interface IProps {
label: string;
hasErrors?: boolean;
touched?: boolean;
+ fullWidth?: boolean;
children?: React.ReactNode;
}
@@ -13,6 +14,7 @@ function TextInput({
fieldProps,
label,
children,
+ fullWidth,
hasErrors,
touched,
}: IProps) {
@@ -26,7 +28,8 @@ function TextInput({
{children}
diff --git a/src/ui/TextInput/TextInput.tsx b/src/ui/TextInput/TextInput.tsx
index 86038ac..ee598d0 100644
--- a/src/ui/TextInput/TextInput.tsx
+++ b/src/ui/TextInput/TextInput.tsx
@@ -6,6 +6,7 @@ interface IProps {
type?: "text" | "number" | "password";
extraClass?: string;
helperText?: string;
+ fullWidth?: boolean;
}
const renderInputError = (error?: string, touched?: boolean) => {
@@ -23,7 +24,7 @@ function TextInput({
type,
label,
extraClass,
-
+ fullWidth,
...props
}: IProps) {
const calculateColors = () => {
@@ -54,7 +55,7 @@ function TextInput({
diff --git a/src/utils/leaderboardStrategies.ts b/src/utils/leaderboardStrategies.ts
new file mode 100644
index 0000000..12a99e4
--- /dev/null
+++ b/src/utils/leaderboardStrategies.ts
@@ -0,0 +1,4 @@
+
+export const scoreStrategies = ["Highest", "Lowest", "Sum", "Latest"];
+
+export const resetStrategies = ["Daily", "Weekly", "Monthly", "Never" ];
\ No newline at end of file