├── .gitignore
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
├── src
├── App.vue
├── assets
│ ├── logo.png
│ └── logo.svg
├── components
│ ├── CardHotel.vue
│ ├── CardHotelDetail.vue
│ ├── FilterByRating.vue
│ └── shared-components
│ │ └── DataEmpty.vue
├── configs
│ └── common.ts
├── main.ts
├── plugins
│ └── vuetify.ts
├── router
│ └── index.ts
├── services
│ └── HotelDataService.ts
├── shims-tsx.d.ts
├── shims-vue.d.ts
├── shims-vuetify.d.ts
├── store
│ └── index.ts
├── types
│ └── HotelType.ts
└── views
│ ├── Home.vue
│ └── HotelDetail.vue
├── tsconfig.json
└── vue.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue test
2 | 
3 | https://test-vue-typescript.vercel.app/
4 | ## Project setup
5 |
6 | ```
7 | npm install
8 | ```
9 |
10 | ### Compiles and hot-reloads for development
11 |
12 | ```
13 | npm run serve
14 | ```
15 |
16 | ### Compiles and minifies for production
17 |
18 | ```
19 | npm run build
20 | ```
21 |
22 | ### Lints and fixes files
23 |
24 | ```
25 | npm run lint
26 | ```
27 |
28 | ### Customize configuration
29 |
30 | See [Configuration Reference](https://cli.vuejs.org/config/).
31 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-test",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "axios": "^0.24.0",
12 | "core-js": "^3.6.5",
13 | "vue": "^2.6.11",
14 | "vue-class-component": "^7.2.3",
15 | "vue-property-decorator": "^9.1.2",
16 | "vue-router": "^3.2.0",
17 | "vuetify": "^2.4.0",
18 | "vuex": "^3.4.0"
19 | },
20 | "devDependencies": {
21 | "@typescript-eslint/eslint-plugin": "^4.18.0",
22 | "@typescript-eslint/parser": "^4.18.0",
23 | "@vue/cli-plugin-babel": "~4.5.0",
24 | "@vue/cli-plugin-eslint": "~4.5.0",
25 | "@vue/cli-plugin-router": "~4.5.0",
26 | "@vue/cli-plugin-typescript": "~4.5.0",
27 | "@vue/cli-plugin-vuex": "~4.5.0",
28 | "@vue/cli-service": "~4.5.0",
29 | "@vue/eslint-config-typescript": "^7.0.0",
30 | "eslint": "^6.7.2",
31 | "eslint-plugin-vue": "^6.2.2",
32 | "node-sass": "^4.12.0",
33 | "sass": "~1.32.0",
34 | "sass-loader": "^10.0.0",
35 | "typescript": "~4.1.5",
36 | "vue-cli-plugin-vuetify": "^2.4.5",
37 | "vue-template-compiler": "^2.6.11",
38 | "vuetify-loader": "^1.7.0"
39 | },
40 | "eslintConfig": {
41 | "root": true,
42 | "env": {
43 | "node": true
44 | },
45 | "extends": [
46 | "plugin:vue/essential",
47 | "eslint:recommended",
48 | "@vue/typescript/recommended"
49 | ],
50 | "parserOptions": {
51 | "ecmaVersion": 2020
52 | },
53 | "rules": {}
54 | },
55 | "browserslist": [
56 | "> 1%",
57 | "last 2 versions",
58 | "not dead"
59 | ]
60 | }
61 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joe0zf/test-vue-typescript/a7e9d101ad56bc878591639c1a7eb4607706879a/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | mdi-domain
5 | Hotels
6 |
7 |
8 | mdi-moon-waning-crescent
9 | mdi-white-balance-sunny
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Jhoel — Vue Test
20 |
21 |
22 |
23 |
24 |
25 |
26 |
43 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joe0zf/test-vue-typescript/a7e9d101ad56bc878591639c1a7eb4607706879a/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/CardHotel.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ hotel.name }}
7 |
8 |
9 |
16 |
17 |
18 |
19 | {{ hotel.description }}
20 |
21 |
22 |
23 |
24 |
25 | Attributes
26 |
27 |
28 | mdi-domain
29 |
30 | Rooms
31 |
32 | {{ hotel.attributes.rooms }}
33 |
34 |
35 |
36 |
37 | mdi-account-multiple-check
38 |
39 | Staff
40 | {{
41 | hotel.attributes.staff
42 | }}
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | View more
51 |
52 |
53 |
54 |
55 |
67 |
--------------------------------------------------------------------------------
/src/components/CardHotelDetail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
17 | {{ hotel.name }}
18 |
19 |
20 | {{ hotel.description }}
21 |
22 |
23 |
24 |
25 |
26 | mdi-domain
27 |
28 | Rooms
29 |
30 | {{ hotel.attributes.rooms }}
31 |
32 |
33 |
34 |
35 | mdi-account-multiple-check
36 |
37 | Staff
38 | {{ hotel.attributes.staff }}
39 |
40 |
41 |
42 |
43 | View list
44 |
45 |
46 |
47 |
48 |
49 |
50 |
63 |
--------------------------------------------------------------------------------
/src/components/FilterByRating.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Filter By Rarity:
6 |
7 |
8 |
16 |
17 |
18 |
19 |
20 |
34 |
--------------------------------------------------------------------------------
/src/components/shared-components/DataEmpty.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | mdi-package-variant
7 |
8 |
9 |
10 |
11 | No Data
12 |
13 |
14 |
15 |
16 |
17 |
23 |
--------------------------------------------------------------------------------
/src/configs/common.ts:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | export default axios.create({
4 | baseURL: "https://my-json-server.typicode.com",
5 | headers: {
6 | "Content-type": "application/json",
7 | },
8 | });
9 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 | import vuetify from './plugins/vuetify'
6 |
7 | Vue.config.productionTip = false
8 |
9 | new Vue({
10 | router,
11 | store,
12 | vuetify,
13 | render: h => h(App)
14 | }).$mount('#app')
15 |
--------------------------------------------------------------------------------
/src/plugins/vuetify.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuetify from 'vuetify/lib/framework';
3 |
4 | Vue.use(Vuetify);
5 |
6 | export default new Vuetify({
7 | });
8 |
--------------------------------------------------------------------------------
/src/router/index.ts:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import VueRouter, { RouteConfig } from "vue-router";
3 | import Home from "../views/Home.vue";
4 |
5 | Vue.use(VueRouter);
6 |
7 | const routes: Array = [
8 | {
9 | path: "/",
10 | name: "Home",
11 | component: Home,
12 | },
13 | {
14 | path: "/hotel-detail/:id",
15 | name: "HotelDetail",
16 | component: () => import("../views/HotelDetail.vue"),
17 | },
18 | ];
19 |
20 | const router = new VueRouter({
21 | mode: "history",
22 | base: process.env.BASE_URL,
23 | routes,
24 | });
25 |
26 | export default router;
27 |
--------------------------------------------------------------------------------
/src/services/HotelDataService.ts:
--------------------------------------------------------------------------------
1 | import api from "@/configs/common";
2 |
3 | class HotelDataService {
4 | getAll() {
5 | return api.get("/yickson/serverjson/hotels");
6 | }
7 | getOne(id: number) {
8 | return api.get(`/yickson/serverjson/hotels/${id}`);
9 | }
10 | }
11 |
12 | export default new HotelDataService();
13 |
--------------------------------------------------------------------------------
/src/shims-tsx.d.ts:
--------------------------------------------------------------------------------
1 | import Vue, { VNode } from 'vue'
2 |
3 | declare global {
4 | namespace JSX {
5 | // tslint:disable no-empty-interface
6 | interface Element extends VNode {}
7 | // tslint:disable no-empty-interface
8 | interface ElementClass extends Vue {}
9 | interface IntrinsicElements {
10 | [elem: string]: any
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import Vue from 'vue'
3 | export default Vue
4 | }
5 |
--------------------------------------------------------------------------------
/src/shims-vuetify.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'vuetify/lib/framework' {
2 | import Vuetify from 'vuetify'
3 | export default Vuetify
4 | }
5 |
--------------------------------------------------------------------------------
/src/store/index.ts:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Vuex from "vuex";
3 | import HotelDataService from "@/services/HotelDataService";
4 | import Hotel from "@/types/HotelType";
5 | Vue.use(Vuex);
6 |
7 | export default new Vuex.Store({
8 | state: {
9 | isLoaded: false,
10 | hotels: [],
11 | oneHotel: {},
12 | query: "All",
13 | error: {},
14 | },
15 | mutations: {
16 | setHotels(state, value) {
17 | state.hotels = value;
18 | },
19 | setOneHotel(state, value) {
20 | state.oneHotel = value;
21 | },
22 | setQuery(state, value) {
23 | state.query = value;
24 | },
25 | setError(state, value) {
26 | state.error = value;
27 | },
28 | setIsLoaded(state, value) {
29 | state.isLoaded = value;
30 | },
31 | },
32 | actions: {
33 | async getHotels({ commit }) {
34 | commit("setIsLoaded", false);
35 | try {
36 | const result = await HotelDataService.getAll();
37 | commit("setHotels", result.data);
38 | commit("setIsLoaded", true);
39 | } catch (err) {
40 | commit("setError", err);
41 | }
42 | },
43 | async getOneHotel({ commit }, id) {
44 | commit("setIsLoaded", false);
45 | try {
46 | const result = await HotelDataService.getOne(id);
47 | commit("setOneHotel", result.data);
48 | commit("setIsLoaded", true);
49 | } catch (err) {
50 | commit("setError", err);
51 | }
52 | },
53 | },
54 | getters: {
55 | getFilteredHotels(state): Hotel[] {
56 | const hotels: Hotel[] = state.hotels.filter(
57 | (e: Hotel): boolean => e.attributes.rarity == Number(state.query)
58 | );
59 | if (state.query != "All") return hotels;
60 | return state.hotels;
61 | },
62 | },
63 | modules: {},
64 | });
65 |
--------------------------------------------------------------------------------
/src/types/HotelType.ts:
--------------------------------------------------------------------------------
1 | export default interface Hotel {
2 | id: number;
3 | description: string;
4 | external_url: string;
5 | image: string;
6 | name: string;
7 | attributes: {
8 | rarity: number;
9 | rooms: number;
10 | staff: number;
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
69 |
--------------------------------------------------------------------------------
/src/views/HotelDetail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
34 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "module": "esnext",
5 | "strict": true,
6 | "jsx": "preserve",
7 | "importHelpers": true,
8 | "moduleResolution": "node",
9 | "experimentalDecorators": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "sourceMap": true,
14 | "baseUrl": ".",
15 | "types": [
16 | "webpack-env"
17 | ],
18 | "paths": {
19 | "@/*": [
20 | "src/*"
21 | ]
22 | },
23 | "lib": [
24 | "esnext",
25 | "dom",
26 | "dom.iterable",
27 | "scripthost"
28 | ]
29 | },
30 | "include": [
31 | "src/**/*.ts",
32 | "src/**/*.tsx",
33 | "src/**/*.vue",
34 | "tests/**/*.ts",
35 | "tests/**/*.tsx"
36 | ],
37 | "exclude": [
38 | "node_modules"
39 | ]
40 | }
41 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | transpileDependencies: [
3 | 'vuetify'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------