ux(ui): beginner-friendly guidance across trainee/admin flows + fix AdminUsers to username
- Chat: add 'How to practice' guide card; render revealed persona as readable label:value grid instead of JSON. - AdminUsers: switch create form to username (matches username login), add step guide, role explanation (user=ฝึก, admin=ดูแลระบบ). - Analytics (admin overview) + MyBoard (personal): add plain-Thai explainer subtitle. - Rebuild dist. Verified user create with username -> 201.
This commit is contained in:
@@ -1,23 +1,38 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>{{ i18n.t('users') }}</h2>
|
||||
<h2>👥 {{ i18n.t('users') }}</h2>
|
||||
|
||||
<div class="card guide">
|
||||
<strong>📋 วิธีเพิ่มผู้ใช้งาน</strong>
|
||||
<ol style="margin:8px 0 0;padding-left:20px;line-height:1.8">
|
||||
<li>กรอก <strong>ชื่อผู้ใช้ (สำหรับเข้าสู่ระบบ)</strong>, ชื่อ, และรหัสผ่านเริ่มต้น</li>
|
||||
<li>เลือกสิทธิ์: <strong>user</strong> = ผู้เข้าฝึกขาย, <strong>admin</strong> = จัดการระบบ</li>
|
||||
<li>กด <strong>สร้าง</strong> — นำชื่อผู้ใช้ + รหัสผ่านไปแจ้งให้ผู้ใช้นั้นเข้าสู่ระบบได้เลย</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="card" style="margin-bottom:16px">
|
||||
<h4>+ {{ i18n.t('create') }} user</h4>
|
||||
<h4 style="margin-top:0">+ {{ i18n.t('create') }} {{ i18n.t('users').toLowerCase() }}</h4>
|
||||
<div class="row">
|
||||
<input v-model="form.name" placeholder="Name" style="flex:1" />
|
||||
<input v-model="form.email" placeholder="Email" style="flex:1" />
|
||||
<input v-model="form.password" type="password" placeholder="Temp password" style="flex:1" />
|
||||
<input v-model="form.username" placeholder="ชื่อผู้ใช้ (เข้าสู่ระบบ)" style="flex:1" />
|
||||
<input v-model="form.name" placeholder="ชื่อจริง" style="flex:1" />
|
||||
<input v-model="form.password" type="password" placeholder="รหัสผ่านเริ่มต้น" style="flex:1" />
|
||||
</div>
|
||||
<div class="row" style="margin-top:10px">
|
||||
<select v-model="form.role" style="flex:1">
|
||||
<option value="user">user</option>
|
||||
<option value="admin">admin</option>
|
||||
<option value="user">🙂 user — ผู้เข้าฝึก</option>
|
||||
<option value="admin">🛠 admin — ผู้ดูแลระบบ</option>
|
||||
</select>
|
||||
<button class="primary" @click="create">{{ i18n.t('create') }}</button>
|
||||
<button class="primary" @click="create" :disabled="!form.username || !form.password">+ {{ i18n.t('create') }}</button>
|
||||
</div>
|
||||
<div class="error" v-if="error">{{ error }}</div>
|
||||
</div>
|
||||
|
||||
<div v-if="users.length === 0" class="card empty-state">
|
||||
<strong>ยังไม่มีผู้ใช้งาน</strong><span>สร้างผู้ใช้งานคนแรกด้วยฟอร์มด้านบน</span>
|
||||
</div>
|
||||
<div class="card" v-for="u in users" :key="u.id" style="margin-bottom:8px;display:flex;align-items:center;gap:12px">
|
||||
<strong style="flex:1">{{ u.name }} ({{ u.email }})</strong>
|
||||
<strong style="flex:1">{{ u.name }} ({{ u.username }})</strong>
|
||||
<span class="badge">{{ u.role }}</span>
|
||||
<span class="badge" :class="u.active ? 'won' : 'lost'">{{ u.active ? 'active' : 'inactive' }}</span>
|
||||
</div>
|
||||
@@ -31,16 +46,20 @@ import { i18n } from '../i18n'
|
||||
|
||||
const users = ref([])
|
||||
const error = ref('')
|
||||
const form = ref({ name: '', email: '', password: '', role: 'user' })
|
||||
const form = ref({ username: '', name: '', password: '', role: 'user' })
|
||||
|
||||
async function load() { users.value = (await api.adminListUsers()).users }
|
||||
async function create() {
|
||||
error.value = ''
|
||||
try {
|
||||
await api.adminCreateUser({ ...form.value })
|
||||
form.value = { name: '', email: '', password: '', role: 'user' }
|
||||
form.value = { username: '', name: '', password: '', role: 'user' }
|
||||
await load()
|
||||
} catch (e) { error.value = e.message }
|
||||
}
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.guide { background: #eef2ff; border-color: #c7d2fe; margin-bottom: 16px; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user