update
This commit is contained in:
		
							parent
							
								
									9b630fe1e1
								
							
						
					
					
						commit
						8cc13276f0
					
				| 
						 | 
				
			
			@ -1,45 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Models\Contact;
 | 
			
		||||
use App\Traits\HasFilterRequest;
 | 
			
		||||
use App\Traits\HasOrderByRequest;
 | 
			
		||||
use App\Traits\HasSearchRequest;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Modules\Admin\app\Http\Requests\ContactRequest;
 | 
			
		||||
 | 
			
		||||
class ContactController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use HasOrderByRequest;
 | 
			
		||||
    use HasFilterRequest;
 | 
			
		||||
    use HasSearchRequest;
 | 
			
		||||
 | 
			
		||||
    public function get(ContactRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $contact = new Contact;
 | 
			
		||||
 | 
			
		||||
        // Order by
 | 
			
		||||
        $this->orderByRequest($contact, $request);
 | 
			
		||||
 | 
			
		||||
        $this->searchRequest(
 | 
			
		||||
            builder: $contact,
 | 
			
		||||
            value: $request->get('search'),
 | 
			
		||||
            fields: [
 | 
			
		||||
                'name',
 | 
			
		||||
                'phone',
 | 
			
		||||
                'company',
 | 
			
		||||
                'email',
 | 
			
		||||
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseData = array_merge(
 | 
			
		||||
            $contact->paginate($request->get('per_page'))->toArray(),
 | 
			
		||||
            ['status' => true]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($responseData);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,133 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Traits\HasFilterRequest;
 | 
			
		||||
use App\Traits\HasOrderByRequest;
 | 
			
		||||
use App\Traits\HasSearchRequest;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Http\Response;
 | 
			
		||||
use Modules\Admin\app\Http\Requests\DiscountRequest;
 | 
			
		||||
use Modules\Admin\app\Models\Discount;
 | 
			
		||||
 | 
			
		||||
class DiscountController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use HasOrderByRequest;
 | 
			
		||||
    use HasFilterRequest;
 | 
			
		||||
    use HasSearchRequest;
 | 
			
		||||
 | 
			
		||||
    public function get(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $discount = new Discount;
 | 
			
		||||
 | 
			
		||||
        // Order by
 | 
			
		||||
        $this->orderByRequest($discount, $request);
 | 
			
		||||
 | 
			
		||||
        // Filter
 | 
			
		||||
        $this->filterRequest(
 | 
			
		||||
            builder: $discount,
 | 
			
		||||
            request: $request,
 | 
			
		||||
            filterKeys: [
 | 
			
		||||
                'active_date' => self::F_THAN_EQ_DATETIME,
 | 
			
		||||
                'expiry' => self::F_LESS_EQ_DATETIME,
 | 
			
		||||
                'date_used' => self::F_IN_DATETIME,
 | 
			
		||||
                'code' => self::F_TEXT,
 | 
			
		||||
                'value' => self::F_TEXT,
 | 
			
		||||
                'email' => self::F_TEXT,
 | 
			
		||||
                'discount_type_id' => self::F_NOT_CONTAIN,
 | 
			
		||||
                'status' => self::F_BOOLEAN,
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $this->searchRequest(
 | 
			
		||||
            builder: $discount,
 | 
			
		||||
            value: $request->get('search'),
 | 
			
		||||
            fields: [
 | 
			
		||||
                'code',
 | 
			
		||||
                'email',
 | 
			
		||||
                'value'
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseData = array_merge(
 | 
			
		||||
            $discount->paginate($request->get('per_page'))->toArray(),
 | 
			
		||||
            ['status' => true]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($responseData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function create(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $payload = $request->all();
 | 
			
		||||
 | 
			
		||||
        $discount = Discount::createWithDefault($payload);
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $discount,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function update(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->get('id');
 | 
			
		||||
 | 
			
		||||
        $discount = Discount::find($id);
 | 
			
		||||
        $payload = $request->all();
 | 
			
		||||
 | 
			
		||||
        if ($discount) {
 | 
			
		||||
            $discount->update($payload);
 | 
			
		||||
        }
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $discount,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function delete(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->get('id');
 | 
			
		||||
 | 
			
		||||
        Discount::destroy($id);
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Delete multiple discounts
 | 
			
		||||
    public function deletes(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $discounts = $request->get('discounts');
 | 
			
		||||
        $ids = collect($discounts)->pluck('id');
 | 
			
		||||
        Discount::whereIn('id', $ids)->delete();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $ids,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Update multiple discounts
 | 
			
		||||
    public function updates(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $discounts = $request->get('discounts');
 | 
			
		||||
        $ids = collect($discounts)->pluck('id');
 | 
			
		||||
 | 
			
		||||
        foreach ($discounts as $discountRequest) {
 | 
			
		||||
            // convert to object|array to array
 | 
			
		||||
            $discountRequest = collect($discountRequest)->toArray();
 | 
			
		||||
            // handle array
 | 
			
		||||
            $discount = Discount::find($discountRequest['id']);
 | 
			
		||||
            if ($discount) {
 | 
			
		||||
                // exclude id field
 | 
			
		||||
                unset($discount['id']);
 | 
			
		||||
 | 
			
		||||
                $discount->update($discountRequest);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => Discount::whereIn('id', $ids)->get(),
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Http\Response;
 | 
			
		||||
use Modules\Admin\app\Http\Requests\DiscountTypeRequest;
 | 
			
		||||
use Modules\Admin\app\Models\DiscountType;
 | 
			
		||||
 | 
			
		||||
class DiscountTypeController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    public function all(DiscountTypeRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => DiscountType::all(),
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,156 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Events\PaymentCanceled;
 | 
			
		||||
use App\Events\PaymentCompleted;
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Models\Client;
 | 
			
		||||
use App\Models\Order;
 | 
			
		||||
use App\Models\Package;
 | 
			
		||||
use App\Traits\HasFilterRequest;
 | 
			
		||||
use App\Traits\HasOrderByRequest;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use JsonException;
 | 
			
		||||
use Modules\Admin\app\Http\Requests\OrderRequest;
 | 
			
		||||
use Modules\Admin\app\Models\Discount;
 | 
			
		||||
use Modules\Paypal\app\Models\HistoryPayment;
 | 
			
		||||
 | 
			
		||||
class OrderController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use HasOrderByRequest;
 | 
			
		||||
    use HasFilterRequest;
 | 
			
		||||
 | 
			
		||||
    const ORDER_STATUS_COMPLETE = 'COMPLETED';
 | 
			
		||||
    const ORDER_STATUS_PENDING = 'PENDING';
 | 
			
		||||
    const ORDER_STATUS_CANCEL = 'CANCELED';
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        // module check model exist and table
 | 
			
		||||
        if (!class_exists(Order::class)) {
 | 
			
		||||
            throw new JsonException("Order table not exist" );
 | 
			
		||||
        }
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function get(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $order = Order::getOrdersWithDiscountAndPackage();
 | 
			
		||||
 | 
			
		||||
        // Order by
 | 
			
		||||
        $this->orderByRequest($order, $request);
 | 
			
		||||
 | 
			
		||||
        // Filter
 | 
			
		||||
        $this->filterRequest(
 | 
			
		||||
            builder: $order,
 | 
			
		||||
            request: $request,
 | 
			
		||||
            filterKeys: [
 | 
			
		||||
                'payment_id' => self::F_TEXT,
 | 
			
		||||
                'discount' => self::F_TEXT,
 | 
			
		||||
                'email' => [
 | 
			
		||||
                    'type' => self::F_TEXT,
 | 
			
		||||
                    'column' => 'users.email'
 | 
			
		||||
                ],
 | 
			
		||||
                'status' => [
 | 
			
		||||
                    'type' => self::F_NOT_CONTAIN,
 | 
			
		||||
                    'column' => 'orders.status'
 | 
			
		||||
                ],
 | 
			
		||||
                'from_date' => [
 | 
			
		||||
                    'type' => self::F_THAN_EQ_DATETIME,
 | 
			
		||||
                    'column' => 'orders.created_at'
 | 
			
		||||
                ],
 | 
			
		||||
                'to_date' => [
 | 
			
		||||
                    'type' => self::F_LESS_EQ_DATETIME,
 | 
			
		||||
                    'column' => 'orders.created_at'
 | 
			
		||||
                ],
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseData = array_merge(
 | 
			
		||||
            $order->paginate($request->get('per_page'))->toArray(),
 | 
			
		||||
            ['status' => true]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($responseData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function update(OrderRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->input('id');
 | 
			
		||||
        $order = Order::find($id);
 | 
			
		||||
        $client = Client::find($order['user_id']);
 | 
			
		||||
        $package = Package::find($order['package_id']);
 | 
			
		||||
 | 
			
		||||
        $order['status'] = $request->input('status');
 | 
			
		||||
 | 
			
		||||
        if ($request->input('status') == self::ORDER_STATUS_COMPLETE) {
 | 
			
		||||
            if ($order['discount']) {
 | 
			
		||||
                // Update discount
 | 
			
		||||
                $discount = Discount::where('code', $order['discount'])->first();
 | 
			
		||||
                if ($discount != null) {
 | 
			
		||||
                    $discount['user_id'] = $client->id;
 | 
			
		||||
                    $discount['email'] = $client->email;
 | 
			
		||||
                    $discount['date_used'] = now();
 | 
			
		||||
                    $discount->save();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // Update point for client
 | 
			
		||||
            $client->point += (int) $order['point'];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $status = -1;
 | 
			
		||||
        if ($request->input('status') == self::ORDER_STATUS_COMPLETE) {
 | 
			
		||||
            $status = 1;
 | 
			
		||||
            event(
 | 
			
		||||
                new PaymentCompleted(
 | 
			
		||||
                    payment_id: $order['payment_id'],
 | 
			
		||||
                    email: $client->email,
 | 
			
		||||
                    name: $client->name,
 | 
			
		||||
                    type: "PAYPAL",
 | 
			
		||||
                    product_name: $package->title,
 | 
			
		||||
                    point: $order->point,
 | 
			
		||||
                    discount_value: view_price((float) $package->price - (float) $order['total_price']),
 | 
			
		||||
                    total_price: $package->price
 | 
			
		||||
                )
 | 
			
		||||
            );
 | 
			
		||||
        } elseif ($request->input('status') == self::ORDER_STATUS_CANCEL) {
 | 
			
		||||
            $status = 0;
 | 
			
		||||
            if ($order['discount']) {
 | 
			
		||||
                $discount = Discount::where('code', $order['discount'])->first();
 | 
			
		||||
                $discount['status'] = 1;
 | 
			
		||||
                $discount->save();
 | 
			
		||||
            }
 | 
			
		||||
            event(
 | 
			
		||||
                new PaymentCanceled(
 | 
			
		||||
                    payment_id: $order['payment_id'],
 | 
			
		||||
                    email: $client->email,
 | 
			
		||||
                    name: $client->name
 | 
			
		||||
                )
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            $status = 2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Create history
 | 
			
		||||
        HistoryPayment::create([
 | 
			
		||||
            'payment_id' => $order['payment_id'],
 | 
			
		||||
            'status' => $status,
 | 
			
		||||
            'payload' => $request->all(),
 | 
			
		||||
            'response' =>
 | 
			
		||||
                [
 | 
			
		||||
                    'order' => $order,
 | 
			
		||||
                    'client' => $client,
 | 
			
		||||
                    'discount' => $discount ?? [],
 | 
			
		||||
                    'message' => "Change by Admin"
 | 
			
		||||
                ]
 | 
			
		||||
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $order->save();
 | 
			
		||||
        $client->save();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $order,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,94 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Helper\Cache\PackagesCacheHelper;
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Http\Response;
 | 
			
		||||
use Modules\Admin\app\Http\Requests\PackageRequest;
 | 
			
		||||
use Modules\Admin\app\Models\Package;
 | 
			
		||||
 | 
			
		||||
class PackageController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    public function all(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $package = new Package;
 | 
			
		||||
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $package->get(),
 | 
			
		||||
            'status' => true,
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function create(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $package = Package::create($request->all());
 | 
			
		||||
        PackagesCacheHelper::cleanCachePackages();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $package,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function update(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->get('id');
 | 
			
		||||
 | 
			
		||||
        $package = Package::find($id);
 | 
			
		||||
        $package->update($request->all());
 | 
			
		||||
        PackagesCacheHelper::cleanCachePackages();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $package,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function delete(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->get('id');
 | 
			
		||||
 | 
			
		||||
        Package::destroy($id);
 | 
			
		||||
        PackagesCacheHelper::cleanCachePackages();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Delete multiple packages
 | 
			
		||||
    public function deletes(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $packages = $request->get('packages');
 | 
			
		||||
        $ids = collect($packages)->pluck('id');
 | 
			
		||||
        Package::whereIn('id', $ids)->delete();
 | 
			
		||||
        PackagesCacheHelper::cleanCachePackages();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $ids,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Update multiple packages
 | 
			
		||||
    public function updates(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $packages = $request->get('packages');
 | 
			
		||||
        $ids = collect($packages)->pluck('id');
 | 
			
		||||
 | 
			
		||||
        foreach ($packages as $packageRequest) {
 | 
			
		||||
            // convert to object|array to array
 | 
			
		||||
            $packageRequest = collect($packageRequest)->toArray();
 | 
			
		||||
            // handle array
 | 
			
		||||
            $package = Package::find($packageRequest['id']);
 | 
			
		||||
            if ($package) {
 | 
			
		||||
                // exclude id field
 | 
			
		||||
                unset($package['id']);
 | 
			
		||||
                $package->update($packageRequest);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        PackagesCacheHelper::cleanCachePackages();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => Package::whereIn('id', $ids)->get(),
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,135 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Models\SerialNumberCheck;
 | 
			
		||||
use Illuminate\Http\RedirectResponse;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Http\Response;
 | 
			
		||||
use App\Traits\HasFilterRequest;
 | 
			
		||||
use App\Traits\HasOrderByRequest;
 | 
			
		||||
use JsonException;
 | 
			
		||||
 | 
			
		||||
class SNCheckController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use HasOrderByRequest;
 | 
			
		||||
    use HasFilterRequest;
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        // module check model exist and table
 | 
			
		||||
        if (!class_exists(SerialNumberCheck::class)) {
 | 
			
		||||
            throw new JsonException("SerialNumberCheck table not exist");
 | 
			
		||||
        }
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
    public function get(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $history = SerialNumberCheck::getHistoryWithUserInfo();
 | 
			
		||||
 | 
			
		||||
        // Order by
 | 
			
		||||
        $this->orderByRequest($history, $request);
 | 
			
		||||
 | 
			
		||||
        // Filter
 | 
			
		||||
        $this->filterRequest(
 | 
			
		||||
            builder: $history,
 | 
			
		||||
            request: $request,
 | 
			
		||||
            filterKeys: [
 | 
			
		||||
                'keyword' => [
 | 
			
		||||
                    'type' => self::F_TEXT,
 | 
			
		||||
                    'column' => 'serial_number_check.keyword'
 | 
			
		||||
                ],
 | 
			
		||||
                'email' => [
 | 
			
		||||
                    'type' => self::F_TEXT,
 | 
			
		||||
                    'column' => 'users.email'
 | 
			
		||||
                ],
 | 
			
		||||
                'status' => [
 | 
			
		||||
                    'type' => self::F_NOT_CONTAIN,
 | 
			
		||||
                    'column' => 'serial_number_check.status'
 | 
			
		||||
                ],
 | 
			
		||||
                'from_date' => [
 | 
			
		||||
                    'type' => self::F_THAN_EQ_DATETIME,
 | 
			
		||||
                    'column' => 'serial_number_check.created_at'
 | 
			
		||||
                ],
 | 
			
		||||
                'to_date' => [
 | 
			
		||||
                    'type' => self::F_LESS_EQ_DATETIME,
 | 
			
		||||
                    'column' => 'serial_number_check.created_at'
 | 
			
		||||
                ],
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseData = array_merge(
 | 
			
		||||
            $history->paginate($request->get('per_page'))->toArray(),
 | 
			
		||||
            ['status' => true]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($responseData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function showDetail(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->input('id');
 | 
			
		||||
        $searchRow = SerialNumberCheck::find($id);
 | 
			
		||||
        if ($searchRow) {
 | 
			
		||||
            $user = $searchRow->user()->get();
 | 
			
		||||
            $tracking = $searchRow->tracking()->get();
 | 
			
		||||
            $trackingDetail = $tracking->map(function ($item) {
 | 
			
		||||
                return [
 | 
			
		||||
                    'current_point' => $item->current_point,
 | 
			
		||||
                    'use_point' => $item->use_point,
 | 
			
		||||
                    'created_at' => $item->created_at
 | 
			
		||||
                ];
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            $response = [
 | 
			
		||||
                'data_search' => $searchRow,
 | 
			
		||||
                'user' => $user[0],
 | 
			
		||||
                'tracking' => $trackingDetail
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            return response()->json(['data' => $response, 'status' => true]);
 | 
			
		||||
        }else{
 | 
			
		||||
            return response()->json(['data' => [], 'status' => false]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Store a newly created resource in storage.
 | 
			
		||||
     */
 | 
			
		||||
    public function store(Request $request): RedirectResponse
 | 
			
		||||
    {
 | 
			
		||||
        //
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Show the specified resource.
 | 
			
		||||
     */
 | 
			
		||||
    public function show($id)
 | 
			
		||||
    {
 | 
			
		||||
        return view('admin::show');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Show the form for editing the specified resource.
 | 
			
		||||
     */
 | 
			
		||||
    public function edit($id)
 | 
			
		||||
    {
 | 
			
		||||
        return view('admin::edit');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the specified resource in storage.
 | 
			
		||||
     */
 | 
			
		||||
    public function update(Request $request, $id): RedirectResponse
 | 
			
		||||
    {
 | 
			
		||||
        //
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove the specified resource from storage.
 | 
			
		||||
     */
 | 
			
		||||
    public function destroy($id)
 | 
			
		||||
    {
 | 
			
		||||
        //
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ class Admin extends Authenticatable implements JWTSubject
 | 
			
		|||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        $this->table = 'admin';
 | 
			
		||||
        $this->table = 'users';
 | 
			
		||||
        $this->guarded = [];
 | 
			
		||||
        $this->hidden = [
 | 
			
		||||
            'password',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,108 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Migrations\Migration;
 | 
			
		||||
use Illuminate\Database\Schema\Blueprint;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Illuminate\Support\Facades\Schema;
 | 
			
		||||
 | 
			
		||||
return new class extends Migration
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Run the migrations.
 | 
			
		||||
     */
 | 
			
		||||
    public function up(): void
 | 
			
		||||
    {
 | 
			
		||||
        Schema::create('admin', function (Blueprint $table) {
 | 
			
		||||
            $table->id();
 | 
			
		||||
            $table->string('name');
 | 
			
		||||
            $table->string('email')->unique();
 | 
			
		||||
            $table->timestamp('email_verified_at')->nullable();
 | 
			
		||||
            $table->string('forgot_code')->nullable();
 | 
			
		||||
            $table->string('password');
 | 
			
		||||
            $table->rememberToken();
 | 
			
		||||
            $table->timestamps();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        DB::table('admin')->insert([
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'BIEN CONG NHUT TRUONG',
 | 
			
		||||
                'email' => 'roger.b@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAN QUOC BAO',
 | 
			
		||||
                'email' => 'ryder.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAM VAN HUYNH',
 | 
			
		||||
                'email' => 'jon.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'VO MINH TRUONG',
 | 
			
		||||
                'email' => 'vincent.vo@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN HUU PHUC',
 | 
			
		||||
                'email' => 'jason.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN VO TINH',
 | 
			
		||||
                'email' => 'alex.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'DANG TRUNG KIEN',
 | 
			
		||||
                'email' => 'kevin.dang@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'HUYNH THI HONG GAM',
 | 
			
		||||
                'email' => 'rose.h@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN TRUNG THAT',
 | 
			
		||||
                'email' => 'andrew.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'LE TAN LUAN',
 | 
			
		||||
                'email' => 'joseph.le@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'VO VAN MINH',
 | 
			
		||||
                'email' => 'michael.vo@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'TON GIA KHANH',
 | 
			
		||||
                'email' => 'kai.t@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAM QUOC HY',
 | 
			
		||||
                'email' => 'asher.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'Admin',
 | 
			
		||||
                'email' => 'admin@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reverse the migrations.
 | 
			
		||||
     */
 | 
			
		||||
    public function down(): void
 | 
			
		||||
    {
 | 
			
		||||
        Schema::dropIfExists('admin');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
 | 
			
		||||
use Illuminate\Database\Migrations\Migration;
 | 
			
		||||
use Illuminate\Database\Schema\Blueprint;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Illuminate\Support\Facades\Schema;
 | 
			
		||||
 | 
			
		||||
return new class extends Migration
 | 
			
		||||
| 
						 | 
				
			
			@ -16,10 +17,86 @@ return new class extends Migration
 | 
			
		|||
            $table->string('name');
 | 
			
		||||
            $table->string('email')->unique();
 | 
			
		||||
            $table->timestamp('email_verified_at')->nullable();
 | 
			
		||||
            $table->string('forgot_code')->nullable();
 | 
			
		||||
            $table->string('password');
 | 
			
		||||
            $table->string('permission')->default('staff');
 | 
			
		||||
            $table->rememberToken();
 | 
			
		||||
            $table->timestamps();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        DB::table('users')->insert([
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'BIEN CONG NHUT TRUONG',
 | 
			
		||||
                'email' => 'roger.b@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAN QUOC BAO',
 | 
			
		||||
                'email' => 'ryder.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAM VAN HUYNH',
 | 
			
		||||
                'email' => 'jon.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'VO MINH TRUONG',
 | 
			
		||||
                'email' => 'vincent.vo@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN HUU PHUC',
 | 
			
		||||
                'email' => 'jason.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN VO TINH',
 | 
			
		||||
                'email' => 'alex.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'DANG TRUNG KIEN',
 | 
			
		||||
                'email' => 'kevin.dang@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'HUYNH THI HONG GAM',
 | 
			
		||||
                'email' => 'rose.h@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN TRUNG THAT',
 | 
			
		||||
                'email' => 'andrew.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'LE TAN LUAN',
 | 
			
		||||
                'email' => 'joseph.le@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'VO VAN MINH',
 | 
			
		||||
                'email' => 'michael.vo@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'TON GIA KHANH',
 | 
			
		||||
                'email' => 'kai.t@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAM QUOC HY',
 | 
			
		||||
                'email' => 'asher.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'Admin',
 | 
			
		||||
                'email' => 'admin@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,14 @@
 | 
			
		|||
import { getAllUserWorklogs } from '@/api/Admin'
 | 
			
		||||
import { get } from '@/rtk/helpers/apiService'
 | 
			
		||||
import { Avatar, Box, Button, Loader, Text } from '@mantine/core'
 | 
			
		||||
import {
 | 
			
		||||
  Avatar,
 | 
			
		||||
  Badge,
 | 
			
		||||
  Box,
 | 
			
		||||
  Button,
 | 
			
		||||
  Loader,
 | 
			
		||||
  Text,
 | 
			
		||||
  Tooltip,
 | 
			
		||||
} from '@mantine/core'
 | 
			
		||||
import { DateInput } from '@mantine/dates'
 | 
			
		||||
import moment from 'moment'
 | 
			
		||||
import { useEffect, useState } from 'react'
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +125,7 @@ const Worklogs = () => {
 | 
			
		|||
    startDate:
 | 
			
		||||
      localStorage.getItem('data') !== null
 | 
			
		||||
        ? JSON.parse(localStorage.getItem('data')!).date.startDate
 | 
			
		||||
        : moment(Date.now()-604800000).format('YYYY-MM-DD'),
 | 
			
		||||
        : moment(Date.now() - 604800000).format('YYYY-MM-DD'),
 | 
			
		||||
    endDate:
 | 
			
		||||
      localStorage.getItem('data') !== null
 | 
			
		||||
        ? JSON.parse(localStorage.getItem('data')!).date.endDate
 | 
			
		||||
| 
						 | 
				
			
			@ -172,361 +180,441 @@ const Worklogs = () => {
 | 
			
		|||
    </Box>
 | 
			
		||||
  ) : (
 | 
			
		||||
    <div style={{ display: 'flex', flexFlow: 'column' }}>
 | 
			
		||||
    <div className={classes.title}>
 | 
			
		||||
      <h3>
 | 
			
		||||
        <Text>Admin/</Text>Worklogs
 | 
			
		||||
        {!updating ? (
 | 
			
		||||
          <Text fs={'italic'} fz={'xs'} c={'gray'}>
 | 
			
		||||
            Updating data in the background ...
 | 
			
		||||
          </Text>
 | 
			
		||||
        ) : (
 | 
			
		||||
          ''
 | 
			
		||||
        )}
 | 
			
		||||
      </h3>
 | 
			
		||||
    </div>
 | 
			
		||||
    <Box
 | 
			
		||||
      display={'flex'}
 | 
			
		||||
      style={{
 | 
			
		||||
        flexFlow: 'column',
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
      <Text fz={12} fs={'italic'} c={'red'} fw={600} mt={'md'}>
 | 
			
		||||
        {`* The current data is from ${JSON.parse(localStorage.getItem('data')!).date.startDate} to ${JSON.parse(localStorage.getItem('data')!).date.endDate}`}
 | 
			
		||||
      </Text>
 | 
			
		||||
      <Text fz={12} fs={'italic'} c={'red'} fw={600}>
 | 
			
		||||
        {`* If you need data outside this time period, please select a date and click "Search" to update the latest data.`}
 | 
			
		||||
      </Text>
 | 
			
		||||
      <Box w={'100%'} display={'flex'} style={{ flexFlow: 'column' }}>
 | 
			
		||||
        <Box
 | 
			
		||||
          w={'100%'}
 | 
			
		||||
          display={'flex'}
 | 
			
		||||
          style={{
 | 
			
		||||
            alignItems: 'end',
 | 
			
		||||
            // justifyContent: 'space-between',
 | 
			
		||||
            flexWrap: 'wrap',
 | 
			
		||||
          }}
 | 
			
		||||
        >
 | 
			
		||||
          <DateInput
 | 
			
		||||
            size="xs"
 | 
			
		||||
            label="From date:"
 | 
			
		||||
            value={new Date(date.startDate)}
 | 
			
		||||
            w={'20%'}
 | 
			
		||||
            clearable
 | 
			
		||||
            onChange={(e) => {
 | 
			
		||||
              setDate({ ...date, startDate: moment(e).format('YYYY-MM-DD') });
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
          <DateInput
 | 
			
		||||
            size="xs"
 | 
			
		||||
            label="To date:"
 | 
			
		||||
            value={new Date(date.endDate)}
 | 
			
		||||
            clearable
 | 
			
		||||
            m={"0 10px"}
 | 
			
		||||
            w={'20%'}
 | 
			
		||||
            onChange={(e) => {
 | 
			
		||||
              setDate({ ...date, endDate: moment(e).format('YYYY-MM-DD') });
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
          <Button
 | 
			
		||||
            size="xs"
 | 
			
		||||
            onClick={() => {
 | 
			
		||||
              getAllWorklogs();
 | 
			
		||||
      <div className={classes.title}>
 | 
			
		||||
        <h3>
 | 
			
		||||
          <Text>Admin/</Text>Worklogs
 | 
			
		||||
          {!updating ? (
 | 
			
		||||
            <Text fs={'italic'} fz={'xs'} c={'gray'}>
 | 
			
		||||
              Updating data in the background ...
 | 
			
		||||
            </Text>
 | 
			
		||||
          ) : (
 | 
			
		||||
            ''
 | 
			
		||||
          )}
 | 
			
		||||
        </h3>
 | 
			
		||||
      </div>
 | 
			
		||||
      <Box
 | 
			
		||||
        display={'flex'}
 | 
			
		||||
        style={{
 | 
			
		||||
          flexFlow: 'column',
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        <Text fz={12} fs={'italic'} c={'red'} fw={600} mt={'md'}>
 | 
			
		||||
          {`* The current data is from ${
 | 
			
		||||
            JSON.parse(localStorage.getItem('data')!).date.startDate
 | 
			
		||||
          } to ${JSON.parse(localStorage.getItem('data')!).date.endDate}`}
 | 
			
		||||
        </Text>
 | 
			
		||||
        <Text fz={12} fs={'italic'} c={'red'} fw={600}>
 | 
			
		||||
          {`* If you need data outside this time period, please select a date and click "Search" to update the latest data.`}
 | 
			
		||||
        </Text>
 | 
			
		||||
        <Box w={'100%'} display={'flex'} style={{ flexFlow: 'column' }}>
 | 
			
		||||
          <Box
 | 
			
		||||
            w={'100%'}
 | 
			
		||||
            display={'flex'}
 | 
			
		||||
            style={{
 | 
			
		||||
              alignItems: 'end',
 | 
			
		||||
              // justifyContent: 'space-between',
 | 
			
		||||
              flexWrap: 'wrap',
 | 
			
		||||
            }}
 | 
			
		||||
          >
 | 
			
		||||
            Search
 | 
			
		||||
          </Button>
 | 
			
		||||
        </Box>
 | 
			
		||||
      </Box>
 | 
			
		||||
    </Box>
 | 
			
		||||
    {/* Box main content */}
 | 
			
		||||
    <Box display={'flex'} mt={'lg'} style={{ flexWrap: 'wrap' }}>
 | 
			
		||||
      <Box w={{ base: '100%', md: '15%' }} mb={'lg'}>
 | 
			
		||||
        <Text fw={700} fz={14}>
 | 
			
		||||
          Members
 | 
			
		||||
        </Text>
 | 
			
		||||
        <Box
 | 
			
		||||
          style={{
 | 
			
		||||
            border: 'solid 1px gray',
 | 
			
		||||
            padding: '10px 20px',
 | 
			
		||||
            marginRight: '10px',
 | 
			
		||||
            borderRadius: '5px',
 | 
			
		||||
            boxShadow: '1px 1px 5px 1px gray',
 | 
			
		||||
          }}
 | 
			
		||||
        >
 | 
			
		||||
          {worklogs.map((w) => (
 | 
			
		||||
            <Box
 | 
			
		||||
              key={w.username}
 | 
			
		||||
              style={{
 | 
			
		||||
                display: 'flex',
 | 
			
		||||
                alignItems: 'center',
 | 
			
		||||
                fontSize: '13px',
 | 
			
		||||
            <DateInput
 | 
			
		||||
              size="xs"
 | 
			
		||||
              label="From date:"
 | 
			
		||||
              value={new Date(date.startDate)}
 | 
			
		||||
              w={'20%'}
 | 
			
		||||
              clearable
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
                setDate({ ...date, startDate: moment(e).format('YYYY-MM-DD') })
 | 
			
		||||
              }}
 | 
			
		||||
            />
 | 
			
		||||
            <DateInput
 | 
			
		||||
              size="xs"
 | 
			
		||||
              label="To date:"
 | 
			
		||||
              value={new Date(date.endDate)}
 | 
			
		||||
              clearable
 | 
			
		||||
              m={'0 10px'}
 | 
			
		||||
              w={'20%'}
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
                setDate({ ...date, endDate: moment(e).format('YYYY-MM-DD') })
 | 
			
		||||
              }}
 | 
			
		||||
            />
 | 
			
		||||
            <Button
 | 
			
		||||
              size="xs"
 | 
			
		||||
              onClick={() => {
 | 
			
		||||
                getAllWorklogs()
 | 
			
		||||
              }}
 | 
			
		||||
              mb={'xs'}
 | 
			
		||||
              className={classes.menuUser}
 | 
			
		||||
            >
 | 
			
		||||
              <Avatar src={w.user.avatarUrls['16x16']} size={'xs'} mr={5} />
 | 
			
		||||
              <a
 | 
			
		||||
                className={classes.menuLink}
 | 
			
		||||
                href={'/worklogs#' + w.username}
 | 
			
		||||
                style={{ textDecoration: 'none' }}
 | 
			
		||||
              >
 | 
			
		||||
                {w.username}
 | 
			
		||||
              </a>
 | 
			
		||||
            </Box>
 | 
			
		||||
          ))}
 | 
			
		||||
              Search
 | 
			
		||||
            </Button>
 | 
			
		||||
          </Box>
 | 
			
		||||
        </Box>
 | 
			
		||||
      </Box>
 | 
			
		||||
      <Box
 | 
			
		||||
        w={{ base: '100%', md: '85%' }}
 | 
			
		||||
        h={'85vh'}
 | 
			
		||||
        display={'flex'}
 | 
			
		||||
        style={{ overflowX: 'auto', flexFlow: 'column' }}
 | 
			
		||||
      >
 | 
			
		||||
        {worklogs?.map((user, index) => (
 | 
			
		||||
          // Box user
 | 
			
		||||
      {/* Box main content */}
 | 
			
		||||
      <Box display={'flex'} mt={'lg'} style={{ flexWrap: 'wrap' }}>
 | 
			
		||||
        <Box w={{ base: '100%', md: '15%' }} mb={'lg'}>
 | 
			
		||||
          <Text fw={700} fz={14}>
 | 
			
		||||
            Members
 | 
			
		||||
          </Text>
 | 
			
		||||
          <Box
 | 
			
		||||
            id={user.username}
 | 
			
		||||
            key={index}
 | 
			
		||||
            p={'sm'}
 | 
			
		||||
            style={{
 | 
			
		||||
              border: 'solid 1px gray',
 | 
			
		||||
              padding: '10px 20px',
 | 
			
		||||
              marginRight: '10px',
 | 
			
		||||
              borderRadius: '5px',
 | 
			
		||||
              borderColor: '#afafaf',
 | 
			
		||||
              marginBottom: '10px',
 | 
			
		||||
              backgroundColor: index % 2 === 0 ? 'rgb(201 201 201 / 28%)' : 'white',
 | 
			
		||||
              boxShadow: '1px 1px 5px 1px gray',
 | 
			
		||||
            }}
 | 
			
		||||
          >
 | 
			
		||||
            <Text ta={'left'} mb={'xs'} fw={800} display={'flex'}>
 | 
			
		||||
              <Avatar src={user.user.avatarUrls['48x48']} size={'sm'} m={'0 5px'} />
 | 
			
		||||
              {user.username}(
 | 
			
		||||
              {user?.information.issues.reduce((total, issue) => {
 | 
			
		||||
                const totalSpent = issue.fields.worklog.worklogs?.reduce(
 | 
			
		||||
                  (accumulator, currentValue) => {
 | 
			
		||||
                    if (
 | 
			
		||||
                      parseInt(moment(date.startDate).format('YYYYMMDD')) <=
 | 
			
		||||
                        parseInt(moment(currentValue.started).format('YYYYMMDD')) &&
 | 
			
		||||
                      parseInt(moment(currentValue.started).format('YYYYMMDD')) <=
 | 
			
		||||
                        parseInt(moment(date.endDate).format('YYYYMMDD')) &&
 | 
			
		||||
                      currentValue.updateAuthor.displayName === user.username
 | 
			
		||||
                    ) {
 | 
			
		||||
                      return accumulator + currentValue.timeSpentSeconds;
 | 
			
		||||
                    }
 | 
			
		||||
                    return accumulator;
 | 
			
		||||
                  },
 | 
			
		||||
                  0,
 | 
			
		||||
                );
 | 
			
		||||
                return total + totalSpent;
 | 
			
		||||
              }, 0) /
 | 
			
		||||
                60 /
 | 
			
		||||
                60}
 | 
			
		||||
              h)
 | 
			
		||||
            </Text>
 | 
			
		||||
            {/* Box issue-todo */}
 | 
			
		||||
            <Box display={'flex'} style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
 | 
			
		||||
              {/* Box issue */}
 | 
			
		||||
            {worklogs.map((w) => (
 | 
			
		||||
              <Box
 | 
			
		||||
                w={{ base: '100%', md: '50%' }}
 | 
			
		||||
                key={w.username}
 | 
			
		||||
                style={{
 | 
			
		||||
                  border: 'solid 1px gray',
 | 
			
		||||
                  borderRadius: '5px',
 | 
			
		||||
                  padding: '10px',
 | 
			
		||||
                  marginBottom: '5px',
 | 
			
		||||
                  overflowX: 'hidden',
 | 
			
		||||
                  color: '#412d2d',
 | 
			
		||||
                  backgroundColor: '#d1cdce',
 | 
			
		||||
                  display: 'flex',
 | 
			
		||||
                  alignItems: 'center',
 | 
			
		||||
                  fontSize: '13px',
 | 
			
		||||
                }}
 | 
			
		||||
                mb={'xs'}
 | 
			
		||||
                className={classes.menuUser}
 | 
			
		||||
              >
 | 
			
		||||
                <Text fw={700} ta={'center'} mb={'5px'}>
 | 
			
		||||
                  WORKLOG
 | 
			
		||||
                </Text>
 | 
			
		||||
                {user.information.issues.map((iss) => {
 | 
			
		||||
                  if (
 | 
			
		||||
                    iss.fields.worklog.worklogs.filter(
 | 
			
		||||
                      (w) =>
 | 
			
		||||
                <Avatar src={w.user.avatarUrls['16x16']} size={'xs'} mr={5} />
 | 
			
		||||
                <a
 | 
			
		||||
                  className={classes.menuLink}
 | 
			
		||||
                  href={'/worklogs#' + w.username}
 | 
			
		||||
                  style={{ textDecoration: 'none' }}
 | 
			
		||||
                >
 | 
			
		||||
                  {w.username}
 | 
			
		||||
                </a>
 | 
			
		||||
              </Box>
 | 
			
		||||
            ))}
 | 
			
		||||
          </Box>
 | 
			
		||||
        </Box>
 | 
			
		||||
        <Box
 | 
			
		||||
          w={{ base: '100%', md: '85%' }}
 | 
			
		||||
          h={'85vh'}
 | 
			
		||||
          display={'flex'}
 | 
			
		||||
          style={{ overflowX: 'auto', flexFlow: 'column' }}
 | 
			
		||||
        >
 | 
			
		||||
          {worklogs?.map((user, index) => (
 | 
			
		||||
            // Box user
 | 
			
		||||
            <Box
 | 
			
		||||
              id={user.username}
 | 
			
		||||
              key={index}
 | 
			
		||||
              p={'sm'}
 | 
			
		||||
              style={{
 | 
			
		||||
                border: 'solid 1px gray',
 | 
			
		||||
                borderRadius: '5px',
 | 
			
		||||
                borderColor: '#afafaf',
 | 
			
		||||
                marginBottom: '10px',
 | 
			
		||||
                backgroundColor:
 | 
			
		||||
                  index % 2 === 0 ? 'rgb(201 201 201 / 28%)' : 'white',
 | 
			
		||||
              }}
 | 
			
		||||
            >
 | 
			
		||||
              <Text ta={'left'} mb={'xs'} fw={800} display={'flex'}>
 | 
			
		||||
                <Avatar
 | 
			
		||||
                  src={user.user.avatarUrls['48x48']}
 | 
			
		||||
                  size={'sm'}
 | 
			
		||||
                  m={'0 5px'}
 | 
			
		||||
                />
 | 
			
		||||
                {user.username}(
 | 
			
		||||
                {user?.information.issues.reduce((total, issue) => {
 | 
			
		||||
                  const totalSpent = issue.fields.worklog.worklogs?.reduce(
 | 
			
		||||
                    (accumulator, currentValue) => {
 | 
			
		||||
                      if (
 | 
			
		||||
                        parseInt(moment(date.startDate).format('YYYYMMDD')) <=
 | 
			
		||||
                          parseInt(moment(w.started).format('YYYYMMDD')) &&
 | 
			
		||||
                        parseInt(moment(date.endDate).format('YYYYMMDD')) >=
 | 
			
		||||
                          parseInt(moment(w.started).format('YYYYMMDD')) &&
 | 
			
		||||
                        w.updateAuthor.displayName === user.username,
 | 
			
		||||
                    ).length > 0
 | 
			
		||||
                  ) {
 | 
			
		||||
                          parseInt(
 | 
			
		||||
                            moment(currentValue.started).format('YYYYMMDD'),
 | 
			
		||||
                          ) &&
 | 
			
		||||
                        parseInt(
 | 
			
		||||
                          moment(currentValue.started).format('YYYYMMDD'),
 | 
			
		||||
                        ) <=
 | 
			
		||||
                          parseInt(moment(date.endDate).format('YYYYMMDD')) &&
 | 
			
		||||
                        currentValue.updateAuthor.displayName === user.username
 | 
			
		||||
                      ) {
 | 
			
		||||
                        return accumulator + currentValue.timeSpentSeconds
 | 
			
		||||
                      }
 | 
			
		||||
                      return accumulator
 | 
			
		||||
                    },
 | 
			
		||||
                    0,
 | 
			
		||||
                  )
 | 
			
		||||
                  return total + totalSpent
 | 
			
		||||
                }, 0) /
 | 
			
		||||
                  60 /
 | 
			
		||||
                  60}
 | 
			
		||||
                h)
 | 
			
		||||
              </Text>
 | 
			
		||||
              {/* Box issue-todo */}
 | 
			
		||||
              <Box
 | 
			
		||||
                display={'flex'}
 | 
			
		||||
                style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}
 | 
			
		||||
              >
 | 
			
		||||
                {/* Box issue */}
 | 
			
		||||
                <Box
 | 
			
		||||
                  w={{ base: '100%', md: '50%' }}
 | 
			
		||||
                  style={{
 | 
			
		||||
                    border: 'solid 1px gray',
 | 
			
		||||
                    borderRadius: '5px',
 | 
			
		||||
                    padding: '10px',
 | 
			
		||||
                    marginBottom: '5px',
 | 
			
		||||
                    overflowX: 'hidden',
 | 
			
		||||
                    color: '#412d2d',
 | 
			
		||||
                    backgroundColor: '#d1cdce',
 | 
			
		||||
                  }}
 | 
			
		||||
                >
 | 
			
		||||
                  <Text fw={700} ta={'center'} mb={'5px'}>
 | 
			
		||||
                    WORKLOG
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  {user.information.issues.map((iss) => {
 | 
			
		||||
                    if (
 | 
			
		||||
                      iss.fields.worklog.worklogs.filter(
 | 
			
		||||
                        (w) =>
 | 
			
		||||
                          parseInt(moment(date.startDate).format('YYYYMMDD')) <=
 | 
			
		||||
                            parseInt(moment(w.started).format('YYYYMMDD')) &&
 | 
			
		||||
                          parseInt(moment(date.endDate).format('YYYYMMDD')) >=
 | 
			
		||||
                            parseInt(moment(w.started).format('YYYYMMDD')) &&
 | 
			
		||||
                          w.updateAuthor.displayName === user.username,
 | 
			
		||||
                      ).length > 0
 | 
			
		||||
                    ) {
 | 
			
		||||
                      return (
 | 
			
		||||
                        <Box
 | 
			
		||||
                          key={iss.id}
 | 
			
		||||
                          style={{
 | 
			
		||||
                            border: 'solid 1px gray',
 | 
			
		||||
                            borderRadius: '5px',
 | 
			
		||||
                            boxShadow: '1px 1px 5px 1px gray',
 | 
			
		||||
                            padding: '10px',
 | 
			
		||||
                            marginBottom: '8px',
 | 
			
		||||
                            maxHeight: '90vh',
 | 
			
		||||
                            overflowX: 'hidden',
 | 
			
		||||
                            color: '#412d2d',
 | 
			
		||||
                            backgroundColor: 'white',
 | 
			
		||||
                          }}
 | 
			
		||||
                        >
 | 
			
		||||
                          {/* Box information issue */}
 | 
			
		||||
                          <Box>
 | 
			
		||||
                            <Text
 | 
			
		||||
                              fz={14}
 | 
			
		||||
                              c={iss.fields.status.statusCategory.colorName}
 | 
			
		||||
                            >
 | 
			
		||||
                              <b>{iss.fields.status.name}</b>
 | 
			
		||||
                            </Text>
 | 
			
		||||
                            <Badge color="#6140c0e0">
 | 
			
		||||
                              <Box
 | 
			
		||||
                                display={'flex'}
 | 
			
		||||
                                style={{ alignItems: 'center' }}
 | 
			
		||||
                              >
 | 
			
		||||
                                <Avatar
 | 
			
		||||
                                  src={iss.fields.project?.avatarUrls['16x16']}
 | 
			
		||||
                                  size={'xs'}
 | 
			
		||||
                                  m={'0 5px 0 0'}
 | 
			
		||||
                                />
 | 
			
		||||
                                {iss.fields.project.name}
 | 
			
		||||
                              </Box>
 | 
			
		||||
                            </Badge>
 | 
			
		||||
                            <Text
 | 
			
		||||
                              fz={14}
 | 
			
		||||
                              display={'flex'}
 | 
			
		||||
                              style={{ alignItems: 'start' }}
 | 
			
		||||
                            >
 | 
			
		||||
                              <b>Summary:</b>{' '}
 | 
			
		||||
                              <Tooltip label={iss.fields.summary}>
 | 
			
		||||
                                <Badge color="#228be64f" fz={12}>
 | 
			
		||||
                                  <a
 | 
			
		||||
                                    href={`https://apactechvn.atlassian.net/browse/${iss.key}`}
 | 
			
		||||
                                    target="_blank"
 | 
			
		||||
                                    style={{textDecoration:"none"}}
 | 
			
		||||
                                  >
 | 
			
		||||
                                    [{iss.key}]{` ${iss.fields.summary}`}
 | 
			
		||||
                                  </a>
 | 
			
		||||
                                </Badge>
 | 
			
		||||
                              </Tooltip>
 | 
			
		||||
                            </Text>
 | 
			
		||||
                            <Text fz={14}>
 | 
			
		||||
                              <b>Estimate:</b>{' '}
 | 
			
		||||
                              <Badge color='red' size='sm'>{iss.fields.timeoriginalestimate / 60 / 60}h</Badge>
 | 
			
		||||
                            </Text>
 | 
			
		||||
                            <Text fz={14}>
 | 
			
		||||
                              <b>Total time spent:</b>{' '}
 | 
			
		||||
                              <Badge color='orange' size='sm'>{iss.fields.timespent / 60 / 60}h</Badge>
 | 
			
		||||
                            </Text>
 | 
			
		||||
                            <Text fz={14}>
 | 
			
		||||
                              <b>
 | 
			
		||||
                                Time spent{' '}
 | 
			
		||||
                                <span style={{ fontSize: '11px' }}>
 | 
			
		||||
                                  (
 | 
			
		||||
                                  {date.startDate === date.endDate
 | 
			
		||||
                                    ? date.startDate
 | 
			
		||||
                                    : date.startDate + ' to ' + date.endDate}
 | 
			
		||||
                                  )
 | 
			
		||||
                                </span>
 | 
			
		||||
                                :
 | 
			
		||||
                              </b>{' '}<Badge color='green' size='sm' mb={'xs'}>
 | 
			
		||||
                              {iss.fields.worklog.worklogs?.reduce(
 | 
			
		||||
                                (accumulator, currentValue) => {
 | 
			
		||||
                                  if (
 | 
			
		||||
                                    parseInt(
 | 
			
		||||
                                      moment(date.startDate).format('YYYYMMDD'),
 | 
			
		||||
                                    ) <=
 | 
			
		||||
                                      parseInt(
 | 
			
		||||
                                        moment(currentValue.started).format(
 | 
			
		||||
                                          'YYYYMMDD',
 | 
			
		||||
                                        ),
 | 
			
		||||
                                      ) &&
 | 
			
		||||
                                    parseInt(
 | 
			
		||||
                                      moment(currentValue.started).format(
 | 
			
		||||
                                        'YYYYMMDD',
 | 
			
		||||
                                      ),
 | 
			
		||||
                                    ) <=
 | 
			
		||||
                                      parseInt(
 | 
			
		||||
                                        moment(date.endDate).format('YYYYMMDD'),
 | 
			
		||||
                                      ) &&
 | 
			
		||||
                                    currentValue.updateAuthor.displayName ===
 | 
			
		||||
                                      user.username
 | 
			
		||||
                                  ) {
 | 
			
		||||
                                    return (
 | 
			
		||||
                                      accumulator +
 | 
			
		||||
                                      currentValue.timeSpentSeconds
 | 
			
		||||
                                    )
 | 
			
		||||
                                  }
 | 
			
		||||
                                  return accumulator
 | 
			
		||||
                                },
 | 
			
		||||
                                0,
 | 
			
		||||
                              ) /
 | 
			
		||||
                                60 /
 | 
			
		||||
                                60}
 | 
			
		||||
                              h</Badge>
 | 
			
		||||
                            </Text>
 | 
			
		||||
                          </Box>
 | 
			
		||||
                          {iss.fields.worklog.worklogs?.map((log, index) => {
 | 
			
		||||
                            if (
 | 
			
		||||
                              moment(date.startDate).format('YYYYMMDD') <=
 | 
			
		||||
                                moment(log.started).format('YYYYMMDD') &&
 | 
			
		||||
                              moment(log.started).format('YYYYMMDD') <=
 | 
			
		||||
                                moment(date.endDate).format('YYYYMMDD') &&
 | 
			
		||||
                              log.updateAuthor.displayName === user.username
 | 
			
		||||
                            ) {
 | 
			
		||||
                              return (
 | 
			
		||||
                                // Box worklog
 | 
			
		||||
                                <Box
 | 
			
		||||
                                  key={index}
 | 
			
		||||
                                  style={{
 | 
			
		||||
                                    padding: '4px 8px',
 | 
			
		||||
                                    marginBottom: '5px',
 | 
			
		||||
                                    marginLeft: '10px',
 | 
			
		||||
                                    backgroundColor: '#d9d9d9',
 | 
			
		||||
                                  }}
 | 
			
		||||
                                >
 | 
			
		||||
                                  <Text fz={13}>
 | 
			
		||||
                                    <b>Start date:</b>{' '}
 | 
			
		||||
                                    {moment(log.started).format(
 | 
			
		||||
                                      'HH:mm YYYY/MM/DD',
 | 
			
		||||
                                    )}
 | 
			
		||||
                                  </Text>
 | 
			
		||||
                                  <Text fz={13}>
 | 
			
		||||
                                    <b>Time spent:</b> {log.timeSpent}
 | 
			
		||||
                                  </Text>
 | 
			
		||||
                                  {log?.comment &&
 | 
			
		||||
                                    log?.comment?.content[0]?.content[0]
 | 
			
		||||
                                      ?.text && (
 | 
			
		||||
                                      <Text fz={13}>
 | 
			
		||||
                                        <b>Comment:</b>{' '}
 | 
			
		||||
                                        {
 | 
			
		||||
                                          log?.comment?.content[0]?.content[0]
 | 
			
		||||
                                            ?.text
 | 
			
		||||
                                        }
 | 
			
		||||
                                      </Text>
 | 
			
		||||
                                    )}
 | 
			
		||||
                                </Box>
 | 
			
		||||
                              )
 | 
			
		||||
                            }
 | 
			
		||||
                          })}
 | 
			
		||||
                        </Box>
 | 
			
		||||
                      )
 | 
			
		||||
                    }
 | 
			
		||||
                  })}
 | 
			
		||||
                </Box>
 | 
			
		||||
                {/* Box todo */}
 | 
			
		||||
                <Box
 | 
			
		||||
                  w={{ base: '100%', md: '49%' }}
 | 
			
		||||
                  style={{
 | 
			
		||||
                    border: 'solid 1px gray',
 | 
			
		||||
                    borderRadius: '5px',
 | 
			
		||||
                    padding: '10px',
 | 
			
		||||
                    marginBottom: '5px',
 | 
			
		||||
                    overflowX: 'hidden',
 | 
			
		||||
                    color: '#412d2d',
 | 
			
		||||
                    backgroundColor: '#f9ffa47a',
 | 
			
		||||
                  }}
 | 
			
		||||
                >
 | 
			
		||||
                  <Text fw={700} ta={'center'} mb={'5px'}>
 | 
			
		||||
                    ASSIGNMENT
 | 
			
		||||
                  </Text>
 | 
			
		||||
                  {user.tasksAssign.issues?.map((iss, index) => {
 | 
			
		||||
                    return (
 | 
			
		||||
                      <Box
 | 
			
		||||
                        key={iss.id}
 | 
			
		||||
                        key={index}
 | 
			
		||||
                        style={{
 | 
			
		||||
                          border: 'solid 1px gray',
 | 
			
		||||
                          borderRadius: '5px',
 | 
			
		||||
                          boxShadow: '1px 1px 5px 1px gray',
 | 
			
		||||
                          padding: '10px',
 | 
			
		||||
                          marginBottom: '8px',
 | 
			
		||||
                          maxHeight: '90vh',
 | 
			
		||||
                          marginBottom: '5px',
 | 
			
		||||
                          overflowX: 'hidden',
 | 
			
		||||
                          color: '#412d2d',
 | 
			
		||||
                          backgroundColor: 'white',
 | 
			
		||||
                        }}
 | 
			
		||||
                      >
 | 
			
		||||
                        {/* Box information issue */}
 | 
			
		||||
                        <Box>
 | 
			
		||||
                          <Text fz={14} c={iss.fields.status.statusCategory.colorName}>
 | 
			
		||||
                            <b>{iss.fields.status.name}</b>
 | 
			
		||||
                          </Text>
 | 
			
		||||
                          <Text fz={14} display={'flex'} style={{ alignItems: 'start' }}>
 | 
			
		||||
                            <b>Summary:</b>{' '}
 | 
			
		||||
                            <Box display={'flex'} style={{ alignItems: 'center' }}>
 | 
			
		||||
                              <Avatar
 | 
			
		||||
                                src={iss.fields.project?.avatarUrls['16x16']}
 | 
			
		||||
                                size={'xs'}
 | 
			
		||||
                                m={'0 5px'}
 | 
			
		||||
                              />
 | 
			
		||||
                              <Text fz={14} mr={'xs'}>
 | 
			
		||||
                                {iss.fields.project.name}
 | 
			
		||||
                              </Text>
 | 
			
		||||
                            </Box>
 | 
			
		||||
                            <a href={`https://apactechvn.atlassian.net/browse/${iss.key}`} target="_blank">
 | 
			
		||||
                              {iss.fields.summary}
 | 
			
		||||
                            </a>
 | 
			
		||||
                          </Text>
 | 
			
		||||
                          <Text fz={14}>
 | 
			
		||||
                            <b>Estimate:</b> {iss.fields.timeoriginalestimate / 60 / 60}h
 | 
			
		||||
                          </Text>
 | 
			
		||||
                          <Text fz={14}>
 | 
			
		||||
                            <b>Total time spent:</b> {iss.fields.timespent / 60 / 60}h
 | 
			
		||||
                          </Text>
 | 
			
		||||
                          <Text fz={14}>
 | 
			
		||||
                            <b>
 | 
			
		||||
                              Time spent{' '}
 | 
			
		||||
                              <span style={{ fontSize: '11px' }}>
 | 
			
		||||
                                (
 | 
			
		||||
                                {date.startDate === date.endDate
 | 
			
		||||
                                  ? date.startDate
 | 
			
		||||
                                  : date.startDate + ' to ' + date.endDate}
 | 
			
		||||
                                )
 | 
			
		||||
                              </span>
 | 
			
		||||
                              :
 | 
			
		||||
                            </b>{' '}
 | 
			
		||||
                            {iss.fields.worklog.worklogs?.reduce(
 | 
			
		||||
                              (accumulator, currentValue) => {
 | 
			
		||||
                                if (
 | 
			
		||||
                                  parseInt(moment(date.startDate).format('YYYYMMDD')) <=
 | 
			
		||||
                                    parseInt(moment(currentValue.started).format('YYYYMMDD')) &&
 | 
			
		||||
                                  parseInt(moment(currentValue.started).format('YYYYMMDD')) <=
 | 
			
		||||
                                    parseInt(moment(date.endDate).format('YYYYMMDD')) &&
 | 
			
		||||
                                  currentValue.updateAuthor.displayName === user.username
 | 
			
		||||
                                ) {
 | 
			
		||||
                                  return accumulator + currentValue.timeSpentSeconds;
 | 
			
		||||
                                }
 | 
			
		||||
                                return accumulator;
 | 
			
		||||
                              },
 | 
			
		||||
                              0,
 | 
			
		||||
                            ) /
 | 
			
		||||
                              60 /
 | 
			
		||||
                              60}
 | 
			
		||||
                            h
 | 
			
		||||
                          </Text>
 | 
			
		||||
                        </Box>
 | 
			
		||||
                        {iss.fields.worklog.worklogs?.map((log, index) => {
 | 
			
		||||
                          if (
 | 
			
		||||
                            moment(date.startDate).format('YYYYMMDD') <= moment(log.started).format('YYYYMMDD') &&
 | 
			
		||||
                            moment(log.started).format('YYYYMMDD') <= moment(date.endDate).format('YYYYMMDD') &&
 | 
			
		||||
                            log.updateAuthor.displayName === user.username
 | 
			
		||||
                          ) {
 | 
			
		||||
                            return (
 | 
			
		||||
                              // Box worklog
 | 
			
		||||
                              <Box
 | 
			
		||||
                                key={index}
 | 
			
		||||
                                style={{
 | 
			
		||||
                                  padding: '4px 8px',
 | 
			
		||||
                                  marginBottom: '5px',
 | 
			
		||||
                                  marginLeft: '10px',
 | 
			
		||||
                                  backgroundColor: '#d9d9d9',
 | 
			
		||||
                                }}
 | 
			
		||||
                        <Text
 | 
			
		||||
                          fz={14}
 | 
			
		||||
                          c={iss.fields.status.statusCategory.colorName}
 | 
			
		||||
                        >
 | 
			
		||||
                          <b>{iss.fields.status.name}</b>
 | 
			
		||||
                        </Text>
 | 
			
		||||
                        <Badge color="#6140c0e0">
 | 
			
		||||
                          <Box
 | 
			
		||||
                            display={'flex'}
 | 
			
		||||
                            style={{ alignItems: 'center' }}
 | 
			
		||||
                          >
 | 
			
		||||
                            <Avatar
 | 
			
		||||
                              src={iss.fields.project?.avatarUrls['16x16']}
 | 
			
		||||
                              size={'xs'}
 | 
			
		||||
                              m={'0 5px 0 0'}
 | 
			
		||||
                            />
 | 
			
		||||
                            {iss.fields.project.name}
 | 
			
		||||
                          </Box>
 | 
			
		||||
                        </Badge>
 | 
			
		||||
                        <Text
 | 
			
		||||
                          fz={14}
 | 
			
		||||
                          display={'flex'}
 | 
			
		||||
                          style={{ alignItems: 'start' }}
 | 
			
		||||
                        >
 | 
			
		||||
                          <b>Summary:</b>{' '}
 | 
			
		||||
                          <Tooltip label={iss.fields.summary}>
 | 
			
		||||
                            <Badge color="#228be64f" fz={12}>
 | 
			
		||||
                              <a
 | 
			
		||||
                                href={`https://apactechvn.atlassian.net/browse/${iss.key}`}
 | 
			
		||||
                                target="_blank"
 | 
			
		||||
                                style={{textDecoration:"none"}}
 | 
			
		||||
                              >
 | 
			
		||||
                                <Text fz={13}>
 | 
			
		||||
                                  <b>Start date:</b> {moment(log.started).format('HH:mm YYYY/MM/DD')}
 | 
			
		||||
                                </Text>
 | 
			
		||||
                                <Text fz={13}>
 | 
			
		||||
                                  <b>Time spent:</b> {log.timeSpent}
 | 
			
		||||
                                </Text>
 | 
			
		||||
                                {log?.comment && log?.comment?.content[0]?.content[0]?.text && (
 | 
			
		||||
                                  <Text fz={13}>
 | 
			
		||||
                                    <b>Comment:</b> {log?.comment?.content[0]?.content[0]?.text}
 | 
			
		||||
                                  </Text>
 | 
			
		||||
                                )}
 | 
			
		||||
                              </Box>
 | 
			
		||||
                            );
 | 
			
		||||
                          }
 | 
			
		||||
                        })}
 | 
			
		||||
                      </Box>
 | 
			
		||||
                    );
 | 
			
		||||
                  }
 | 
			
		||||
                })}
 | 
			
		||||
              </Box>
 | 
			
		||||
              {/* Box todo */}
 | 
			
		||||
              <Box
 | 
			
		||||
                w={{ base: '100%', md: '49%' }}
 | 
			
		||||
                style={{
 | 
			
		||||
                  border: 'solid 1px gray',
 | 
			
		||||
                  borderRadius: '5px',
 | 
			
		||||
                  padding: '10px',
 | 
			
		||||
                  marginBottom: '5px',
 | 
			
		||||
                  overflowX: 'hidden',
 | 
			
		||||
                  color: '#412d2d',
 | 
			
		||||
                  backgroundColor: '#f9ffa47a',
 | 
			
		||||
                }}
 | 
			
		||||
              >
 | 
			
		||||
                <Text fw={700} ta={'center'} mb={'5px'}>
 | 
			
		||||
                  ASSIGNMENT
 | 
			
		||||
                </Text>
 | 
			
		||||
                {user.tasksAssign.issues?.map((iss, index) => {
 | 
			
		||||
                  return (
 | 
			
		||||
                    <Box
 | 
			
		||||
                      key={index}
 | 
			
		||||
                      style={{
 | 
			
		||||
                        border: 'solid 1px gray',
 | 
			
		||||
                        borderRadius: '5px',
 | 
			
		||||
                        boxShadow: '1px 1px 5px 1px gray',
 | 
			
		||||
                        padding: '10px',
 | 
			
		||||
                        marginBottom: '5px',
 | 
			
		||||
                        overflowX: 'hidden',
 | 
			
		||||
                        color: '#412d2d',
 | 
			
		||||
                        backgroundColor: 'white',
 | 
			
		||||
                      }}
 | 
			
		||||
                    >
 | 
			
		||||
                      <Box display={'flex'} style={{ alignItems: 'center' }}>
 | 
			
		||||
                        <Avatar
 | 
			
		||||
                          src={iss.fields.project?.avatarUrls['16x16']}
 | 
			
		||||
                          size={'xs'}
 | 
			
		||||
                          m={'0 5px 0 0'}
 | 
			
		||||
                        />
 | 
			
		||||
                        <Text fz={14} mr={'xs'}>
 | 
			
		||||
                          {iss.fields.project.name}
 | 
			
		||||
                                [{iss.key}]{` ${iss.fields.summary}`}
 | 
			
		||||
                              </a>
 | 
			
		||||
                            </Badge>
 | 
			
		||||
                          </Tooltip>
 | 
			
		||||
                        </Text>
 | 
			
		||||
                        <Text fz={13}>
 | 
			
		||||
                          <b>Time spent:</b> <Badge color='orange' size='sm'>{iss.fields.timespent / 60 / 60}h</Badge>
 | 
			
		||||
                        </Text>
 | 
			
		||||
                        <Text fz={13}>
 | 
			
		||||
                          <b>Estimate:</b>{' '}
 | 
			
		||||
                          <Badge color='red' size='sm'>{iss.fields.timeoriginalestimate / 60 / 60}h</Badge>
 | 
			
		||||
                        </Text>
 | 
			
		||||
                      </Box>
 | 
			
		||||
                      <Text fz={14} display={'flex'} style={{ alignItems: 'start' }}>
 | 
			
		||||
                        <b style={{ marginRight: '5px' }}>Summary:</b>
 | 
			
		||||
                        <a href={`https://apactechvn.atlassian.net/browse/${iss.key}`} target="_blank">
 | 
			
		||||
                          {iss.fields.summary}
 | 
			
		||||
                        </a>
 | 
			
		||||
                      </Text>
 | 
			
		||||
                      <Text fz={13}>
 | 
			
		||||
                        <b>Time spent:</b> {iss.fields.timespent / 60 / 60}h
 | 
			
		||||
                      </Text>
 | 
			
		||||
                      <Text fz={13}>
 | 
			
		||||
                        <b>Estimate:</b> {iss.fields.timeoriginalestimate / 60 / 60}h
 | 
			
		||||
                      </Text>
 | 
			
		||||
                      <Text fz={14} c={iss.fields.status.statusCategory.colorName}>
 | 
			
		||||
                        <b>{iss.fields.status.name}</b>
 | 
			
		||||
                      </Text>
 | 
			
		||||
                    </Box>
 | 
			
		||||
                  );
 | 
			
		||||
                })}
 | 
			
		||||
                    )
 | 
			
		||||
                  })}
 | 
			
		||||
                </Box>
 | 
			
		||||
              </Box>
 | 
			
		||||
            </Box>
 | 
			
		||||
          </Box>
 | 
			
		||||
        ))}
 | 
			
		||||
          ))}
 | 
			
		||||
        </Box>
 | 
			
		||||
      </Box>
 | 
			
		||||
    </Box>
 | 
			
		||||
  </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue