Create basic Person component + collect data by getter

This commit is contained in:
2020-12-21 22:05:53 +01:00
parent a9771243a1
commit 188625a413
4 changed files with 80 additions and 96 deletions

View File

@@ -0,0 +1,27 @@
<template>
<router-link
class="person flex items-center cursor-pointer p-3 mb-2 rounded bg-gray-300 hover:bg-gray-400"
:to="`/people/${person.id}`"
tag="article"
>
<span class="mr-2 text-xl font-bold">{{
person.gender === "Female" ? "&#9792;" : "&#9794;"
}}</span>
<h4>{{ person.name }}</h4>
</router-link>
</template>
<script>
export default {
name: "Person",
props: {
person: {
type: Object,
default: {},
required: true
}
}
};
</script>
<style lang="css" scoped></style>

View File

@@ -1,7 +1,9 @@
<template> <template>
<div class="py-4 flex flex-col lg:flex-row items-center lg:items-start"> <div
class="py-4 flex flex-col lg:flex-row items-center lg:items-start justify-center"
>
<article <article
class="mb-4 flex flex-col justify-between bg-gray-100 prose prose-sm rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl" class="mb-4 inline-flex flex-col justify-between bg-gray-100 prose prose-sm rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl"
> >
<header class="p-4 rounded-t-md"> <header class="p-4 rounded-t-md">
<h1> <h1>
@@ -26,27 +28,33 @@
</section> </section>
</article> </article>
<aside class="w-full lg:ml-4"> <aside class="lg:inline-flex lg:ml-4">
<section <section
class="p-4 mb-4 bg-gray-100 rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl" class="p-4 lg:mr-4 bg-gray-100 rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl"
> >
<h3 class="font-medium text-lg">People</h3> <h3 class="font-medium text-lg mb-4">People</h3>
<div>{{ film.people }}</div> <ul v-if="people.length">
<li :key="person.id" v-for="person in people">
<Person :person="person" />
</li>
</ul>
</section> </section>
<section <!-- <section
class="p-4 mb-4 bg-gray-100 rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl" v-if="Object.keys(film.vehicles).length"
class="p-4 lg:mr-4 bg-gray-100 rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl"
> >
<h3 class="font-medium text-lg">Vehicles</h3> <h3 class="font-medium text-lg mb-4">Vehicles</h3>
<div>{{ film.vehicles }}</div> <div>{{ film.vehicles }}</div>
</section> </section>
<section <section
class="p-4 mb-4 bg-gray-100 rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl" v-if="Object.keys(film.locations).length"
class="p-4 lg:mr-4 bg-gray-100 rounded-md shadow-md transition-shadow duration-300 hover:shadow-xl"
> >
<h3 class="font-medium text-lg">Locations</h3> <h3 class="font-medium text-lg">Locations</h3>
<div>{{ film.locations }}</div> <div>{{ film.locations }}</div>
</section> </section> -->
</aside> </aside>
</div> </div>
</template> </template>
@@ -56,6 +64,9 @@ import { mapGetters } from "vuex";
export default { export default {
name: "Film", name: "Film",
components: {
Person: () => import("@/components/Person")
},
head() { head() {
return { return {
titleTemplate: `%s - ${this.film.title}` titleTemplate: `%s - ${this.film.title}`
@@ -72,14 +83,12 @@ export default {
await store.dispatch("films/getFilm", params.id); await store.dispatch("films/getFilm", params.id);
}, },
computed: { computed: {
people() {
return this.$store.getters["people/getPeopleByFilmId"](this.film.id);
},
...mapGetters({ ...mapGetters({
film: "films/film" film: "films/film"
}) })
},
async mounted() {
await this.$store.dispatch("films/getPeople");
await this.$store.dispatch("films/getVehicles");
await this.$store.dispatch("films/getLocations");
} }
}; };
</script> </script>

View File

@@ -9,22 +9,15 @@ export const mutations = {
}, },
setFilm: (state, film) => { setFilm: (state, film) => {
state.film = film; state.film = film;
},
setPeople: (state, people) => {
state.film.people = people;
},
setVehicles: (state, vehicles) => {
state.film.vehicles = vehicles;
},
setLocations: (state, locations) => {
state.film.locations = locations;
} }
}; };
export const actions = { export const actions = {
async getList({ commit }) { async getList({ commit }) {
try { try {
const films = await this.$axios.$get("/api/films"); const films = await this.$axios.$get(
"/api/films?fields=id,title,release_date,director,description,rt_score"
);
commit("setList", films); commit("setList", films);
} catch (e) { } catch (e) {
throw Error(`API Error occurred: ${e.message}`); throw Error(`API Error occurred: ${e.message}`);
@@ -32,77 +25,13 @@ export const actions = {
}, },
async getFilm({ commit }, id) { async getFilm({ commit }, id) {
try { try {
const film = await this.$axios.$get(`/api/films/${id}`); const film = await this.$axios.$get(
`/api/films/${id}?fields=id,title,release_date,director,description,rt_score`
);
commit("setFilm", film); commit("setFilm", film);
} catch (e) { } catch (e) {
throw Error(`API Error occurred: ${e.message}`); throw Error(`API Error occurred: ${e.message}`);
} }
},
async getPeople({ commit, dispatch, state }) {
let people = {};
try {
if (state.film.people[0].split("/")[4] !== "") {
const promises = state.film.people.map(async person => {
const id = person.split("/")[4];
return await dispatch(
"people/getPerson",
{
id: id,
callback: true
},
{ root: true }
);
});
people = await Promise.all(promises);
}
commit("setPeople", people);
} catch (e) {
throw Error(`API Error occurred: ${e.message}`);
}
},
async getVehicles({ commit, dispatch, state }) {
let vehicles = {};
try {
if (state.film.vehicles[0].split("/")[4] !== "") {
const promises = state.film.vehicles.map(async vehicle => {
const id = vehicle.split("/")[4];
return await dispatch(
"vehicles/getVehicle",
{
id: id,
callback: true
},
{ root: true }
);
});
vehicles = await Promise.all(promises);
}
commit("setVehicles", vehicles);
} catch (e) {
throw Error(`API Error occurred: ${e.message}`);
}
},
async getLocations({ commit, dispatch, state }) {
let locations = {};
try {
if (state.film.locations[0].split("/")[4] !== "") {
const promises = state.film.locations.map(async location => {
const id = location.split("/")[4];
return await dispatch(
"locations/getLocation",
{
id: id,
callback: true
},
{ root: true }
);
});
locations = await Promise.all(promises);
}
commit("setLocations", locations);
} catch (e) {
throw Error(`API Error occurred: ${e.message}`);
}
} }
}; };

View File

@@ -1,18 +1,31 @@
export const state = () => ({ export const state = () => ({
list: [],
person: {} person: {}
}); });
export const mutations = { export const mutations = {
setList: (state, people) => {
state.list = people;
},
setPerson: (state, person) => { setPerson: (state, person) => {
state.person = person; state.person = person;
} }
}; };
export const actions = { export const actions = {
async getPerson({ commit }, { id, callback = false }) { async getList({ commit }) {
try {
const people = await this.$axios.$get(
"/api/people?fields=id,name,gender,age,eye_color,hair_color,films"
);
commit("setList", people);
} catch (e) {
throw Error(`API Error occurred: ${e.message}`);
}
},
async getPerson({ commit }, id) {
try { try {
const person = await this.$axios.$get(`/api/people/${id}`); const person = await this.$axios.$get(`/api/people/${id}`);
if (callback) return person;
commit("setPerson", person); commit("setPerson", person);
} catch (e) { } catch (e) {
throw Error(`API Error occurred: ${e.message}`); throw Error(`API Error occurred: ${e.message}`);
@@ -21,5 +34,11 @@ export const actions = {
}; };
export const getters = { export const getters = {
person: state => state.person list: state => state.list,
person: state => state.person,
getPeopleByFilmId: state => id => {
return state.list.filter(person =>
person.films.find(film => film.split("/")[4] === id)
);
}
}; };