🙆‍♀️

GataGridのCRUD

2024/07/01に公開
"use client";
import React, { useState } from "react";
import { TextField, Typography, Grid } from "@mui/material";
import { useForm } from "react-hook-form";
import { DataGrid, GridColDef } from "@mui/x-data-grid";

type FormData = {
  eraNumber: string;
  year: string;
  month: string;
  day: string;
};

type BirthdayFormValues = {
  id: number;
  birthDay: string;
};

const initialData: BirthdayFormValues[] = [
  { id: 1, birthDay: "19900101" },
  { id: 2, birthDay: "20000216" },
  { id: 3, birthDay: "19800607" },
];

const eraMapping = {
  "1": "M",
  "2": "T",
  "3": "S",
  "4": "H",
  "5": "R",
};

const convertToWesternYear = (eraNumber: string, year: string): string => {
  let westernYear;
  switch (eraNumber) {
    case "5": // 令和
      westernYear = 2018 + parseInt(year);
      break;
    case "4": // 平成
      westernYear = 1988 + parseInt(year);
      break;
    case "3": // 昭和
      westernYear = 1925 + parseInt(year);
      break;
    case "2": // 大正
      westernYear = 1911 + parseInt(year);
      break;
    case "1": // 明治
      westernYear = 1867 + parseInt(year);
      break;
    default:
      westernYear = parseInt(year);
  }
  return westernYear.toString();
};

const convertToJapaneseEra = (dateString: string): string => {
  if (!dateString) return "不明";

  const year = parseInt(dateString.slice(0, 4));
  let eraYear;
  let era;

  if (year >= 2019) {
    era = "R";
    eraYear = year - 2018;
  } else if (year >= 1989) {
    era = "H";
    eraYear = year - 1988;
  } else if (year >= 1926) {
    era = "S";
    eraYear = year - 1925;
  } else if (year >= 1912) {
    era = "T";
    eraYear = year - 1911;
  } else if (year >= 1868) {
    era = "M";
    eraYear = year - 1867;
  } else {
    era = "不明";
    eraYear = year;
  }

  return `${era}${eraYear}.${dateString.slice(4, 6)}.${dateString.slice(6)}`;
};

const convertToFormattedDate = (dateString: string): string => {
  return convertToJapaneseEra(dateString);
};

const columns: GridColDef[] = [
  { field: "id", headerName: "ID", width: 70 },
  {
    field: "birthDay",
    headerName: "誕生日(和暦)",
    width: 200,
    renderCell: (params) => {
      return <span>{convertToFormattedDate(params.value)}</span>;
    },
  },
];

const BirthdayForm: React.FC = () => {
  const { register, handleSubmit, watch } = useForm<FormData>();
  const [birthdays, setBirthdays] = useState<BirthdayFormValues[]>(initialData);

  const [editingId, setEditingId] = useState<number | null>(null);
  const [deletingId, setDeletingId] = useState<number | null>(null);

  const eraNumber = watch("eraNumber");
  const eraLetter = eraMapping[eraNumber] || "";

  const handleEdit = (id: number, field: string, value: string) => {
    setBirthdays((prev) =>
      prev.map((b) => (b.id === id ? { ...b, [field]: value } : b))
    );
  };

  const handleDelete = (id: number) => {
    setBirthdays((prev) => prev.filter((b) => b.id !== id));
  };

  const onSubmit = (data: FormData) => {
    const westernYear = convertToWesternYear(data.eraNumber, data.year);
    const dateString = `${westernYear}${data.month.padStart(
      2,
      "0"
    )}${data.day.padStart(2, "0")}`;

    const newId = Math.max(...birthdays.map((b) => b.id)) + 1;
    setBirthdays([...birthdays, { id: newId, birthDay: dateString }]);
  };

  const handleEraNumberInput = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    if (!/^[1-5]?$/.test(value)) {
      event.preventDefault();
    }
  };

  console.log("Current birthdays data:", birthdays); // デバッグ情報を追加

  return (
    <>
      <form onSubmit={handleSubmit(onSubmit)}>
        <Grid container spacing={2}>
          <Grid item>
            <TextField
              {...register("eraNumber")}
              label="元号 (1-明治, 2-大正, 3-昭和, 4-平成, 5-令和)"
              inputProps={{ maxLength: 1 }}
              onInput={handleEraNumberInput}
            />
          </Grid>
          <Grid item>
            <TextField
              label="元号の頭文字"
              value={eraLetter}
              disabled
              //   sx={{ backgroundColor: "#888888" }}
            />
          </Grid>
        </Grid>
        <TextField {...register("year")} label="年" />
        <TextField {...register("month")} label="月" />
        <TextField {...register("day")} label="日" />
        <button type="submit">追加</button>
      </form>
      {birthdays.map((b) => (
        <Typography key={b.id} variant="subtitle1">
          {`ID: ${b.id}, 誕生日(和暦): ${convertToJapaneseEra(b.birthDay)}`}
        </Typography>
      ))}

      <div style={{ height: 400, width: "100%" }}>
        <DataGrid
          getRowId={(row) => row.id}
          rows={birthdays}
          columns={columns}
          pageSize={5}
          onCellEditCommit={(params) => {
            handleEdit(
              params.id as number,
              params.field,
              params.value as string
            );
          }}
          onSelectionModelChange={(newSelection) => {
            setDeletingId(
              newSelection.length > 0 ? (newSelection[0] as number) : null
            );
          }}
        />
        {deletingId !== null && (
          <button onClick={() => handleDelete(deletingId)}>
            選択した行を削除
          </button>
        )}
      </div>
    </>
  );
};

export default BirthdayForm;

Discussion