見出し画像

メンバー・勤怠・タスクをひとつの画面へ。React初心者がMembersページで学んだこと

前回の記事では、Team VisualizerのTasksページについて紹介しました。

今回は、チームに所属するメンバーを確認・管理するMembersページについて書いていきます。

Membersページでは、メンバーの追加・削除・検索だけでなく、勤怠状況や担当タスクも確認できます。

制作を通して学んだuseState・useEffect・useMemo・React Routerの使い方も、初心者なりの言葉で紹介します。

メンバー管理画面

チーム全体の状況を4つのカードで表示

ページ上部には、次の情報をカード形式で表示しています。

  • 登録メンバー数

  • 本日の出勤人数

  • 進行中のタスク数

  • 部署数

ダッシュボードと同じように、チームの状況を短時間で確認できるようにするためです。

出勤人数や進行中のタスク数は、useMemoを使って計算しています。

const workingMemberCount = useMemo(() => {
  return membersWithAttendance.filter(
    (member) => member.attendance === "出勤"
  ).length;
}, [membersWithAttendance]);

const totalActiveTasks = useMemo(() => {
  return tasks.filter(
    (task) => task.status === "進行中"
  ).length;
}, [tasks]);

useMemoは、指定したデータが変わったときだけ計算をやり直すReact Hooksです。

今回は、勤怠情報が変わったときに出勤人数を、タスク情報が変わったときに進行中のタスク数を計算しています。

新しいメンバーを追加する

「新規メンバー」ボタンを押すと、名前・役割・部署・役職を入力する画面が開きます。

新規メンバー追加

入力内容はuseStateで管理しています。

const [newMember, setNewMember] = useState({
  name: "",
  role: "メンバー",
  department: "",
  position: "",
});

useStateは、画面上で変化するデータを管理するReact Hooksです。

保存すると、入力したメンバーを一覧の先頭に追加します。

setMemberList((previousMembers) => [
  member,
  ...previousMembers,
]);

setMemberListによってデータが変わると、Reactが画面を再表示するため、新しいメンバーがすぐに一覧へ反映されます。

追加後のメンバー管理画面

また、名前・部署・役職が入力されていない場合や、同じ名前がすでに登録されている場合は、追加できないようにしています。

担当タスクがあるメンバーは削除できない

各メンバーカードの削除ボタンから、登録したメンバーを削除できます。

削除にはfilter()を使用しています。

setMemberList((previousMembers) =>
  previousMembers.filter(
    (member) => member.id !== deletingMember.id
  )
);

ただし、担当タスクが残っているメンバーを削除すると、担当者のいないタスクが発生してしまいます。

そこで、削除するメンバーが担当しているタスクを確認しています。

const deletingMemberTasks = useMemo(() => {
  if (!deletingMember) return [];

  return tasks.filter(
    (task) =>
      task.assignee === deletingMember.name
  );
}, [deletingMember, tasks]);

担当タスクが1件以上ある場合は削除ボタンを無効にし、先に担当者を変更するように案内します。

今回のMembersページで、特に意識した部分です。

検索と絞り込みでメンバーを探す

メンバーが増えても目的の人を見つけられるように、次の検索・絞り込み機能も実装しました。

  • 名前・部署・役職から検索

  • 部署で絞り込み

  • リーダー・メンバーで絞り込み

  • 出勤・未出勤などの勤怠で絞り込み

絞り込み後のメンバーは、useMemoとfilter()で作っています。

const filteredMembers = useMemo(() => {
  return membersWithAttendance.filter(
    (member) => {
      // 検索条件に一致するか確認
      return (
        matchesKeyword &&
        matchesDepartment &&
        matchesRole &&
        matchesAttendance
      );
    }
  );
}, [
  membersWithAttendance,
  searchKeyword,
  departmentFilter,
  roleFilter,
  attendanceFilter,
]);

検索条件が変わると、条件に一致したメンバーだけが表示されます。

useEffectでほかのページとデータをつなぐ

Membersページでは、メンバー情報だけでなく、Tasksページのタスクと本日の勤怠記録も読み込んでいます。

useEffectは、ページを表示したときや、指定したデータが変わったときに処理を実行するReact Hooksです。

useEffect(() => {
  localStorage.setItem(
    "members",
    JSON.stringify(memberList)
  );
}, [memberList]);

メンバーを追加・削除してmemberListが変わると、最新の情報をlocalStorageへ保存します。

また、タスクや勤怠の更新を検知し、Membersページにも最新の情報を反映しています。

この仕組みによって、メンバー・タスク・勤怠が別々の情報ではなく、つながったデータとして表示されます。

React Routerで詳細ページへ移動する

各カードの「メンバー詳細」を押すと、そのメンバー専用の詳細ページへ移動します。

<Link to={`/members/${member.id}`}>
  メンバー詳細
</Link>

例えば、IDがaのメンバーなら、移動先は/members/aになります。

React Routerを使うことで、ページ全体を読み込み直さずに画面を切り替えられます。

メンバーごとに異なるIDをURLへ含めることで、同じ詳細ページの仕組みを複数のメンバーに使えるようにしています。

メンバー詳細

Membersページは情報をつなぐ画面

今回は、Team VisualizerのMembersページについて紹介しました。

このページで意識したのは、次の点です。

  • チーム全体の状況を4つのカードで確認する

  • メンバーを追加・削除する

  • 検索や絞り込みから目的のメンバーを探す

  • 担当タスクがあるメンバーの誤削除を防ぐ

  • メンバーの詳細ページへ移動する

  • タスクや勤怠の情報をメンバーとつなげる

制作を通して、useState・useEffect・useMemo・React Routerを、実際のアプリでどのように使うのか学ぶことができました。

まだlocalStorageを使った学習段階ですが、今後はFirebaseへ移行し、複数人で情報を共有できるようにしていく予定です。

少しずつでも機能を追加していくことで、React初心者でもオリジナルアプリを形にできると感じています。

最後まで読んでいただき、ありがとうございました。

いいなと思ったら応援しよう!