From f594a45e84ab80f6f06b533472e4cbc5e08b59c4 Mon Sep 17 00:00:00 2001 From: antv Date: Thu, 2 Jul 2026 17:02:02 +0700 Subject: [PATCH] m --- .../Controllers/Admin/AdminController.php | 12 ++- app/Http/Controllers/User/UserController.php | 5 +- app/Models/AddCard.php | 3 +- app/Models/User.php | 7 +- app/Services/Admin/AdminService.php | 6 +- app/Services/Auth/AuthService.php | 9 +- app/Services/User/UserService.php | 5 + .../0001_01_01_000000_create_users_table.php | 16 +-- ...26_06_27_132957_create_add_cards_table.php | 3 +- ...27_132957_create_administrations_table.php | 8 +- database/seeders/MockDataSeeder.php | 102 ++++++++++-------- docker/README.md | 29 +++-- docker/docker-compose.yml | 2 + lang/vi/messages.php | 1 + .../views/components/user-form.blade.php | 33 +++++- resources/views/user/dashboard.blade.php | 12 +-- tests/Feature/AdminUserListStatsTest.php | 69 ++++++------ 17 files changed, 200 insertions(+), 122 deletions(-) diff --git a/app/Http/Controllers/Admin/AdminController.php b/app/Http/Controllers/Admin/AdminController.php index d1fb405..3160185 100644 --- a/app/Http/Controllers/Admin/AdminController.php +++ b/app/Http/Controllers/Admin/AdminController.php @@ -42,13 +42,15 @@ class AdminController extends Controller public function store(Request $request) { $request->validate([ - 'msnv' => 'required|unique:user,msnv', - 'mail' => 'required|email|unique:user,mail', - 'password' => 'required|min:6', - 'role' => 'required|in:' . User::ROLE_MEMBER . ',' . User::ROLE_ADMIN, + 'msnv' => 'required|integer|unique:user,msnv', + 'name' => 'required|string|max:255', + 'mail' => 'required|email|unique:user,mail', + 'departments' => 'required|integer|min:1|max:5', + 'password' => 'required|string', + 'role' => 'required|in:' . User::ROLE_MEMBER . ',' . User::ROLE_ADMIN, ]); - $this->adminService->createUser($request->only('msnv', 'mail', 'password', 'role')); + $this->adminService->createUser($request->only('msnv', 'name', 'mail', 'departments', 'password', 'role')); return redirect()->route('admin.users.index')->with('success', __('messages.user_create_success')); } diff --git a/app/Http/Controllers/User/UserController.php b/app/Http/Controllers/User/UserController.php index 5794a72..ba8909c 100644 --- a/app/Http/Controllers/User/UserController.php +++ b/app/Http/Controllers/User/UserController.php @@ -34,7 +34,10 @@ class UserController extends Controller public function storeThankcards(Request $request) { $request->validate([ - 'receiver' => 'required|exists:user,msnv', + 'receiver' => [ + 'required', + \Illuminate\Validation\Rule::exists('user', 'msnv')->where('status', \App\Models\User::STATUS_ACTIVE) + ], 'amount' => 'required|integer|min:1|max:' . Administration::MAX_SEND_CARD_PER_MONTH, ]); diff --git a/app/Models/AddCard.php b/app/Models/AddCard.php index de3931f..0706ebe 100644 --- a/app/Models/AddCard.php +++ b/app/Models/AddCard.php @@ -11,8 +11,7 @@ class AddCard extends Model protected $table = 'add_card'; public $timestamps = false; - protected $primaryKey = null; - public $incrementing = false; + protected $primaryKey = 'id'; protected $fillable = [ 'buyer', diff --git a/app/Models/User.php b/app/Models/User.php index 52b40d5..e2259ad 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -25,14 +25,15 @@ class User extends Authenticatable protected $table = 'user'; public $timestamps = false; - protected $primaryKey = 'msnv'; - public $incrementing = false; - protected $keyType = 'string'; + protected $primaryKey = 'id'; protected $fillable = [ 'msnv', + 'name', 'mail', 'pass', + 'departments', + 'avatar', 'role', 'status', 'card', diff --git a/app/Services/Admin/AdminService.php b/app/Services/Admin/AdminService.php index 433fad2..7a74993 100644 --- a/app/Services/Admin/AdminService.php +++ b/app/Services/Admin/AdminService.php @@ -66,8 +66,10 @@ class AdminService implements AdminServiceInterface { User::create([ 'msnv' => $data['msnv'], + 'name' => $data['name'], 'mail' => $data['mail'], 'pass' => Hash::make($data['password']), + 'departments' => $data['departments'], 'role' => $data['role'], 'status' => User::STATUS_ACTIVE, 'card' => 0, @@ -83,9 +85,9 @@ class AdminService implements AdminServiceInterface DB::transaction(function () use ($data, $user) { if (!empty($data['num_card'])) { AddCard::create([ - 'buyer' => abs(crc32($user->msnv)) % 1000000, + 'buyer' => $user->msnv, 'num_card' => $data['num_card'], - 'seller' => abs(crc32(Auth::user()->msnv)) % 1000000, + 'seller' => Auth::user()->msnv, 'date' => Carbon::today(), ]); $user->card += $data['num_card']; diff --git a/app/Services/Auth/AuthService.php b/app/Services/Auth/AuthService.php index 83a331a..c5b40de 100644 --- a/app/Services/Auth/AuthService.php +++ b/app/Services/Auth/AuthService.php @@ -11,14 +11,15 @@ class AuthService implements AuthServiceInterface { public function attemptLogin(array $credentials, Request $request): array { - if (!Auth::attempt(['mail' => $credentials['mail'], 'password' => $credentials['password']])) { + // Manual MD5 password check + $user = User::where('mail', $credentials['mail'])->first(); + if (!$user || $user->pass !== md5($credentials['password'])) { return ['success' => false, 'error_key' => 'mail', 'error_msg' => __('auth.failed')]; } + // Log the user in manually + Auth::login($user); $request->session()->regenerate(); - - $user = Auth::user(); - if ($user->status != User::STATUS_ACTIVE) { Auth::logout(); return ['success' => false, 'error_key' => 'mail', 'error_msg' => __('auth.inactive')]; diff --git a/app/Services/User/UserService.php b/app/Services/User/UserService.php index 3637651..63284aa 100644 --- a/app/Services/User/UserService.php +++ b/app/Services/User/UserService.php @@ -38,6 +38,11 @@ class UserService implements UserServiceInterface throw new \RuntimeException(__('messages.error.no_send_permission')); } + $receiver = User::where('msnv', $receiverMsnv)->first(); + if (!$receiver || $receiver->status != User::STATUS_ACTIVE) { + throw new \RuntimeException(__('messages.error.receiver_invalid')); + } + $startOfMonth = Carbon::now()->startOfMonth(); $endOfMonth = Carbon::now()->endOfMonth(); diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 41867cc..cf0ca65 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -12,14 +12,18 @@ return new class extends Migration public function up(): void { Schema::create('user', function (Blueprint $table) { - $table->string('msnv')->primary(); + $table->increments('id'); + $table->integer('msnv')->unique(); + $table->string('name'); $table->string('mail'); $table->string('pass'); - $table->tinyInteger('role')->default(0)->comment('0: member / 1: admin'); - $table->tinyInteger('status')->default(1)->comment('0: đã nghỉ / 1: đang làm'); - $table->integer('card')->nullable(); - $table->tinyInteger('flag_send')->default(0)->comment('0: không được gửi / 1: được gửi'); - $table->tinyInteger('first_login')->default(1)->comment('0: không là lần đầu / 1: lần đầu'); + $table->integer('departments')->default(1); + $table->string('avatar')->nullable(); + $table->tinyInteger('role')->default(0)->comment('0: member, default / 1: admin'); + $table->tinyInteger('status')->default(1)->comment('0: đã nghỉ / 1: đang làm, default'); + $table->integer('card')->default(0); + $table->tinyInteger('flag_send')->default(0)->comment('0: không được gửi card / 1: được gửi card'); + $table->tinyInteger('first_login')->default(1)->comment('0: không là lần đầu / 1: lần đầu, default'); }); // Only user table remains diff --git a/database/migrations/2026_06_27_132957_create_add_cards_table.php b/database/migrations/2026_06_27_132957_create_add_cards_table.php index 1ab3bc8..791ac86 100644 --- a/database/migrations/2026_06_27_132957_create_add_cards_table.php +++ b/database/migrations/2026_06_27_132957_create_add_cards_table.php @@ -12,10 +12,11 @@ return new class extends Migration public function up(): void { Schema::create('add_card', function (Blueprint $table) { + $table->increments('id'); $table->integer('buyer'); $table->integer('num_card'); $table->integer('seller'); - $table->date('date')->nullable(); + $table->date('date'); }); } diff --git a/database/migrations/2026_06_27_132957_create_administrations_table.php b/database/migrations/2026_06_27_132957_create_administrations_table.php index 22b2720..2060a14 100644 --- a/database/migrations/2026_06_27_132957_create_administrations_table.php +++ b/database/migrations/2026_06_27_132957_create_administrations_table.php @@ -12,12 +12,12 @@ return new class extends Migration public function up(): void { Schema::create('administration', function (Blueprint $table) { - $table->id(); - $table->string('msnv'); + $table->increments('id'); + $table->integer('msnv'); $table->integer('received')->nullable(); - $table->string('sender')->nullable(); + $table->integer('sender')->nullable(); $table->integer('sent')->nullable(); - $table->string('receiver')->nullable(); + $table->integer('receiver')->nullable(); $table->date('date')->nullable(); }); } diff --git a/database/seeders/MockDataSeeder.php b/database/seeders/MockDataSeeder.php index b2bb92c..f4b21b5 100644 --- a/database/seeders/MockDataSeeder.php +++ b/database/seeders/MockDataSeeder.php @@ -24,14 +24,17 @@ class MockDataSeeder extends Seeder AddCard::truncate(); DB::statement('SET FOREIGN_KEY_CHECKS=1;'); - $password = Hash::make('123456'); + // The default password is now set to 1234@Dcba according to the design requirements + $password = md5('1234@Dcba'); // 1. CREATE USERS // Admins User::create([ - 'msnv' => 'ADMIN', + 'msnv' => 9999, + 'name' => 'System Admin', 'mail' => 'admin@runsystem.net', 'pass' => $password, + 'departments' => 1, 'role' => User::ROLE_ADMIN, 'status' => User::STATUS_ACTIVE, 'card' => 0, @@ -40,9 +43,11 @@ class MockDataSeeder extends Seeder ]); User::create([ - 'msnv' => 'ADMIN2', + 'msnv' => 9998, + 'name' => 'Second Admin', 'mail' => 'admin2@runsystem.net', 'pass' => $password, + 'departments' => 1, 'role' => User::ROLE_ADMIN, 'status' => User::STATUS_ACTIVE, 'card' => 0, @@ -52,19 +57,24 @@ class MockDataSeeder extends Seeder // Active Users (Initialize with specific users needed for logs/transactions) $users = [ - ['msnv' => 'DEV001', 'mail' => 'nguyenvana@runsystem.net', 'card' => 10, 'flag' => User::FLAG_SEND_ENABLED, 'first_login' => User::FIRST_LOGIN_FALSE], - ['msnv' => 'DEV002', 'mail' => 'tranthingoc@runsystem.net', 'card' => 3, 'flag' => User::FLAG_SEND_ENABLED, 'first_login' => User::FIRST_LOGIN_FALSE], - ['msnv' => 'TEST01', 'mail' => 'lekiemthu@runsystem.net', 'card' => 6, 'flag' => User::FLAG_SEND_ENABLED, 'first_login' => User::FIRST_LOGIN_TRUE], // First-time login - ['msnv' => 'HR001', 'mail' => 'phongnhansu@runsystem.net', 'card' => 0, 'flag' => User::FLAG_SEND_DISABLED, 'first_login' => User::FIRST_LOGIN_FALSE], // Disabled sending permission - ['msnv' => 'SALE01', 'mail' => 'bangiang@runsystem.net', 'card' => 36, 'flag' => User::FLAG_SEND_ENABLED, 'first_login' => User::FIRST_LOGIN_FALSE], + ['msnv' => 1001, 'name' => 'Nguyễn Văn A', 'mail' => 'nguyenvana@runsystem.net', 'card' => 10, 'flag' => User::FLAG_SEND_ENABLED, 'first_login' => User::FIRST_LOGIN_FALSE], + ['msnv' => 1002, 'name' => 'Trần Thị Ngọc', 'mail' => 'tranthingoc@runsystem.net', 'card' => 3, 'flag' => User::FLAG_SEND_ENABLED, 'first_login' => User::FIRST_LOGIN_FALSE], + ['msnv' => 1003, 'name' => 'Lê Kim Thư', 'mail' => 'lekiemthu@runsystem.net', 'card' => 6, 'flag' => User::FLAG_SEND_ENABLED, 'first_login' => User::FIRST_LOGIN_TRUE], // First-time login + ['msnv' => 1004, 'name' => 'Phòng Nhân Sự', 'mail' => 'phongnhansu@runsystem.net', 'card' => 0, 'flag' => User::FLAG_SEND_DISABLED, 'first_login' => User::FIRST_LOGIN_FALSE], // Disabled sending permission + ['msnv' => 1005, 'name' => 'Bản Giang', 'mail' => 'bangiang@runsystem.net', 'card' => 36, 'flag' => User::FLAG_SEND_ENABLED, 'first_login' => User::FIRST_LOGIN_FALSE], ]; // Generate additional users to reach exactly 100 member users - for ($i = 3; $i <= 97; $i++) { - $numStr = str_pad($i, 3, '0', STR_PAD_LEFT); + $firstNames = ['Nguyễn', 'Trần', 'Lê', 'Phạm', 'Hoàng', 'Huỳnh', 'Phan', 'Vũ', 'Võ', 'Đặng']; + $middleNames = ['Văn', 'Thị', 'Minh', 'Đức', 'Quốc', 'Thanh', 'Hữu', 'Ngọc', 'Quỳnh', 'Thu']; + $lastNames = ['Anh', 'Bình', 'Chi', 'Dương', 'Em', 'Giang', 'Huy', 'Khánh', 'Lâm', 'Nam', 'Oanh', 'Phúc', 'Quang', 'Sơn', 'Trang', 'Vy']; + + for ($i = 6; $i <= 100; $i++) { + $randomName = $firstNames[array_rand($firstNames)] . ' ' . $middleNames[array_rand($middleNames)] . ' ' . $lastNames[array_rand($lastNames)]; $users[] = [ - 'msnv' => 'DEV' . $numStr, - 'mail' => 'dev' . $numStr . '@runsystem.net', + 'msnv' => 1000 + $i, + 'name' => $randomName, + 'mail' => 'dev' . str_pad($i, 3, '0', STR_PAD_LEFT) . '@runsystem.net', 'card' => rand(0, 30), 'flag' => rand(0, 5) > 0 ? User::FLAG_SEND_ENABLED : User::FLAG_SEND_DISABLED, 'first_login' => rand(0, 4) == 0 ? User::FIRST_LOGIN_TRUE : User::FIRST_LOGIN_FALSE @@ -74,8 +84,10 @@ class MockDataSeeder extends Seeder foreach ($users as $u) { User::create([ 'msnv' => $u['msnv'], + 'name' => $u['name'], 'mail' => $u['mail'], 'pass' => $password, + 'departments' => rand(1, 5), 'role' => User::ROLE_MEMBER, 'status' => User::STATUS_ACTIVE, 'card' => $u['card'], @@ -84,12 +96,12 @@ class MockDataSeeder extends Seeder ]); // For other users, if they have cards, create a matching purchase log in June 2026 - if (!in_array($u['msnv'], ['DEV001', 'DEV002', 'TEST01', 'SALE01'])) { + if (!in_array($u['msnv'], [1001, 1002, 1003, 1005])) { if ($u['card'] > 0) { AddCard::create([ - 'buyer' => abs(crc32($u['msnv'])) % 1000000, + 'buyer' => $u['msnv'], 'num_card' => $u['card'], - 'seller' => abs(crc32('ADMIN')) % 1000000, + 'seller' => 9999, 'date' => '2026-06-01' ]); } @@ -98,9 +110,11 @@ class MockDataSeeder extends Seeder // Inactive User User::create([ - 'msnv' => 'OLD001', + 'msnv' => 9997, + 'name' => 'Nghi Duy', 'mail' => 'nghiduy@runsystem.net', 'pass' => $password, + 'departments' => 2, 'role' => User::ROLE_MEMBER, 'status' => User::STATUS_INACTIVE, 'card' => 0, @@ -111,28 +125,28 @@ class MockDataSeeder extends Seeder // 2. CREATE CARD ADDITION LOGS (add_card table) // Manual purchase history for specific users: $addCardLogs = [ - // DEV001: total 30 cards bought - ['buyer' => 'DEV001', 'num_card' => 15, 'date' => '2026-06-01'], - ['buyer' => 'DEV001', 'num_card' => 10, 'date' => '2026-07-01'], - ['buyer' => 'DEV001', 'num_card' => 5, 'date' => '2026-08-01'], + // 1001: total 30 cards bought + ['buyer' => 1001, 'num_card' => 15, 'date' => '2026-06-01'], + ['buyer' => 1001, 'num_card' => 10, 'date' => '2026-07-01'], + ['buyer' => 1001, 'num_card' => 5, 'date' => '2026-08-01'], - // DEV002: total 15 cards bought - ['buyer' => 'DEV002', 'num_card' => 10, 'date' => '2026-06-02'], - ['buyer' => 'DEV002', 'num_card' => 5, 'date' => '2026-07-01'], + // 1002: total 15 cards bought + ['buyer' => 1002, 'num_card' => 10, 'date' => '2026-06-02'], + ['buyer' => 1002, 'num_card' => 5, 'date' => '2026-07-01'], - // TEST01: total 15 cards bought - ['buyer' => 'TEST01', 'num_card' => 10, 'date' => '2026-06-03'], - ['buyer' => 'TEST01', 'num_card' => 5, 'date' => '2026-08-02'], + // 1003: total 15 cards bought + ['buyer' => 1003, 'num_card' => 10, 'date' => '2026-06-03'], + ['buyer' => 1003, 'num_card' => 5, 'date' => '2026-08-02'], - // SALE01: total 50 cards bought - ['buyer' => 'SALE01', 'num_card' => 50, 'date' => '2026-06-04'], + // 1005: total 50 cards bought + ['buyer' => 1005, 'num_card' => 50, 'date' => '2026-06-04'], ]; foreach ($addCardLogs as $log) { AddCard::create([ - 'buyer' => abs(crc32($log['buyer'])) % 1000000, + 'buyer' => $log['buyer'], 'num_card' => $log['num_card'], - 'seller' => abs(crc32('ADMIN')) % 1000000, + 'seller' => 9999, 'date' => $log['date'] ]); } @@ -140,24 +154,24 @@ class MockDataSeeder extends Seeder // 3. CREATE CARD SENDING HISTORY (administration table) $transactions = [ // June 2026 transactions - ['sender' => 'DEV001', 'receiver' => 'SALE01', 'amount' => 5, 'date' => '2026-06-05'], - ['sender' => 'DEV001', 'receiver' => 'DEV002', 'amount' => 3, 'date' => '2026-06-12'], - ['sender' => 'DEV002', 'receiver' => 'HR001', 'amount' => 4, 'date' => '2026-06-10'], - ['sender' => 'TEST01', 'receiver' => 'DEV001', 'amount' => 2, 'date' => '2026-06-15'], - ['sender' => 'SALE01', 'receiver' => 'DEV002', 'amount' => 5, 'date' => '2026-06-20'], + ['sender' => 1001, 'receiver' => 1005, 'amount' => 5, 'date' => '2026-06-05'], + ['sender' => 1001, 'receiver' => 1002, 'amount' => 3, 'date' => '2026-06-12'], + ['sender' => 1002, 'receiver' => 1004, 'amount' => 4, 'date' => '2026-06-10'], + ['sender' => 1003, 'receiver' => 1001, 'amount' => 2, 'date' => '2026-06-15'], + ['sender' => 1005, 'receiver' => 1002, 'amount' => 5, 'date' => '2026-06-20'], // July 2026 transactions - ['sender' => 'DEV001', 'receiver' => 'DEV002', 'amount' => 5, 'date' => '2026-07-02'], - ['sender' => 'DEV001', 'receiver' => 'TEST01', 'amount' => 3, 'date' => '2026-07-10'], - ['sender' => 'DEV002', 'receiver' => 'DEV001', 'amount' => 5, 'date' => '2026-07-15'], - ['sender' => 'TEST01', 'receiver' => 'HR001', 'amount' => 4, 'date' => '2026-07-08'], - ['sender' => 'SALE01', 'receiver' => 'DEV002', 'amount' => 4, 'date' => '2026-07-12'], + ['sender' => 1001, 'receiver' => 1002, 'amount' => 5, 'date' => '2026-07-02'], + ['sender' => 1001, 'receiver' => 1003, 'amount' => 3, 'date' => '2026-07-10'], + ['sender' => 1002, 'receiver' => 1001, 'amount' => 5, 'date' => '2026-07-15'], + ['sender' => 1003, 'receiver' => 1004, 'amount' => 4, 'date' => '2026-07-08'], + ['sender' => 1005, 'receiver' => 1002, 'amount' => 4, 'date' => '2026-07-12'], // August 2026 transactions - ['sender' => 'DEV001', 'receiver' => 'SALE01', 'amount' => 4, 'date' => '2026-08-05'], - ['sender' => 'DEV002', 'receiver' => 'TEST01', 'amount' => 3, 'date' => '2026-08-12'], - ['sender' => 'TEST01', 'receiver' => 'DEV001', 'amount' => 3, 'date' => '2026-08-10'], - ['sender' => 'SALE01', 'receiver' => 'HR001', 'amount' => 5, 'date' => '2026-08-15'], + ['sender' => 1001, 'receiver' => 1005, 'amount' => 4, 'date' => '2026-08-05'], + ['sender' => 1002, 'receiver' => 1003, 'amount' => 3, 'date' => '2026-08-12'], + ['sender' => 1003, 'receiver' => 1001, 'amount' => 3, 'date' => '2026-08-10'], + ['sender' => 1005, 'receiver' => 1004, 'amount' => 5, 'date' => '2026-08-15'], ]; foreach ($transactions as $t) { diff --git a/docker/README.md b/docker/README.md index 7d6c6ae..fac62f6 100644 --- a/docker/README.md +++ b/docker/README.md @@ -67,16 +67,27 @@ docker compose -f docker/docker-compose.yml exec app composer install ### 4.2. Khi cập nhật giao diện (CSS / JS / Tailwind classes mới) -Do Docker container không cài Node.js, bạn cần chạy các lệnh compile frontend trực tiếp **ở máy thật (host)**: +Cập nhật giao diện cần biên dịch lại tài nguyên frontend. Bạn có 2 cách: -- **Chạy chế độ phát triển (Hot Reload):** - ```bash - npm run dev - ``` -- **Build production tĩnh:** - ```bash - npm run build - ``` +**1️⃣ Chạy trên máy host (đề xuất)** +```bash +npm install # một lần, nếu chưa có các package +npm run dev # Vite dev server, hot‑reload +``` + +**2️⃣ Chạy trong Docker (sử dụng container `node`)** +```bash +# Cài đặt các package (chỉ chạy 1 lần) +docker compose -f docker/docker-compose.yml exec node npm install + +# Chế độ phát triển (hot‑reload) +docker compose -f docker/docker-compose.yml exec node npm run dev + +# Hoặc biên dịch bản production +docker compose -f docker/docker-compose.yml exec node npm run build +``` + +Container `node` đã expose port **5173**, cho phép truy cập Vite dev server tại `http://localhost:5173`. Khi `npm run dev` đang chạy, mọi thay đổi CSS/JS sẽ tự động cập nhật trong container `app` nhờ volume mount. ### 4.3. Khi cập nhật Database (Migrations) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 829b35d..da55f96 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -34,6 +34,8 @@ services: volumes: - ..:/var/www/html command: sh -c "npm install && npm run build" + ports: + - "5173:5173" networks: - thankcard-system-network diff --git a/lang/vi/messages.php b/lang/vi/messages.php index e20033e..a9928f3 100644 --- a/lang/vi/messages.php +++ b/lang/vi/messages.php @@ -12,5 +12,6 @@ return [ 'no_send_permission' => 'Bạn hiện không có quyền gửi Thank Card.', 'not_enough_cards' => 'Số lượng card của bạn không đủ. Vui lòng liên hệ Admin.', 'max_send_limit_template' => 'Một tháng bạn chỉ được gửi tối đa :max card cho một người. Bạn đã gửi :sent card cho nhân viên này.', + 'receiver_invalid' => 'Người nhận không tồn tại hoặc đã nghỉ việc.', ] ]; diff --git a/resources/views/components/user-form.blade.php b/resources/views/components/user-form.blade.php index e70ef4e..8a32119 100644 --- a/resources/views/components/user-form.blade.php +++ b/resources/views/components/user-form.blade.php @@ -69,11 +69,24 @@ - + @error('msnv'){{ $message }}@enderror +
+ +
+ + + + + + +
+ @error('name'){{ $message }}@enderror +
+
@@ -82,11 +95,23 @@ - +
@error('mail'){{ $message }}@enderror
+
+ + + @error('departments'){{ $message }}@enderror +
+
@@ -95,9 +120,9 @@ - +
- Lưu ý: User sẽ bị buộc phải đổi mật khẩu này ở lần đăng nhập đầu tiên. + Mật khẩu mặc định cho tất cả user mới tạo. @error('password'){{ $message }}@enderror
diff --git a/resources/views/user/dashboard.blade.php b/resources/views/user/dashboard.blade.php index b0e0d91..990829c 100644 --- a/resources/views/user/dashboard.blade.php +++ b/resources/views/user/dashboard.blade.php @@ -53,9 +53,9 @@ -
+
-
+

Thanks gần đây

Xem tất cả @@ -96,22 +96,22 @@
-
+

Bảng xếp hạng

Xem tất cả
-
- -