Skip to content

Commit

Permalink
Merge pull request #987 from bounswe/frontend-create-character
Browse files Browse the repository at this point in the history
Frontend Create Character Functionality
  • Loading branch information
cisel-zumbul authored Dec 12, 2023
2 parents 7391aae + fb494e2 commit 35a8493
Show file tree
Hide file tree
Showing 5 changed files with 296 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@import "../../../../colors";

.container {
padding: 4rem;

.header {
color: green;
}

.form {
width: 40rem;
}

.select {
width: 100%;
}

.input {
margin-bottom: 2rem;
}
.colorHeader {
color: #6ea2bb;
margin: 0 0 0.5rem 0;
}

.button {
width: 25%;
}

.picker {
margin-bottom: 2rem;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import { useState } from "react";
import { useMutation, useQuery } from "react-query";
import styles from "./CreateCharacter.module.scss";
import "react-datepicker/dist/react-datepicker.css";
import { Button, Input, Upload } from "antd";
import MultipleSelect from "../../../../Components/MultipleSelect/MultipleSelect";
import { InboxOutlined } from "@ant-design/icons";
import { uploadImage } from "../../../../Services/image";
import { NotificationUtil } from "../../../../Library/utils/notification";
import { handleAxiosError } from "../../../../Library/utils/handleError";
import { createGame, getGames } from "../../../../Services/games";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import { createCharacter } from "../../../../Services/character";

function CreateCharacter() {
const [name, setName] = useState("");
const [type, setType] = useState("");
const [gender, setGender] = useState("");
const [race, setRace] = useState("");
const [status, setStatus] = useState("");
const [occupation, setOccupation] = useState("");
const [birthDate, setBirthDate] = useState<Date | null>(new Date());
const [voiceActor, setVoiceActor] = useState("");
const [height, setHeight] = useState("");
const [age, setAge] = useState("");
const [characterGames, setCharacterGames] = useState<string[]>([]);

const [fileList, setFileList] = useState<any[]>([]);

const { data: games } = useQuery(["games"], () => getGames());

const { Dragger } = Upload;

const addCharacterMutation = useMutation(createCharacter, {
onSuccess: async () => {
NotificationUtil.success("You successfully create character.");
},
onError: (error) => {
handleAxiosError(error);
},
});

const uploadImageMutation = useMutation(
(i: any) => uploadImage(i, "character-icons"),
{
onError: (error) => {
handleAxiosError(error);
},
}
);
const handleClick = async () => {
const gameIcon = await uploadImageMutation.mutateAsync(
fileList[0].originFileObj
);
const gameIds = characterGames.map((gameName) => {
return games.find((game) => game.gameName === gameName).id;
});

addCharacterMutation.mutate({
name,
type,
gender,
race,
status,
occupation,
birthDate: birthDate as Date,
voiceActor,
height,
age,
games: gameIds,
icon: gameIcon,
});
};

const handleChange = async (info: any) => {
let fileList = [...info.fileList];

fileList = fileList.slice(-1);

if (fileList.length === 0) {
setFileList([]);
return;
}

fileList.map((file) => {
if (file.type.indexOf("image") === -1) {
NotificationUtil.error("You can only upload image files!");
setFileList([]);
} else {
setFileList([file]);
}
});
};

const onGameChange = async (_filterKey: string, value: string[]) => {
setCharacterGames(value);
};

return (
<div className={styles.container}>
<h1 className={styles.header}>Create Character</h1>

<div className={styles.form}>
<Input
placeholder="Name"
value={name}
className={styles.input}
onChange={(event) => setName(event.target.value)}
/>
<h4 className={styles.colorHeader}>Character Image</h4>
<Dragger
fileList={fileList}
beforeUpload={() => false}
onChange={handleChange}
className={styles.dragger}
>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">
Click or drag an image file to this area to upload
</p>
<p className="ant-upload-hint">You can only upload one image file.</p>
</Dragger>
<br></br>
{games?.length > 0 && (
<MultipleSelect
title="Games"
filterKey="games"
elements={games.map((game) => game.gameName)}
reset={false}
onChange={onGameChange}
></MultipleSelect>
)}
<br></br>
<h4 className={styles.colorHeader}>Birth Date</h4>
<DatePicker
selected={birthDate}
onChange={(date) => setBirthDate(date)}
className={styles.datePicker}
/>
<br></br>
<br></br>
<br></br>
<Input
placeholder="Type"
value={type}
className={styles.input}
onChange={(event) => setType(event.target.value)}
/>
<Input
placeholder="Gender"
value={gender}
className={styles.input}
onChange={(event) => setGender(event.target.value)}
/>
<Input
placeholder="Race"
value={race}
className={styles.input}
onChange={(event) => setRace(event.target.value)}
/>
<Input
placeholder="Status"
value={status}
className={styles.input}
onChange={(event) => setStatus(event.target.value)}
/>
<Input
placeholder="Occupation"
value={occupation}
className={styles.input}
onChange={(event) => setOccupation(event.target.value)}
/>

<Input
placeholder="Voice Actor"
value={voiceActor}
className={styles.input}
onChange={(event) => setVoiceActor(event.target.value)}
/>
<Input
placeholder="Height"
value={height}
className={styles.input}
onChange={(event) => setHeight(event.target.value)}
/>
<Input
placeholder="Age"
value={age}
className={styles.input}
onChange={(event) => setAge(event.target.value)}
/>

<Button className={styles.filterButton} onClick={handleClick}>
Create Character
</Button>
</div>
</div>
);
}

export default CreateCharacter;
6 changes: 6 additions & 0 deletions app/frontend/src/Pages/Admin/Main/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ function Main() {
key: "achievement",
dataIndex: "achievement",
},
{
title: "Character",
key: "character",
dataIndex: "character",
},
];

const data = [
Expand All @@ -64,6 +69,7 @@ function Main() {
tag: AddButton("Create Tag", "/create-tag"),
user: DeleteButton("Ban User", "/ban-user"),
achievement: AddButton("Create Achievement", "/create-achievement"),
character: AddButton("Add Character", "/add-character"),
},
{
key: "2",
Expand Down
48 changes: 48 additions & 0 deletions app/frontend/src/Services/character.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,57 @@
import axios from "axios";

export const createCharacter = async ({
name,
type,
gender,
race,
status,
occupation,
birthDate,
voiceActor,
height,
age,
games,
icon,
}: {
name: string;
type: string;
gender: string;
race: string;
status: string;
occupation: string;
birthDate: Date;
voiceActor: string;
height: string;
age: string;
games: any;
icon: string;
}) => {
const response = await axios.post(
`${import.meta.env.VITE_APP_API_URL}/character/create`,
{
name,
type,
gender,
race,
status,
occupation,
birthDate,
voiceActor,
height,
age,
games,
icon,
}
);

return response.data;
};
export async function getCharacterByGame(gameId: string) {
const response = await axios.get(
`${import.meta.env.VITE_APP_API_URL}/character/get-game-characters`,
{ params: { gameId: gameId } }
);
return response.data;
}

5 changes: 5 additions & 0 deletions app/frontend/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Achievements from "./Pages/Achievement/Achievements";
import Profile from "./Pages/Profile/Profile";
import CreateAchievement from "./Pages/Admin/Achievement/CreateAchievement/CreateAchievement";
import DeleteAchievement from "./Pages/Admin/Achievement/DeleteAchievement/DeleteAchievement";
import CreateCharacter from "./Pages/Admin/Character/CreateCharacter/CreateCharacter";
import UpdateGame from "./Pages/Admin/Game/UpdateGame/UpdateGame";
import HomePage from "./Pages/HomePage/HomePage";
import Char from "./Pages/Char/Char";
Expand Down Expand Up @@ -125,6 +126,10 @@ const router = createBrowserRouter([
path: "ban-user",
element: <BanUser />,
},
{
path: "add-character",
element: <CreateCharacter />,
},
{
path: "admin-permission",
element: <GiveAdminPermission />,
Expand Down

0 comments on commit 35a8493

Please sign in to comment.