keyboard_tabSkip to content
listVue Firebase Masterclass

ทำหน้า 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
javascript
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

javascript
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"
html
<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 ข้อมูลกลับไปได้
html
<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