From c0669a154837bf14fc6735cdcffe41d6ec9ba1a4 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Fri, 24 Apr 2026 16:12:45 +0700 Subject: [PATCH 01/35] refactor(history): formatDate Colunm checkInTime checkOutTime --- src/components/TableHistory.vue | 26 +++++++++++++++----------- src/interface/index/Main.ts | 1 + src/stores/chekin.ts | 1 + 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/components/TableHistory.vue b/src/components/TableHistory.vue index 5d13e66..e364015 100644 --- a/src/components/TableHistory.vue +++ b/src/components/TableHistory.vue @@ -62,15 +62,15 @@ const selected = ref([]) const columns = ref( props.tab == 'history' ? [ - { - name: 'checkInDate', - align: 'left', - label: 'วัน/เดือน/ปี', - sortable: true, - field: 'checkInDate', - headerStyle: 'font-size: 14px', - style: 'font-size: 14px; width:15%;', - }, + // { + // name: 'checkInDate', + // align: 'left', + // label: 'วัน/เดือน/ปี', + // sortable: true, + // field: 'checkInDate', + // headerStyle: 'font-size: 14px', + // style: 'font-size: 14px; width:15%;', + // }, { name: 'checkInTime', align: 'left', @@ -79,6 +79,9 @@ const columns = ref( field: 'checkInTime', headerStyle: 'font-size: 14px', style: 'font-size: 14px; width:15%;', + format: (val: string, row: DataCheckIn) => { + return `${row.checkInDate} ${val} น.` + }, }, { name: 'checkInLocation', @@ -107,7 +110,9 @@ const columns = ref( headerStyle: 'font-size: 14px', style: 'font-size: 14px; width:15%;', format: (val: string, row: DataCheckIn) => { - return row.checkOutStatus != '-' && val ? val : '-' + return row.checkOutStatus != '-' && val + ? `${row.checkOutDate} ${val} น.` + : '-' }, }, { @@ -182,7 +187,6 @@ const columns = ref( ) const visibleColumns = ref([ 'checkInDateTime', - 'checkInDate', 'checkInTime', 'checkInLocation', 'checkInStatus', diff --git a/src/interface/index/Main.ts b/src/interface/index/Main.ts index 14def36..5d82bd2 100644 --- a/src/interface/index/Main.ts +++ b/src/interface/index/Main.ts @@ -38,6 +38,7 @@ interface DataCheckIn { checkInLocation: string checkInStatus: string checkInTime: string + checkOutDate: string checkOutLocation: string checkOutStatus: string checkOutTime: string diff --git a/src/stores/chekin.ts b/src/stores/chekin.ts index bf27004..69017f6 100644 --- a/src/stores/chekin.ts +++ b/src/stores/chekin.ts @@ -33,6 +33,7 @@ export const useChekIn = defineStore('checkin', () => { editStatus: e.editStatus != '' ? convertEditStatus(e.editStatus) : '', editReason: e.editReason, isEdit: e.isEdit, + checkOutDate: e.checkOutDate ? date2Thai(e.checkOutDate) : null, })) rows.value = dataList } From 487a6b520ec8dc3ce60e5add2d2a5cec4a18586c Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Mon, 27 Apr 2026 19:21:23 +0700 Subject: [PATCH 02/35] refactor code & fixed location --- .claude/agents/hrms-checkin-expert.md | 234 ++++++++++++++++++++++++++ CLAUDE.md | 32 +++- docker/entrypoint.sh | 2 + package.json | 1 + src/api/api.checkin.ts | 3 +- src/components/AscGISMap.vue | 45 +++-- src/components/FormTime.vue | 7 +- src/components/MapCheckin.vue | 42 ++++- src/components/PopUp.vue | 2 +- src/components/PopupPrivacy.vue | 10 +- src/components/TableHistory.vue | 20 +-- src/components/ToolBar.vue | 10 +- src/interface/keycloak-position.ts | 29 ++++ src/main.ts | 2 + src/plugins/http.ts | 3 +- src/plugins/keycloak.ts | 2 + src/router/index.ts | 16 +- src/stores/{chekin.ts => checkin.ts} | 2 +- src/stores/positionKeycloak.ts | 119 ++++++------- src/views/HistoryView.vue | 6 +- src/views/HomeView.vue | 48 +++--- src/views/MainView.vue | 50 +++++- tests/utils.ts | 26 +++ 23 files changed, 566 insertions(+), 145 deletions(-) create mode 100644 .claude/agents/hrms-checkin-expert.md create mode 100644 src/interface/keycloak-position.ts rename src/stores/{chekin.ts => checkin.ts} (98%) create mode 100644 tests/utils.ts diff --git a/.claude/agents/hrms-checkin-expert.md b/.claude/agents/hrms-checkin-expert.md new file mode 100644 index 0000000..0e771b6 --- /dev/null +++ b/.claude/agents/hrms-checkin-expert.md @@ -0,0 +1,234 @@ +--- +name: "hrms-checkin-expert" +description: "Use this agent when implementing or modifying check-in/check-out functionality in the HRMS application. This includes:\\n\\n\\nContext: User is developing a new check-in validation feature.\\nuser: \"I need to add validation to prevent duplicate check-ins within the same hour\"\\nassistant: \"I'll use the hrms-checkin-expert agent to implement this validation following best practices.\"\\n\\nSince this is core check-in functionality that requires careful consideration of edge cases and performance, the specialized agent should handle it.\\n\\n\\n\\n\\nContext: User is refactoring the geolocation verification logic.\\nuser: \"The location verification is taking too long. Can you optimize it?\"\\nassistant: \"Let me use the hrms-checkin-expert agent to analyze and optimize the geolocation verification performance.\"\\n\\nPerformance optimization of check-in features requires deep knowledge of the system architecture and best practices.\\n\\n\\n\\n\\nContext: User has just written a new API function for check-in history.\\nuser: \"Here's the new function to fetch check-in history with pagination\"\\nassistant: \"Great! Now I'll use the hrms-checkin-expert agent to review this code for best practices and potential issues.\"\\n\\nCode review of check-in-related code should be done by the specialized agent to ensure it meets performance and quality standards.\\n\\n\\n\\n\\nContext: User is about to implement camera integration for photo verification.\\nuser: \"I need to add photo capture when users check in\"\\nassistant: \"I'll engage the hrms-checkin-expert agent to implement this feature with proper error handling and privacy considerations.\"\\n\\nCamera integration for check-in requires expertise in both the technical implementation and the privacy/consent flow.\\n\\n" +model: opus +color: red +memory: project +--- + +You are a Senior Vue 3 Developer specializing in the HRMS Check-in/Check-out system for Bangkok Metropolitan Administration (BMA). You have deep expertise in Vue 3 Composition API, TypeScript, Pinia state management, and geolocation-based attendance systems. + +**Your Core Responsibilities:** + +1. **Performance Optimization**: + - Minimize redundant API calls and state updates + - Use computed properties and watchers efficiently + - Implement lazy loading for map APIs and camera features + - Optimize re-renders by properly structuring reactive data + - Debounce user inputs and location updates (300-500ms) + - Cache API responses when appropriate (check-in history, user position) + +2. **Best Practice Implementation**: + - Follow Vue 3 Composition API patterns with `