238 lines
9.4 KiB
TypeScript
238 lines
9.4 KiB
TypeScript
import { AppDispatch } from "app/store";
|
||
import React, { useCallback, useEffect, useState } from "react";
|
||
import Header from "components/header";
|
||
import Footer from "components/footer";
|
||
import styles from "styles/app.module.scss";
|
||
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
|
||
import { useDispatch, useSelector } from "react-redux";
|
||
import { listUsersAsync, selectDomain } from "features/user";
|
||
import { useTranslation } from "react-i18next";
|
||
import { getTranslationID } from "translation";
|
||
import personAdd from "../../assets/images/person_add.svg";
|
||
import editImg from "../../assets/images/edit.svg";
|
||
import deleteImg from "../../assets/images/delete.svg";
|
||
import badgeImg from "../../assets/images/badge.svg";
|
||
import checkFill from "../../assets/images/check_fill.svg";
|
||
import circle from "../../assets/images/circle.svg";
|
||
import { UserAddPopup } from "./popup";
|
||
|
||
const UserListPage: React.FC = (): JSX.Element => {
|
||
const dispatch: AppDispatch = useDispatch();
|
||
const [t] = useTranslation();
|
||
|
||
const [isPopupOpen, setIsPopupOpen] = useState(false);
|
||
|
||
const onOpen = useCallback(() => {
|
||
setIsPopupOpen(true);
|
||
}, [setIsPopupOpen]);
|
||
|
||
useEffect(() => {
|
||
// ユーザ一覧取得処理を呼び出す
|
||
dispatch(listUsersAsync());
|
||
}, [dispatch]);
|
||
|
||
const domain = useSelector(selectDomain);
|
||
|
||
return (
|
||
<>
|
||
<UserAddPopup
|
||
isOpen={isPopupOpen}
|
||
onClose={() => {
|
||
setIsPopupOpen(false);
|
||
}}
|
||
/>
|
||
<div className={styles.wrap}>
|
||
{/* XXX デザイン上はヘッダに「Account」「User」「License」等の項目が設定されているが、そのままでは使用できない。PBI1128ではユーザ一覧画面は作りこまないので、ユーザ一覧のPBIでヘッダをデザイン通りにする必要がある */}
|
||
<Header />
|
||
<UpdateTokenTimer />
|
||
<main className={styles.main}>
|
||
<div className="">
|
||
<div className={styles.pageHeader}>
|
||
<h1 className={styles.pageTitle}>
|
||
{t(getTranslationID("userListPage.label.title"))}
|
||
</h1>
|
||
<p className="pageTxt" />
|
||
</div>
|
||
<section className={styles.user}>
|
||
<div>
|
||
<ul className={styles.menuAction}>
|
||
<li>
|
||
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
|
||
<a
|
||
className={`${styles.menuLink} ${styles.isActive}`}
|
||
onClick={onOpen}
|
||
>
|
||
<img src={personAdd} alt="" className={styles.menuIcon} />
|
||
{t(getTranslationID("userListPage.label.addUser"))}
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="" className={styles.menuLink}>
|
||
<img src={editImg} alt="" className={styles.menuIcon} />
|
||
{t(getTranslationID("userListPage.label.edit"))}
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="" className={styles.menuLink}>
|
||
<img src={deleteImg} alt="" className={styles.menuIcon} />
|
||
{t(getTranslationID("userListPage.label.delete"))}
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="" className={styles.menuLink}>
|
||
<img src={badgeImg} alt="" className={styles.menuIcon} />
|
||
{t(
|
||
getTranslationID("userListPage.label.licenseAllocation")
|
||
)}
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
<table className={styles.table}>
|
||
<tbody>
|
||
<tr className={styles.tableHeader}>
|
||
<th>
|
||
<a className={styles.hasSort}>
|
||
{t(getTranslationID("userListPage.label.name"))}
|
||
</a>
|
||
</th>
|
||
<th>
|
||
<a className={styles.hasSort}>
|
||
{t(getTranslationID("userListPage.label.role"))}
|
||
</a>
|
||
</th>
|
||
<th>
|
||
<a className={styles.hasSort}>
|
||
{t(getTranslationID("userListPage.label.authorID"))}
|
||
</a>
|
||
</th>
|
||
<th>
|
||
<a className={styles.hasSort}>
|
||
{t(
|
||
getTranslationID("userListPage.label.typistGroup")
|
||
)}
|
||
</a>
|
||
</th>
|
||
<th>
|
||
<a className={styles.hasSort}>
|
||
{t(getTranslationID("userListPage.label.email"))}
|
||
</a>
|
||
</th>
|
||
<th>
|
||
<a className={styles.hasSort}>
|
||
{t(getTranslationID("userListPage.label.status"))}
|
||
</a>
|
||
</th>
|
||
<th>
|
||
<a className={styles.hasSort}>
|
||
{t(getTranslationID("userListPage.label.expiration"))}
|
||
</a>
|
||
</th>
|
||
<th>
|
||
<a className={styles.hasSort}>
|
||
{t(getTranslationID("userListPage.label.remaining"))}
|
||
</a>
|
||
</th>
|
||
<th>
|
||
{t(getTranslationID("userListPage.label.autoRenew"))}
|
||
</th>
|
||
<th>
|
||
{t(getTranslationID("userListPage.label.licenseAlert"))}
|
||
</th>
|
||
<th>
|
||
{t(getTranslationID("userListPage.label.notification"))}
|
||
</th>
|
||
</tr>
|
||
{/* XXX 「固定」の項目と、isSelected、isAlertの対応が必要 */}
|
||
{domain.users.map((user) => (
|
||
<tr key={user.email}>
|
||
<td>{user.name}</td>
|
||
<td>{user.role}</td>
|
||
<td>{user.authorId}</td>
|
||
<td>{user.typistGroupName}</td>
|
||
<td>{user.email}</td>
|
||
<td>固定:Uploaded</td>
|
||
<td>固定:2023/8/3</td>
|
||
<td>固定:114</td>
|
||
<td>
|
||
{user.autoRenew ? (
|
||
<img
|
||
src={checkFill}
|
||
alt=""
|
||
className={styles.icCheckCircle}
|
||
/>
|
||
) : (
|
||
<img
|
||
src={circle}
|
||
alt=""
|
||
className={styles.icCheckCircle}
|
||
/>
|
||
)}
|
||
</td>
|
||
<td>
|
||
{user.licenseAlert ? (
|
||
<img
|
||
src={checkFill}
|
||
alt=""
|
||
className={styles.icCheckCircle}
|
||
/>
|
||
) : (
|
||
<img
|
||
src={circle}
|
||
alt=""
|
||
className={styles.icCheckCircle}
|
||
/>
|
||
)}
|
||
</td>
|
||
<td>
|
||
{user.notification ? (
|
||
<img
|
||
src={checkFill}
|
||
alt=""
|
||
className={styles.icCheckCircle}
|
||
/>
|
||
) : (
|
||
<img
|
||
src={circle}
|
||
alt=""
|
||
className={styles.icCheckCircle}
|
||
/>
|
||
)}
|
||
</td>
|
||
</tr>
|
||
))}
|
||
</tbody>
|
||
</table>
|
||
<div className={styles.pagenation}>
|
||
<nav className={styles.pagenationNav}>
|
||
<span className={styles.pagenationTotal}>
|
||
{domain.users.length}{" "}
|
||
{t(getTranslationID("userListPage.label.users"))}
|
||
</span>
|
||
{/* XXX 複数ページの挙動、対応が必要 */}
|
||
<a href="" className="pagenationNavFirst">
|
||
«
|
||
</a>
|
||
<a href="" className="pagenationNavPrev">
|
||
‹
|
||
</a>
|
||
1 {t(getTranslationID("userListPage.label.of"))} 1
|
||
<a href="" className="pagenationNavNext isActive">
|
||
›
|
||
</a>
|
||
<a href="" className="pagenationNavLast isActive">
|
||
»
|
||
</a>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</main>
|
||
<Footer />
|
||
</div>
|
||
</>
|
||
);
|
||
};
|
||
|
||
export default UserListPage;
|