import React, {
createContext,
Dispatch,
SetStateAction,
ReactNode,
useState,
} from "react";
import { User } from "../types/api/user";
// ログインユーザでisAdminを追加する
type LoginUser = User & { isAdmin: boolean };
export type LoginUserContextType = {
loginUser: LoginUser | undefined;
setLoginUser: Dispatch<SetStateAction<LoginUser | undefined>>;
};
export const LoginUserContext = createContext<LoginUserContextType>(
{} as LoginUserContextType
);
export const LoginUserProvider = (props: { children: ReactNode }) => {
const { children } = props;
const [loginUser, setLoginUser] = useState<User | undefined>(undefined);
return (
<LoginUserContext.Provider value=>
{children}
</LoginUserContext.Provider>
);
};
import axios from "axios";
import { useCallback, useState } from "react";
import { User } from "../types/api/user";
import { useHistory } from "react-router-dom";
import { useMessage } from "./useMessage";
import { useLoginUser } from "./useLoginUser";
export const useAuth = () => {
const history = useHistory();
const { showMessage } = useMessage();
const [loading, setLoading] = useState(false);
const { setLoginUser } = useLoginUser();
const login = useCallback(
(id: string) => {
setLoading(true);
axios
.get<User>(`https://jsonplaceholder.typicode.com/users/${id}`)
.then((res) => {
if (res.data) {
const isAdmin = res.data.id === 10 ? true : false;
setLoginUser({ ...res.data, isAdmin });
showMessage({ title: "ログインしました", status: "success" });
history.push("/home");
} else {
showMessage({
title: "ユーザーが見つかりませんでした",
status: "error",
});
setLoading(false);
}
})
.catch(() => {
showMessage({
title: "ログイン出来ませんでした",
status: "error",
});
setLoading(false);
});
},
[history, showMessage, setLoginUser]
);
return { login, loading };
};
import React, { memo, VFC, useState, useEffect, ChangeEvent } from "react";
import {
Stack,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalBody,
FormControl,
FormLabel,
Input,
ModalFooter,
} from "@chakra-ui/react";
import { User } from "../../../types/api/user";
import { PrimaryButton } from "../../atoms/button/PrimaryButton";
type Props = {
user: User | undefined;
isOpen: boolean;
onClose: () => void;
isAdmin: boolean;
};
export const UserDetailModal: VFC<Props> = memo((props) => {
const { user, isOpen, onClose, isAdmin } = props;
const [username, setUsername] = useState("");
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [phone, setPhone] = useState("");
useEffect(() => {
setUsername(user?.username ?? "");
setName(user?.name ?? "");
setEmail(user?.email ?? "");
setPhone(user?.phone ?? "");
}, [user]);
const onChangeUserName = (e: ChangeEvent<HTMLInputElement>) =>
setUsername(e.target.value);
const onChangeName = (e: ChangeEvent<HTMLInputElement>) =>
setName(e.target.value);
const onChangeEmail = (e: ChangeEvent<HTMLInputElement>) =>
setEmail(e.target.value);
const onChangePhone = (e: ChangeEvent<HTMLInputElement>) =>
setPhone(e.target.value);
const onClickUpdate = () => alert();
return (
<Modal
isOpen={isOpen}
onClose={onClose}
autoFocus={false}
motionPreset="slideInBottom"
>
<ModalOverlay />
<ModalContent pb={6}>
<ModalHeader>ユーザー詳細</ModalHeader>
<ModalCloseButton />
<ModalBody mx={4}>
<Stack spacing={4}>
<FormControl>
<FormLabel>名前</FormLabel>
<Input
value={username}
onChange={onChangeUserName}
isReadOnly={!isAdmin}
/>
<FormLabel>フルネーム</FormLabel>
<Input
value={name}
onChange={onChangeName}
isReadOnly={!isAdmin}
/>
<FormLabel>MAIL</FormLabel>
<Input
value={email}
onChange={onChangeEmail}
isReadOnly={!isAdmin}
/>
<FormLabel>TEL</FormLabel>
<Input
value={phone}
onChange={onChangePhone}
isReadOnly={!isAdmin}
/>
</FormControl>
</Stack>
{isAdmin && (
<ModalFooter>
<PrimaryButton onClick={onClickUpdate}>更新</PrimaryButton>
</ModalFooter>
)}
</ModalBody>
</ModalContent>
</Modal>
);
});