Webアプリケーションで効率的な運用を支えるためには、管理機能の強化が欠かせません。今回、メールアカウント申請システムに「ユーザー管理」のCRUD機能(Create, Read, Update, Delete)を追加しました。この機能により、管理者はユーザー情報の作成・閲覧・編集・削除が可能になり、運用がスムーズになりました。
実装した機能の概要
以下の操作がユーザー管理画面で可能になりました:
- ユーザーの新規追加
新しいユーザーを登録できます。名前やメールアドレス、権限を指定するシンプルなUIを提供します。 - ユーザー情報の閲覧
ユーザー一覧を確認する「Read」機能で、登録済みのユーザーを一目で把握できます。 - ユーザー情報の編集
名前やメールアドレスの変更だけでなく、権限の更新も可能です。 - ユーザーの削除
必要に応じて登録済みのユーザーを削除する機能を提供します。
フロントエンドの実装
ユーザー管理画面は、Vue.jsを使用して構築しました。以下に主なコードを示します。
ユーザー管理画面のUI構築
管理者がユーザーを操作するためのインターフェースを用意しました。CRUD操作をモーダルウィンドウで行えるように設計し、直感的な操作が可能です。
メインのユーザー管理画面
export default {
template: `
<div class="max-w-4xl mx-auto bg-white shadow-lg rounded-lg p-6 mt-10">
<h2 class="text-2xl font-bold mb-4 text-gray-800">ユーザー管理</h2>
<button @click="openCreateModal" class="bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600 mb-4">
新規ユーザー追加
</button>
<div v-if="loading" class="text-center">読み込み中...</div>
<div v-else>
<table class="table-auto w-full border-collapse border border-gray-300">
<thead>
<tr class="bg-gray-100">
<th class="border border-gray-300 px-4 py-2">ユーザーID</th>
<th class="border border-gray-300 px-4 py-2">名前</th>
<th class="border border-gray-300 px-4 py-2">メールアドレス</th>
<th class="border border-gray-300 px-4 py-2">権限</th>
<th class="border border-gray-300 px-4 py-2">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="user in users" :key="user.id">
<td class="border border-gray-300 px-4 py-2">{{ user.id }}</td>
<td class="border border-gray-300 px-4 py-2">{{ user.name }}</td>
<td class="border border-gray-300 px-4 py-2">{{ user.email }}</td>
<td class="border border-gray-300 px-4 py-2">{{ translateRole(user.role) }}</td>
<td class="border border-gray-300 px-4 py-2">
<button @click="openEditModal(user)" class="bg-yellow-500 text-white px-2 py-1 rounded-lg hover:bg-yellow-600">編集</button>
<button @click="deleteUser(user.id)" class="bg-red-500 text-white px-2 py-1 rounded-lg hover:bg-red-600 ml-2">削除</button>
</td>
</tr>
</tbody>
</table>
</div>
<create-edit-modal v-if="showModal" :user="selectedUser" @close="closeModal" @refresh="fetchUsers"></create-edit-modal>
</div>
`,
data() {
return {
users: [],
loading: true,
showModal: false,
selectedUser: null,
};
},
methods: {
translateRole(role) {
return role === 'admin' ? '管理者' : 'ユーザー';
},
async fetchUsers() {
try {
const response = await fetch('/api/admin/users');
const data = await response.json();
if (data.success) {
this.users = data.users;
} else {
alert('ユーザー一覧の取得に失敗しました: ' + data.message);
}
} catch (error) {
console.error('エラー:', error);
} finally {
this.loading = false;
}
},
openCreateModal() {
this.selectedUser = null;
this.showModal = true;
},
openEditModal(user) {
this.selectedUser = { ...user };
this.showModal = true;
},
closeModal() {
this.showModal = false;
},
async deleteUser(userId) {
if (!confirm('本当に削除しますか?')) return;
try {
const response = await fetch('/api/admin/users/delete', {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_id: userId }),
});
const data = await response.json();
if (data.success) {
alert('ユーザーを削除しました。');
this.fetchUsers();
} else {
alert('削除に失敗しました: ' + data.message);
}
} catch (error) {
console.error('削除エラー:', error);
}
},
},
async created() {
this.fetchUsers();
},
components: {
'create-edit-modal': {
template: `
<div class="fixed inset-0 bg-gray-800 bg-opacity-50 flex items-center justify-center">
<div class="bg-white p-6 rounded shadow-lg">
<h3 class="text-lg font-bold mb-4" v-if="user">ユーザー編集</h3>
<h3 class="text-lg font-bold mb-4" v-else>新規ユーザー追加</h3>
<form @submit.prevent="saveUser">
<div class="mb-4">
<label class="block text-gray-700 font-bold mb-2">名前</label>
<input type="text" v-model="form.name" required class="w-full px-3 py-2 border rounded-lg">
</div>
<div class="mb-4">
<label class="block text-gray-700 font-bold mb-2">メールアドレス</label>
<input type="email" v-model="form.email" required class="w-full px-3 py-2 border rounded-lg">
</div>
<div class="mb-4">
<label class="block text-gray-700 font-bold mb-2">パスワード</label>
<input type="password" v-model="form.password" placeholder="変更時のみ入力" class="w-full px-3 py-2 border rounded-lg">
</div>
<div class="mb-4">
<label class="block text-gray-700 font-bold mb-2">権限</label>
<select v-model="form.role" required class="w-full px-3 py-2 border rounded-lg">
<option value="user">ユーザー</option>
<option value="admin">管理者</option>
</select>
</div>
<div class="flex justify-end">
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600">
保存
</button>
<button @click="$emit('close')" class="bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 ml-2">
キャンセル
</button>
</div>
</form>
</div>
</div>
`,
props: ['user'],
data() {
return {
form: {
name: this.user ? this.user.name : '',
email: this.user ? this.user.email : '',
password: '',
role: this.user ? this.user.role : 'user',
},
};
},
methods: {
async saveUser() {
try {
const url = this.user ? '/api/admin/users/update' : '/api/admin/users/create';
const method = this.user ? 'PUT' : 'POST';
const response = await fetch(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(this.form),
});
const data = await response.json();
if (data.success) {
alert(this.user ? 'ユーザーを更新しました。' : 'ユーザーを追加しました。');
this.$emit('refresh');
this.$emit('close');
} else {
alert('保存に失敗しました: ' + data.message);
}
} catch (error) {
console.error('保存エラー:', error);
}
},
},
},
},
};
最後に
今回の実装で、ユーザー管理機能にCRUD操作を加え、管理者がより快適に業務を行える環境を構築しました。この取り組みを通じて、システムの使いやすさと運用性が大幅に向上したと感じています。
次のステップでは、権限管理の強化や操作ログの記録機能の追加を検討し、さらに高度な管理機能を提供できるよう努めていきます。この記事が、同様の課題に取り組む方々の参考になれば幸いです!
コメント