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()
 | 
					    public function __construct()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->table = 'admin';
 | 
					        $this->table = 'users';
 | 
				
			||||||
        $this->guarded = [];
 | 
					        $this->guarded = [];
 | 
				
			||||||
        $this->hidden = [
 | 
					        $this->hidden = [
 | 
				
			||||||
            'password',
 | 
					            '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\Migrations\Migration;
 | 
				
			||||||
use Illuminate\Database\Schema\Blueprint;
 | 
					use Illuminate\Database\Schema\Blueprint;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\DB;
 | 
				
			||||||
use Illuminate\Support\Facades\Schema;
 | 
					use Illuminate\Support\Facades\Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return new class extends Migration
 | 
					return new class extends Migration
 | 
				
			||||||
| 
						 | 
					@ -16,10 +17,86 @@ return new class extends Migration
 | 
				
			||||||
            $table->string('name');
 | 
					            $table->string('name');
 | 
				
			||||||
            $table->string('email')->unique();
 | 
					            $table->string('email')->unique();
 | 
				
			||||||
            $table->timestamp('email_verified_at')->nullable();
 | 
					            $table->timestamp('email_verified_at')->nullable();
 | 
				
			||||||
 | 
					            $table->string('forgot_code')->nullable();
 | 
				
			||||||
            $table->string('password');
 | 
					            $table->string('password');
 | 
				
			||||||
 | 
					            $table->string('permission')->default('staff');
 | 
				
			||||||
            $table->rememberToken();
 | 
					            $table->rememberToken();
 | 
				
			||||||
            $table->timestamps();
 | 
					            $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 { getAllUserWorklogs } from '@/api/Admin'
 | 
				
			||||||
import { get } from '@/rtk/helpers/apiService'
 | 
					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 { DateInput } from '@mantine/dates'
 | 
				
			||||||
import moment from 'moment'
 | 
					import moment from 'moment'
 | 
				
			||||||
import { useEffect, useState } from 'react'
 | 
					import { useEffect, useState } from 'react'
 | 
				
			||||||
| 
						 | 
					@ -117,7 +125,7 @@ const Worklogs = () => {
 | 
				
			||||||
    startDate:
 | 
					    startDate:
 | 
				
			||||||
      localStorage.getItem('data') !== null
 | 
					      localStorage.getItem('data') !== null
 | 
				
			||||||
        ? JSON.parse(localStorage.getItem('data')!).date.startDate
 | 
					        ? JSON.parse(localStorage.getItem('data')!).date.startDate
 | 
				
			||||||
        : moment(Date.now()-604800000).format('YYYY-MM-DD'),
 | 
					        : moment(Date.now() - 604800000).format('YYYY-MM-DD'),
 | 
				
			||||||
    endDate:
 | 
					    endDate:
 | 
				
			||||||
      localStorage.getItem('data') !== null
 | 
					      localStorage.getItem('data') !== null
 | 
				
			||||||
        ? JSON.parse(localStorage.getItem('data')!).date.endDate
 | 
					        ? JSON.parse(localStorage.getItem('data')!).date.endDate
 | 
				
			||||||
| 
						 | 
					@ -172,361 +180,441 @@ const Worklogs = () => {
 | 
				
			||||||
    </Box>
 | 
					    </Box>
 | 
				
			||||||
  ) : (
 | 
					  ) : (
 | 
				
			||||||
    <div style={{ display: 'flex', flexFlow: 'column' }}>
 | 
					    <div style={{ display: 'flex', flexFlow: 'column' }}>
 | 
				
			||||||
    <div className={classes.title}>
 | 
					      <div className={classes.title}>
 | 
				
			||||||
      <h3>
 | 
					        <h3>
 | 
				
			||||||
        <Text>Admin/</Text>Worklogs
 | 
					          <Text>Admin/</Text>Worklogs
 | 
				
			||||||
        {!updating ? (
 | 
					          {!updating ? (
 | 
				
			||||||
          <Text fs={'italic'} fz={'xs'} c={'gray'}>
 | 
					            <Text fs={'italic'} fz={'xs'} c={'gray'}>
 | 
				
			||||||
            Updating data in the background ...
 | 
					              Updating data in the background ...
 | 
				
			||||||
          </Text>
 | 
					            </Text>
 | 
				
			||||||
        ) : (
 | 
					          ) : (
 | 
				
			||||||
          ''
 | 
					            ''
 | 
				
			||||||
        )}
 | 
					          )}
 | 
				
			||||||
      </h3>
 | 
					        </h3>
 | 
				
			||||||
    </div>
 | 
					      </div>
 | 
				
			||||||
    <Box
 | 
					      <Box
 | 
				
			||||||
      display={'flex'}
 | 
					        display={'flex'}
 | 
				
			||||||
      style={{
 | 
					        style={{
 | 
				
			||||||
        flexFlow: 'column',
 | 
					          flexFlow: 'column',
 | 
				
			||||||
      }}
 | 
					        }}
 | 
				
			||||||
    >
 | 
					      >
 | 
				
			||||||
      <Text fz={12} fs={'italic'} c={'red'} fw={600} mt={'md'}>
 | 
					        <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}`}
 | 
					          {`* The current data is from ${
 | 
				
			||||||
      </Text>
 | 
					            JSON.parse(localStorage.getItem('data')!).date.startDate
 | 
				
			||||||
      <Text fz={12} fs={'italic'} c={'red'} fw={600}>
 | 
					          } to ${JSON.parse(localStorage.getItem('data')!).date.endDate}`}
 | 
				
			||||||
        {`* If you need data outside this time period, please select a date and click "Search" to update the latest data.`}
 | 
					        </Text>
 | 
				
			||||||
      </Text>
 | 
					        <Text fz={12} fs={'italic'} c={'red'} fw={600}>
 | 
				
			||||||
      <Box w={'100%'} display={'flex'} style={{ flexFlow: 'column' }}>
 | 
					          {`* If you need data outside this time period, please select a date and click "Search" to update the latest data.`}
 | 
				
			||||||
        <Box
 | 
					        </Text>
 | 
				
			||||||
          w={'100%'}
 | 
					        <Box w={'100%'} display={'flex'} style={{ flexFlow: 'column' }}>
 | 
				
			||||||
          display={'flex'}
 | 
					          <Box
 | 
				
			||||||
          style={{
 | 
					            w={'100%'}
 | 
				
			||||||
            alignItems: 'end',
 | 
					            display={'flex'}
 | 
				
			||||||
            // justifyContent: 'space-between',
 | 
					            style={{
 | 
				
			||||||
            flexWrap: 'wrap',
 | 
					              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();
 | 
					 | 
				
			||||||
            }}
 | 
					            }}
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            Search
 | 
					            <DateInput
 | 
				
			||||||
          </Button>
 | 
					              size="xs"
 | 
				
			||||||
        </Box>
 | 
					              label="From date:"
 | 
				
			||||||
      </Box>
 | 
					              value={new Date(date.startDate)}
 | 
				
			||||||
    </Box>
 | 
					              w={'20%'}
 | 
				
			||||||
    {/* Box main content */}
 | 
					              clearable
 | 
				
			||||||
    <Box display={'flex'} mt={'lg'} style={{ flexWrap: 'wrap' }}>
 | 
					              onChange={(e) => {
 | 
				
			||||||
      <Box w={{ base: '100%', md: '15%' }} mb={'lg'}>
 | 
					                setDate({ ...date, startDate: moment(e).format('YYYY-MM-DD') })
 | 
				
			||||||
        <Text fw={700} fz={14}>
 | 
					              }}
 | 
				
			||||||
          Members
 | 
					            />
 | 
				
			||||||
        </Text>
 | 
					            <DateInput
 | 
				
			||||||
        <Box
 | 
					              size="xs"
 | 
				
			||||||
          style={{
 | 
					              label="To date:"
 | 
				
			||||||
            border: 'solid 1px gray',
 | 
					              value={new Date(date.endDate)}
 | 
				
			||||||
            padding: '10px 20px',
 | 
					              clearable
 | 
				
			||||||
            marginRight: '10px',
 | 
					              m={'0 10px'}
 | 
				
			||||||
            borderRadius: '5px',
 | 
					              w={'20%'}
 | 
				
			||||||
            boxShadow: '1px 1px 5px 1px gray',
 | 
					              onChange={(e) => {
 | 
				
			||||||
          }}
 | 
					                setDate({ ...date, endDate: moment(e).format('YYYY-MM-DD') })
 | 
				
			||||||
        >
 | 
					              }}
 | 
				
			||||||
          {worklogs.map((w) => (
 | 
					            />
 | 
				
			||||||
            <Box
 | 
					            <Button
 | 
				
			||||||
              key={w.username}
 | 
					              size="xs"
 | 
				
			||||||
              style={{
 | 
					              onClick={() => {
 | 
				
			||||||
                display: 'flex',
 | 
					                getAllWorklogs()
 | 
				
			||||||
                alignItems: 'center',
 | 
					 | 
				
			||||||
                fontSize: '13px',
 | 
					 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
              mb={'xs'}
 | 
					 | 
				
			||||||
              className={classes.menuUser}
 | 
					 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
              <Avatar src={w.user.avatarUrls['16x16']} size={'xs'} mr={5} />
 | 
					              Search
 | 
				
			||||||
              <a
 | 
					            </Button>
 | 
				
			||||||
                className={classes.menuLink}
 | 
					          </Box>
 | 
				
			||||||
                href={'/worklogs#' + w.username}
 | 
					 | 
				
			||||||
                style={{ textDecoration: 'none' }}
 | 
					 | 
				
			||||||
              >
 | 
					 | 
				
			||||||
                {w.username}
 | 
					 | 
				
			||||||
              </a>
 | 
					 | 
				
			||||||
            </Box>
 | 
					 | 
				
			||||||
          ))}
 | 
					 | 
				
			||||||
        </Box>
 | 
					        </Box>
 | 
				
			||||||
      </Box>
 | 
					      </Box>
 | 
				
			||||||
      <Box
 | 
					      {/* Box main content */}
 | 
				
			||||||
        w={{ base: '100%', md: '85%' }}
 | 
					      <Box display={'flex'} mt={'lg'} style={{ flexWrap: 'wrap' }}>
 | 
				
			||||||
        h={'85vh'}
 | 
					        <Box w={{ base: '100%', md: '15%' }} mb={'lg'}>
 | 
				
			||||||
        display={'flex'}
 | 
					          <Text fw={700} fz={14}>
 | 
				
			||||||
        style={{ overflowX: 'auto', flexFlow: 'column' }}
 | 
					            Members
 | 
				
			||||||
      >
 | 
					          </Text>
 | 
				
			||||||
        {worklogs?.map((user, index) => (
 | 
					 | 
				
			||||||
          // Box user
 | 
					 | 
				
			||||||
          <Box
 | 
					          <Box
 | 
				
			||||||
            id={user.username}
 | 
					 | 
				
			||||||
            key={index}
 | 
					 | 
				
			||||||
            p={'sm'}
 | 
					 | 
				
			||||||
            style={{
 | 
					            style={{
 | 
				
			||||||
              border: 'solid 1px gray',
 | 
					              border: 'solid 1px gray',
 | 
				
			||||||
 | 
					              padding: '10px 20px',
 | 
				
			||||||
 | 
					              marginRight: '10px',
 | 
				
			||||||
              borderRadius: '5px',
 | 
					              borderRadius: '5px',
 | 
				
			||||||
              borderColor: '#afafaf',
 | 
					              boxShadow: '1px 1px 5px 1px gray',
 | 
				
			||||||
              marginBottom: '10px',
 | 
					 | 
				
			||||||
              backgroundColor: index % 2 === 0 ? 'rgb(201 201 201 / 28%)' : 'white',
 | 
					 | 
				
			||||||
            }}
 | 
					            }}
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <Text ta={'left'} mb={'xs'} fw={800} display={'flex'}>
 | 
					            {worklogs.map((w) => (
 | 
				
			||||||
              <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 */}
 | 
					 | 
				
			||||||
              <Box
 | 
					              <Box
 | 
				
			||||||
                w={{ base: '100%', md: '50%' }}
 | 
					                key={w.username}
 | 
				
			||||||
                style={{
 | 
					                style={{
 | 
				
			||||||
                  border: 'solid 1px gray',
 | 
					                  display: 'flex',
 | 
				
			||||||
                  borderRadius: '5px',
 | 
					                  alignItems: 'center',
 | 
				
			||||||
                  padding: '10px',
 | 
					                  fontSize: '13px',
 | 
				
			||||||
                  marginBottom: '5px',
 | 
					 | 
				
			||||||
                  overflowX: 'hidden',
 | 
					 | 
				
			||||||
                  color: '#412d2d',
 | 
					 | 
				
			||||||
                  backgroundColor: '#d1cdce',
 | 
					 | 
				
			||||||
                }}
 | 
					                }}
 | 
				
			||||||
 | 
					                mb={'xs'}
 | 
				
			||||||
 | 
					                className={classes.menuUser}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                <Text fw={700} ta={'center'} mb={'5px'}>
 | 
					                <Avatar src={w.user.avatarUrls['16x16']} size={'xs'} mr={5} />
 | 
				
			||||||
                  WORKLOG
 | 
					                <a
 | 
				
			||||||
                </Text>
 | 
					                  className={classes.menuLink}
 | 
				
			||||||
                {user.information.issues.map((iss) => {
 | 
					                  href={'/worklogs#' + w.username}
 | 
				
			||||||
                  if (
 | 
					                  style={{ textDecoration: 'none' }}
 | 
				
			||||||
                    iss.fields.worklog.worklogs.filter(
 | 
					                >
 | 
				
			||||||
                      (w) =>
 | 
					                  {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(date.startDate).format('YYYYMMDD')) <=
 | 
				
			||||||
                          parseInt(moment(w.started).format('YYYYMMDD')) &&
 | 
					                          parseInt(
 | 
				
			||||||
                        parseInt(moment(date.endDate).format('YYYYMMDD')) >=
 | 
					                            moment(currentValue.started).format('YYYYMMDD'),
 | 
				
			||||||
                          parseInt(moment(w.started).format('YYYYMMDD')) &&
 | 
					                          ) &&
 | 
				
			||||||
                        w.updateAuthor.displayName === user.username,
 | 
					                        parseInt(
 | 
				
			||||||
                    ).length > 0
 | 
					                          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 (
 | 
					                    return (
 | 
				
			||||||
                      <Box
 | 
					                      <Box
 | 
				
			||||||
                        key={iss.id}
 | 
					                        key={index}
 | 
				
			||||||
                        style={{
 | 
					                        style={{
 | 
				
			||||||
                          border: 'solid 1px gray',
 | 
					                          border: 'solid 1px gray',
 | 
				
			||||||
                          borderRadius: '5px',
 | 
					                          borderRadius: '5px',
 | 
				
			||||||
                          boxShadow: '1px 1px 5px 1px gray',
 | 
					                          boxShadow: '1px 1px 5px 1px gray',
 | 
				
			||||||
                          padding: '10px',
 | 
					                          padding: '10px',
 | 
				
			||||||
                          marginBottom: '8px',
 | 
					                          marginBottom: '5px',
 | 
				
			||||||
                          maxHeight: '90vh',
 | 
					 | 
				
			||||||
                          overflowX: 'hidden',
 | 
					                          overflowX: 'hidden',
 | 
				
			||||||
                          color: '#412d2d',
 | 
					                          color: '#412d2d',
 | 
				
			||||||
                          backgroundColor: 'white',
 | 
					                          backgroundColor: 'white',
 | 
				
			||||||
                        }}
 | 
					                        }}
 | 
				
			||||||
                      >
 | 
					                      >
 | 
				
			||||||
                        {/* Box information issue */}
 | 
					                        <Text
 | 
				
			||||||
                        <Box>
 | 
					                          fz={14}
 | 
				
			||||||
                          <Text fz={14} c={iss.fields.status.statusCategory.colorName}>
 | 
					                          c={iss.fields.status.statusCategory.colorName}
 | 
				
			||||||
                            <b>{iss.fields.status.name}</b>
 | 
					                        >
 | 
				
			||||||
                          </Text>
 | 
					                          <b>{iss.fields.status.name}</b>
 | 
				
			||||||
                          <Text fz={14} display={'flex'} style={{ alignItems: 'start' }}>
 | 
					                        </Text>
 | 
				
			||||||
                            <b>Summary:</b>{' '}
 | 
					                        <Badge color="#6140c0e0">
 | 
				
			||||||
                            <Box display={'flex'} style={{ alignItems: 'center' }}>
 | 
					                          <Box
 | 
				
			||||||
                              <Avatar
 | 
					                            display={'flex'}
 | 
				
			||||||
                                src={iss.fields.project?.avatarUrls['16x16']}
 | 
					                            style={{ alignItems: 'center' }}
 | 
				
			||||||
                                size={'xs'}
 | 
					                          >
 | 
				
			||||||
                                m={'0 5px'}
 | 
					                            <Avatar
 | 
				
			||||||
                              />
 | 
					                              src={iss.fields.project?.avatarUrls['16x16']}
 | 
				
			||||||
                              <Text fz={14} mr={'xs'}>
 | 
					                              size={'xs'}
 | 
				
			||||||
                                {iss.fields.project.name}
 | 
					                              m={'0 5px 0 0'}
 | 
				
			||||||
                              </Text>
 | 
					                            />
 | 
				
			||||||
                            </Box>
 | 
					                            {iss.fields.project.name}
 | 
				
			||||||
                            <a href={`https://apactechvn.atlassian.net/browse/${iss.key}`} target="_blank">
 | 
					                          </Box>
 | 
				
			||||||
                              {iss.fields.summary}
 | 
					                        </Badge>
 | 
				
			||||||
                            </a>
 | 
					                        <Text
 | 
				
			||||||
                          </Text>
 | 
					                          fz={14}
 | 
				
			||||||
                          <Text fz={14}>
 | 
					                          display={'flex'}
 | 
				
			||||||
                            <b>Estimate:</b> {iss.fields.timeoriginalestimate / 60 / 60}h
 | 
					                          style={{ alignItems: 'start' }}
 | 
				
			||||||
                          </Text>
 | 
					                        >
 | 
				
			||||||
                          <Text fz={14}>
 | 
					                          <b>Summary:</b>{' '}
 | 
				
			||||||
                            <b>Total time spent:</b> {iss.fields.timespent / 60 / 60}h
 | 
					                          <Tooltip label={iss.fields.summary}>
 | 
				
			||||||
                          </Text>
 | 
					                            <Badge color="#228be64f" fz={12}>
 | 
				
			||||||
                          <Text fz={14}>
 | 
					                              <a
 | 
				
			||||||
                            <b>
 | 
					                                href={`https://apactechvn.atlassian.net/browse/${iss.key}`}
 | 
				
			||||||
                              Time spent{' '}
 | 
					                                target="_blank"
 | 
				
			||||||
                              <span style={{ fontSize: '11px' }}>
 | 
					                                style={{textDecoration:"none"}}
 | 
				
			||||||
                                (
 | 
					 | 
				
			||||||
                                {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={13}>
 | 
					                                [{iss.key}]{` ${iss.fields.summary}`}
 | 
				
			||||||
                                  <b>Start date:</b> {moment(log.started).format('HH:mm YYYY/MM/DD')}
 | 
					                              </a>
 | 
				
			||||||
                                </Text>
 | 
					                            </Badge>
 | 
				
			||||||
                                <Text fz={13}>
 | 
					                          </Tooltip>
 | 
				
			||||||
                                  <b>Time spent:</b> {log.timeSpent}
 | 
					                        </Text>
 | 
				
			||||||
                                </Text>
 | 
					                        <Text fz={13}>
 | 
				
			||||||
                                {log?.comment && log?.comment?.content[0]?.content[0]?.text && (
 | 
					                          <b>Time spent:</b> <Badge color='orange' size='sm'>{iss.fields.timespent / 60 / 60}h</Badge>
 | 
				
			||||||
                                  <Text fz={13}>
 | 
					                        </Text>
 | 
				
			||||||
                                    <b>Comment:</b> {log?.comment?.content[0]?.content[0]?.text}
 | 
					                        <Text fz={13}>
 | 
				
			||||||
                                  </Text>
 | 
					                          <b>Estimate:</b>{' '}
 | 
				
			||||||
                                )}
 | 
					                          <Badge color='red' size='sm'>{iss.fields.timeoriginalestimate / 60 / 60}h</Badge>
 | 
				
			||||||
                              </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}
 | 
					 | 
				
			||||||
                        </Text>
 | 
					                        </Text>
 | 
				
			||||||
                      </Box>
 | 
					                      </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">
 | 
					                </Box>
 | 
				
			||||||
                          {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>
 | 
					      </Box>
 | 
				
			||||||
    </Box>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue