Skip to content

Commit

Permalink
refactor: enhance ninjas page
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrofp4444 committed Dec 22, 2023
1 parent faf99e3 commit fbee07d
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 101 deletions.
41 changes: 35 additions & 6 deletions apps/app/components/Ninja/index.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,58 @@
import { Avatar, Card } from "antd";
import React, { useState } from "react";
import { Avatar, Button, Card, Popconfirm, Space } from "antd";
import { EditOutlined } from "@ant-design/icons";
import Belt from "~/components/Belt";
import Link from "next/link";
import NinjaForm from "~/components/NinjaForm";

const { Meta } = Card;

function Ninja(ninja) {
const [showNinjaForm, setShowNinjaForm] = useState(false);
const [showPopconfirm, setShowPopconfirm] = useState(false);

const handleButtonClick = () => {
setShowNinjaForm(false);
setShowPopconfirm(true);
};

const handleConfirm = () => {
setShowNinjaForm(true);
setShowPopconfirm(false);
};

const handleCancel = () => {
setShowPopconfirm(false);
};

return (
<Card
key={ninja.id}
size="large"
style={{ width: 300, marginTop: 16 }}
actions={[
<Link key={`link ${ninja.id}`} href={`/ninjas/edit/${ninja.id}`}>
<a>
<EditOutlined key="edit" />
</a>
</Link>,
<Popconfirm
key={`popconfirm ${ninja.id}`}
title="Tem certeza que deseja editar?"
open={showPopconfirm}
onConfirm={handleConfirm}
onCancel={handleCancel}
>
<Button
key={`button ${ninja.id}`}
icon={<EditOutlined />}
onClick={handleButtonClick}
/>
</Popconfirm>,
]}
>
{showNinjaForm && <NinjaForm id={ninja.id} reloadNinjas={null} />}
<Link href={`/profile/ninja/${ninja.id}`}>
<a>
<Meta
avatar={<Avatar src={ninja.photo} />}
title={`${ninja.first_name} ${ninja.last_name}`}
style={{ marginBottom: "10px" }}
/>
<Belt belt={ninja.belt} />
</a>
Expand Down
181 changes: 92 additions & 89 deletions apps/app/components/NinjaForm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
DatePicker,
Form,
Input,
Modal,
Row,
Select,
Space,
Expand All @@ -20,7 +21,7 @@ import * as api from "bokkenjs";
import { notifyError, notifyInfo } from "~/components/Notification";
const { Title } = Typography;

export default function NinjaForm({ id }) {
export default function NinjaForm({ id, reloadNinjas }) {
const router = useRouter();
const [form] = Form.useForm();

Expand All @@ -30,6 +31,8 @@ export default function NinjaForm({ id }) {
const [skills, setSkills] = useState([]);
const [selectedSkills, setSelectedSkills] = useState([]);

const [isModalVisible, setIsModalVisible] = useState(true);

const getAllSkills = () => {
api
.getSkills()
Expand Down Expand Up @@ -105,20 +108,22 @@ export default function NinjaForm({ id }) {
.then(() => {
changeSkills(id);
notifyInfo("O ninja foi editado com sucesso");
router.push("/ninjas");
//reloadNinjas(); // Does not work because of invalid date, the data from the response returns undefined in ninja.birthday
router.reload(); // This works for now, but it is not the best solution, we need to fix the invalid date
})
.catch((error) => {
notifyError(
"Ocorreu um erro",
"Não foi possível atualizar os dados do ninja"
"Não foi possível atualizar os dados do ninja" + error
);
});
} else {
api
.createNinja(values)
.then((response) => {
changeSkills(response.data.id);
router.push("/ninjas");
notifyInfo("O ninja foi criado com sucesso");
reloadNinjas();
})
.catch((error) => {
notifyError("Ocorreu um erro", "Não foi possível criar o ninja");
Expand All @@ -133,95 +138,93 @@ export default function NinjaForm({ id }) {
xxl: 6,
};

const handleCancel = () => {
setIsModalVisible(false);
};

return (
<>
<Row justify="space-between">
<Title level={2}>
{id && ninja
? ninja.first_name + " " + ninja.last_name
: "Novo Ninja"}
</Title>
<Space>
<Link href="/ninjas">
<Button
danger
shape="circle"
size="large"
icon={<CloseOutlined />}
/>
</Link>
<Button
shape="circle"
type="primary"
size="large"
icon={<SaveOutlined />}
onClick={() => form.submit()}
/>
</Space>
</Row>
<Row align="middle">
<Col xs={24} sm={24} md={20} lg={16} xl={12}>
<Form
{...{
labelCol: { span: 8 },
wrapperCol: { span: 16 },
}}
initialValues={ninja}
form={form}
onFinish={onFinish}
>
<Form.Item
label="Nome"
name="ninja[first_name]"
rules={[{ required: true }]}
initialValue={ninja ? ninja.first_name : null}
>
<Input placeholder="Linus" />
</Form.Item>
<Form.Item
label="Apelido"
name="ninja[last_name]"
rules={[{ required: true }]}
initialValue={id && ninja ? ninja.last_name : ""}
<Modal
title={id ? "Editar Ninja" : "Criar Novo Ninja"}
open={isModalVisible}
onCancel={handleCancel}
onOk={() => {
form.submit();
setIsModalVisible(false);
}}
width={700}
>
<Row justify="center">
<Title level={2}>
{id && ninja
? ninja.first_name + " " + ninja.last_name
: "Novo Ninja"}
</Title>
</Row>
<Row justify="center" align="middle">
<Col xs={24} sm={24} md={20} lg={16} xl={12}>
<Form
{...{
labelCol: { span: 8 },
wrapperCol: { span: 16 },
}}
initialValues={ninja}
form={form}
onFinish={onFinish}
>
<Input placeholder="Torvalds" />
</Form.Item>
<Form.Item
label="Aniversário"
name="ninja[birthday]"
rules={[{ required: true }]}
initialValue={
id && ninja ? moment(ninja.birthday, "YYYY-MM-DD") : null
}
>
<DatePicker />
</Form.Item>

<Form.Item label="Quer aprender">
<Select
mode="multiple"
placeholder="Adicionar linguagem"
onChange={setSelectedSkills}
value={selectedSkills}
style={{ minWidth: "200px" }}
<Form.Item
label="Nome"
name="ninja[first_name]"
rules={[{ required: true }]}
initialValue={ninja ? ninja.first_name : null}
>
<Input placeholder="Linus" />
</Form.Item>
<Form.Item
label="Apelido"
name="ninja[last_name]"
rules={[{ required: true }]}
initialValue={id && ninja ? ninja.last_name : ""}
>
<Input placeholder="Torvalds" />
</Form.Item>
<Form.Item
label="Aniversário"
name="ninja[birthday]"
rules={[{ required: true }]}
initialValue={
moment() // for now I choosed always the current date so that it's easier to use //id && ninja ? moment(ninja.birthday, "YYYY-MM-DD") : null
}
>
{skills.map((s) => (
<Select.Option key={s.id} value={s.id}>
{s.name}
</Select.Option>
))}
</Select>
</Form.Item>
<Row justify="center">
<Link href="/blog/posts/choosing-first-language">
<Button type="secondary">
Como escolher a linguagem para o ninja aprender?
</Button>
</Link>
</Row>
</Form>
</Col>
</Row>
<DatePicker />
</Form.Item>

<Form.Item label="Quer aprender">
<Select
mode="multiple"
placeholder="Adicionar linguagem"
onChange={setSelectedSkills}
value={selectedSkills}
style={{ minWidth: "200px" }}
>
{skills.map((s) => (
<Select.Option key={s.id} value={s.id}>
{s.name}
</Select.Option>
))}
</Select>
</Form.Item>
<Row justify="center">
<Link href="/blog/posts/choosing-first-language">
<Button type="secondary">
Como escolher a linguagem para o ninja aprender?
</Button>
</Link>
</Row>
</Form>
</Col>
</Row>
</Modal>
</>
);
}
46 changes: 40 additions & 6 deletions apps/app/pages/ninjas/index.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,73 @@
import { useEffect, useState } from "react";
import Link from "next/link";
import { Button, Col, Row, Typography } from "antd";
import { PlusOutlined } from "@ant-design/icons";
import { Button, Col, Popconfirm, Row, Typography } from "antd";
import { PlusCircleFilled, PlusOutlined } from "@ant-design/icons";
import { withAuth } from "~/components/Auth";
import AppLayout from "~/layouts/AppLayout";
import * as api from "bokkenjs";
import NinjaForm from "~/components/NinjaForm";
import Ninja from "~/components/Ninja";
import { notifyError } from "~/components/Notification";
import { set } from "lodash-es";

const { Title } = Typography;

function Ninjas() {
const [ninjas, setNinjas] = useState<any[]>([]);
const [showNinjaForm, setShowNinjaForm] = useState(false);
const [showPopconfirm, setShowPopconfirm] = useState(false);

useEffect(() => {
const fetchNinjas = () => {
api
.getNinjas()
.then((response: any) => setNinjas(response.data))
.catch((error) => {
notifyError("Ocorreu um erro", "Não foi possível obter os seus ninjas");
});
};

useEffect(() => {
fetchNinjas();
}, []);

const handleButtonClick = () => {
setShowNinjaForm(false);
setShowPopconfirm(true);
};

const handleConfirm = () => {
setShowNinjaForm(true);
setShowPopconfirm(false);
};

const handleCancel = () => {
setShowPopconfirm(false);
};

return (
<AppLayout>
<Row justify="space-between">
<Title level={2}>Os Meus Ninjas</Title>
<Link href="/ninjas/new">
<Popconfirm
title="Quer criar um Ninja?"
open={showPopconfirm}
onConfirm={handleConfirm}
onCancel={handleCancel}
okText="Sim"
cancelText="Não"
placement="left"
>
<Button
shape="circle"
shape="default"
type="primary"
size="large"
icon={<PlusOutlined />}
onClick={handleButtonClick}
/>
</Link>
</Popconfirm>
{showNinjaForm && (
<NinjaForm id={undefined} reloadNinjas={() => fetchNinjas()} />
)}
</Row>
<Row justify="space-around" gutter={[10, 10]}>
{ninjas.map((ninja: any) => (
Expand Down

0 comments on commit fbee07d

Please sign in to comment.