Skip to main content

ทำหน้า User Management

ทำ stores/admin/user.js สำหรับลองส่งข้อมูลระหว่างหน้า

เราจะสร้าง store สำหรับจัดการ user ออกมาก่อนโดยการสร้างไฟล์ stores/admin/user.js

สิ่งที่เราจะทำ

  • เพิ่ม state list สำหรับเก็บ list user เอาไว้ (แต่เราจะไม่ใช้ localstorage เนื่องจากไม่ได้มีโจทย์ใช้งานต่อเนื่องในตอนนี้)
  • เพิ่ม action
    • getUser (index) ดึงข้อมูล user ตาม index
    • updateUser (index, userData) แก้ไขข้อมูล user ตาม index โดยส่ง userData ไป update
    • removeUser (index) ลบข้อมูล user ตาม index
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
state: () => ({
list: [
{
name: 'Mike',
role: 'admin',
status: 'active',
updatedAt: '9/15/2023, 11:50:24 PM',
},
{
name: 'Test',
role: 'moderator',
status: 'inactive',
updatedAt: '9/15/2023, 11:50:24 PM',
},
{
name: 'TP',
role: 'member',
status: 'active',
updatedAt: '9/15/2023, 11:50:24 PM',
}
]
}),
actions: {
getUser (index) {
return this.list[index]
},
updateUser (index, userData) {
this.list[index].name = userData.name
this.list[index].status = userData.status
this.list[index].role = userData.role
this.list[index].updatedAt = (new Date()).toLocaleString()
},
removeUser (index) {
this.list.splice(index, 1)
}
}
})

เพิ่ม router user

เพิ่ม path สำหรับ file user ListView, UpdateView

import AdminUserList from '@/views/admin/user/ListView.vue'
import AdminUserUpdate from '@/views/admin/user/UpdateView.vue'

const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/admin/users',
name: 'admin-users',
component: AdminUserList
},
{
path: '/admin/users/:id',
name: 'admin-user-update',
component: AdminUserUpdate
}
]
})

ทำ user/ListView.vue

เพิ่มหน้าแสดง user ทั้งหมดออกมาโดย

  • แต่ง UI ตารางสำหรับใส่ข้อมูล user name, role, status, updated at
  • โดยในหน้านี้จะมีปุ่ม 2 ปุ่มคือ
    • ปุ่ม "Edit" = สำหรับไปยังหน้าแก้ไขข้อมูล user
    • ปุ่ม "Enable / Disable" = สำหรับปรับ status ระหว่าง active, inactive ไปมา
  • เพิ่ม function toggleStatus สำหรับปรับ status ปุ่ม "Enable / Disable"
<script setup>
import { useUserStore } from '@/stores/admin/user'
import { RouterLink } from 'vue-router'

import AdminLayout from '@/layouts/AdminLayout.vue'

const userStore = useUserStore()

const toggleStatus = (index) => {
const updateUser = userStore.list[index]
updateUser.status = updateUser.status === 'inactive' ? 'active' : 'inactive'
userStore.updateUser(index, updateUser)
}
</script>

<template>
<AdminLayout>
<div class="flex-1 pt-8 px-6 bg-base-100">
<div class="card w-full p-6 mt-2">
<div class="text-xl font-semibold inline-block">
User
</div>
<div class="divider mt-2"></div>
<div class="h-full w-full pb-6 bg-base-100">
<div class="overflow-x-auto w-full">
<table class="table w-full">
<thead>
<tr>
<th>Name</th>
<th>Role</th>
<th>Status</th>
<th>Updated At</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="(user, index) in userStore.list" :key="index">
<td>
<div class="font-bold">{{ user.name }}</div>
</td>
<td>{{ user.role }}</td>
<td>
<div class="badge" :class="user.status === 'active' ? 'badge-success' : 'badge-ghost'">
{{ user.status }}
</div>
</td>
<td>{{ user.updatedAt }}</td>
<td>
<RouterLink :to="{ name: 'admin-user-update', params: { id: index } }">
<button class="btn">
Edit
</button>
</RouterLink>
<button @click="toggleStatus(index)" class="btn mx-2">
{{ user.status === 'active' ? 'Enable' : 'Disable' }}
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</AdminLayout>
</template>

ผลลัพธ์

user-01

เมื่อลองกด "Enable/Disable"

user-03

ทำ user/UpdateView.vue

ทำหน้าสำหรับแก้ไข user

สิ่งที่จะทำ

  • สร้าง UI Form + style ที่มี field name, role, status
  • ตัว Form สามารถ
    • แก้ไข name ได้
    • แก้ไข role ได้ผ่าน select โดยเลือกได้แค่ Admin, Moderator, User
    • แก้ไข status ได้ผ่าน select โดยเลือกได้แค่ active, inactive
  • เพิ่มปุ่ม "Update" และสามารถ update ข้อมูลกลับไปได้
<script setup>
import { onMounted, ref, reactive } from 'vue'
import { useRoute } from 'vue-router'
import { useUserStore } from '@/stores/admin/user'
import { useEventStore } from '@/stores/event'
import AdminLayout from '@/layouts/AdminLayout.vue'

const userStore = useUserStore()
const eventStore = useEventStore()

const route = useRoute()

const userId = ref(-1)
let userData = reactive({})

onMounted(() => {
if (route.params.id) {
userId.value = route.params.id
userData = userStore.getUser(userId.value)
console.log('userData', userData)
}
})

const updateUser = () => {
userStore.updateUser(userId.value, userData)
eventStore.popupMessage('success', 'Update Product successful!')
}

</script>

<template>
<AdminLayout>
<div class="flex pt-8 px-6">
<div class="card w-full p-6 bg-base-100 shadow-xl mt-2">
<div class="text-xl font-semibold">Update user id: {{ userId }}</div>
<div class="divider"></div>

<div class="form-control w-full">
<label class="label">
<span class="label-text text-base-content">Name</span>
</label>
<input
type="text"
placeholder=""
class="input input-bordered w-full"
v-model="userData.name"
/>
</div>

<div class="form-control w-full">
<label class="label">
<span class="label-text text-base-content">Role</span>
</label>
<select class="select select-bordered w-full" v-model="userData.role">
<option disabled selected>Select Role</option>
<option value="admin">Admin</option>
<option value="moderator">Moderator</option>
<option value="member">Member</option>
</select>
</div>

<div class="form-control w-full">
<label class="label">
<span class="label-text text-base-content">Status</span>
</label>
<select class="select select-bordered w-full" v-model="userData.status">
<option disabled selected>Status</option>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</div>

<div class="mt-4 flex justify-end">
<RouterLink to="/admin/users" class="btn btn-ghost">
Back
</RouterLink>
<button @click="updateUser()" class="btn btn-primary ml-4">
Update
</button>
</div>
</div>
</div>
</AdminLayout>
</template>

ผลลัพธ์

user-02