add new project action
This commit is contained in:
@@ -2,9 +2,10 @@ import { Box } from "@mui/material";
|
|||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { useAuth } from "../../hooks/useAuth";
|
import { useAuth } from "../../hooks/useAuth";
|
||||||
import { createSWRFetcher } from "../../utils/swrFetcher";
|
import { createSWRFetcher } from "../../utils/swrFetcher";
|
||||||
|
import { NewProjectAction } from "./components/NewProjectAction";
|
||||||
import { Project } from "./components/Project";
|
import { Project } from "./components/Project";
|
||||||
|
|
||||||
type APIProjectList = {
|
export type APIProjectList = {
|
||||||
data: {
|
data: {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -17,15 +18,18 @@ export const Projects = () => {
|
|||||||
const { data, mutate } = useSWR<APIProjectList>("projects", fetcher);
|
const { data, mutate } = useSWR<APIProjectList>("projects", fetcher);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<>
|
||||||
sx={{
|
<NewProjectAction mutate={mutate} />
|
||||||
display: "grid",
|
<Box
|
||||||
gridAutoColumns: "repeat(auto-fit, minmax(250px, 1fr))",
|
sx={{
|
||||||
}}
|
display: "grid",
|
||||||
>
|
gridAutoColumns: "repeat(auto-fit, minmax(250px, 1fr))",
|
||||||
{data?.data.map((project) => (
|
}}
|
||||||
<Project projectMutate={mutate} key={project.id} {...project} />
|
>
|
||||||
))}
|
{data?.data.map((project) => (
|
||||||
</Box>
|
<Project projectMutate={mutate} key={project.id} {...project} />
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
84
client/src/pages/Projects/components/NewProjectAction.tsx
Normal file
84
client/src/pages/Projects/components/NewProjectAction.tsx
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Dialog,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
DialogTitle,
|
||||||
|
TextField,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { SubmitHandler, useForm } from "react-hook-form";
|
||||||
|
import { KeyedMutator } from "swr";
|
||||||
|
import { useAuth } from "../../../hooks/useAuth";
|
||||||
|
import { APIProjectList } from "../Projects";
|
||||||
|
|
||||||
|
type NewProjectForm = {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type NewProjectActionProps = {
|
||||||
|
mutate: KeyedMutator<APIProjectList>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const NewProjectAction = ({ mutate }: NewProjectActionProps) => {
|
||||||
|
const { register, handleSubmit, reset } = useForm<NewProjectForm>();
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const { apiClient } = useAuth();
|
||||||
|
|
||||||
|
const onSubmit: SubmitHandler<NewProjectForm> = (data) => {
|
||||||
|
setIsLoading(true);
|
||||||
|
apiClient("projects", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
}).then(async () => {
|
||||||
|
reset();
|
||||||
|
await mutate();
|
||||||
|
setIsLoading(false);
|
||||||
|
setOpen(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setOpen(false);
|
||||||
|
reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpen = () => {
|
||||||
|
setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box sx={{ textAlign: "right" }}>
|
||||||
|
<Button onClick={handleOpen} variant="contained" size="large">
|
||||||
|
New project
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
<Dialog open={open} onClose={handleClose}>
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<DialogTitle>New project</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<TextField
|
||||||
|
{...register("name")}
|
||||||
|
disabled={isLoading}
|
||||||
|
autoFocus
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
variant="standard"
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button disabled={isLoading} onClick={handleClose}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button type="submit" disabled={isLoading}>
|
||||||
|
Create
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</form>
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user