Skip to main content

จัดการ user

เพิ่ม Add user เข้า collection user ผ่าน onAuthStagedChange

  • ถ้าไม่มี user = สร้างใหม่
// ทำการ import firestore เพิ่มเข้ามา
import { doc, getDoc, setDoc } from 'firebase/firestore'

// ทำการเพิ่ม db สำหรับเขียนข้อมูลเข้ามา
import { db, auth } from '@/firebase'


export const useAccountStore = defineStore('user-account', {
state: () => ({
isLoggedIn: false,
isAdmin: false,
user: {},
profile: {} // สร้างตัวแปรนี้ขึ้นมาสำหรับเก็บ role
}),
actions: {
async checkAuthState () {
return new Promise((resolve) => {
onAuthStateChanged(auth, async (user) => {
try {
if (user) {
this.user = user
this.isLoggedIn = true
// เพิ่มการอ้างอิงถึง collection users, document id
const docRef = doc(db, 'users', user.uid)
const docSnap = await getDoc(docRef)

// ถ้าข้อมูลไม่มีอยู่ = เขียนข้อมูลเข้าไปใหม่
if (!docSnap.exists()) {
const userData = {
name: user.displayName,
role: 'member',
status: 'active',
updatedAt: new Date()
}
await setDoc(docRef, userData)
this.profile = userData
} else {
this.profile = docSnap.data()
}
if (this.profile.role !== 'member') {
this.isAdmin = true
}
resolve(true)
} else {
resolve(false)
}
} catch (error) {
console.log('error', error)
resolve(false)
}
})
},
/* code ส่วนที่เหลือเหมือนเดิม */
}
})

เพิ่ม edit user ฝั่ง admin

  • ให้แก้ไข role, active ได้

แก้ที่ store/admin/user.js

import { defineStore } from 'pinia'

import {
collection,
getDocs,
doc,
getDoc,
setDoc
} from 'firebase/firestore'

import { db } from '@/firebase'

export const useUserStore = defineStore('user', {
state: () => ({
loaded: false,
list: []
}),
actions: {
async loadUser () {
const usersCol = collection(db, 'users')
const userSnapshot = await getDocs(usersCol)
const userList = userSnapshot.docs.map(doc => {
let convertedData = doc.data()
convertedData.updatedAt = convertedData.updatedAt.toDate()
convertedData.uid = doc.id
return convertedData
})
if (userList && userList.length > 0) {
this.list = userList
}
this.loaded = true
},
async getUser (userUid) {
try {
const docRef = doc(db, 'users', userUid)
const docSnap = await getDoc(docRef)
return docSnap.data()
} catch (error) {
console.log('error', error)
}
},
async updateUser (userUid, userData) {
try {
let updatedUser = {
name: userData.name,
status: userData.status,
role: userData.role,
updatedAt: new Date()
}
const docRef = doc(db, 'users', userUid)
await setDoc(docRef, updatedUser)
} catch (error) {
console.log('error', error)
}
},
removeUser (index) {
this.list.splice(index, 1)
}
}
})

ที่ admin/user/Listview.vue

<script setup>
import { onMounted } from 'vue'

// เพิ่มจังหวะ load user ครั้งแรกออกมา
onMounted(async () => {
await userStore.loadUser()
})

const toggleStatus = (index) => {
try {
const updateUser = userStore.list[index]
updateUser.status = updateUser.status === 'inactive' ? 'active' : 'inactive'
// เปลี่ยนเป็น uid แทน index
userStore.updateUser(updateUser.uid, updateUser)
eventStore.popupMessage('success', 'Update Status successful!')
} catch (error) {
console.log('error', error)
}
}
</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>
<!-- เปลี่ยนเป็น uid แทนที่จะเป็น index -->
<RouterLink :to="{ name: 'admin-user-update', params: { id: user.uid } }">
<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>

ที่ admin/user/Updateview.vue

<script setup>
import { onMounted, ref } from 'vue'

const userId = ref(-1)
// เปลี่ยนเป็น ref แทนเพื่อให้แทนค่าทั้งหมดได้
let userData = ref({})

onMounted(async () => {
if (route.params.id) {
userId.value = route.params.id
// เปลี่ยนมาเรียกใช้ผ่าน value แทน
userData.value = await userStore.getUser(userId.value)
}
})

const updateUser = () => {
// เปลี่ยนมาเรียกใช้ผ่าน value แทน
userStore.updateUser(userId.value, userData.value)
eventStore.popupMessage('success', 'Update User successful!')
}

</script>

<template>
<!-- code ส่วนนี้เหมือนเดิม ไม่ต้องแก้ไขอะไร -->
</template>

กั้นให้ moderator จัดการ user ไม่ได้

  • มีแค่ admin ที่เห็นหน้านี้ได้

ที่ AdminLayout.vue

<script setup>

import { useAccountStore } from '@/stores/account'

const accountStore = useAccountStore()

// เพิ่ม role ตรง pageData มาเพื่อบอกว่าอนุญาตใครหน้าไหนบ้าง
const pageData = [
{
name: 'Dashboard',
route: '/admin/dashboard',
roles: ['admin', 'moderator']
},
{
name: 'Product',
route: '/admin/products',
roles: ['admin', 'moderator']
},
{
name: 'Order',
route: '/admin/orders',
roles: ['admin', 'moderator']
},
{
name: 'User',
route: '/admin/users',
roles: ['admin']
}
]
</script>

<template>
<div class="drawer drawer-open">
<input id="my-drawer-2" type="checkbox" class="drawer-toggle" />
<div class="drawer-content p-4">
<slot></slot>
</div>
<div class="drawer-side">
<label for="my-drawer-2" class="drawer-overlay"></label>
<ul class="menu p-4 w-60 h-full bg-base-200 text-base-content">
<!-- Sidebar content here -->
<li class="mb-2 font-semibold text-2xl">
<div>Admin {{ pageName }}</div>
</li>
<li v-for="page in pageData">
<!-- เพ่ิมการ check role เข้ามา -->
<RouterLink
v-if="page.roles.includes(accountStore.profile.role)"
:to="page.route"
:class="currentPath === page.route ? 'active' : ''">
{{ page.name }}
</RouterLink>
</li>
<li>
<a @click="logout()">Logout</a>
</li>
</ul>
</div>
</div>
</template>