diff --git a/README.md b/README.md
new file mode 100644
index 0000000..17e9493
--- /dev/null
+++ b/README.md
@@ -0,0 +1,29 @@
+# my-app
+
+## Project setup
+
+```
+npm install
+```
+
+### Compiles and hot-reloads for development
+
+```
+npm run dev
+```
+
+### Compiles and minifies for production
+
+```
+npm run build
+```
+
+### Lints and fixes files
+
+```
+npm run lint
+```
+
+### Customize configuration
+
+See [Configuration Reference](https://cli.vuejs.org/config/).
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..162a3ea
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: ["@vue/cli-plugin-babel/preset"],
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..04d128b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,46 @@
+{
+ "name": "my-app",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "vue-cli-service serve",
+ "build": "vue-cli-service build",
+ "lint": "eslint --fix ",
+ "format": "prettier --write ."
+ },
+ "dependencies": {
+ "@fawmi/vue-google-maps": "^0.9.79",
+ "@mdi/font": "^7.3.67",
+ "@quasar/extras": "^1.0.0",
+ "core-js": "^3.8.3",
+ "moment": "^2.29.4",
+ "pinia": "^2.1.7",
+ "quasar": "^2.0.0",
+ "register-service-worker": "^1.7.2",
+ "vue": "^3.2.13",
+ "vue-class-component": "^8.0.0-0",
+ "vue-router": "^4.0.3",
+ "vue3-geolocation": "^1.0.0",
+ "vue3-google-map": "^0.18.0"
+ },
+ "devDependencies": {
+ "@types/googlemaps": "^3.43.3",
+ "@typescript-eslint/eslint-plugin": "^5.4.0",
+ "@typescript-eslint/parser": "^5.4.0",
+ "@vue/cli-plugin-babel": "~5.0.0",
+ "@vue/cli-plugin-eslint": "~5.0.0",
+ "@vue/cli-plugin-pwa": "~5.0.0",
+ "@vue/cli-plugin-router": "~5.0.0",
+ "@vue/cli-plugin-typescript": "~5.0.0",
+ "@vue/cli-service": "~5.0.0",
+ "@vue/eslint-config-typescript": "^9.1.0",
+ "eslint-config-prettier": "^8.10.0",
+ "eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-vue": "^8.0.3",
+ "prettier": "^2.4.1",
+ "sass": "1.32.12",
+ "sass-loader": "^12.0.0",
+ "typescript": "~4.5.5",
+ "vue-cli-plugin-quasar": "~5.0.2"
+ }
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..ae7bbdb
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/img/icons/android-chrome-192x192.png b/public/img/icons/android-chrome-192x192.png
new file mode 100644
index 0000000..b02aa64
Binary files /dev/null and b/public/img/icons/android-chrome-192x192.png differ
diff --git a/public/img/icons/android-chrome-512x512.png b/public/img/icons/android-chrome-512x512.png
new file mode 100644
index 0000000..06088b0
Binary files /dev/null and b/public/img/icons/android-chrome-512x512.png differ
diff --git a/public/img/icons/android-chrome-maskable-192x192.png b/public/img/icons/android-chrome-maskable-192x192.png
new file mode 100644
index 0000000..791e9c8
Binary files /dev/null and b/public/img/icons/android-chrome-maskable-192x192.png differ
diff --git a/public/img/icons/android-chrome-maskable-512x512.png b/public/img/icons/android-chrome-maskable-512x512.png
new file mode 100644
index 0000000..5f2098e
Binary files /dev/null and b/public/img/icons/android-chrome-maskable-512x512.png differ
diff --git a/public/img/icons/apple-touch-icon-120x120.png b/public/img/icons/apple-touch-icon-120x120.png
new file mode 100644
index 0000000..1427cf6
Binary files /dev/null and b/public/img/icons/apple-touch-icon-120x120.png differ
diff --git a/public/img/icons/apple-touch-icon-152x152.png b/public/img/icons/apple-touch-icon-152x152.png
new file mode 100644
index 0000000..f24d454
Binary files /dev/null and b/public/img/icons/apple-touch-icon-152x152.png differ
diff --git a/public/img/icons/apple-touch-icon-180x180.png b/public/img/icons/apple-touch-icon-180x180.png
new file mode 100644
index 0000000..404e192
Binary files /dev/null and b/public/img/icons/apple-touch-icon-180x180.png differ
diff --git a/public/img/icons/apple-touch-icon-60x60.png b/public/img/icons/apple-touch-icon-60x60.png
new file mode 100644
index 0000000..cf10a56
Binary files /dev/null and b/public/img/icons/apple-touch-icon-60x60.png differ
diff --git a/public/img/icons/apple-touch-icon-76x76.png b/public/img/icons/apple-touch-icon-76x76.png
new file mode 100644
index 0000000..c500769
Binary files /dev/null and b/public/img/icons/apple-touch-icon-76x76.png differ
diff --git a/public/img/icons/apple-touch-icon.png b/public/img/icons/apple-touch-icon.png
new file mode 100644
index 0000000..03c0c5d
Binary files /dev/null and b/public/img/icons/apple-touch-icon.png differ
diff --git a/public/img/icons/favicon-16x16.png b/public/img/icons/favicon-16x16.png
new file mode 100644
index 0000000..42af009
Binary files /dev/null and b/public/img/icons/favicon-16x16.png differ
diff --git a/public/img/icons/favicon-32x32.png b/public/img/icons/favicon-32x32.png
new file mode 100644
index 0000000..46ca04d
Binary files /dev/null and b/public/img/icons/favicon-32x32.png differ
diff --git a/public/img/icons/msapplication-icon-144x144.png b/public/img/icons/msapplication-icon-144x144.png
new file mode 100644
index 0000000..7808237
Binary files /dev/null and b/public/img/icons/msapplication-icon-144x144.png differ
diff --git a/public/img/icons/mstile-150x150.png b/public/img/icons/mstile-150x150.png
new file mode 100644
index 0000000..3b37a43
Binary files /dev/null and b/public/img/icons/mstile-150x150.png differ
diff --git a/public/img/icons/safari-pinned-tab.svg b/public/img/icons/safari-pinned-tab.svg
new file mode 100644
index 0000000..e44c0d5
--- /dev/null
+++ b/public/img/icons/safari-pinned-tab.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..2e6fd57
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ <%= htmlWebpackPlugin.options.title %>
+
+
+
+
+
+
+
+
+
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..eb05362
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow:
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..1643ebf
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
+
diff --git a/src/assets/logo.png b/src/assets/logo.png
new file mode 100644
index 0000000..f3d2503
Binary files /dev/null and b/src/assets/logo.png differ
diff --git a/src/assets/logo.svg b/src/assets/logo.svg
new file mode 100644
index 0000000..87a1eee
--- /dev/null
+++ b/src/assets/logo.svg
@@ -0,0 +1,15 @@
+
diff --git a/src/assets/map1.png b/src/assets/map1.png
new file mode 100644
index 0000000..34d643d
Binary files /dev/null and b/src/assets/map1.png differ
diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue
new file mode 100644
index 0000000..ac76175
--- /dev/null
+++ b/src/components/HelloWorld.vue
@@ -0,0 +1,488 @@
+
+
+
+
+
+
+
+
+
+ ลงเวลาเข้างาน
+ ลงเวลาออกงาน
+
+
+
+
+
+
+
+
+
+ {{ Thai }}
+
+
+
+
+ {{ formattedH }}:
+
+
+
+
+ {{ formattedM }}:
+
+
+
+
+
+
+
+
+
+
+
+
+ พื้นที่ใกล้เคียง
+ :
+ {{ location }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ สถานที่ทำงาน
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ *หมายเหตุ คลิกลงเวลาเข้างานแล้วระบบจะลงเวลาทันที
+
+
+
+
+
+
+
+
+
+
+
+
+ ลงเวลาเข้างานของคุณ
+ ลงเวลาออกงานของคุณ
+
+
+
+
+
+ {{ Thai }}
+
+
+
+ {{ formattedH }}:
+
+
{{ formattedM }}
+
+
+
+
+ {{ location }}
+
+
{{ coordinates }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..7e254f9
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,23 @@
+import { createApp } from "vue";
+import App from "./App.vue";
+import { createPinia } from "pinia";
+import "./registerServiceWorker";
+import router from "./router";
+import { Quasar } from "quasar";
+import quasarUserOptions from "./quasar-user-options";
+// import GMap from "vue3-google-map";
+import VueGoogleMaps from "@fawmi/vue-google-maps";
+
+const app = createApp(App);
+const pinia = createPinia();
+
+app.use(router);
+app.use(pinia);
+app.use(Quasar, quasarUserOptions);
+app.use(VueGoogleMaps, {
+ load: {
+ key: "AIzaSyC83QLHjctDyKKyL4XZgwNfqp338xZiRnQ",
+ },
+});
+
+app.mount("#app");
diff --git a/src/modules/checkin/componenst/mapCheck.vue b/src/modules/checkin/componenst/mapCheck.vue
new file mode 100644
index 0000000..282c882
--- /dev/null
+++ b/src/modules/checkin/componenst/mapCheck.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/checkin/componenst/tableHistory.vue b/src/modules/checkin/componenst/tableHistory.vue
new file mode 100644
index 0000000..010ad39
--- /dev/null
+++ b/src/modules/checkin/componenst/tableHistory.vue
@@ -0,0 +1,203 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/checkin/componenst/toolBar.vue b/src/modules/checkin/componenst/toolBar.vue
new file mode 100644
index 0000000..eefe74b
--- /dev/null
+++ b/src/modules/checkin/componenst/toolBar.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
+
diff --git a/src/modules/checkin/interface/index/Main.ts b/src/modules/checkin/interface/index/Main.ts
new file mode 100644
index 0000000..08effb0
--- /dev/null
+++ b/src/modules/checkin/interface/index/Main.ts
@@ -0,0 +1,5 @@
+interface DataOption {
+ id: string;
+ name: string;
+}
+export type { DataOption };
diff --git a/src/modules/checkin/interface/response/checkin.ts b/src/modules/checkin/interface/response/checkin.ts
new file mode 100644
index 0000000..5745b88
--- /dev/null
+++ b/src/modules/checkin/interface/response/checkin.ts
@@ -0,0 +1,7 @@
+interface FormRef {
+ model: object | null;
+ useLocation: object | null;
+ [key: string]: any;
+}
+
+export type { FormRef };
diff --git a/src/modules/checkin/router.ts b/src/modules/checkin/router.ts
new file mode 100644
index 0000000..5f514e7
--- /dev/null
+++ b/src/modules/checkin/router.ts
@@ -0,0 +1,38 @@
+/**
+ * Router Checkin
+ */
+
+const Checkin = () => import("@/modules/04_checkin/views/CheckIn.vue");
+const History = () => import("@/modules/04_checkin/views/History.vue");
+
+/* const Checkout = () => import("@/modules/04_checkin/views/Checkout.vue");
+ */
+export default [
+ {
+ path: "/check-in",
+ name: "Checkin",
+ component: Checkin,
+ meta: {
+ Auth: true,
+ Key: [7],
+ },
+ },
+ {
+ path: "/check-in/history",
+ name: "History",
+ component: History,
+ meta: {
+ Auth: true,
+ Key: [7],
+ },
+ },
+ /* {
+ path: "/check-out",
+ name: "Checkout",
+ component: Checkout,
+ meta: {
+ Auth: true,
+ Key: [7],
+ },
+ }, */
+];
diff --git a/src/modules/checkin/views/HistoryView.vue b/src/modules/checkin/views/HistoryView.vue
new file mode 100644
index 0000000..7cbab8c
--- /dev/null
+++ b/src/modules/checkin/views/HistoryView.vue
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
+
+
+
ประวัติการลงเวลา
+
+
+
+
+
+
+
+
+ {{ props.rowIndex + 1 }}
+
+
+ {{ props.row.date }}
+
+
+ {{ props.row.in }}
+
+
+ {{ props.row.loIn }}
+
+
+ {{ props.row.out }}
+
+
+ {{ props.row.loOut }}
+
+
+ {{ props.row.status }}
+
+
+
+
+
+
+
+
+
+ {{ col.label }}
+
+
+
+ {{ col.value }}
+ {{ col.value }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/quasar-user-options.ts b/src/quasar-user-options.ts
new file mode 100644
index 0000000..28f60f7
--- /dev/null
+++ b/src/quasar-user-options.ts
@@ -0,0 +1,11 @@
+import "./styles/quasar.scss";
+import "@quasar/extras/material-icons/material-icons.css";
+import "@quasar/extras/material-icons-outlined/material-icons-outlined.css";
+import "@quasar/extras/material-icons-round/material-icons-round.css";
+import "@quasar/extras/material-icons-sharp/material-icons-sharp.css";
+
+// To be used on app.use(Quasar, { ... })
+export default {
+ config: {},
+ plugins: {},
+};
diff --git a/src/registerServiceWorker.ts b/src/registerServiceWorker.ts
new file mode 100644
index 0000000..0f13c06
--- /dev/null
+++ b/src/registerServiceWorker.ts
@@ -0,0 +1,33 @@
+/* eslint-disable no-console */
+
+import { register } from "register-service-worker";
+if (process.env.NODE_ENV === "production") {
+ register(`${process.env.BASE_URL}service-worker.js`, {
+ ready() {
+ console.log(
+ "App is being served from cache by a service worker.\n" +
+ "For more details, visit https://goo.gl/AFskqB"
+ );
+ },
+ registered() {
+ console.log("Service worker has been registered.");
+ },
+ cached() {
+ console.log("Content has been cached for offline use.");
+ },
+ updatefound() {
+ console.log("New content is downloading.");
+ },
+ updated() {
+ console.log("New content is available; please refresh.");
+ },
+ offline() {
+ console.log(
+ "No internet connection found. App is running in offline mode."
+ );
+ },
+ error(error) {
+ console.error("Error during service worker registration:", error);
+ },
+ });
+}
diff --git a/src/router/index.ts b/src/router/index.ts
new file mode 100644
index 0000000..65ac2b1
--- /dev/null
+++ b/src/router/index.ts
@@ -0,0 +1,31 @@
+import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
+import HomeView from "../views/HomeView.vue";
+import history from "../modules/checkin/views/HistoryView.vue";
+const routes: Array = [
+ {
+ path: "/",
+ name: "home",
+ component: HomeView,
+ },
+ {
+ path: "/about",
+ name: "about",
+ // route level code-splitting
+ // this generates a separate chunk (about.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () =>
+ import(/* webpackChunkName: "about" */ "../views/AboutView.vue"),
+ },
+ {
+ path: "/check-in/history",
+ name: "history",
+ component: history,
+ },
+];
+
+const router = createRouter({
+ history: createWebHistory(process.env.BASE_URL),
+ routes,
+});
+
+export default router;
diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts
new file mode 100644
index 0000000..55e0ca6
--- /dev/null
+++ b/src/shims-vue.d.ts
@@ -0,0 +1,6 @@
+/* eslint-disable */
+declare module "*.vue" {
+ import type { DefineComponent } from "vue";
+ const component: DefineComponent<{}, {}, any>;
+ export default component;
+}
diff --git a/src/stores/mixin.ts b/src/stores/mixin.ts
new file mode 100644
index 0000000..593b971
--- /dev/null
+++ b/src/stores/mixin.ts
@@ -0,0 +1,78 @@
+import { defineStore } from "pinia";
+
+export const useCounterMixin = defineStore("mixin", () => {
+ function date2Thai(
+ srcDate: Date,
+ isFullMonth: boolean = false,
+ isTime: boolean = false
+ ) {
+ if (srcDate == null) {
+ return null;
+ `
+ `;
+ }
+ const date = new Date(srcDate);
+ const isValidDate = Boolean(+date);
+ if (!isValidDate) return srcDate.toString();
+ if (isValidDate && date.getFullYear() < 1000) return srcDate.toString();
+ const fullMonthThai = [
+ "มกราคม",
+ "กุมภาพันธ์",
+ "มีนาคม",
+ "เมษายน",
+ "พฤษภาคม",
+ "มิถุนายน",
+ "กรกฎาคม",
+ "สิงหาคม",
+ "กันยายน",
+ "ตุลาคม",
+ "พฤศจิกายน",
+ "ธันวาคม",
+ ];
+ const abbrMonthThai = [
+ "ม.ค.",
+ "ก.พ.",
+ "มี.ค.",
+ "เม.ย.",
+ "พ.ค.",
+ "มิ.ย.",
+ "ก.ค.",
+ "ส.ค.",
+ "ก.ย.",
+ "ต.ค.",
+ "พ.ย.",
+ "ธ.ค.",
+ ];
+ let dstYear = 0;
+ if (date.getFullYear() > 2500) {
+ dstYear = date.getFullYear();
+ } else {
+ dstYear = date.getFullYear() + 543;
+ }
+ let dstMonth = "";
+ if (isFullMonth) {
+ dstMonth = fullMonthThai[date.getMonth()];
+ } else {
+ dstMonth = abbrMonthThai[date.getMonth()];
+ }
+ let dstTime = "";
+ if (isTime) {
+ const H = date.getHours().toString().padStart(2, "0");
+ const M = date.getMinutes().toString().padStart(2, "0");
+ // const S = date.getSeconds().toString().padStart(2, "0")
+ // dstTime = " " + H + ":" + M + ":" + S + " น."
+ dstTime = " " + H + ":" + M + " น.";
+ }
+ return (
+ date.getDate().toString().padStart(2, "0") +
+ " " +
+ dstMonth +
+ " " +
+ dstYear +
+ dstTime
+ );
+ }
+ return {
+ date2Thai,
+ };
+});
diff --git a/src/styles/quasar.scss b/src/styles/quasar.scss
new file mode 100644
index 0000000..835a742
--- /dev/null
+++ b/src/styles/quasar.scss
@@ -0,0 +1,3 @@
+@import "./quasar.variables.scss";
+@import "~quasar-styl";
+// @import '~quasar-addon-styl';
diff --git a/src/styles/quasar.variables.scss b/src/styles/quasar.variables.scss
new file mode 100644
index 0000000..dc43e04
--- /dev/null
+++ b/src/styles/quasar.variables.scss
@@ -0,0 +1,15 @@
+// It's highly recommended to change the default colors
+// to match your app's branding.
+
+$primary: #02a998;
+$secondary: #016987;
+$accent: #9c27b0;
+
+$dark: #35473c;
+
+$positive: #21ba45;
+$negative: #c10015;
+$info: #31ccec;
+$warning: #f2c037;
+
+@import "~quasar-variables-styl";
diff --git a/src/views/AboutView.vue b/src/views/AboutView.vue
new file mode 100644
index 0000000..3fa2807
--- /dev/null
+++ b/src/views/AboutView.vue
@@ -0,0 +1,5 @@
+
+
+
This is an about page
+
+
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
new file mode 100644
index 0000000..072e84b
--- /dev/null
+++ b/src/views/HomeView.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..66c82bf
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,30 @@
+{
+ "compilerOptions": {
+ "target": "esnext",
+ "module": "esnext",
+ "strict": true,
+ "jsx": "preserve",
+ "moduleResolution": "node",
+ "experimentalDecorators": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "forceConsistentCasingInFileNames": true,
+ "useDefineForClassFields": true,
+ "sourceMap": true,
+ "baseUrl": ".",
+ "types": ["webpack-env"],
+ "paths": {
+ "@/*": ["src/*"]
+ },
+ "lib": ["esnext", "dom", "dom.iterable", "scripthost"]
+ },
+ "include": [
+ "src/**/*.ts",
+ "src/**/*.tsx",
+ "src/**/*.vue",
+ "tests/**/*.ts",
+ "tests/**/*.tsx"
+ ],
+ "exclude": ["node_modules"]
+}
diff --git a/vue.config.js b/vue.config.js
new file mode 100644
index 0000000..d7b733d
--- /dev/null
+++ b/vue.config.js
@@ -0,0 +1,12 @@
+const { defineConfig } = require("@vue/cli-service");
+module.exports = defineConfig({
+ transpileDependencies: ["quasar"],
+
+ pluginOptions: {
+ quasar: {
+ importStrategy: "kebab",
+ rtlSupport: false,
+ },
+ },
+
+});