|
@@ -1,74 +1,499 @@
|
|
|
-@extends('admin::layouts.master')
|
|
|
|
|
|
|
+<x-admin::layouts>
|
|
|
|
|
+ <x-slot:title>
|
|
|
|
|
+ @lang('Reward Rules')
|
|
|
|
|
+ </x-slot>
|
|
|
|
|
|
|
|
-@section('page_title')
|
|
|
|
|
- Reward Rules
|
|
|
|
|
-@stop
|
|
|
|
|
|
|
+ {{-- 页面标题和操作按钮 --}}
|
|
|
|
|
+ <div class="flex flex-wrap gap-4 justify-between items-center mb-6">
|
|
|
|
|
+ <div class="flex items-center gap-3">
|
|
|
|
|
+ <div class="icon-star text-2xl text-yellow-500"></div>
|
|
|
|
|
+ <p class="text-2xl text-gray-800 dark:text-white font-bold">
|
|
|
|
|
+ @lang('Reward Rules')
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <span class="px-2.5 py-0.5 text-sm bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 rounded-full">
|
|
|
|
|
+ {{ $rules->total() }} @lang('Total')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
-@section('content-wrapper')
|
|
|
|
|
- <div class="content full-page">
|
|
|
|
|
- <div class="page-header">
|
|
|
|
|
- <div class="page-title">
|
|
|
|
|
- <h1>Reward Rules</h1>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="page-action">
|
|
|
|
|
- <a href="{{ route('admin.reward-points.rules.create') }}" class="btn btn-lg btn-primary">
|
|
|
|
|
- Add Rule
|
|
|
|
|
- </a>
|
|
|
|
|
|
|
+ <div class="flex gap-x-2.5 items-center">
|
|
|
|
|
+ <a href="{{ route('admin.reward-points.rules.create') }}" class="primary-button flex items-center gap-2">
|
|
|
|
|
+ <span class="icon-plus text-lg"></span>
|
|
|
|
|
+ @lang('Add Rule')
|
|
|
|
|
+ </a>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 搜索和筛选区域 --}}
|
|
|
|
|
+ <div class="mb-6 bg-white dark:bg-gray-900 rounded-lg shadow-sm p-4 border border-gray-200 dark:border-gray-800">
|
|
|
|
|
+ <div class="flex flex-wrap gap-4 items-center justify-between">
|
|
|
|
|
+ <div class="flex flex-wrap gap-3">
|
|
|
|
|
+ <div class="relative">
|
|
|
|
|
+ <input
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ id="searchInput"
|
|
|
|
|
+ placeholder="@lang('Search by rule name...')"
|
|
|
|
|
+ class="pl-9 pr-3 py-2 w-64 border border-gray-300 dark:border-gray-700 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-800 dark:text-gray-300"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span class="absolute left-3 top-2.5 icon-search text-gray-400 text-sm"></span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <select
|
|
|
|
|
+ id="transactionTypeFilter"
|
|
|
|
|
+ class="px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:text-gray-300"
|
|
|
|
|
+ >
|
|
|
|
|
+ <option value="">@lang('All Types')</option>
|
|
|
|
|
+ <option value="1">@lang('Order')</option>
|
|
|
|
|
+ <option value="2">@lang('Registration')</option>
|
|
|
|
|
+ <option value="3">@lang('Product Review')</option>
|
|
|
|
|
+ <option value="4">@lang('Daily Sign In')</option>
|
|
|
|
|
+ <option value="5">@lang('Referral')</option>
|
|
|
|
|
+ <option value="6">@lang('Birthday')</option>
|
|
|
|
|
+ <option value="7">@lang('Share')</option>
|
|
|
|
|
+ </select>
|
|
|
|
|
+
|
|
|
|
|
+ <select
|
|
|
|
|
+ id="statusFilter"
|
|
|
|
|
+ class="px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:text-gray-300"
|
|
|
|
|
+ >
|
|
|
|
|
+ <option value="">@lang('All Status')</option>
|
|
|
|
|
+ <option value="1">@lang('Active')</option>
|
|
|
|
|
+ <option value="0">@lang('Inactive')</option>
|
|
|
|
|
+ </select>
|
|
|
|
|
+
|
|
|
|
|
+ <select
|
|
|
|
|
+ id="groupPointsFilter"
|
|
|
|
|
+ class="px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:text-gray-300"
|
|
|
|
|
+ >
|
|
|
|
|
+ <option value="">@lang('All Rules')</option>
|
|
|
|
|
+ <option value="1">@lang('Different Points by Group')</option>
|
|
|
|
|
+ <option value="0">@lang('Uniform Points')</option>
|
|
|
|
|
+ </select>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
- <div class="page-content">
|
|
|
|
|
- <div class="table">
|
|
|
|
|
- <table class="table table-bordered">
|
|
|
|
|
- <thead>
|
|
|
|
|
|
|
+ {{-- 表格列表 --}}
|
|
|
|
|
+ <div class="bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-800 overflow-hidden">
|
|
|
|
|
+ <div class="overflow-x-auto">
|
|
|
|
|
+ <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-800">
|
|
|
|
|
+ <thead class="bg-gray-50 dark:bg-gray-800">
|
|
|
<tr>
|
|
<tr>
|
|
|
- <th>ID</th>
|
|
|
|
|
- <th>Rule Name</th>
|
|
|
|
|
- <th>Transaction Type</th>
|
|
|
|
|
- <th>Reward Points</th>
|
|
|
|
|
- <th>Status</th>
|
|
|
|
|
- <th>Actions</th>
|
|
|
|
|
|
|
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
|
|
|
+ @lang('ID')
|
|
|
|
|
+ </th>
|
|
|
|
|
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
|
|
|
+ @lang('Rule Name')
|
|
|
|
|
+ </th>
|
|
|
|
|
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
|
|
|
+ @lang('Transaction Type')
|
|
|
|
|
+ </th>
|
|
|
|
|
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
|
|
|
+ @lang('Group Settings')
|
|
|
|
|
+ </th>
|
|
|
|
|
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
|
|
|
+ @lang('Points Configuration')
|
|
|
|
|
+ </th>
|
|
|
|
|
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
|
|
|
+ @lang('Status')
|
|
|
|
|
+ </th>
|
|
|
|
|
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
|
|
|
+ @lang('Expiry')
|
|
|
|
|
+ </th>
|
|
|
|
|
+ <th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
|
|
|
+ @lang('Actions')
|
|
|
|
|
+ </th>
|
|
|
</tr>
|
|
</tr>
|
|
|
- </thead>
|
|
|
|
|
- <tbody>
|
|
|
|
|
- @foreach($rules as $rule)
|
|
|
|
|
- <tr>
|
|
|
|
|
- <td>{{ $rule->rule_id }}</td>
|
|
|
|
|
- <td>{{ $rule->rule_name }}</td>
|
|
|
|
|
- <td>
|
|
|
|
|
- @switch($rule->type_of_transaction)
|
|
|
|
|
- @case(1) Order @break
|
|
|
|
|
- @case(2) Registration @break
|
|
|
|
|
- @case(3) Product Review @break
|
|
|
|
|
- @case(4) Daily Sign In @break
|
|
|
|
|
- @case(5) Referral @break
|
|
|
|
|
- @case(6) Birthday @break
|
|
|
|
|
- @endswitch
|
|
|
|
|
|
|
+ </thead>
|
|
|
|
|
+ <tbody class="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-800">
|
|
|
|
|
+ @forelse($rules as $rule)
|
|
|
|
|
+ <tr class="hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors">
|
|
|
|
|
+ {{-- ID --}}
|
|
|
|
|
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-300">
|
|
|
|
|
+ #{{ $rule->rule_id }}
|
|
|
</td>
|
|
</td>
|
|
|
- <td>{{ $rule->reward_point }}</td>
|
|
|
|
|
- <td>
|
|
|
|
|
- <span class="badge badge-{{ $rule->status ? 'success' : 'danger' }}">
|
|
|
|
|
- {{ $rule->status ? 'Active' : 'Inactive' }}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 规则名称 --}}
|
|
|
|
|
+ <td class="px-6 py-4">
|
|
|
|
|
+ <div class="text-sm font-medium text-gray-900 dark:text-white">
|
|
|
|
|
+ {{ $rule->rule_name }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ @if($rule->comment)
|
|
|
|
|
+ <div class="text-xs text-gray-500 dark:text-gray-400 mt-1 line-clamp-1">
|
|
|
|
|
+ {{ $rule->comment }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ @endif
|
|
|
</td>
|
|
</td>
|
|
|
- <td>
|
|
|
|
|
- <a href="{{ route('admin.reward-points.rules.edit', $rule->rule_id) }}" class="btn btn-sm btn-primary">
|
|
|
|
|
- Edit
|
|
|
|
|
- </a>
|
|
|
|
|
- <form action="{{ route('admin.reward-points.rules.delete', $rule->rule_id) }}" method="POST" style="display:inline">
|
|
|
|
|
- @csrf
|
|
|
|
|
- @method('DELETE')
|
|
|
|
|
- <button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('Are you sure?')">
|
|
|
|
|
- Delete
|
|
|
|
|
- </button>
|
|
|
|
|
- </form>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 交易类型 --}}
|
|
|
|
|
+ <td class="px-6 py-4 whitespace-nowrap">
|
|
|
|
|
+ <div class="flex items-center gap-2">
|
|
|
|
|
+ @switch($rule->type_of_transaction)
|
|
|
|
|
+ @case(1)
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300">
|
|
|
|
|
+ <span class="icon-shopping-cart text-xs"></span>
|
|
|
|
|
+ @lang('Order')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @break
|
|
|
|
|
+ @case(2)
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300">
|
|
|
|
|
+ <span class="icon-user text-xs"></span>
|
|
|
|
|
+ @lang('Registration')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @break
|
|
|
|
|
+ @case(3)
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-yellow-100 dark:bg-yellow-900 text-yellow-700 dark:text-yellow-300">
|
|
|
|
|
+ <span class="icon-star text-xs"></span>
|
|
|
|
|
+ @lang('Product Review')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @break
|
|
|
|
|
+ @case(4)
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-purple-100 dark:bg-purple-900 text-purple-700 dark:text-purple-300">
|
|
|
|
|
+ <span class="icon-calendar text-xs"></span>
|
|
|
|
|
+ @lang('Daily Sign In')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @break
|
|
|
|
|
+ @case(5)
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-indigo-100 dark:bg-indigo-900 text-indigo-700 dark:text-indigo-300">
|
|
|
|
|
+ <span class="icon-share text-xs"></span>
|
|
|
|
|
+ @lang('Referral')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @break
|
|
|
|
|
+ @case(6)
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-pink-100 dark:bg-pink-900 text-pink-700 dark:text-pink-300">
|
|
|
|
|
+ <span class="icon-gift text-xs"></span>
|
|
|
|
|
+ @lang('Birthday')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @break
|
|
|
|
|
+ @case(7)
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-orange-100 dark:bg-orange-900 text-orange-700 dark:text-orange-300">
|
|
|
|
|
+ <span class="icon-share-alt text-xs"></span>
|
|
|
|
|
+ @lang('Share')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @break
|
|
|
|
|
+ @default
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400">
|
|
|
|
|
+ <span class="icon-question text-xs"></span>
|
|
|
|
|
+ @lang('Unknown')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @endswitch
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </td>
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 群组设置类型 --}}
|
|
|
|
|
+ <td class="px-6 py-4 whitespace-nowrap">
|
|
|
|
|
+ @if($rule->enable_different_points_by_group)
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-purple-100 dark:bg-purple-900 text-purple-700 dark:text-purple-300">
|
|
|
|
|
+ <span class="icon-users text-xs"></span>
|
|
|
|
|
+ @lang('积分不同')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @else
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300">
|
|
|
|
|
+ <span class="icon-star text-xs"></span>
|
|
|
|
|
+ @lang('积分相同')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ </td>
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 积分配置 --}}
|
|
|
|
|
+ <td class="px-6 py-4">
|
|
|
|
|
+ @if($rule->enable_different_points_by_group)
|
|
|
|
|
+ {{-- 积分不同模式:显示群组和对应积分 --}}
|
|
|
|
|
+ @php
|
|
|
|
|
+ $groupPoints = json_decode($rule->customer_group_ids, true) ?: [];
|
|
|
|
|
+ @endphp
|
|
|
|
|
+
|
|
|
|
|
+ @if(!empty($groupPoints))
|
|
|
|
|
+ <div class="space-y-1">
|
|
|
|
|
+ @foreach($groupPoints as $groupId => $points)
|
|
|
|
|
+ @if(!empty($groupId) && $groupId !== '')
|
|
|
|
|
+ <div class="flex items-center justify-between gap-2 text-sm">
|
|
|
|
|
+ <span class="text-gray-600 dark:text-gray-400">
|
|
|
|
|
+ {{ $customerGroupsList[$groupId] ?? 'Group ' . $groupId }}:
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <span class="font-medium text-yellow-600 dark:text-yellow-500">
|
|
|
|
|
+ {{ $points }} @lang('pts')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ @endforeach
|
|
|
|
|
+ </div>
|
|
|
|
|
+ @else
|
|
|
|
|
+ <span class="text-sm text-gray-400 dark:text-gray-500">
|
|
|
|
|
+ @lang('No groups configured')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ @else
|
|
|
|
|
+ {{-- 积分相同模式:显示统一积分 --}}
|
|
|
|
|
+ <div class="flex items-center gap-1">
|
|
|
|
|
+ <span class="text-2xl font-bold text-yellow-600 dark:text-yellow-500">
|
|
|
|
|
+ {{ $rule->reward_point }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <span class="text-xs text-gray-500">@lang('points')</span>
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 显示适用的客户群组 --}}
|
|
|
|
|
+ @php
|
|
|
|
|
+ $customerGroups = $rule->customer_group_ids ? explode(',', $rule->customer_group_ids) : [];
|
|
|
|
|
+ @endphp
|
|
|
|
|
+ @if(!empty($customerGroups) && $customerGroups[0] !== '')
|
|
|
|
|
+ <div class="ml-2 flex flex-wrap gap-1">
|
|
|
|
|
+ @foreach(array_slice($customerGroups, 0, 2) as $groupId)
|
|
|
|
|
+ <span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200">
|
|
|
|
|
+ {{ $customerGroupsList[$groupId] ?? 'Group ' . $groupId }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @endforeach
|
|
|
|
|
+ @if(count($customerGroups) > 2)
|
|
|
|
|
+ <span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400">
|
|
|
|
|
+ +{{ count($customerGroups) - 2 }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ </div>
|
|
|
|
|
+ @else
|
|
|
|
|
+ <span class="ml-2 text-xs text-gray-400">
|
|
|
|
|
+ (All Groups)
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ </div>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ </td>
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 状态 --}}
|
|
|
|
|
+ <td class="px-6 py-4 whitespace-nowrap">
|
|
|
|
|
+ @if($rule->status)
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300">
|
|
|
|
|
+ <span class="icon-check-circle text-xs"></span>
|
|
|
|
|
+ @lang('Active')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @else
|
|
|
|
|
+ <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400">
|
|
|
|
|
+ <span class="icon-x-circle text-xs"></span>
|
|
|
|
|
+ @lang('Inactive')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ </td>
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 过期信息 --}}
|
|
|
|
|
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
|
|
|
|
|
+ @if($rule->expired_day > 0)
|
|
|
|
|
+ <span class="flex items-center gap-1">
|
|
|
|
|
+ <span class="icon-calendar text-xs"></span>
|
|
|
|
|
+ {{ $rule->expired_day }} @lang('days')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @else
|
|
|
|
|
+ <span class="flex items-center gap-1">
|
|
|
|
|
+ <span class="icon-minus text-xs"></span>
|
|
|
|
|
+ @lang('Never')
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ </td>
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 操作按钮 --}}
|
|
|
|
|
+ <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
|
|
|
+ <div class="flex items-center justify-end gap-2">
|
|
|
|
|
+ <a
|
|
|
|
|
+ href="{{ route('admin.reward-points.rules.edit', $rule->rule_id) }}"
|
|
|
|
|
+ class="inline-flex items-center gap-1 px-3 py-1.5 bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 hover:bg-blue-100 dark:hover:bg-blue-900/30 rounded-lg transition-colors"
|
|
|
|
|
+ title="@lang('Edit')"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span class="icon-pencil text-sm"></span>
|
|
|
|
|
+ <span class="text-sm">@lang('Edit')</span>
|
|
|
|
|
+ </a>
|
|
|
|
|
+
|
|
|
|
|
+ <form
|
|
|
|
|
+ method="POST"
|
|
|
|
|
+ action="{{ route('admin.reward-points.rules.delete', $rule->rule_id) }}"
|
|
|
|
|
+ class="inline"
|
|
|
|
|
+ onsubmit="return confirm('@lang('Are you sure you want to delete this rule? This action cannot be undone.')');"
|
|
|
|
|
+ >
|
|
|
|
|
+ @csrf
|
|
|
|
|
+ @method('DELETE')
|
|
|
|
|
+ <button
|
|
|
|
|
+ type="submit"
|
|
|
|
|
+ class="inline-flex items-center gap-1 px-3 py-1.5 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 hover:bg-red-100 dark:hover:bg-red-900/30 rounded-lg transition-colors"
|
|
|
|
|
+ title="@lang('Delete')"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span class="icon-delete text-sm"></span>
|
|
|
|
|
+ <span class="text-sm">@lang('Delete')</span>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </form>
|
|
|
|
|
+ </div>
|
|
|
</td>
|
|
</td>
|
|
|
</tr>
|
|
</tr>
|
|
|
- @endforeach
|
|
|
|
|
- </tbody>
|
|
|
|
|
- </table>
|
|
|
|
|
- {{ $rules->links() }}
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ @empty
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <td colspan="8" class="px-6 py-12 text-center">
|
|
|
|
|
+ <div class="flex flex-col items-center gap-4">
|
|
|
|
|
+ <div class="w-20 h-20 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center">
|
|
|
|
|
+ <span class="icon-star text-4xl text-gray-400"></span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <p class="text-lg font-medium text-gray-600 dark:text-gray-400 mb-1">
|
|
|
|
|
+ @lang('No Reward Rules Found')
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <p class="text-sm text-gray-500 dark:text-gray-500">
|
|
|
|
|
+ @lang('Get started by creating your first reward rule')
|
|
|
|
|
+ </p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <a href="{{ route('admin.reward-points.rules.create') }}" class="primary-button mt-2">
|
|
|
|
|
+ @lang('Create Your First Rule')
|
|
|
|
|
+ </a>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </td>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ @endforelse
|
|
|
|
|
+ </tbody>
|
|
|
|
|
+ </table>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 分页 --}}
|
|
|
|
|
+ @if($rules->hasPages())
|
|
|
|
|
+ <div class="border-t border-gray-200 dark:border-gray-800 px-6 py-4">
|
|
|
|
|
+ <div class="flex flex-col sm:flex-row justify-between items-center gap-4">
|
|
|
|
|
+ <div class="text-sm text-gray-600 dark:text-gray-400">
|
|
|
|
|
+ {!! __('Showing :firstItem to :lastItem of :total items', [
|
|
|
|
|
+ 'firstItem' => $rules->firstItem(),
|
|
|
|
|
+ 'lastItem' => $rules->lastItem(),
|
|
|
|
|
+ 'total' => $rules->total()
|
|
|
|
|
+ ]) !!}
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="flex gap-1">
|
|
|
|
|
+ {{-- 上一页 --}}
|
|
|
|
|
+ @if($rules->onFirstPage())
|
|
|
|
|
+ <span class="px-3 py-2 rounded-lg bg-gray-100 dark:bg-gray-800 text-gray-400 cursor-not-allowed">
|
|
|
|
|
+ <span class="icon-chevron-left text-sm"></span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @else
|
|
|
|
|
+ <a href="{{ $rules->previousPageUrl() }}" class="px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
|
|
|
|
+ <span class="icon-chevron-left text-sm"></span>
|
|
|
|
|
+ </a>
|
|
|
|
|
+ @endif
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 页码 --}}
|
|
|
|
|
+ @php
|
|
|
|
|
+ $currentPage = $rules->currentPage();
|
|
|
|
|
+ $lastPage = $rules->lastPage();
|
|
|
|
|
+ $start = max(1, $currentPage - 2);
|
|
|
|
|
+ $end = min($lastPage, $currentPage + 2);
|
|
|
|
|
+ @endphp
|
|
|
|
|
+
|
|
|
|
|
+ @if($start > 1)
|
|
|
|
|
+ <a href="{{ $rules->url(1) }}" class="px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
|
|
|
|
+ 1
|
|
|
|
|
+ </a>
|
|
|
|
|
+ @if($start > 2)
|
|
|
|
|
+ <span class="px-3 py-2 text-gray-500">...</span>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ @endif
|
|
|
|
|
+
|
|
|
|
|
+ @for($i = $start; $i <= $end; $i++)
|
|
|
|
|
+ @if($i == $currentPage)
|
|
|
|
|
+ <span class="px-3 py-2 rounded-lg bg-blue-600 text-white cursor-default">
|
|
|
|
|
+ {{ $i }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @else
|
|
|
|
|
+ <a href="{{ $rules->url($i) }}" class="px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
|
|
|
|
+ {{ $i }}
|
|
|
|
|
+ </a>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ @endfor
|
|
|
|
|
+
|
|
|
|
|
+ @if($end < $lastPage)
|
|
|
|
|
+ @if($end < $lastPage - 1)
|
|
|
|
|
+ <span class="px-3 py-2 text-gray-500">...</span>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ <a href="{{ $rules->url($lastPage) }}" class="px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
|
|
|
|
+ {{ $lastPage }}
|
|
|
|
|
+ </a>
|
|
|
|
|
+ @endif
|
|
|
|
|
+
|
|
|
|
|
+ {{-- 下一页 --}}
|
|
|
|
|
+ @if($rules->hasMorePages())
|
|
|
|
|
+ <a href="{{ $rules->nextPageUrl() }}" class="px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
|
|
|
|
+ <span class="icon-chevron-right text-sm"></span>
|
|
|
|
|
+ </a>
|
|
|
|
|
+ @else
|
|
|
|
|
+ <span class="px-3 py-2 rounded-lg bg-gray-100 dark:bg-gray-800 text-gray-400 cursor-not-allowed">
|
|
|
|
|
+ <span class="icon-chevron-right text-sm"></span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ @endif
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ @endif
|
|
|
</div>
|
|
</div>
|
|
|
-@stop
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <script>
|
|
|
|
|
+ // 实时搜索和筛选功能
|
|
|
|
|
+ document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
|
+ const searchInput = document.getElementById('searchInput');
|
|
|
|
|
+ const transactionTypeFilter = document.getElementById('transactionTypeFilter');
|
|
|
|
|
+ const statusFilter = document.getElementById('statusFilter');
|
|
|
|
|
+ const groupPointsFilter = document.getElementById('groupPointsFilter');
|
|
|
|
|
+
|
|
|
|
|
+ function filterRules() {
|
|
|
|
|
+ const searchTerm = searchInput.value.toLowerCase();
|
|
|
|
|
+ const transactionTypeValue = transactionTypeFilter.value;
|
|
|
|
|
+ const statusValue = statusFilter.value;
|
|
|
|
|
+ const groupPointsValue = groupPointsFilter.value;
|
|
|
|
|
+
|
|
|
|
|
+ const rows = document.querySelectorAll('tbody tr');
|
|
|
|
|
+
|
|
|
|
|
+ rows.forEach(row => {
|
|
|
|
|
+ if (row.querySelector('td[colspan]')) return; // 跳过空状态行
|
|
|
|
|
+
|
|
|
|
|
+ const ruleName = row.querySelector('td:nth-child(2) .font-medium')?.innerText.toLowerCase() || '';
|
|
|
|
|
+ const transactionTypeText = row.querySelector('td:nth-child(3) .rounded-full')?.innerText || '';
|
|
|
|
|
+ const statusBadge = row.querySelector('td:nth-child(6) .rounded-full')?.innerText.includes('Active') || false;
|
|
|
|
|
+ const groupPointsType = row.querySelector('td:nth-child(4) .rounded-full')?.innerText.includes('积分不同') || false;
|
|
|
|
|
+
|
|
|
|
|
+ let show = true;
|
|
|
|
|
+
|
|
|
|
|
+ // 搜索过滤
|
|
|
|
|
+ if (searchTerm && !ruleName.includes(searchTerm)) {
|
|
|
|
|
+ show = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 交易类型过滤
|
|
|
|
|
+ if (transactionTypeValue !== '') {
|
|
|
|
|
+ const typeMap = {
|
|
|
|
|
+ '1': 'Order',
|
|
|
|
|
+ '2': 'Registration',
|
|
|
|
|
+ '3': 'Product Review',
|
|
|
|
|
+ '4': 'Daily Sign In',
|
|
|
|
|
+ '5': 'Referral',
|
|
|
|
|
+ '6': 'Birthday',
|
|
|
|
|
+ '7': 'Share'
|
|
|
|
|
+ };
|
|
|
|
|
+ const expectedType = typeMap[transactionTypeValue];
|
|
|
|
|
+ if (!transactionTypeText.includes(expectedType)) {
|
|
|
|
|
+ show = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 状态过滤
|
|
|
|
|
+ if (statusValue !== '') {
|
|
|
|
|
+ const isActive = statusValue === '1';
|
|
|
|
|
+ if (statusBadge !== isActive) {
|
|
|
|
|
+ show = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 群组积分类型过滤
|
|
|
|
|
+ if (groupPointsValue !== '') {
|
|
|
|
|
+ const isDifferentPoints = groupPointsValue === '1';
|
|
|
|
|
+ if (groupPointsType !== isDifferentPoints) {
|
|
|
|
|
+ show = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ row.style.display = show ? '' : 'none';
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (searchInput) searchInput.addEventListener('keyup', filterRules);
|
|
|
|
|
+ if (transactionTypeFilter) transactionTypeFilter.addEventListener('change', filterRules);
|
|
|
|
|
+ if (statusFilter) statusFilter.addEventListener('change', filterRules);
|
|
|
|
|
+ if (groupPointsFilter) groupPointsFilter.addEventListener('change', filterRules);
|
|
|
|
|
+ });
|
|
|
|
|
+ </script>
|
|
|
|
|
+</x-admin::layouts>
|