diff --git a/components.d.ts b/components.d.ts index b12a615..3cd7803 100644 --- a/components.d.ts +++ b/components.d.ts @@ -4,7 +4,14 @@ declare module 'vue' { export interface GlobalComponents { Header: typeof import('./src/components/Header.vue')['default'] - Input: typeof import('./src/components/Input.vue')['default'] + LoginForm: typeof import('./src/components/LoginForm.vue')['default'] + RegisterAccountLinks: typeof import('./src/components/RegisterAccountLinks.vue')['default'] + SSOLogin: typeof import('./src/components/SSOLogin.vue')['default'] + TheCheckbox: typeof import('./src/components/TheCheckbox.vue')['default'] + TheInput: typeof import('./src/components/TheInput.vue')['default'] + TheRadio: typeof import('./src/components/TheRadio.vue')['default'] + TheSelect: typeof import('./src/components/TheSelect.vue')['default'] + AuthLayout: typeof import('./src/components/layout/AuthLayout.vue')['default'] } } diff --git a/package.json b/package.json index 99bc0af..2f21e52 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,16 @@ "lint:fix": "eslint --fix --ext .js,.ts,.vue,.json ." }, "dependencies": { + "@vee-validate/i18n": "^4.1.20", + "@vee-validate/rules": "^4.1.20", "@vueuse/core": "^5.0.2", + "vee-validate": "^4.4.4", "vue": "^3.1.1", - "vue-router": "^4.0.8" + "vue-router": "^4.0.8", + "yup": "^0.32.9" }, "devDependencies": { - "@hannoeru/eslint-config": "^0.1.1", + "@hannoeru/eslint-config": "^0.1.2", "@iconify/json": "^1.1.354", "@vitejs/plugin-vue": "^1.2.3", "@vue/compiler-sfc": "^3.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5ce63e2..f7ddebb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,13 +1,16 @@ lockfileVersion: 5.3 specifiers: - '@hannoeru/eslint-config': ^0.1.1 + '@hannoeru/eslint-config': ^0.1.2 '@iconify/json': ^1.1.354 + '@vee-validate/i18n': ^4.1.20 + '@vee-validate/rules': ^4.1.20 '@vitejs/plugin-vue': ^1.2.3 '@vue/compiler-sfc': ^3.1.1 '@vueuse/core': ^5.0.2 eslint: ^7.28.0 typescript: ^4.3.2 + vee-validate: ^4.4.4 vite: ^2.3.7 vite-plugin-components: ^0.10.4 vite-plugin-icons: ^0.6.1 @@ -17,14 +20,19 @@ specifiers: vue-router: ^4.0.8 vue-tsc: ^0.1.7 windicss: ^3.1.3 + yup: ^0.32.9 dependencies: + '@vee-validate/i18n': 4.1.20 + '@vee-validate/rules': 4.1.20 '@vueuse/core': 5.0.2_vue@3.1.1 + vee-validate: 4.4.4_vue@3.1.1 vue: 3.1.1 vue-router: 4.0.8_vue@3.1.1 + yup: 0.32.9 devDependencies: - '@hannoeru/eslint-config': 0.1.1_eslint@7.28.0+typescript@4.3.2 + '@hannoeru/eslint-config': 0.1.2_eslint@7.28.0+typescript@4.3.2 '@iconify/json': 1.1.354 '@vitejs/plugin-vue': 1.2.3_@vue+compiler-sfc@3.1.1 '@vue/compiler-sfc': 3.1.1_vue@3.1.1 @@ -217,6 +225,12 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + /@babel/runtime/7.14.0: + resolution: {integrity: sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==} + dependencies: + regenerator-runtime: 0.13.7 + dev: false + /@babel/template/7.12.13: resolution: {integrity: sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==} dependencies: @@ -279,8 +293,8 @@ packages: - supports-color dev: true - /@hannoeru/eslint-config-basic/0.1.1_eslint@7.28.0: - resolution: {integrity: sha512-WP3gk6hR3wv57b+n3LvlDR3kUXpNov7G4xT7eDW23qn8O8AuTntdegA9xOPF1oS1YJhATFSrf/3ZfL66h3zv6A==} + /@hannoeru/eslint-config-basic/0.1.2_eslint@7.28.0: + resolution: {integrity: sha512-aoEF9+7V+dtUBG9kFy+L7FhmU2MzLE1IeUwE/wozjYZH1yzMEqwwGF5w0QqOgOUd4aOZDUuOD1KEL7O1WLsq/Q==} peerDependencies: eslint: '>=7.4.0' dependencies: @@ -300,12 +314,12 @@ packages: - supports-color dev: true - /@hannoeru/eslint-config-react/0.1.1_eslint@7.28.0+typescript@4.3.2: - resolution: {integrity: sha512-r+hKH/ZQeq8R8stsJNPY4Xgxi9ycWocg62zZBbMyUgtUOqt+ofd6uqqQJc4FbeeT3wBma715lkMWo71ArLp9FQ==} + /@hannoeru/eslint-config-react/0.1.2_eslint@7.28.0+typescript@4.3.2: + resolution: {integrity: sha512-FHh3VcxhjUpw9dHYDWcYDaAeioeT+6090mJeAe88IGx278QY+muXihIWzEsEmfq3N6/ggSzttM9SibjtnL1PiQ==} peerDependencies: eslint: '>=7.4.0' dependencies: - '@hannoeru/eslint-config-ts': 0.1.1_eslint@7.28.0+typescript@4.3.2 + '@hannoeru/eslint-config-ts': 0.1.2_eslint@7.28.0+typescript@4.3.2 eslint: 7.28.0 eslint-plugin-react: 7.24.0_eslint@7.28.0 transitivePeerDependencies: @@ -313,13 +327,13 @@ packages: - typescript dev: true - /@hannoeru/eslint-config-ts/0.1.1_eslint@7.28.0+typescript@4.3.2: - resolution: {integrity: sha512-ydM8yfiVfwcAD/wkWVkZAEiOorcgzM1MXYvtEDrpZNpO2NN6osS9J3PqX1T/CSJgR9qr/e/zudEoaWZcAXx4gg==} + /@hannoeru/eslint-config-ts/0.1.2_eslint@7.28.0+typescript@4.3.2: + resolution: {integrity: sha512-hQtFRC7tS7KX1u0kVPih6039uO9/crqbNk1hmH5ghmqpym4r17Ai5++18gIWvG881nRiFr+56zULT/qMdZnZDQ==} peerDependencies: eslint: '>=7.4.0' typescript: '>=3.9' dependencies: - '@hannoeru/eslint-config-basic': 0.1.1_eslint@7.28.0 + '@hannoeru/eslint-config-basic': 0.1.2_eslint@7.28.0 '@typescript-eslint/eslint-plugin': 4.26.1_c8cbd5e7f5f92609ec78d991aced454b '@typescript-eslint/parser': 4.26.1_eslint@7.28.0+typescript@4.3.2 eslint: 7.28.0 @@ -328,12 +342,12 @@ packages: - supports-color dev: true - /@hannoeru/eslint-config-vue/0.1.1_eslint@7.28.0+typescript@4.3.2: - resolution: {integrity: sha512-Re5UUenP7WEXV3Xx30GOEoGfhPrgrbur/pyES0DpsZU34jyrvQfotHBXs0xzQSxRVeNB3y3O2H3MWOpMnBDxOA==} + /@hannoeru/eslint-config-vue/0.1.2_eslint@7.28.0+typescript@4.3.2: + resolution: {integrity: sha512-4+tc2O/cxF/OypAcJArvkTQaVxY09xh6ocqShVZBOERX93fK9Bv2zZKbKLOHroh1z91nS8EQQl6iW17lkXt2Ew==} peerDependencies: eslint: '>=7.4.0' dependencies: - '@hannoeru/eslint-config-ts': 0.1.1_eslint@7.28.0+typescript@4.3.2 + '@hannoeru/eslint-config-ts': 0.1.2_eslint@7.28.0+typescript@4.3.2 eslint: 7.28.0 eslint-plugin-vue: 7.10.0_eslint@7.28.0 transitivePeerDependencies: @@ -341,13 +355,13 @@ packages: - typescript dev: true - /@hannoeru/eslint-config/0.1.1_eslint@7.28.0+typescript@4.3.2: - resolution: {integrity: sha512-Rw98399zFNlJZwBNSoXACWGM0+Rz1BUzO5DknpBfgbiP7RhvkkJe/GxUGrR6oZmSEiKD2pTx7e5TcZZUGtpS7Q==} + /@hannoeru/eslint-config/0.1.2_eslint@7.28.0+typescript@4.3.2: + resolution: {integrity: sha512-BL5Q8WEXSR+cX3sTNneCYgCc7tByF72t29mv0iWtomRh5cOBFB7jGasvC8fbjIFkWXW8RMVJfag+foLrF79bDA==} peerDependencies: eslint: '>=7.4.0' dependencies: - '@hannoeru/eslint-config-react': 0.1.1_eslint@7.28.0+typescript@4.3.2 - '@hannoeru/eslint-config-vue': 0.1.1_eslint@7.28.0+typescript@4.3.2 + '@hannoeru/eslint-config-react': 0.1.2_eslint@7.28.0+typescript@4.3.2 + '@hannoeru/eslint-config-vue': 0.1.2_eslint@7.28.0+typescript@4.3.2 eslint: 7.28.0 transitivePeerDependencies: - supports-color @@ -513,6 +527,10 @@ packages: resolution: {integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4=} dev: true + /@types/lodash/4.14.170: + resolution: {integrity: sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==} + dev: false + /@types/node/15.12.2: resolution: {integrity: sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==} dev: true @@ -646,6 +664,14 @@ packages: eslint-visitor-keys: 2.1.0 dev: true + /@vee-validate/i18n/4.1.20: + resolution: {integrity: sha512-3K7R3m3Z206Hq6iJpXHJNSYDjJFFHzZrA7wjowTts52iEsv9kNpA/WCkdJsQLae8J+QLiKyK53ma35gAet8yFg==} + dev: false + + /@vee-validate/rules/4.1.20: + resolution: {integrity: sha512-DsG+NrCv/rEIpEEOqv+R7Za5rsA9xdIq4XEARjcHI3liXgkd8aeNWCnnmGyDbkz2BVav7n37IhP16ceJHnFXBA==} + dev: false + /@vitejs/plugin-vue/1.2.3_@vue+compiler-sfc@3.1.1: resolution: {integrity: sha512-LlnLpObkGKZ+b7dcpL4T24l13nPSHLjo+6Oc7MbZiKz5PMAUzADfNJ3EKfYIQ0l0969nxf2jp/9vsfnuJ7h6fw==} engines: {node: '>=12.0.0'} @@ -2737,6 +2763,10 @@ packages: p-locate: 4.1.0 dev: true + /lodash-es/4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false + /lodash.camelcase/4.3.0: resolution: {integrity: sha1-soqmKIorn8ZRA1x3EfZathkDMaY=} dev: true @@ -2759,7 +2789,6 @@ packages: /lodash/4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true /loose-envify/1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} @@ -2902,6 +2931,10 @@ packages: resolution: {integrity: sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==} dev: true + /nanoclone/0.2.1: + resolution: {integrity: sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==} + dev: false + /nanoid/3.1.23: resolution: {integrity: sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -3307,6 +3340,10 @@ packages: react-is: 16.13.1 dev: true + /property-expr/2.0.4: + resolution: {integrity: sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==} + dev: false + /property-information/5.6.0: resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} dependencies: @@ -3510,6 +3547,10 @@ packages: strip-indent: 2.0.0 dev: true + /regenerator-runtime/0.13.7: + resolution: {integrity: sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==} + dev: false + /regexp-tree/0.1.23: resolution: {integrity: sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==} hasBin: true @@ -3967,6 +4008,10 @@ packages: resolution: {integrity: sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=} dev: true + /toposort/2.0.2: + resolution: {integrity: sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=} + dev: false + /trim-newlines/2.0.0: resolution: {integrity: sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=} engines: {node: '>=4'} @@ -4206,6 +4251,14 @@ packages: spdx-expression-parse: 3.0.1 dev: true + /vee-validate/4.4.4_vue@3.1.1: + resolution: {integrity: sha512-1zVt1wJEE/I7ozD2Ixrz7pfAbcZsCItvSNVJq3CAw48cKZOM/m6i8IM/LfbhwIs/HF4xjx0G7YbMQZTG6N8keA==} + peerDependencies: + vue: ^3.0.0 + dependencies: + vue: 3.1.1 + dev: false + /vfile-message/1.1.1: resolution: {integrity: sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==} dependencies: @@ -4699,3 +4752,16 @@ packages: dependencies: camelcase: 4.1.0 dev: true + + /yup/0.32.9: + resolution: {integrity: sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg==} + engines: {node: '>=10'} + dependencies: + '@babel/runtime': 7.14.0 + '@types/lodash': 4.14.170 + lodash: 4.17.21 + lodash-es: 4.17.21 + nanoclone: 0.2.1 + property-expr: 2.0.4 + toposort: 2.0.2 + dev: false diff --git a/public/favicon.ico b/public/favicon.ico index df36fcf..d67e4e4 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/src/components/Input.vue b/src/components/Input.vue deleted file mode 100644 index 1635999..0000000 --- a/src/components/Input.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - - - {{ label }} - - - diff --git a/src/components/LoginForm.vue b/src/components/LoginForm.vue new file mode 100644 index 0000000..f5a00d8 --- /dev/null +++ b/src/components/LoginForm.vue @@ -0,0 +1,45 @@ + + + + + + + + + + 忘記密碼 + + + 登入 + + + + diff --git a/src/components/RegisterAccountLinks.vue b/src/components/RegisterAccountLinks.vue new file mode 100644 index 0000000..fdb0200 --- /dev/null +++ b/src/components/RegisterAccountLinks.vue @@ -0,0 +1,20 @@ + + + + + 註冊帳號: + + + 一線單位 + + + 一般民眾 + + + + diff --git a/src/components/SSOLogin.vue b/src/components/SSOLogin.vue new file mode 100644 index 0000000..01ee06e --- /dev/null +++ b/src/components/SSOLogin.vue @@ -0,0 +1,24 @@ + + + + + + Line 登入 + + + Facebook 登入 + + + Twitter 登入 + + + diff --git a/src/components/TheCheckbox.vue b/src/components/TheCheckbox.vue new file mode 100644 index 0000000..5494353 --- /dev/null +++ b/src/components/TheCheckbox.vue @@ -0,0 +1,43 @@ + + + + + + + {{ label }} + + + {{ errorMessage }} + + + diff --git a/src/components/TheInput.vue b/src/components/TheInput.vue new file mode 100644 index 0000000..eee1d24 --- /dev/null +++ b/src/components/TheInput.vue @@ -0,0 +1,73 @@ + + + + + + {{ label }} + * + + + + {{ errorMessage }} + + + diff --git a/src/components/TheRadio.vue b/src/components/TheRadio.vue new file mode 100644 index 0000000..7219601 --- /dev/null +++ b/src/components/TheRadio.vue @@ -0,0 +1,48 @@ + + + + + + {{ label }} + * + + + + {{ text }} + + + + + diff --git a/src/components/TheSelect.vue b/src/components/TheSelect.vue new file mode 100644 index 0000000..fc38882 --- /dev/null +++ b/src/components/TheSelect.vue @@ -0,0 +1,69 @@ + + + + + + {{ label }} + * + + + + {{ text }} + + + + {{ errorMessage }} + + + diff --git a/src/components/layout/AuthLayout.vue b/src/components/layout/AuthLayout.vue new file mode 100644 index 0000000..03bdc4e --- /dev/null +++ b/src/components/layout/AuthLayout.vue @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/data/index.ts b/src/data/index.ts new file mode 100644 index 0000000..4e2cc6d --- /dev/null +++ b/src/data/index.ts @@ -0,0 +1,10 @@ +import { data, select_columns } from './tw-county-list.json' + +export const TWCountyList = data.map((item) => { + return { + text: item[select_columns.indexOf('NAME_2014')], + value: item[select_columns.indexOf('ISO3166')], + } +}).filter((item) => { + return !!item.text +}) diff --git a/src/data/tw-county-list.json b/src/data/tw-county-list.json new file mode 100644 index 0000000..254d0cd --- /dev/null +++ b/src/data/tw-county-list.json @@ -0,0 +1,158 @@ +{ + "sheet": { + "name": "\u4e2d\u83ef\u6c11\u570b\u7e23\u5e02", + "user": { "name": "ronnywang", "url": "https:\/\/sheethub.com\/ronnywang" }, + "url": "https:\/\/sheethub.com\/ronnywang\/%E4%B8%AD%E8%8F%AF%E6%B0%91%E5%9C%8B%E7%B8%A3%E5%B8%82", + "id": "ronnywang\/\u4e2d\u83ef\u6c11\u570b\u7e23\u5e02", + "meta": {}, + "geo": true, + "description": "From http:\/\/data.gov.tw\/node\/7442", + "uri_columns": [0], + "columns": [ + { + "name": "COUNTYID", + "description": "\u4e2d\u83ef\u6c11\u570b\u884c\u653f\u5340\u57df\u53ca\u6751\u91cc\u4ee3\u78bc", + "column_id": 0 + }, + { + "name": "NAME_1984", + "description": "1984 \u5e74\u65b0\u7af9\u5e02\u5347\u683c\u7701\u8f44\u5e02\u5f8c\u7684\u540d\u7a31", + "column_id": 1 + }, + { "name": "NAME_1984_ALIAS", "column_id": 2 }, + { + "name": "NAME_2010", + "description": "2010 \u5e74\u4e94\u90fd(\u53f0\u5317\u3001\u65b0\u5317\u3001\u53f0\u4e2d\u3001\u53f0\u5357\u3001\u9ad8\u96c4)\u5347\u683c\u7248\u672c", + "column_id": 3 + }, + { "name": "NAME_2010_ALIAS", "column_id": 4 }, + { + "name": "NAME_2014", + "description": "2014\u5e74\u6843\u5712\u5e02\u5347\u683c\u76f4\u8f44\u5e02", + "column_id": 5 + }, + { "name": "NAME_2014_ALIAS", "column_id": 6 }, + { "name": "ISO3166", "column_id": 7 }, + { + "name": "SEGIS_COUNTY_ID", + "description": "\u884c\u653f\u5340\u7a7a\u9593\u55ae\u5143\u4ee3\u78bc", + "column_id": 8 + }, + { + "name": "AREA_ID", + "description": "\u7e23\u5e02\u82f1\u6587\u5b57\u4ee3\u78bc\uff0c\u540c\u8eab\u4efd\u8b49\u7b2c\u4e00\u78bc\u898f\u5247", + "column_id": 9 + } + ], + "links": [ + { + "link_id": 347, + "columns": { + "column": { + "name": "NAME_2014", + "description": "2014\u5e74\u6843\u5712\u5e02\u5347\u683c\u76f4\u8f44\u5e02", + "column_id": 5 + } + }, + "reference": { + "reference_id": 71, + "sheet": { + "name": "\u4e2d\u83ef\u6c11\u570b\u884c\u653f\u5340_map_\u540d\u7a312014", + "user": { + "name": "area.reference.tw", + "url": "https:\/\/sheethub.com\/area.reference.tw" + }, + "url": "https:\/\/sheethub.com\/area.reference.tw\/%E4%B8%AD%E8%8F%AF%E6%B0%91%E5%9C%8B%E8%A1%8C%E6%94%BF%E5%8D%80_map_%E5%90%8D%E7%A8%B12014", + "id": "area.reference.tw\/\u4e2d\u83ef\u6c11\u570b\u884c\u653f\u5340_map_\u540d\u7a312014", + "meta": {}, + "geo": false, + "description": "", + "uri_columns": [0] + }, + "columns": { "column": { "name": "name", "column_id": 0 } }, + "need_update": false + }, + "need_update": true, + "miss_count": 7 + } + ] + }, + "total_count": 29, + "count": 29, + "indexes": [], + "select_columns": [ + "COUNTYID", + "NAME_1984", + "NAME_1984_ALIAS", + "NAME_2010", + "NAME_2010_ALIAS", + "NAME_2014", + "NAME_2014_ALIAS", + "ISO3166", + "SEGIS_COUNTY_ID", + "AREA_ID" + ], + "data": [ + ["63", "臺北市", "台北市", "臺北市", "台北市", "臺北市", "台北市", "TPE", "63000", "A"], + ["10001", "臺北縣", "台北縣", "", "", "", "", "", "10001", ""], + ["66", "", "", "臺中市", "台中市", "臺中市", "台中市", "TXG", "66000", "B"], + ["67", "", "", "臺南市", "台南市", "臺南市", "台南市", "TNN", "67000", "D"], + ["10021", "臺南市", "台南市", "", "", "", "", "", "10021", ""], + ["9007", "連江縣", "", "連江縣", "", "連江縣", "", "LJF", "9007", "Z"], + ["9020", "金門縣", "", "金門縣", "", "金門縣", "", "JME", "9020", "W"], + ["10002", "宜蘭縣", "", "宜蘭縣", "", "宜蘭縣", "", "ILA", "10002", "G"], + ["10004", "新竹縣", "", "新竹縣", "", "新竹縣", "", "HSQ", "10004", "J"], + ["10005", "苗栗縣", "", "苗栗縣", "", "苗栗縣", "", "MIA", "10005", "K"], + ["10007", "彰化縣", "", "彰化縣", "", "彰化縣", "", "CHA", "10007", "N"], + ["10008", "南投縣", "", "南投縣", "", "南投縣", "", "NAN", "10008", "M"], + ["10009", "雲林縣", "", "雲林縣", "", "雲林縣", "", "YUN", "10009", "P"], + ["10010", "嘉義縣", "", "嘉義縣", "", "嘉義縣", "", "CYQ", "10010", "Q"], + ["10013", "屏東縣", "", "屏東縣", "", "屏東縣", "", "PIF", "10013", "T"], + ["10014", "臺東縣", "台東縣", "臺東縣", "台東縣", "臺東縣", "台東縣", "TTT", "10014", "V"], + ["10015", "花蓮縣", "", "花蓮縣", "", "花蓮縣", "", "HUA", "10015", "U"], + ["10016", "澎湖縣", "", "澎湖縣", "", "澎湖縣", "", "PEN", "10016", "X"], + ["10017", "基隆市", "", "基隆市", "", "基隆市", "", "KEE", "10017", "C"], + ["10018", "新竹市", "", "新竹市", "", "新竹市", "", "HSZ", "10018", "O"], + ["10020", "嘉義市", "", "嘉義市", "", "嘉義市", "", "CYI", "10020", "I"], + ["64", "高雄市", "", "高雄市", "", "高雄市", "", "KHH", "64000", "E"], + ["65", "", "", "新北市", "", "新北市", "", "TPQ", "65000", "F"], + ["68", "", "", "", "", "桃園市", "", "TAO", "68000", "H"], + ["10019", "臺中市", "台中市", "", "", "", "", "", "10019", ""], + ["10003", "桃園縣", "", "桃園縣", "", "", "", "", "10003", ""], + ["10006", "臺中縣", "台中縣", "", "", "", "", "TXQ", "10006", "L"], + ["10011", "臺南縣", "台南縣", "", "", "", "", "TNQ", "10011", "R"], + ["10012", "高雄縣", "", "", "", "", "", "KHQ", "10012", "S"] + ], + "ids": [ + 18744641, + 18744647, + 18744644, + 18744645, + 19517270, + 18744625, + 18744626, + 18744627, + 18744628, + 18744629, + 18744630, + 18744631, + 18744632, + 18744633, + 18744634, + 18744635, + 18744636, + 18744637, + 18744638, + 18744639, + 18744640, + 18744642, + 18744643, + 18744646, + 18744648, + 18744649, + 18744650, + 18744651, + 18744652 + ], + "sheet_updated_at": 0 +} diff --git a/src/logics/auth.ts b/src/logics/auth.ts index d01ca83..6f385cf 100644 --- a/src/logics/auth.ts +++ b/src/logics/auth.ts @@ -15,14 +15,24 @@ interface LogoutResponse { export interface LoginArgs { username: string password: string + remember: boolean } export function useAuth() { const router = useRouter() - const userId = useStorage('userId', null) + const userId = useStorage('userId', null, undefined, { + serializer: { + read(raw) { + return raw === 'null' ? null : raw + }, + write(raw) { + return String(raw) + }, + }, + }) const isAuthorized = computed(() => { - return userId.value !== 'null' + return userId.value !== null }) function login(user: LoginArgs) { @@ -41,6 +51,17 @@ export function useAuth() { } } + // handle SSO logins + function loginWithLine() { + alert('Login with Line') + } + function loginWithFacebook() { + alert('Login with Facebook') + } + function loginWithTwitter() { + alert('Login with Twitter') + } + function logout() { const { isFetching, error, data } = useFetch(`${API_ENDPOINT}/logout`).json().post() @@ -57,10 +78,18 @@ export function useAuth() { } } + function resetPassword(email: string) { + alert(email) + } + return { userId, login, + loginWithLine, + loginWithFacebook, + loginWithTwitter, logout, isAuthorized, + resetPassword, } } diff --git a/src/main.ts b/src/main.ts index 95522f8..ee961a7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,9 +3,13 @@ import { createRouter, createWebHistory } from 'vue-router' import routes from 'virtual:generated-pages' import App from './App.vue' +// css import 'virtual:windi.css' import './style/main.css' +// plugins +import './plugins/vee-validate' + const app = createApp(App) const router = createRouter({ history: createWebHistory(), diff --git a/src/pages/account/password_reset.vue b/src/pages/account/password_reset.vue new file mode 100644 index 0000000..0b22be5 --- /dev/null +++ b/src/pages/account/password_reset.vue @@ -0,0 +1,42 @@ + + + + + + 重設密碼 + + + + + + 取消 + + + 送出 + + + + + diff --git a/src/pages/login.vue b/src/pages/login.vue index 2f2e790..0ff8f18 100644 --- a/src/pages/login.vue +++ b/src/pages/login.vue @@ -1,67 +1,16 @@ - - - - 登入 - - - - - - - 記住我 - - - - 忘記密碼 - - - 登入 - - - - - - Line 登入 - - - Facebook 登入 - - - Twitter 登入 - - - - 註冊帳號: - - - 機構單位 - - - 一般民眾 - - - - - + + + 登入 + + + + + diff --git a/src/pages/register/personal.vue b/src/pages/register/personal.vue new file mode 100644 index 0000000..cce26db --- /dev/null +++ b/src/pages/register/personal.vue @@ -0,0 +1,124 @@ + + + + + + 註冊帳號(一般民眾) + + + + + + + + + + + + + 取消 + + + 註冊 + + + + + diff --git a/src/pages/register/unit.vue b/src/pages/register/unit.vue new file mode 100644 index 0000000..17ff989 --- /dev/null +++ b/src/pages/register/unit.vue @@ -0,0 +1,161 @@ + + + + + + 註冊帳號(一線單位) + + + + + + + + + + + + + + + + 取消 + + + 註冊 + + + + + diff --git a/src/plugins/vee-validate.ts b/src/plugins/vee-validate.ts new file mode 100644 index 0000000..2e731d4 --- /dev/null +++ b/src/plugins/vee-validate.ts @@ -0,0 +1,20 @@ +import { defineRule, configure } from 'vee-validate' +import { required, email, min, confirmed } from '@vee-validate/rules' +import { localize, setLocale } from '@vee-validate/i18n' +import zh_TW from '@vee-validate/i18n/dist/locale/zh_TW.json' + +// 導入驗證規則 +defineRule('min', min) +defineRule('email', email) +defineRule('required', required) +defineRule('confirmed', confirmed) + +// 新增語言(用於錯誤信息) +configure({ + generateMessage: localize({ + 'zh-tw': zh_TW, + }), +}) + +// 設定當前語言 +setLocale('zh-tw') diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..e910a81 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,4 @@ +export interface InputChildren { + text: string + value: string +} diff --git a/tsconfig.json b/tsconfig.json index 9563901..4424932 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,5 +16,11 @@ "@/*": ["src/*"] } }, - "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] + "include": [ + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue", + "*.d.ts" + ] } diff --git a/windi.config.ts b/windi.config.ts index 102dff2..ac9f7c0 100644 --- a/windi.config.ts +++ b/windi.config.ts @@ -18,8 +18,11 @@ export default defineConfig({ '&:focus': { '@apply': 'outline-none', }, + '&:disabled': { + '@apply': 'bg-gray-300', + }, '&-outline': { - '@apply': ' py-1.5 bg-white border border-primary text-primary', + '@apply': 'py-1.5 bg-white border border-primary text-primary', }, }, 'icon-btn': {
+ {{ errorMessage }} +