From d3fdba1139b3c95dfbadbdbdd9654baae5a60503 Mon Sep 17 00:00:00 2001 From: Pacharapol Withayasakpunt Date: Sun, 24 Oct 2021 21:49:18 +0700 Subject: [PATCH] add some tabs and api --- assets/api.ts | 153 ++++++++- components/tabs/BrowseTab.vue | 379 ++++++++++++++++++++++ components/tabs/CharacterTab.vue | 517 +++++++++++++++++++++++++++++++ package.json | 1 + yarn.lock | 27 +- 5 files changed, 1072 insertions(+), 5 deletions(-) create mode 100644 components/tabs/BrowseTab.vue create mode 100644 components/tabs/CharacterTab.vue diff --git a/assets/api.ts b/assets/api.ts index d54cd1a..b139abf 100644 --- a/assets/api.ts +++ b/assets/api.ts @@ -1,5 +1,27 @@ import _axios, { AxiosInstance } from 'axios' +export type IType = 'character' | 'vocabulary' | 'sentence' + +export interface IEntry { + id: string + entry: string[] + reading: string[] + english: string[] + type: IType + description: string + tag: string[] +} + +export type ILookup = T & { + offset?: number + limit?: number +} + +export interface ILookupResult { + result: T[] + count: number +} + class Api { axios: AxiosInstance _isAuthorized = true @@ -89,8 +111,8 @@ class Api { ) } - async quiz_create(params: { entries: string[]; type: string }) { - return await this.axios.put('/api/quiz', params).then( + async quiz_create(payload: { entries: string[]; type: IType }) { + return await this.axios.put('/api/quiz', payload).then( (r) => r.data as { result: { @@ -100,15 +122,138 @@ class Api { ) } - async quiz_deleteMany(params: { entries: string[]; type: string }) { + async quiz_deleteMany(params: { entries: string[]; type: IType }) { return await this.axios.post('/api/quiz/deleteMany', params) } + async extra_getQuery(params: ILookup<{ q: string }>) { + params.offset = params.offset || 0 + params.limit = params.limit || 5 + + return await this.axios + .get('/api/extra/q', { params }) + .then((r) => r.data as ILookupResult) + } + + async extra_create(payload: Omit) { + return await this.axios + .put('/api/extra', payload) + .then((r) => r.data as { id: string }) + } + + async extra_update(payload: IEntry) { + return await this.axios.patch('/api/extra', payload, { + params: { id: payload.id }, + }) + } + async extra_delete(params: { id: string }) { - return await this.axios.delete('/extra/delete', { + return await this.axios.delete('/api/extra/delete', { params, }) } + + async character_getRadical(params: { entry: string }) { + return await this.axios.get('/api/character/radical', { params }).then( + (r) => + r.data as { + result: { + sub: string[] + sup: string[] + variant: string[] + visual: string[] + } | null + } + ) + } + + async character_getVocabulary(params: ILookup<{ entry: string }>) { + return await this.axios.get('/api/character/vocabulary', { params }).then( + (r) => + r.data as ILookupResult<{ + entry: string + }> + ) + } + + async character_getSentence(params: ILookup<{ entry: string }>) { + return await this.axios.get('/api/character/sentence', { params }).then( + (r) => + r.data as ILookupResult<{ + entry: string + }> + ) + } + + async all_getRandom(params: { type: IType }) { + return await this.axios.get('/api/all/random', { params }).then( + (r) => + r.data as { + result: string + level: number + } + ) + } + + async all_getQuery(params: ILookup<{ q: string }>) { + params.offset = params.offset || 0 + params.limit = params.limit || 5 + + return await this.axios.get('/api/all/q', { params }).then( + (r) => + r.data as ILookupResult<{ + entry: string + type: IType + }> + ) + } + + async all_getLookup(params: ILookup<{ entry: string; type: IType }>) { + params.offset = params.offset || 0 + params.limit = params.limit || 5 + + return await this.axios + .get('/api/all', { + params, + }) + .then( + (r) => + r.data as ILookupResult< + IEntry & { + level?: number + } + > + ) + } + + async all_getReading(params: { entry: string }) { + return await this.axios + .get('/api/all/reading', { + params, + }) + .then( + (r) => + r.data as { + result: string + } + ) + } + + async all_getMeaning(params: { entry: string }) { + return await this.axios + .get('/api/all/meaning', { + params, + }) + .then( + (r) => + r.data as { + result: { + entry?: string + meaning: string + }[] + } + ) + } } export const api = new Api() diff --git a/components/tabs/BrowseTab.vue b/components/tabs/BrowseTab.vue new file mode 100644 index 0000000..787df5e --- /dev/null +++ b/components/tabs/BrowseTab.vue @@ -0,0 +1,379 @@ + + + + + diff --git a/components/tabs/CharacterTab.vue b/components/tabs/CharacterTab.vue new file mode 100644 index 0000000..62faab2 --- /dev/null +++ b/components/tabs/CharacterTab.vue @@ -0,0 +1,517 @@ + + + + + diff --git a/package.json b/package.json index 52e0f50..1baad86 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@nuxtjs/pwa": "^3.3.5", "axios": "^0.23.0", "core-js": "^3.15.1", + "jsonschema-definer": "^1.3.2", "nuxt": "^2.15.7", "nuxt-buefy": "^0.4.8", "nuxt-property-decorator": "^2.9.1", diff --git a/yarn.lock b/yarn.lock index afd0946..c63dde0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1596,6 +1596,11 @@ dependencies: source-map "^0.6.1" +"@types/uuid@^8.3.0": + version "8.3.1" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f" + integrity sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg== + "@types/webpack-bundle-analyzer@3.9.3": version "3.9.3" resolved "https://registry.yarnpkg.com/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.9.3.tgz#3a12025eb5d86069c30b47a157e62c0aca6e39a1" @@ -1944,7 +1949,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -4830,6 +4835,16 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsonschema-definer@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/jsonschema-definer/-/jsonschema-definer-1.3.2.tgz#41c5a57dcd62b8e2b234fb4cf2defd1e526dc450" + integrity sha512-5bFNbTsJb/LFHQjKiNJJw3HEUzEEcv3lENy1muIDYXjYYLRw/xNnZ8UVsKN1X6gYb0yc+acuEinaeAH7fUAMMA== + dependencies: + "@types/uuid" "^8.3.0" + ajv "^6.12.0" + ts-toolbelt "^6.3.6" + uuid "^8.3.0" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -7782,6 +7797,11 @@ ts-pnp@^1.1.6: resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== +ts-toolbelt@^6.3.6: + version "6.15.5" + resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz#cb3b43ed725cb63644782c64fbcad7d8f28c0a83" + integrity sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A== + tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -8038,6 +8058,11 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + vary@^1.1.2, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"