View note theo ngày và note tổng chức năng timekepping
This commit is contained in:
		
							parent
							
								
									9a5e81111a
								
							
						
					
					
						commit
						b203e8d82c
					
				| 
						 | 
				
			
			@ -0,0 +1,40 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
 | 
			
		||||
class AbstractController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    public static function ResultData($models)
 | 
			
		||||
    {
 | 
			
		||||
        return $models->withPath('');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function ResultSuccess($data = [], $message = "Successfull")
 | 
			
		||||
    {
 | 
			
		||||
        return response()->json(
 | 
			
		||||
            [
 | 
			
		||||
                'message' => $message,
 | 
			
		||||
                'errors' => false,
 | 
			
		||||
                'result' => "Success",
 | 
			
		||||
                'status' => true,
 | 
			
		||||
                'data' => $data,
 | 
			
		||||
            ],
 | 
			
		||||
            200
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    public static function ResultError($message, $data = [], $statusCode = 500)
 | 
			
		||||
    {
 | 
			
		||||
        return response()->json(
 | 
			
		||||
            [
 | 
			
		||||
                'message' => $message,
 | 
			
		||||
                'errors' => true,
 | 
			
		||||
                'status' => false,
 | 
			
		||||
                'result' => 'ERROR',
 | 
			
		||||
                'data' => $data,
 | 
			
		||||
            ],
 | 
			
		||||
            $statusCode
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Modules\Admin\app\Models\Category;
 | 
			
		||||
 | 
			
		||||
class CategoryController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieves a list of master data based on the given request type.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Request $request The HTTP request object.
 | 
			
		||||
     * @return \Illuminate\Http\JsonResponse The JSON response containing the list of master data.
 | 
			
		||||
     */
 | 
			
		||||
    public function getListMaster(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $data = Category::where('c_type', '=', $request->type)->where('c_active', '=', 1)->select('id', 'c_code', 'c_name', 'c_value', 'c_type')->get();
 | 
			
		||||
        return AbstractController::ResultSuccess($data);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +32,8 @@ class TimekeepingController extends Controller
 | 
			
		|||
        $data = MonthlyTimekeeping::where('month', '=', $request->month)->where('year', '=', $request->year)->first();
 | 
			
		||||
        if ($currentMonth == (int)$request->month && $currentYear == (int)$request->year) {
 | 
			
		||||
            $cacheData = CurrentMonthTimekeeping::getCacheCurrentMonthTimekeeping();
 | 
			
		||||
            // $result = $this->analyzeCurrentMonthTimeKeepingData($currentMonth, $currentYear);
 | 
			
		||||
            // dd($result);die;
 | 
			
		||||
            if ($cacheData) {
 | 
			
		||||
                $cacheData->data = json_decode($cacheData->data, true);
 | 
			
		||||
                return response()->json(['status' => true, 'data' => $cacheData->data, 'working_days'=> $cacheData->working_days, 'message' => 'Get from cache']);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Models;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
 | 
			
		||||
class Category extends Model
 | 
			
		||||
{
 | 
			
		||||
    use HasFactory;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ use App\Http\Middleware\CheckPermission;
 | 
			
		|||
use Illuminate\Support\Facades\Route;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\AdminController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\BannerController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\CategoryController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\ClientController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\CountryController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\CustomThemeController;
 | 
			
		||||
| 
						 | 
				
			
			@ -116,21 +117,28 @@ Route::middleware('api')
 | 
			
		|||
                Route::post('/create', [TrackingController::class, 'create'])->middleware('check.permission:admin.hr');
 | 
			
		||||
                Route::post('/update', [TrackingController::class, 'update'])->middleware('check.permission:admin.hr');
 | 
			
		||||
                Route::get('/delete', [TrackingController::class, 'delete'])->middleware('check.permission:admin.hr');
 | 
			
		||||
                });
 | 
			
		||||
                });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
                Route::group([
 | 
			
		||||
                    'prefix' => 'v1/admin/tracking',
 | 
			
		||||
            Route::group([
 | 
			
		||||
                'prefix' => 'category',
 | 
			
		||||
            ], function () {
 | 
			
		||||
                Route::get('/get-list-master', [CategoryController::class, 'getListMaster']);
 | 
			
		||||
    
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
Route::group([
 | 
			
		||||
    'prefix' => 'v1/admin/tracking',
 | 
			
		||||
], function () {
 | 
			
		||||
    Route::get('/', [TrackingController::class, 'get'])->middleware('check.permission:admin.hr.staff');
 | 
			
		||||
    Route::post('/scan-create', [TrackingController::class, 'create']);
 | 
			
		||||
    Route::post('/send-image', [TrackingController::class, 'saveImage']);
 | 
			
		||||
    // Route::get('/clear-cache', [SettingController::class, 'clearCache']);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
    Route::group([
 | 
			
		||||
        'prefix' => 'v1/admin/jira',
 | 
			
		||||
        ], function () {
 | 
			
		||||
Route::group([
 | 
			
		||||
    'prefix' => 'v1/admin/jira',
 | 
			
		||||
], function () {
 | 
			
		||||
    Route::get('/send-worklog-report', [JiraController::class, 'sendReport']);
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,40 +34,42 @@ trait AnalyzeData
 | 
			
		|||
        $history = DB::table('tracking')->select('*')->whereBetween('tracking.created_at', [$startOfMonth, $endOfMonth])->orderBy('tracking.created_at', 'asc')->get();
 | 
			
		||||
        $history = collect($history);
 | 
			
		||||
        $result = [];
 | 
			
		||||
        foreach ($admins as $admin) {
 | 
			
		||||
            $user_data = [];
 | 
			
		||||
            for ($i = 1; $i <= $daysInMonth; $i++) {
 | 
			
		||||
                // Tạo ngày cụ thể trong tháng
 | 
			
		||||
                $date = Carbon::create($now->year, $now->month, $i)->setTimezone(env('TIME_ZONE'))->format('Y-m-d');
 | 
			
		||||
                // Kiểm tra xem có mục nào trong $history có created_at trùng với $date
 | 
			
		||||
                $hasEntry = $history->filter(function ($entry) use ($date, $admin) {
 | 
			
		||||
        foreach ($admins as $key => $admin) {
 | 
			
		||||
            if ($key == 0) {
 | 
			
		||||
                $user_data = [];
 | 
			
		||||
                for ($i = 1; $i <= $daysInMonth; $i++) {
 | 
			
		||||
                    // Tạo ngày cụ thể trong tháng
 | 
			
		||||
                    $date = Carbon::create($now->year, $now->month, $i)->setTimezone(env('TIME_ZONE'))->format('Y-m-d');
 | 
			
		||||
                    // Kiểm tra xem có mục nào trong $history có created_at trùng với $date
 | 
			
		||||
                    $hasEntry = $history->filter(function ($entry) use ($date, $admin) {
 | 
			
		||||
                        // echo($hasEntry);
 | 
			
		||||
                        return Carbon::parse($entry->created_at)->setTimezone(env('TIME_ZONE'))->format('Y-m-d') === $date && $entry->user_id == $admin->id;
 | 
			
		||||
                    });
 | 
			
		||||
                    // echo($hasEntry);
 | 
			
		||||
                    return Carbon::parse($entry->created_at)->setTimezone(env('TIME_ZONE'))->format('Y-m-d') === $date && $entry->user_id == $admin->id;
 | 
			
		||||
                });
 | 
			
		||||
                // echo($hasEntry);
 | 
			
		||||
                    // dd($date,$admin,$history,$daysInMonth);
 | 
			
		||||
                    if (count($hasEntry) > 0) {
 | 
			
		||||
                        $values = array_values($hasEntry->toArray());
 | 
			
		||||
                        $last_checkin = null;
 | 
			
		||||
                        $total = 0;
 | 
			
		||||
                        foreach ($values as $value) {
 | 
			
		||||
                            $createdAt = Carbon::parse($value->created_at)->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
                            if ($value->status == 'check out' && $last_checkin != null) {
 | 
			
		||||
                                $lastCheckInTime = Carbon::parse($last_checkin)->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
                                // Tính thời gian làm việc bằng hiệu của thời gian check out và check in
 | 
			
		||||
                                $workingTime = $createdAt->diffInSeconds($lastCheckInTime);
 | 
			
		||||
                                $total += $workingTime;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                if (count($hasEntry) > 0) {
 | 
			
		||||
                    $values = array_values($hasEntry->toArray());
 | 
			
		||||
                    $last_checkin = null;
 | 
			
		||||
                    $total = 0;
 | 
			
		||||
                    foreach ($values as $value) {
 | 
			
		||||
                        $createdAt = Carbon::parse($value->created_at)->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
                        if ($value->status == 'check out' && $last_checkin != null) {
 | 
			
		||||
                            $lastCheckInTime = Carbon::parse($last_checkin)->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
                            // Tính thời gian làm việc bằng hiệu của thời gian check out và check in
 | 
			
		||||
                            $workingTime = $createdAt->diffInSeconds($lastCheckInTime);
 | 
			
		||||
                            $total += $workingTime;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if ($value->status == 'check in') {
 | 
			
		||||
                            $last_checkin = $createdAt;
 | 
			
		||||
                            if ($value->status == 'check in') {
 | 
			
		||||
                                $last_checkin = $createdAt;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        $user_data[] = ['values' => array_values($hasEntry->toArray()), 'total' => $total, 'day' => $i];
 | 
			
		||||
                    }
 | 
			
		||||
                    $user_data[] = ['values' => array_values($hasEntry->toArray()), 'total' => $total, 'day' => $i];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $result[] = ['user' => $admin, 'history' => $user_data];
 | 
			
		||||
                $result[] = ['user' => $admin, 'history' => $user_data];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Migrations\Migration;
 | 
			
		||||
use Illuminate\Database\Schema\Blueprint;
 | 
			
		||||
use Illuminate\Support\Facades\Schema;
 | 
			
		||||
 | 
			
		||||
return new class extends Migration
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Run the migrations.
 | 
			
		||||
     */
 | 
			
		||||
    public function up(): void
 | 
			
		||||
    {
 | 
			
		||||
        Schema::create('categories', function (Blueprint $table) {
 | 
			
		||||
            $table->id();
 | 
			
		||||
            $table->string('c_code');
 | 
			
		||||
            $table->string('c_name');
 | 
			
		||||
            $table->string('c_type');
 | 
			
		||||
            $table->string('c_value');
 | 
			
		||||
            $table->integer('c_active');
 | 
			
		||||
            $table->timestamps();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reverse the migrations.
 | 
			
		||||
     */
 | 
			
		||||
    public function down(): void
 | 
			
		||||
    {
 | 
			
		||||
        Schema::dropIfExists('categories');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -25,17 +25,18 @@
 | 
			
		|||
    "@uiw/react-codemirror": "^4.21.21",
 | 
			
		||||
    "@vanilla-extract/css": "^1.13.0",
 | 
			
		||||
    "axios": "^1.6.1",
 | 
			
		||||
    "clsx": "^2.0.0",
 | 
			
		||||
    "clsx": "^2.1.1",
 | 
			
		||||
    "dayjs": "^1.11.10",
 | 
			
		||||
    "dotenv": "^16.3.1",
 | 
			
		||||
    "handsontable": "^14.0.0",
 | 
			
		||||
    "history": "^5.3.0",
 | 
			
		||||
    "jwt-decode": "^4.0.0",
 | 
			
		||||
    "moment": "^2.29.4",
 | 
			
		||||
    "moment": "^2.30.1",
 | 
			
		||||
    "react": "^18.2.0",
 | 
			
		||||
    "react-dom": "^18.2.0",
 | 
			
		||||
    "react-redux": "^8.1.3",
 | 
			
		||||
    "react-router-dom": "^6.19.0",
 | 
			
		||||
    "reactstrap": "^9.2.2",
 | 
			
		||||
    "recharts": "^2.11.0",
 | 
			
		||||
    "tailwind-merge": "^2.0.0",
 | 
			
		||||
    "tests": "^0.4.2"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,51 +1,57 @@
 | 
			
		|||
.title {
 | 
			
		||||
    background-color: light-dark(var(white), var(--mantine-color-dark-7));
 | 
			
		||||
    z-index: 100;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    padding: 0 var(--mantine-spacing-sm) var(--mantine-spacing-lg)
 | 
			
		||||
      var(--mantine-spacing-sm);
 | 
			
		||||
    border-bottom: solid rgba(201, 201, 201, 0.377) 1px;
 | 
			
		||||
  }
 | 
			
		||||
  background-color: light-dark(var(white), var(--mantine-color-dark-7));
 | 
			
		||||
  z-index: 100;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  padding: 0 var(--mantine-spacing-sm) var(--mantine-spacing-lg)
 | 
			
		||||
    var(--mantine-spacing-sm);
 | 
			
		||||
  border-bottom: solid rgba(201, 201, 201, 0.377) 1px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  .optionIcon {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: space-evenly;
 | 
			
		||||
  }
 | 
			
		||||
.optionIcon {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: space-evenly;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  .deleteIcon {
 | 
			
		||||
    color: red;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    padding: 2px;
 | 
			
		||||
    border-radius: 25%;
 | 
			
		||||
  }
 | 
			
		||||
.deleteIcon {
 | 
			
		||||
  color: red;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  padding: 2px;
 | 
			
		||||
  border-radius: 25%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  .deleteIcon:hover {
 | 
			
		||||
    background-color: rgba(203, 203, 203, 0.809);
 | 
			
		||||
  }
 | 
			
		||||
.deleteIcon:hover {
 | 
			
		||||
  background-color: rgba(203, 203, 203, 0.809);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  .editIcon {
 | 
			
		||||
    color: rgb(9, 132, 132);
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    padding: 2px;
 | 
			
		||||
    border-radius: 25%;
 | 
			
		||||
  }
 | 
			
		||||
.editIcon {
 | 
			
		||||
  color: rgb(9, 132, 132);
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  padding: 2px;
 | 
			
		||||
  border-radius: 25%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  .editIcon:hover {
 | 
			
		||||
    background-color: rgba(203, 203, 203, 0.809);
 | 
			
		||||
  }
 | 
			
		||||
.editIcon:hover {
 | 
			
		||||
  background-color: rgba(203, 203, 203, 0.809);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  .dialog {
 | 
			
		||||
    background-color: light-dark(white, #2d353c);
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    border: solid 1px rgb(255, 145, 0);
 | 
			
		||||
  }
 | 
			
		||||
.dialog {
 | 
			
		||||
  background-color: light-dark(white, #2d353c);
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  border: solid 1px rgb(255, 145, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  .dialogText {
 | 
			
		||||
    color: light-dark(#2d353c, white);
 | 
			
		||||
  }
 | 
			
		||||
.dialogText {
 | 
			
		||||
  color: light-dark(#2d353c, white);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  .tableTr:hover {
 | 
			
		||||
    background-color: rgb(205, 255, 255);
 | 
			
		||||
  }
 | 
			
		||||
.tableTr:hover {
 | 
			
		||||
  background-color: rgb(205, 255, 255);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.popoverFooter {
 | 
			
		||||
  margin-top: 5px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: end;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,13 +16,16 @@ import {
 | 
			
		|||
  Table,
 | 
			
		||||
  Text,
 | 
			
		||||
  TextInput,
 | 
			
		||||
  Tooltip
 | 
			
		||||
  Tooltip,
 | 
			
		||||
} from '@mantine/core'
 | 
			
		||||
import { useDisclosure } from '@mantine/hooks'
 | 
			
		||||
import { notifications } from '@mantine/notifications'
 | 
			
		||||
import { IconCheck, IconExclamationMark, IconX } from '@tabler/icons-react'
 | 
			
		||||
import moment from 'moment'
 | 
			
		||||
import { useEffect, useState } from 'react'
 | 
			
		||||
import React, { useEffect, useRef, useState } from 'react'
 | 
			
		||||
import { Link } from 'react-router-dom'
 | 
			
		||||
import { Popover, PopoverBody } from 'reactstrap'
 | 
			
		||||
 | 
			
		||||
import classes from './Timekeeping.module.css'
 | 
			
		||||
 | 
			
		||||
interface User {
 | 
			
		||||
| 
						 | 
				
			
			@ -64,12 +67,34 @@ const Timekeeping = () => {
 | 
			
		|||
  const [daysInMonth, setDaysInMonth] = useState(
 | 
			
		||||
    Array.from({ length: 31 }, (_, index) => index + 1),
 | 
			
		||||
  )
 | 
			
		||||
  const [customAddData, setCustomAddData] = useState<{data:string[], type: string, day: number}>({
 | 
			
		||||
  const [customAddData, setCustomAddData] = useState<{
 | 
			
		||||
    data: string[]
 | 
			
		||||
    type: string
 | 
			
		||||
    day: number
 | 
			
		||||
  }>({
 | 
			
		||||
    data: [],
 | 
			
		||||
    type: '',
 | 
			
		||||
    day: 0
 | 
			
		||||
    day: 0,
 | 
			
		||||
  })
 | 
			
		||||
  const [workingDays, setWorkingDays] = useState(30)
 | 
			
		||||
  const [isOpen, setIsOpen] = useState('')
 | 
			
		||||
  const popoverRef = useRef<HTMLElement>(null)
 | 
			
		||||
 | 
			
		||||
  const [selectedOption1, setSelectedOption1] = useState('')
 | 
			
		||||
  const [selectedOption2, setSelectedOption2] = useState('')
 | 
			
		||||
  const [textValue, setTextValue] = useState('')
 | 
			
		||||
 | 
			
		||||
  const handleSave = () => {
 | 
			
		||||
    // Send data to API
 | 
			
		||||
    const data = {
 | 
			
		||||
      option1: selectedOption1,
 | 
			
		||||
      option2: selectedOption2,
 | 
			
		||||
      text: textValue,
 | 
			
		||||
    }
 | 
			
		||||
    console.log(data) // Replace with actual API call
 | 
			
		||||
    setIsOpen(false)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const [data, setData] = useState<UserData[]>([])
 | 
			
		||||
  const [date, setDate] = useState({
 | 
			
		||||
    month: (new Date().getMonth() + 1).toString(),
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +193,49 @@ const Timekeeping = () => {
 | 
			
		|||
    getTimeSheet()
 | 
			
		||||
  }, [date])
 | 
			
		||||
 | 
			
		||||
  console.log(customAddData)
 | 
			
		||||
  // useEffect(() => {
 | 
			
		||||
  //   const handleClickOutside = (event: MouseEvent | React.MouseEvent) => {
 | 
			
		||||
  //     if (
 | 
			
		||||
  //       popoverRef.current &&
 | 
			
		||||
  //       !(popoverRef.current as HTMLElement).contains(event.target as Node)
 | 
			
		||||
  //     ) {
 | 
			
		||||
  //       setIsOpen('')
 | 
			
		||||
  //     }
 | 
			
		||||
  //   }
 | 
			
		||||
 | 
			
		||||
  //   document.addEventListener('click', handleClickOutside)
 | 
			
		||||
 | 
			
		||||
  //   return () => {
 | 
			
		||||
  //     document.removeEventListener('click', handleClickOutside)
 | 
			
		||||
  //   }
 | 
			
		||||
  // }, [popoverRef])
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const handleClickOutside = (event: React.MouseEvent) => {
 | 
			
		||||
      if (
 | 
			
		||||
        popoverRef.current &&
 | 
			
		||||
        !(popoverRef.current as HTMLElement).contains(event.target as Node)
 | 
			
		||||
      ) {
 | 
			
		||||
        setIsOpen('')
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    document.addEventListener('mousedown', handleClickOutside)
 | 
			
		||||
    document.addEventListener('scroll', handleClickOutside)
 | 
			
		||||
    document
 | 
			
		||||
      .getElementById('my-child-div')
 | 
			
		||||
      ?.addEventListener('scroll', handleClickOutside)
 | 
			
		||||
 | 
			
		||||
    return () => {
 | 
			
		||||
      document.removeEventListener('mousedown', handleClickOutside)
 | 
			
		||||
      document.removeEventListener('scroll', handleClickOutside)
 | 
			
		||||
      document
 | 
			
		||||
        .getElementById('my-child-div')
 | 
			
		||||
        ?.removeEventListener('scroll', handleClickOutside)
 | 
			
		||||
    }
 | 
			
		||||
  }, [popoverRef])
 | 
			
		||||
 | 
			
		||||
  // console.log(daysInMonth, 'daysInMonth')
 | 
			
		||||
  return (
 | 
			
		||||
    <div>
 | 
			
		||||
      <div className={classes.title}>
 | 
			
		||||
| 
						 | 
				
			
			@ -190,7 +257,9 @@ const Timekeeping = () => {
 | 
			
		|||
          data={data.map((user) => {
 | 
			
		||||
            return { value: user.user.id.toString(), label: user.user.name }
 | 
			
		||||
          })}
 | 
			
		||||
          onChange={(e)=>{setCustomAddData({...customAddData, data: e})}}
 | 
			
		||||
          onChange={(e) => {
 | 
			
		||||
            setCustomAddData({ ...customAddData, data: e })
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
        <Select
 | 
			
		||||
          mb={'md'}
 | 
			
		||||
| 
						 | 
				
			
			@ -199,21 +268,36 @@ const Timekeeping = () => {
 | 
			
		|||
            { value: 'half', label: 'Half day' },
 | 
			
		||||
            { value: 'one', label: 'A day' },
 | 
			
		||||
          ]}
 | 
			
		||||
          onChange={(e)=>{setCustomAddData({...customAddData, type: e!})}}
 | 
			
		||||
          onChange={(e) => {
 | 
			
		||||
            setCustomAddData({ ...customAddData, type: e! })
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
        <Button onClick={()=>{
 | 
			
		||||
          setDisableBtn(true)
 | 
			
		||||
          if(customAddData.type === "" || customAddData.data.length === 0 || customAddData.day === 0){
 | 
			
		||||
            notifications.show({
 | 
			
		||||
              title: 'Error',
 | 
			
		||||
              message: "Input data required",
 | 
			
		||||
              color: 'red',
 | 
			
		||||
            })
 | 
			
		||||
            setDisableBtn(false)
 | 
			
		||||
          }else{
 | 
			
		||||
            updateMultipleUser(customAddData.data.map((u)=>parseInt(u)), customAddData.day, customAddData.type)
 | 
			
		||||
          }
 | 
			
		||||
        }} disabled={disableBtn}>Submit</Button>
 | 
			
		||||
        <Button
 | 
			
		||||
          onClick={() => {
 | 
			
		||||
            setDisableBtn(true)
 | 
			
		||||
            if (
 | 
			
		||||
              customAddData.type === '' ||
 | 
			
		||||
              customAddData.data.length === 0 ||
 | 
			
		||||
              customAddData.day === 0
 | 
			
		||||
            ) {
 | 
			
		||||
              notifications.show({
 | 
			
		||||
                title: 'Error',
 | 
			
		||||
                message: 'Input data required',
 | 
			
		||||
                color: 'red',
 | 
			
		||||
              })
 | 
			
		||||
              setDisableBtn(false)
 | 
			
		||||
            } else {
 | 
			
		||||
              updateMultipleUser(
 | 
			
		||||
                customAddData.data.map((u) => parseInt(u)),
 | 
			
		||||
                customAddData.day,
 | 
			
		||||
                customAddData.type,
 | 
			
		||||
              )
 | 
			
		||||
            }
 | 
			
		||||
          }}
 | 
			
		||||
          disabled={disableBtn}
 | 
			
		||||
        >
 | 
			
		||||
          Submit
 | 
			
		||||
        </Button>
 | 
			
		||||
      </Drawer>
 | 
			
		||||
      <Box display={'flex'}>
 | 
			
		||||
        <Box style={{ display: 'flex', flexFlow: 'column' }} w={'30%'}>
 | 
			
		||||
| 
						 | 
				
			
			@ -371,7 +455,7 @@ const Timekeeping = () => {
 | 
			
		|||
              <Table.Th></Table.Th>
 | 
			
		||||
              {daysInMonth.map((d) => {
 | 
			
		||||
                return (
 | 
			
		||||
                  <Menu width={200} shadow="md">
 | 
			
		||||
                  <Menu width={200} shadow="md" key={d}>
 | 
			
		||||
                    <Menu.Target>
 | 
			
		||||
                      <Table.Th
 | 
			
		||||
                        key={d}
 | 
			
		||||
| 
						 | 
				
			
			@ -406,10 +490,13 @@ const Timekeeping = () => {
 | 
			
		|||
                        + Add 1 day of work
 | 
			
		||||
                      </Menu.Item>
 | 
			
		||||
                      <Menu.Item>
 | 
			
		||||
                        <Text size="sm" onClick={()=>{
 | 
			
		||||
                          open()
 | 
			
		||||
                          setCustomAddData({...customAddData, day: d})
 | 
			
		||||
                        }}>
 | 
			
		||||
                        <Text
 | 
			
		||||
                          size="sm"
 | 
			
		||||
                          onClick={() => {
 | 
			
		||||
                            open()
 | 
			
		||||
                            setCustomAddData({ ...customAddData, day: d })
 | 
			
		||||
                          }}
 | 
			
		||||
                        >
 | 
			
		||||
                          + Add custom worklog
 | 
			
		||||
                        </Text>
 | 
			
		||||
                      </Menu.Item>
 | 
			
		||||
| 
						 | 
				
			
			@ -450,7 +537,28 @@ const Timekeeping = () => {
 | 
			
		|||
                  2
 | 
			
		||||
              return (
 | 
			
		||||
                <Table.Tr key={user.user.id} className={classes.tableTr}>
 | 
			
		||||
                  <Table.Td>{user.user.name}</Table.Td>
 | 
			
		||||
                  <Table.Td>
 | 
			
		||||
                    <Tooltip
 | 
			
		||||
                      multiline
 | 
			
		||||
                      label={
 | 
			
		||||
                        <div>
 | 
			
		||||
                          <p style={{ fontWeight: 'bold' }}>Day 1:</p>
 | 
			
		||||
                          <p style={{ paddingLeft: '10px' }}>
 | 
			
		||||
                            - Work For Home (Buổi Sáng): Bị bể bánh xe
 | 
			
		||||
                          </p>
 | 
			
		||||
                          <p style={{ paddingLeft: '10px' }}>- Nghỉ phép (Buổi Chiều): Bị cảm</p>
 | 
			
		||||
 | 
			
		||||
                          <p style={{ fontWeight: 'bold' }}>Day 2:</p>
 | 
			
		||||
                          <p style={{ paddingLeft: '10px' }}>
 | 
			
		||||
                            - Work For Home (Buổi Sáng): Bị bể bánh xe
 | 
			
		||||
                          </p>
 | 
			
		||||
                          <p style={{ paddingLeft: '10px' }}>- Nghỉ phép (Buổi Chiều): Bị cảm</p>
 | 
			
		||||
                        </div>
 | 
			
		||||
                      }
 | 
			
		||||
                    >
 | 
			
		||||
                      <div>{user.user.name}</div>
 | 
			
		||||
                    </Tooltip>
 | 
			
		||||
                  </Table.Td>
 | 
			
		||||
                  <Table.Td ta={'center'}>{totalDays}</Table.Td>
 | 
			
		||||
                  <Table.Td ta={'center'}>{workingDays - totalDays}</Table.Td>
 | 
			
		||||
                  {daysInMonth.map((d) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -586,69 +694,354 @@ const Timekeeping = () => {
 | 
			
		|||
                            </Tooltip>
 | 
			
		||||
                          )
 | 
			
		||||
                        ) : total >= 7 ? (
 | 
			
		||||
                          <Tooltip
 | 
			
		||||
                            multiline
 | 
			
		||||
                            label={
 | 
			
		||||
                              <div>
 | 
			
		||||
                                {`Total: ${(total / 60 / 60).toFixed(1)}h`}
 | 
			
		||||
                                {user.history
 | 
			
		||||
                                  .find((h) => h.day === d)
 | 
			
		||||
                                  ?.values.map((v) => {
 | 
			
		||||
                                    return (
 | 
			
		||||
                                      <Box
 | 
			
		||||
                                        style={{
 | 
			
		||||
                                          display: 'flex',
 | 
			
		||||
                                          alignItems: 'center',
 | 
			
		||||
                                          justifyContent: 'space-between',
 | 
			
		||||
                                        }}
 | 
			
		||||
                                        key={v.id}
 | 
			
		||||
                          <>
 | 
			
		||||
                            <Tooltip
 | 
			
		||||
                              multiline
 | 
			
		||||
                              label={
 | 
			
		||||
                                <div>
 | 
			
		||||
                                  {`Total: ${(total / 60 / 60).toFixed(1)}h`}
 | 
			
		||||
                                  {user.history
 | 
			
		||||
                                    .find((h) => h.day === d)
 | 
			
		||||
                                    ?.values.map((v) => {
 | 
			
		||||
                                      return (
 | 
			
		||||
                                        <Box
 | 
			
		||||
                                          style={{
 | 
			
		||||
                                            display: 'flex',
 | 
			
		||||
                                            alignItems: 'center',
 | 
			
		||||
                                            justifyContent: 'space-between',
 | 
			
		||||
                                          }}
 | 
			
		||||
                                          key={v.id}
 | 
			
		||||
                                        >
 | 
			
		||||
                                          <p>
 | 
			
		||||
                                            {v.status + ': ' + v.time_string}
 | 
			
		||||
                                          </p>{' '}
 | 
			
		||||
                                          {v.image && (
 | 
			
		||||
                                            <Image
 | 
			
		||||
                                              w={100}
 | 
			
		||||
                                              h={100}
 | 
			
		||||
                                              src={
 | 
			
		||||
                                                import.meta.env.VITE_BACKEND_URL.includes(
 | 
			
		||||
                                                  'local',
 | 
			
		||||
                                                )
 | 
			
		||||
                                                  ? import.meta.env
 | 
			
		||||
                                                      .VITE_BACKEND_URL +
 | 
			
		||||
                                                    'storage/' +
 | 
			
		||||
                                                    v.image
 | 
			
		||||
                                                  : import.meta.env
 | 
			
		||||
                                                      .VITE_BACKEND_URL +
 | 
			
		||||
                                                    'image/storage/' +
 | 
			
		||||
                                                    v.image
 | 
			
		||||
                                              }
 | 
			
		||||
                                            />
 | 
			
		||||
                                          )}
 | 
			
		||||
                                        </Box>
 | 
			
		||||
                                      )
 | 
			
		||||
                                    })}
 | 
			
		||||
                                </div>
 | 
			
		||||
                              }
 | 
			
		||||
                            >
 | 
			
		||||
                              <IconCheck
 | 
			
		||||
                                size={20}
 | 
			
		||||
                                style={{
 | 
			
		||||
                                  backgroundColor: 'green',
 | 
			
		||||
                                  color: 'white',
 | 
			
		||||
                                  borderRadius: '5px',
 | 
			
		||||
                                  padding: '2px',
 | 
			
		||||
                                }}
 | 
			
		||||
                                id={`indexBySN${user.user.id}_${d}`}
 | 
			
		||||
                                onClick={() => {
 | 
			
		||||
                                  setIsOpen(
 | 
			
		||||
                                    isOpen == user.user.email + d
 | 
			
		||||
                                      ? ''
 | 
			
		||||
                                      : user.user.email + d,
 | 
			
		||||
                                  )
 | 
			
		||||
                                }}
 | 
			
		||||
                              />
 | 
			
		||||
                            </Tooltip>
 | 
			
		||||
 | 
			
		||||
                            <Popover
 | 
			
		||||
                              placement="bottom"
 | 
			
		||||
                              isOpen={isOpen === user.user.email + d}
 | 
			
		||||
                              target={`indexBySN${user.user.id}_${d}`}
 | 
			
		||||
                              toggle={() =>
 | 
			
		||||
                                setIsOpen(
 | 
			
		||||
                                  isOpen == user.user.email + d
 | 
			
		||||
                                    ? ''
 | 
			
		||||
                                    : user.user.email + d,
 | 
			
		||||
                                )
 | 
			
		||||
                              }
 | 
			
		||||
                              innerRef={popoverRef}
 | 
			
		||||
                            >
 | 
			
		||||
                              <PopoverBody
 | 
			
		||||
                                style={{
 | 
			
		||||
                                  width: '300px',
 | 
			
		||||
                                  backgroundColor: 'white',
 | 
			
		||||
                                  boxShadow:
 | 
			
		||||
                                    '0 5px 15px rgba(30, 32, 37, 0.12)',
 | 
			
		||||
                                }}
 | 
			
		||||
                              >
 | 
			
		||||
                                <div>
 | 
			
		||||
                                  <div>
 | 
			
		||||
                                    <label htmlFor="option1">
 | 
			
		||||
                                      Select Option 1:
 | 
			
		||||
                                    </label>
 | 
			
		||||
                                    <select
 | 
			
		||||
                                      id="option1"
 | 
			
		||||
                                      value={selectedOption1}
 | 
			
		||||
                                      onChange={(e) =>
 | 
			
		||||
                                        setSelectedOption1(e.target.value)
 | 
			
		||||
                                      }
 | 
			
		||||
                                      className="form-select"
 | 
			
		||||
                                    >
 | 
			
		||||
                                      <option value="">Select...</option>
 | 
			
		||||
                                      <option value="option1">Option 1</option>
 | 
			
		||||
                                      <option value="option2">Option 2</option>
 | 
			
		||||
                                    </select>
 | 
			
		||||
                                  </div>
 | 
			
		||||
                                  {selectedOption1 && (
 | 
			
		||||
                                    <div className="mt-2">
 | 
			
		||||
                                      <label htmlFor="option2">
 | 
			
		||||
                                        Select Option 2:
 | 
			
		||||
                                      </label>
 | 
			
		||||
                                      <select
 | 
			
		||||
                                        id="option2"
 | 
			
		||||
                                        value={selectedOption2}
 | 
			
		||||
                                        onChange={(e) =>
 | 
			
		||||
                                          setSelectedOption2(e.target.value)
 | 
			
		||||
                                        }
 | 
			
		||||
                                        className="form-select"
 | 
			
		||||
                                      >
 | 
			
		||||
                                        <p>{v.status + ': ' + v.time_string}</p>{' '}
 | 
			
		||||
                                        {v.image && (
 | 
			
		||||
                                          <Image
 | 
			
		||||
                                            w={100}
 | 
			
		||||
                                            h={100}
 | 
			
		||||
                                            src={
 | 
			
		||||
                                              import.meta.env.VITE_BACKEND_URL.includes(
 | 
			
		||||
                                                'local',
 | 
			
		||||
                                              )
 | 
			
		||||
                                                ? import.meta.env
 | 
			
		||||
                                                    .VITE_BACKEND_URL +
 | 
			
		||||
                                                  'storage/' +
 | 
			
		||||
                                                  v.image
 | 
			
		||||
                                                : import.meta.env
 | 
			
		||||
                                                    .VITE_BACKEND_URL +
 | 
			
		||||
                                                  'image/storage/' +
 | 
			
		||||
                                                  v.image
 | 
			
		||||
                                            }
 | 
			
		||||
                                          />
 | 
			
		||||
                                        )}
 | 
			
		||||
                                      </Box>
 | 
			
		||||
                                    )
 | 
			
		||||
                                  })}
 | 
			
		||||
                              </div>
 | 
			
		||||
                            }
 | 
			
		||||
                          >
 | 
			
		||||
                            <IconCheck
 | 
			
		||||
                              size={20}
 | 
			
		||||
                              style={{
 | 
			
		||||
                                backgroundColor: 'green',
 | 
			
		||||
                                color: 'white',
 | 
			
		||||
                                borderRadius: '5px',
 | 
			
		||||
                                padding: '2px',
 | 
			
		||||
                              }}
 | 
			
		||||
                            />
 | 
			
		||||
                          </Tooltip>
 | 
			
		||||
                                        <option value="">Select...</option>
 | 
			
		||||
                                        <option value="optionA">
 | 
			
		||||
                                          Option A
 | 
			
		||||
                                        </option>
 | 
			
		||||
                                        <option value="optionB">
 | 
			
		||||
                                          Option B
 | 
			
		||||
                                        </option>
 | 
			
		||||
                                      </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                  )}
 | 
			
		||||
                                  {selectedOption2 && (
 | 
			
		||||
                                    <div className="mt-2">
 | 
			
		||||
                                      <label htmlFor="textInput">
 | 
			
		||||
                                        Enter Text:
 | 
			
		||||
                                      </label>
 | 
			
		||||
                                      <textarea
 | 
			
		||||
                                        id="textInput"
 | 
			
		||||
                                        value={textValue}
 | 
			
		||||
                                        onChange={(e) =>
 | 
			
		||||
                                          setTextValue(e.target.value)
 | 
			
		||||
                                        }
 | 
			
		||||
                                        className="form-control"
 | 
			
		||||
                                      />
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                  )}
 | 
			
		||||
 | 
			
		||||
                                  <MultiSelect
 | 
			
		||||
                                    mb={'md'}
 | 
			
		||||
                                    searchable
 | 
			
		||||
                                    label="User(s)"
 | 
			
		||||
                                    data={data.map((user) => {
 | 
			
		||||
                                      return {
 | 
			
		||||
                                        value: user.user.id.toString(),
 | 
			
		||||
                                        label: user.user.name,
 | 
			
		||||
                                      }
 | 
			
		||||
                                    })}
 | 
			
		||||
                                    onChange={(e) => {
 | 
			
		||||
                                      setCustomAddData({
 | 
			
		||||
                                        ...customAddData,
 | 
			
		||||
                                        data: e,
 | 
			
		||||
                                      })
 | 
			
		||||
                                    }}
 | 
			
		||||
                                  />
 | 
			
		||||
                                  <Select
 | 
			
		||||
                                    mb={'md'}
 | 
			
		||||
                                    label="Type"
 | 
			
		||||
                                    data={[
 | 
			
		||||
                                      { value: 'half', label: 'Half day' },
 | 
			
		||||
                                      { value: 'one', label: 'A day' },
 | 
			
		||||
                                    ]}
 | 
			
		||||
                                    onChange={(e) => {
 | 
			
		||||
                                      setCustomAddData({
 | 
			
		||||
                                        ...customAddData,
 | 
			
		||||
                                        type: e!,
 | 
			
		||||
                                      })
 | 
			
		||||
                                    }}
 | 
			
		||||
                                  />
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div className={classes.popoverFooter}>
 | 
			
		||||
                                  <Button
 | 
			
		||||
                                    variant="filled"
 | 
			
		||||
                                    color="red"
 | 
			
		||||
                                    onClick={() => setIsOpen('')}
 | 
			
		||||
                                  >
 | 
			
		||||
                                    Close
 | 
			
		||||
                                  </Button>
 | 
			
		||||
                                  <Button variant="filled" onClick={handleSave}>
 | 
			
		||||
                                    Save
 | 
			
		||||
                                  </Button>
 | 
			
		||||
                                </div>
 | 
			
		||||
                              </PopoverBody>
 | 
			
		||||
                            </Popover>
 | 
			
		||||
                          </>
 | 
			
		||||
                        ) : (
 | 
			
		||||
                          <IconX
 | 
			
		||||
                            size={20}
 | 
			
		||||
                            style={{
 | 
			
		||||
                              backgroundColor: '#ff4646',
 | 
			
		||||
                              color: 'white',
 | 
			
		||||
                              borderRadius: '5px',
 | 
			
		||||
                              padding: '2px',
 | 
			
		||||
                            }}
 | 
			
		||||
                          />
 | 
			
		||||
                          <>
 | 
			
		||||
                            <Tooltip
 | 
			
		||||
                              multiline
 | 
			
		||||
                              label={
 | 
			
		||||
                                <div key={d}>
 | 
			
		||||
                                  <p>
 | 
			
		||||
                                    - Work For Home (Buổi Sáng): Bị bể bánh xe
 | 
			
		||||
                                  </p>
 | 
			
		||||
                                  <p>- Nghỉ phép (Buổi Chiều): Bị cảm</p>
 | 
			
		||||
                                </div>
 | 
			
		||||
                              }
 | 
			
		||||
                            >
 | 
			
		||||
                              <IconX
 | 
			
		||||
                                size={20}
 | 
			
		||||
                                style={{
 | 
			
		||||
                                  backgroundColor: '#ff4646',
 | 
			
		||||
                                  color: 'white',
 | 
			
		||||
                                  borderRadius: '5px',
 | 
			
		||||
                                  padding: '2px',
 | 
			
		||||
                                }}
 | 
			
		||||
                                id={`indexBySN${user.user.id}_${d}`}
 | 
			
		||||
                                onClick={() => {
 | 
			
		||||
                                  setIsOpen(
 | 
			
		||||
                                    isOpen == user.user.email + d
 | 
			
		||||
                                      ? ''
 | 
			
		||||
                                      : user.user.email + d,
 | 
			
		||||
                                  )
 | 
			
		||||
                                }}
 | 
			
		||||
                              />
 | 
			
		||||
                            </Tooltip>
 | 
			
		||||
 | 
			
		||||
                            <Popover
 | 
			
		||||
                              placement="bottom"
 | 
			
		||||
                              isOpen={isOpen === user.user.email + d}
 | 
			
		||||
                              target={`indexBySN${user.user.id}_${d}`}
 | 
			
		||||
                              toggle={() =>
 | 
			
		||||
                                setIsOpen(
 | 
			
		||||
                                  isOpen == user.user.email + d
 | 
			
		||||
                                    ? ''
 | 
			
		||||
                                    : user.user.email + d,
 | 
			
		||||
                                )
 | 
			
		||||
                              }
 | 
			
		||||
                              innerRef={popoverRef}
 | 
			
		||||
                            >
 | 
			
		||||
                              <PopoverBody
 | 
			
		||||
                                style={{
 | 
			
		||||
                                  width: '300px',
 | 
			
		||||
                                  backgroundColor: 'white',
 | 
			
		||||
                                  boxShadow:
 | 
			
		||||
                                    '0 5px 15px rgba(30, 32, 37, 0.12)',
 | 
			
		||||
                                  padding: '20px',
 | 
			
		||||
                                }}
 | 
			
		||||
                              >
 | 
			
		||||
                                <div>
 | 
			
		||||
                                  <div>
 | 
			
		||||
                                    <label htmlFor="option1">
 | 
			
		||||
                                      Select Option 1:
 | 
			
		||||
                                    </label>
 | 
			
		||||
                                    <select
 | 
			
		||||
                                      id="option1"
 | 
			
		||||
                                      value={selectedOption1}
 | 
			
		||||
                                      onChange={(e) =>
 | 
			
		||||
                                        setSelectedOption1(e.target.value)
 | 
			
		||||
                                      }
 | 
			
		||||
                                      className="form-select"
 | 
			
		||||
                                    >
 | 
			
		||||
                                      <option value="">Select...</option>
 | 
			
		||||
                                      <option value="option1">Option 1</option>
 | 
			
		||||
                                      <option value="option2">Option 2</option>
 | 
			
		||||
                                    </select>
 | 
			
		||||
                                  </div>
 | 
			
		||||
                                  {selectedOption1 && (
 | 
			
		||||
                                    <div className="mt-2">
 | 
			
		||||
                                      <label htmlFor="option2">
 | 
			
		||||
                                        Select Option 2:
 | 
			
		||||
                                      </label>
 | 
			
		||||
                                      <select
 | 
			
		||||
                                        id="option2"
 | 
			
		||||
                                        value={selectedOption2}
 | 
			
		||||
                                        onChange={(e) =>
 | 
			
		||||
                                          setSelectedOption2(e.target.value)
 | 
			
		||||
                                        }
 | 
			
		||||
                                        className="form-select"
 | 
			
		||||
                                      >
 | 
			
		||||
                                        <option value="">Select...</option>
 | 
			
		||||
                                        <option value="optionA">
 | 
			
		||||
                                          Option A
 | 
			
		||||
                                        </option>
 | 
			
		||||
                                        <option value="optionB">
 | 
			
		||||
                                          Option B
 | 
			
		||||
                                        </option>
 | 
			
		||||
                                      </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                  )}
 | 
			
		||||
                                  {selectedOption2 && (
 | 
			
		||||
                                    <div className="mt-2">
 | 
			
		||||
                                      <label htmlFor="textInput">
 | 
			
		||||
                                        Enter Text:
 | 
			
		||||
                                      </label>
 | 
			
		||||
                                      <textarea
 | 
			
		||||
                                        id="textInput"
 | 
			
		||||
                                        value={textValue}
 | 
			
		||||
                                        onChange={(e) =>
 | 
			
		||||
                                          setTextValue(e.target.value)
 | 
			
		||||
                                        }
 | 
			
		||||
                                        className="form-control"
 | 
			
		||||
                                      />
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                  )}
 | 
			
		||||
 | 
			
		||||
                                  <MultiSelect
 | 
			
		||||
                                    mb={'md'}
 | 
			
		||||
                                    searchable
 | 
			
		||||
                                    label="User(s)"
 | 
			
		||||
                                    data={data.map((user) => {
 | 
			
		||||
                                      return {
 | 
			
		||||
                                        value: user.user.id.toString(),
 | 
			
		||||
                                        label: user.user.name,
 | 
			
		||||
                                      }
 | 
			
		||||
                                    })}
 | 
			
		||||
                                    onChange={(e) => {
 | 
			
		||||
                                      setCustomAddData({
 | 
			
		||||
                                        ...customAddData,
 | 
			
		||||
                                        data: e,
 | 
			
		||||
                                      })
 | 
			
		||||
                                    }}
 | 
			
		||||
                                  />
 | 
			
		||||
                                  <Select
 | 
			
		||||
                                    mb={'md'}
 | 
			
		||||
                                    label="Type"
 | 
			
		||||
                                    data={[
 | 
			
		||||
                                      { value: 'half', label: 'Half day' },
 | 
			
		||||
                                      { value: 'one', label: 'A day' },
 | 
			
		||||
                                    ]}
 | 
			
		||||
                                    onChange={(e) => {
 | 
			
		||||
                                      setCustomAddData({
 | 
			
		||||
                                        ...customAddData,
 | 
			
		||||
                                        type: e!,
 | 
			
		||||
                                      })
 | 
			
		||||
                                    }}
 | 
			
		||||
                                  />
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div className={classes.popoverFooter}>
 | 
			
		||||
                                  <Button
 | 
			
		||||
                                    variant="filled"
 | 
			
		||||
                                    color="red"
 | 
			
		||||
                                    onClick={() => setIsOpen('')}
 | 
			
		||||
                                  >
 | 
			
		||||
                                    Close
 | 
			
		||||
                                  </Button>
 | 
			
		||||
                                  <Button variant="filled" onClick={handleSave}>
 | 
			
		||||
                                    Save
 | 
			
		||||
                                  </Button>
 | 
			
		||||
                                </div>
 | 
			
		||||
                              </PopoverBody>
 | 
			
		||||
                            </Popover>
 | 
			
		||||
                          </>
 | 
			
		||||
                        )}
 | 
			
		||||
                      </Table.Td>
 | 
			
		||||
                    )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue