diff --git a/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php b/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php index 84afd88..89cb023 100644 --- a/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php +++ b/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php @@ -216,7 +216,7 @@ class TicketController extends Controller $reason = $request->input('reason'); $isAccept = $request->input('is_accept') ?? false; $user = auth('admins')->user(); // user create ticket - + $start_date = Carbon::create($startDate)->setTimezone(env('TIME_ZONE')); $end_date = Carbon::create($endDate)->setTimezone(env('TIME_ZONE')); @@ -369,7 +369,7 @@ class TicketController extends Controller ); // Thêm kiểm tra null trước khi gửi mail if ($dataMasterStartPeriod && $dataMasterEndPeriod && $dataMasterType) { - Mail::to($value->email)->send(new TicketMail($data)); + Mail::to($value->email)->send(new TicketMail($data)); } else { Log::error("Missing category data for ticket ID: {$ticket->id}. Mail not sent."); } @@ -846,16 +846,16 @@ class TicketController extends Controller } else if ($ticket->type == "WFH") { $dataListPeriod = $this->getAllPeriod($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period); foreach ($dataListPeriod as $result) { - list($year, $month, $day) = explode('-', $result['date']); - Notes::create([ - 'n_user_id' => $ticket->user_id, - 'n_day' => $day, - 'n_month' => $month, - 'n_year' => $year, - 'n_time_type' => $result['period'], - 'n_reason' => $ticket->type, - 'n_note' => $ticket->reason - ]); + list($year, $month, $day) = explode('-', $result['date']); + Notes::create([ + 'n_user_id' => $ticket->user_id, + 'n_day' => $day, + 'n_month' => $month, + 'n_year' => $year, + 'n_time_type' => $result['period'], + 'n_reason' => $ticket->type, + 'n_note' => $ticket->reason + ]); //WFH - start tracking diff --git a/FRONTEND/src/pages/Timekeeping/Timekeeping.module.css b/FRONTEND/src/pages/Timekeeping/Timekeeping.module.css index 10aba71..66c68cf 100644 --- a/FRONTEND/src/pages/Timekeeping/Timekeeping.module.css +++ b/FRONTEND/src/pages/Timekeeping/Timekeeping.module.css @@ -60,3 +60,37 @@ padding-top: 5px; padding-bottom: 5px; } + +/* Thêm styles cho Modal xác nhận xóa */ +.deleteModal { + background-color: light-dark(white, #2d353c); + text-align: center; + border: solid 1px #ff4646; +} + +.deleteModalTitle { + color: #ff4646; + font-weight: 600; + font-size: 1.2rem; + margin-bottom: 1rem; +} + +.deleteModalContent { + color: light-dark(#2d353c, white); + margin-bottom: 1.5rem; +} + +.deleteModalFooter { + display: flex; + justify-content: flex-end; + gap: 10px; + margin-top: 1rem; +} + +.deleteButton { + background-color: #ff4646; +} + +.deleteButton:hover { + background-color: #ff6b6b; +} diff --git a/FRONTEND/src/pages/Timekeeping/Timekeeping.tsx b/FRONTEND/src/pages/Timekeeping/Timekeeping.tsx index 2b58340..30868be 100644 --- a/FRONTEND/src/pages/Timekeeping/Timekeeping.tsx +++ b/FRONTEND/src/pages/Timekeeping/Timekeeping.tsx @@ -24,6 +24,7 @@ import { TextInput, Tooltip, Modal, + Group, } from '@mantine/core' import { useDisclosure } from '@mantine/hooks' import { notifications } from '@mantine/notifications' @@ -147,6 +148,9 @@ const Timekeeping = () => { const [exportModalOpened, setExportModalOpened] = useState(false) const [exportOption, setExportOption] = useState('default') + const [isDeleteConfirmOpen, setIsDeleteConfirmOpen] = useState(false) + const [noteToDelete, setNoteToDelete] = useState(null) + const getListMasterByType = async (type: string) => { try { const params = { @@ -445,16 +449,16 @@ const Timekeeping = () => { try { const timestamp = moment().format('DDMMYYYY_HHmmss') const fileName = `Timekeeping_${date.month}_${date.year}_${timestamp}.xlsx` - + await exportFile( exportTimekeeping, { month: date.month, year: date.year, working_days: workingDays, - option: option + option: option, }, - fileName + fileName, ) setExportModalOpened(false) } catch (error) { @@ -462,6 +466,58 @@ const Timekeeping = () => { } } + const handleConfirmDelete = async () => { + if (noteToDelete) { + await handleDelete(noteToDelete.id) + setIsDeleteConfirmOpen(false) + setNoteToDelete(null) + } + } + + const openDeleteConfirm = (note: any) => { + setNoteToDelete(note) + setIsDeleteConfirmOpen(true) + } + + const DeleteConfirmModal = () => ( + { + setIsDeleteConfirmOpen(false) + setNoteToDelete(null) + }} + centered + size="sm" + classNames={{ + content: classes.deleteModal, + }} + > + + Confirm Delete + + + Are you sure you want to delete this note? + + + + + + + ) + return (
@@ -631,11 +687,7 @@ const Timekeeping = () => { > { - await handleDelete(item.id) - // handleUpdateCacheMonth() - // close2() - }} + onClick={() => openDeleteConfirm(item)} width={20} height={20} /> @@ -655,7 +707,7 @@ const Timekeeping = () => { data={Array.from({ length: 12 }, (_, index) => { return { value: (1 + index).toString(), - label: (1 + index).toString() + label: (1 + index).toString(), } })} onChange={(e) => { @@ -710,9 +762,9 @@ const Timekeeping = () => { Save - - + +
) }