今回の狙い
フロント処理となるREACT(MUI)を利用して、入力画面機能を準備します。
前回の記事の環境を、そのまま使って、Reactのプログラムだけ差し替えます。
狙いとしては、チェック処理やメッセージ等は、後からユーザ要望が出てくるので、簡単に修正できるように、別ファイルにしたいと思います。
RedmineのRestAPI
RedmineのAPIを利用して、Redmineのユーザを登録したいと思います。
APIの仕様としては、POSTアクセスで、ヘッダー情報にAPIキーをセットして、登録するユーザ情報をJSONを渡す事になります。
Reactのプログラム
以下のプログラムを用意します。
フォルダ構成
└── src
├── index.js (初期起動プログラム)
├── App.js (画面へ表示される本体)
├── ErrCheck.js (エラーチェック処理部)
└── msg.jp.js (エラーメッセージ部)
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
App.js
import { useForm } from 'react-hook-form';
import React from 'react';
import { TextField, Button } from '@mui/material';
import Grid from '@mui/material/Grid';
import ErrCheck from './ErrCheck';
import { yupResolver } from '@hookform/resolvers/yup';
export default function App() {
const { register, handleSubmit, formState: { errors } } = useForm({
defaultValues: {
loginid: '1234567890',
passwd: '12345Aa!',
firstnm: 'a',
lastnm: 'b',
mailad: 'c@d'
},
resolver: yupResolver(ErrCheck),
});
const onsubmit = async (data) => {
try {
const response = await fetch('http://localhost:3001/users.json', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Redmine-API-Key': '※ここにredmineのAPIキー',
},
body: JSON.stringify({
user: {
login: data.loginid,
password: data.passwd,
firstname: data.firstnm,
lastname: data.lastnm,
mail: data.mailad,
},
}),
});
if (response.ok) {
const responseData = await response.json();
console.log('Redmine登録成功:', responseData);
alert('ユーザー登録が完了しました。');
} else {
const errorData = await response.json();
console.error('Redmine登録失敗:', errorData);
alert('ユーザー登録に失敗しました。');
}
} catch (error) {
console.error('送信エラー:', error);
alert('送信中にエラーが発生しました。');
}
};
const onerror = err => console.log(err);
return (
<div className="App">
<form onSubmit={handleSubmit(onsubmit, onerror)} noValidate>
<Grid container spacing={1}>
<Grid size={{xs:12}}>
<TextField id="loginid" type="text" label={ErrCheck.fields.loginid.describe().label}
error={!!errors.loginid}
helperText={errors.loginid?.message}
{...register('loginid')} />
</Grid>
<Grid size={{xs:12}}>
<TextField id="passwd" type="password" label={ErrCheck.fields.passwd.describe().label}
error={!!errors.passwd}
helperText={errors.passwd?.message}
{...register('passwd')} />
</Grid>
<Grid size={{xs:12}}>
<TextField id="firstnm" type="text" label={ErrCheck.fields.firstnm.describe().label}
error={!!errors.firstnm}
helperText={errors.firstnm?.message}
{...register('firstnm')} />
</Grid>
<Grid size={{xs:12}}>
<TextField id="lastnm" type="text" label={ErrCheck.fields.lastnm.describe().label}
error={!!errors.lastnm}
helperText={errors.lastnm?.message}
{...register('lastnm')} />
</Grid>
<Grid size={{xs:12}}>
<TextField id="mailad" type="text" label={ErrCheck.fields.mailad.describe().label}
error={!!errors.mailad}
helperText={errors.mailad?.message}
{...register('mailad')} />
</Grid>
<Grid size={{xs:12}}>
<Button variant="contained" type="submit">登録</Button>
</Grid>
</Grid>
</form>
</div>
);
}
ErrCheck.js
import msg from './msg.jp';
const hasMixedCase = /(?=.*[a-z])(?=.*[A-Z])/;
const hasNumber = /(?=.*[0-9])/;
const hasSymbol = /(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?])/;
const ErrCheck = msg.object({
loginid : msg.string().label('ログインID')
.required()
.max(10),
passwd : msg.string().label('パスワード')
.min(8)
.required()
.matches(hasMixedCase, 'パスワードは英大文字と英小文字を含めてください。')
.matches(hasNumber, 'パスワードは数字を含めてください。')
.matches(hasSymbol, 'パスワードは記号を含めてください。'),
firstnm : msg.string().label('姓')
.required(),
lastnm : msg.string().label('名')
.required(),
mailad : msg.string().label('メールアドレス')
.required()
.email(),
});
export default ErrCheck;
msg.jp.js
import * as yup from 'yup';
const jpLocale = {
mixed: {
required: param => `${param.label}は必須です。`,
},
string: {
min: param => `${param.label}は${param.min}文字以上でなければなりません。`,
max: param => `${param.label}は${param.max}文字以下でなければなりません。`,
matches: param => `${param.label}は「${param.regex}」形式に一致していなければなりません。`,
email: param => `${param.label}はメールアドレス形式でなければなりません。`,
},
};
yup.setLocale(jpLocale);
export default yup;
入力エラーの場合
赤文字+赤枠になり、下段にエラーメッセージが表示されます。
ちなみに、RedmineのAPIにも、エラーチェックが実装されています。
1)同じ「ログインID」は登録できない
2)同じ「メールアドレス」は登録できない
エラーの場合は、以下のポップアップ画面が表示されるはずです。
正常に登録されると、以下のポップアップ画面が表示されるはずです。
登録したユーザで、RedmineにログインできればOKです。
お疲れ様でしたぁ~。