From f0dbea1af500f905faca136a2e8184059602fca7 Mon Sep 17 00:00:00 2001 From: gbanyan Date: Tue, 10 Feb 2026 15:31:29 +0800 Subject: [PATCH] Add Line ID field to member lifecycle --- app/Console/Commands/ImportMembers.php | 2 ++ .../Controllers/AdminMemberController.php | 15 ++++++++-- .../Controllers/MemberDashboardController.php | 4 ++- .../PublicMemberRegistrationController.php | 2 ++ app/Http/Requests/StoreMemberRequest.php | 1 + app/Http/Requests/UpdateMemberRequest.php | 1 + app/Models/Member.php | 1 + ...10_120000_add_line_id_to_members_table.php | 28 +++++++++++++++++++ .../views/admin/members/create.blade.php | 18 +++++++++++- resources/views/admin/members/edit.blade.php | 18 +++++++++++- .../views/admin/members/import.blade.php | 1 + resources/views/admin/members/index.blade.php | 6 ++-- resources/views/admin/members/show.blade.php | 9 ++++++ .../views/member/create-profile.blade.php | 7 +++++ resources/views/member/dashboard.blade.php | 9 ++++++ resources/views/register/member.blade.php | 7 +++++ tests/Feature/MemberRegistrationTest.php | 3 ++ tests/Traits/CreatesMemberData.php | 1 + 18 files changed, 124 insertions(+), 9 deletions(-) create mode 100644 database/migrations/2026_02_10_120000_add_line_id_to_members_table.php diff --git a/app/Console/Commands/ImportMembers.php b/app/Console/Commands/ImportMembers.php index 818e48d..966900b 100644 --- a/app/Console/Commands/ImportMembers.php +++ b/app/Console/Commands/ImportMembers.php @@ -85,6 +85,7 @@ class ImportMembers extends Command $memberNumber = isset($indexes['member_number']) ? trim($row[$indexes['member_number']] ?? '') : ''; $nationalId = isset($indexes['national_id']) ? trim($row[$indexes['national_id']] ?? '') : ''; $phone = trim($row[$indexes['phone']] ?? ''); + $lineId = isset($indexes['line_id']) ? trim($row[$indexes['line_id']] ?? '') : ''; $phoneHome = isset($indexes['phone_home']) ? trim($row[$indexes['phone_home']] ?? '') : ''; $phoneFax = isset($indexes['phone_fax']) ? trim($row[$indexes['phone_fax']] ?? '') : ''; $birthDate = isset($indexes['birth_date']) ? trim($row[$indexes['birth_date']] ?? '') : ''; @@ -125,6 +126,7 @@ class ImportMembers extends Command 'email' => $email, 'national_id' => $nationalId !== '' ? $nationalId : null, 'phone' => $phone !== '' ? $phone : null, + 'line_id' => $lineId !== '' ? $lineId : null, 'phone_home' => $phoneHome !== '' ? $phoneHome : null, 'phone_fax' => $phoneFax !== '' ? $phoneFax : null, 'birth_date' => $birthDate !== '' ? $birthDate : null, diff --git a/app/Http/Controllers/AdminMemberController.php b/app/Http/Controllers/AdminMemberController.php index a104b01..a4ef94e 100644 --- a/app/Http/Controllers/AdminMemberController.php +++ b/app/Http/Controllers/AdminMemberController.php @@ -17,12 +17,13 @@ class AdminMemberController extends Controller { $query = Member::query()->with('user'); - // Text search (name, email, phone, national ID) + // Text search (name, email, phone, Line ID, national ID) if ($search = $request->string('search')->toString()) { $query->where(function ($q) use ($search) { $q->where('full_name', 'like', "%{$search}%") ->orWhere('email', 'like', "%{$search}%") - ->orWhere('phone', 'like', "%{$search}%"); + ->orWhere('phone', 'like', "%{$search}%") + ->orWhere('line_id', 'like', "%{$search}%"); // Search by national ID hash if provided if (!empty($search)) { @@ -256,7 +257,13 @@ class AdminMemberController extends Controller if ($search = $request->string('search')->toString()) { $query->where(function ($q) use ($search) { $q->where('full_name', 'like', "%{$search}%") - ->orWhere('email', 'like', "%{$search}%"); + ->orWhere('email', 'like', "%{$search}%") + ->orWhere('phone', 'like', "%{$search}%") + ->orWhere('line_id', 'like', "%{$search}%"); + + if (!empty($search)) { + $q->orWhere('national_id_hash', hash('sha256', $search)); + } }); } @@ -276,6 +283,7 @@ class AdminMemberController extends Controller 'Full Name', 'Email', 'Phone', + 'Line ID', 'Address Line 1', 'Address Line 2', 'City', @@ -297,6 +305,7 @@ class AdminMemberController extends Controller $member->full_name, $member->email, $member->phone, + $member->line_id, $member->address_line_1, $member->address_line_2, $member->city, diff --git a/app/Http/Controllers/MemberDashboardController.php b/app/Http/Controllers/MemberDashboardController.php index f63cee2..b5961de 100644 --- a/app/Http/Controllers/MemberDashboardController.php +++ b/app/Http/Controllers/MemberDashboardController.php @@ -54,6 +54,7 @@ class MemberDashboardController extends Controller $validated = $request->validate([ 'full_name' => ['required', 'string', 'max:255'], 'phone' => ['nullable', 'string', 'max:20'], + 'line_id' => ['nullable', 'string', 'max:100'], 'national_id' => ['nullable', 'string', 'max:20'], 'address_line_1' => ['nullable', 'string', 'max:255'], 'address_line_2' => ['nullable', 'string', 'max:255'], @@ -69,6 +70,7 @@ class MemberDashboardController extends Controller 'full_name' => $validated['full_name'], 'email' => $user->email, 'phone' => $validated['phone'] ?? null, + 'line_id' => $validated['line_id'] ?? null, 'national_id' => $validated['national_id'] ?? null, 'address_line_1' => $validated['address_line_1'] ?? null, 'address_line_2' => $validated['address_line_2'] ?? null, @@ -88,4 +90,4 @@ class MemberDashboardController extends Controller return redirect()->route('member.dashboard') ->with('status', __('Profile completed! Please submit your membership payment.')); } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/PublicMemberRegistrationController.php b/app/Http/Controllers/PublicMemberRegistrationController.php index df07e97..09255a3 100644 --- a/app/Http/Controllers/PublicMemberRegistrationController.php +++ b/app/Http/Controllers/PublicMemberRegistrationController.php @@ -32,6 +32,7 @@ class PublicMemberRegistrationController extends Controller 'email' => ['required', 'string', 'email', 'max:255', 'unique:users,email', 'unique:members,email'], 'password' => ['required', 'confirmed', Password::defaults()], 'phone' => ['nullable', 'string', 'max:20'], + 'line_id' => ['nullable', 'string', 'max:100'], 'national_id' => ['nullable', 'string', 'max:20'], 'address_line_1' => ['nullable', 'string', 'max:255'], 'address_line_2' => ['nullable', 'string', 'max:255'], @@ -57,6 +58,7 @@ class PublicMemberRegistrationController extends Controller 'full_name' => $validated['full_name'], 'email' => $validated['email'], 'phone' => $validated['phone'] ?? null, + 'line_id' => $validated['line_id'] ?? null, 'national_id' => $validated['national_id'] ?? null, 'address_line_1' => $validated['address_line_1'] ?? null, 'address_line_2' => $validated['address_line_2'] ?? null, diff --git a/app/Http/Requests/StoreMemberRequest.php b/app/Http/Requests/StoreMemberRequest.php index 6dfc775..96a077f 100644 --- a/app/Http/Requests/StoreMemberRequest.php +++ b/app/Http/Requests/StoreMemberRequest.php @@ -27,6 +27,7 @@ class StoreMemberRequest extends FormRequest 'email' => ['required', 'email', 'max:255', 'unique:users,email'], 'national_id' => ['nullable', 'string', 'max:50'], 'phone' => ['nullable', 'string', 'max:50'], + 'line_id' => ['nullable', 'string', 'max:100'], 'phone_home' => ['nullable', 'string', 'max:50'], 'phone_fax' => ['nullable', 'string', 'max:50'], 'birth_date' => ['nullable', 'date'], diff --git a/app/Http/Requests/UpdateMemberRequest.php b/app/Http/Requests/UpdateMemberRequest.php index bd9c3e5..2f4bb7a 100644 --- a/app/Http/Requests/UpdateMemberRequest.php +++ b/app/Http/Requests/UpdateMemberRequest.php @@ -33,6 +33,7 @@ class UpdateMemberRequest extends FormRequest 'email' => ['required', 'email', 'max:255'], 'national_id' => ['nullable', 'string', 'max:50'], 'phone' => ['nullable', 'string', 'max:50'], + 'line_id' => ['nullable', 'string', 'max:100'], 'phone_home' => ['nullable', 'string', 'max:50'], 'phone_fax' => ['nullable', 'string', 'max:50'], 'birth_date' => ['nullable', 'date'], diff --git a/app/Models/Member.php b/app/Models/Member.php index 9e0cb4e..19eb0f6 100644 --- a/app/Models/Member.php +++ b/app/Models/Member.php @@ -42,6 +42,7 @@ class Member extends Model 'full_name', 'email', 'phone', + 'line_id', 'phone_home', 'phone_fax', 'address_line_1', diff --git a/database/migrations/2026_02_10_120000_add_line_id_to_members_table.php b/database/migrations/2026_02_10_120000_add_line_id_to_members_table.php new file mode 100644 index 0000000..ef8ff0f --- /dev/null +++ b/database/migrations/2026_02_10_120000_add_line_id_to_members_table.php @@ -0,0 +1,28 @@ +string('line_id', 100)->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('members', function (Blueprint $table) { + $table->dropColumn('line_id'); + }); + } +}; diff --git a/resources/views/admin/members/create.blade.php b/resources/views/admin/members/create.blade.php index 994d274..1e63eb2 100644 --- a/resources/views/admin/members/create.blade.php +++ b/resources/views/admin/members/create.blade.php @@ -169,7 +169,7 @@

-
+
+
+ + + @error('line_id') +

{{ $message }}

+ @enderror +
+
-
+
+
+ + + @error('line_id') +

{{ $message }}

+ @enderror +
+
+
+
+ Line ID +
+
+ {{ $member->line_id ?? __('Not set') }} +
+
+
室內電話/傳真 diff --git a/resources/views/member/create-profile.blade.php b/resources/views/member/create-profile.blade.php index c690544..f13be99 100644 --- a/resources/views/member/create-profile.blade.php +++ b/resources/views/member/create-profile.blade.php @@ -34,6 +34,13 @@
+ +
+ + + +
+
diff --git a/resources/views/member/dashboard.blade.php b/resources/views/member/dashboard.blade.php index 6e53b96..d8b9298 100644 --- a/resources/views/member/dashboard.blade.php +++ b/resources/views/member/dashboard.blade.php @@ -92,6 +92,15 @@
+
+
+ {{ __('Line ID') }} +
+
+ {{ $member->line_id ?: __('Not set') }} +
+
+
{{ __('Membership Type') }} diff --git a/resources/views/register/member.blade.php b/resources/views/register/member.blade.php index dc7aeda..11fd5bc 100644 --- a/resources/views/register/member.blade.php +++ b/resources/views/register/member.blade.php @@ -50,6 +50,13 @@
+ +
+ + + +
+
diff --git a/tests/Feature/MemberRegistrationTest.php b/tests/Feature/MemberRegistrationTest.php index 25ee02e..323f666 100644 --- a/tests/Feature/MemberRegistrationTest.php +++ b/tests/Feature/MemberRegistrationTest.php @@ -41,6 +41,7 @@ class MemberRegistrationTest extends TestCase 'password' => 'Password123!', 'password_confirmation' => 'Password123!', 'phone' => '0912345678', + 'line_id' => 'john_doe_line', 'address_line_1' => '123 Test St', 'city' => 'Taipei', 'postal_code' => '100', @@ -62,6 +63,7 @@ class MemberRegistrationTest extends TestCase 'full_name' => 'John Doe', 'email' => 'john@example.com', 'phone' => '0912345678', + 'line_id' => 'john_doe_line', 'membership_status' => Member::STATUS_PENDING, ]); } @@ -256,6 +258,7 @@ class MemberRegistrationTest extends TestCase $member = Member::where('email', 'john@example.com')->first(); $this->assertNull($member->phone); + $this->assertNull($member->line_id); $this->assertNull($member->address_line_1); } } diff --git a/tests/Traits/CreatesMemberData.php b/tests/Traits/CreatesMemberData.php index d5462d3..d79de08 100644 --- a/tests/Traits/CreatesMemberData.php +++ b/tests/Traits/CreatesMemberData.php @@ -132,6 +132,7 @@ trait CreatesMemberData 'password' => 'Password123!', 'password_confirmation' => 'Password123!', 'phone' => '0912345678', + 'line_id' => 'line.member.test', 'national_id' => 'A123456789', 'address_line_1' => '123 Test Street', 'address_line_2' => '',