add link upvote/downvote and authenticated comp
This commit is contained in:
parent
8d58ff3590
commit
98c29f5694
@ -3,9 +3,20 @@
|
|||||||
<nav>
|
<nav>
|
||||||
<router-link :to="{ name: 'links' }">Derniers liens publiés</router-link>
|
<router-link :to="{ name: 'links' }">Derniers liens publiés</router-link>
|
||||||
/
|
/
|
||||||
<router-link :to="{ name: 'register' }">Créer un compte</router-link>
|
<authenticated>
|
||||||
/
|
<template v-slot="{ username }">
|
||||||
<router-link :to="{ name: 'login' }">Se connecter</router-link>
|
<p>Vous êtes connecté en tant que {{ username }}</p>
|
||||||
|
-
|
||||||
|
<button @click.prevent="$store.commit('auth/logout')">
|
||||||
|
Se déconnecter
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<template v-slot:anonymous>
|
||||||
|
<router-link :to="{ name: 'register' }">Créer un compte</router-link>
|
||||||
|
/
|
||||||
|
<router-link :to="{ name: 'login' }">Se connecter</router-link>
|
||||||
|
</template>
|
||||||
|
</authenticated>
|
||||||
</nav>
|
</nav>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
<notifications-panel />
|
<notifications-panel />
|
||||||
@ -14,8 +25,9 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NotificationsPanel from "./components/NotificationsPanel";
|
import NotificationsPanel from "./components/NotificationsPanel";
|
||||||
|
import Authenticated from "./components/Authenticated";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { NotificationsPanel },
|
components: { NotificationsPanel, Authenticated },
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -16,6 +16,14 @@ class Api {
|
|||||||
return this._get(`/api/links/${id}`);
|
return this._get(`/api/links/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upvoteLink(id) {
|
||||||
|
return this._put(`/api/links/${id}/upvote`);
|
||||||
|
}
|
||||||
|
|
||||||
|
downvoteLink(id) {
|
||||||
|
return this._put(`/api/links/${id}/downvote`);
|
||||||
|
}
|
||||||
|
|
||||||
getLinkComments(id) {
|
getLinkComments(id) {
|
||||||
return this._get(`/api/links/${id}/comments`);
|
return this._get(`/api/links/${id}/comments`);
|
||||||
}
|
}
|
||||||
@ -80,6 +88,30 @@ class Api {
|
|||||||
return r.json();
|
return r.json();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_put(path, data) {
|
||||||
|
return fetch(this._baseUrl + path, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: {
|
||||||
|
Accept: "application/json",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...this._authorizationHeader(),
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
}).then((r) => {
|
||||||
|
if (!r.ok) {
|
||||||
|
return Promise.reject(new Error("Erreur dans la requête"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r.status === 204) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (!r.headers['Content-Length'] === '0') {
|
||||||
|
|
||||||
|
return r.json();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new Api(process.env.VUE_APP_API_URL);
|
export default new Api(process.env.VUE_APP_API_URL);
|
||||||
|
|||||||
9
hn-vue/src/components/Authenticated.vue
Normal file
9
hn-vue/src/components/Authenticated.vue
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<slot
|
||||||
|
:username="$store.state.auth.username"
|
||||||
|
v-if="$store.state.auth.token"
|
||||||
|
></slot>
|
||||||
|
<slot v-else name="anonymous"></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -6,18 +6,48 @@
|
|||||||
}}</router-link>
|
}}</router-link>
|
||||||
</h2>
|
</h2>
|
||||||
<p>Publié le {{ link.createdAt }} par {{ link.createdBy.username }}</p>
|
<p>Publié le {{ link.createdAt }} par {{ link.createdBy.username }}</p>
|
||||||
<p>👍 {{ link.upvotesCount }} / 👎 {{ link.downvotesCount }}</p>
|
<authenticated>
|
||||||
|
<button @click.prevent="upvote">👍 {{ link.upvotesCount }}</button>
|
||||||
|
/ <button @click.prevent="downvote">👎 {{ link.downvotesCount }}</button>
|
||||||
|
<template v-slot:anonymous>
|
||||||
|
<p>👍 {{ link.upvotesCount }} / 👎 {{ link.downvotesCount }}</p>
|
||||||
|
</template>
|
||||||
|
</authenticated>
|
||||||
</article>
|
</article>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Authenticated from "./Authenticated";
|
||||||
|
import api from "../api";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "LinkItem",
|
name: "LinkItem",
|
||||||
|
components: { Authenticated },
|
||||||
props: {
|
props: {
|
||||||
link: {
|
link: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
async upvote() {
|
||||||
|
await api.upvoteLink(this.link.id);
|
||||||
|
|
||||||
|
// const link = await api.getLinkById(this.link.id);
|
||||||
|
|
||||||
|
// this.link.downvotesCount = link.downvotesCount;
|
||||||
|
// this.link.upvotesCount = link.upvotesCount;
|
||||||
|
this.$emit("refresh", this.link.id);
|
||||||
|
},
|
||||||
|
async downvote() {
|
||||||
|
await api.downvoteLink(this.link.id);
|
||||||
|
|
||||||
|
// const link = await api.getLinkById(this.link.id);
|
||||||
|
|
||||||
|
// this.link.upvotesCount = link.upvotesCount;
|
||||||
|
// this.link.downvotesCount = link.downvotesCount;
|
||||||
|
this.$emit("refresh", this.link.id);
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
message="Chargement du lien en cours ..."
|
message="Chargement du lien en cours ..."
|
||||||
/>
|
/>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<link-item :link="link" />
|
<link-item :link="link" @refresh="refreshLink" />
|
||||||
<loading v-if="comments === null" message="Chargement des commentaires" />
|
<loading v-if="comments === null" message="Chargement des commentaires" />
|
||||||
<p v-else-if="comments.length === 0">Aucun commentaire pour ce lien</p>
|
<p v-else-if="comments.length === 0">Aucun commentaire pour ce lien</p>
|
||||||
<ul v-else>
|
<ul v-else>
|
||||||
@ -52,6 +52,9 @@ export default {
|
|||||||
// '$route': 'fetchLinkDetail'
|
// '$route': 'fetchLinkDetail'
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async refreshLink() {
|
||||||
|
this.link = await api.getLinkById(this.id);
|
||||||
|
},
|
||||||
async fetchLinkDetail() {
|
async fetchLinkDetail() {
|
||||||
this.link = null;
|
this.link = null;
|
||||||
this.comments = null;
|
this.comments = null;
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
/>
|
/>
|
||||||
<ul v-else>
|
<ul v-else>
|
||||||
<li v-for="link in links" :key="link.id">
|
<li v-for="link in links" :key="link.id">
|
||||||
<link-item :link="link" />
|
<link-item :link="link" @refresh="refreshLink" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -41,6 +41,14 @@ export default {
|
|||||||
// this.loading = false;
|
// this.loading = false;
|
||||||
// }
|
// }
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
async refreshLink(id) {
|
||||||
|
const link = await api.getLinkById(id);
|
||||||
|
const index = this.links.findIndex((l) => l.id === id);
|
||||||
|
|
||||||
|
this.links.splice(index, 1, link);
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,10 @@ export default function createStore() {
|
|||||||
state.token = token;
|
state.token = token;
|
||||||
state.username = username;
|
state.username = username;
|
||||||
},
|
},
|
||||||
|
logout(state) {
|
||||||
|
state.token = null;
|
||||||
|
state.username = null;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async login({ commit }, data) {
|
async login({ commit }, data) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user