🙆♀️
GataGridのCRUD
"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