13 Commits

Author SHA1 Message Date
Alexis
265d8faebd Merge branch 'develop' into main 2021-03-29 16:44:31 +02:00
Alexis
b91bc080dd / Cleanup of error layout, readme 2021-03-29 16:44:24 +02:00
Alexis
b9fe9ca514 + Added layout page and error handler 2021-03-29 16:18:37 +02:00
Alexis
ef49660376 - Removed all useless readme 2021-03-29 16:18:14 +02:00
Alexis
ee6e55452a Merge branch 'develop' into main 2021-03-29 15:19:19 +02:00
Alexis
88b88281bd + Added hover effect on heart icon 2021-03-29 15:19:10 +02:00
Alexis
03c7328bfb + Added link to toast card 2021-03-29 15:15:50 +02:00
Alexis
cb505812c5 / Fixed loader not appearing on favourites / celestials 2021-03-29 14:59:00 +02:00
Alexis
a1df7d1143 + Added favourites page 2021-03-29 14:43:09 +02:00
Alexis
c6fe4f9d98 / Changed html / data display 2021-03-29 14:24:19 +02:00
Alexis
51dffd48dc / Refactored btn component / icons and revamped list layout 2021-03-29 14:16:36 +02:00
Alexis
984b5fdd9d / Fixed linter dep 2021-03-29 11:56:45 +02:00
Alexis
e8533f881f Merge branch 'develop-nuxt' into develop 2021-03-29 11:31:25 +02:00
33 changed files with 270 additions and 193 deletions

View File

@@ -1,6 +1,7 @@
# full-skies
Ce projet a pour but d'exploiter [l'API Le Système Solaire](https://api.le-systeme-solaire.net/) et de proposer une interface simple pour selectionner des favoris.
Il a été conçu lors d'un module d'apprentissage de Nuxt/Vue à MyDigitalSchool.
- [Dependencies](#dependencies)
- [How to install](#how-to-install)
## Dependencies

View File

@@ -1,7 +0,0 @@
# ASSETS
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).

View File

@@ -63,6 +63,13 @@ a {
color: inherit;
text-decoration: none;
}
&.fs-link {
color: $primary-xxlight;
text-decoration: underline;
&:hover {
color: $primary-xlight;
}
}
}
button {

View File

@@ -0,0 +1,39 @@
<template>
<button
class="btn btn-primary"
:class="[
icon ? 'btn-icon' : ''
]"
>
<slot />
<span v-if="icon">
<img
:src="
white ? `/icons/${icon}.svg` : `/icons/${icon}-white.svg`
"
alt=""
class="fs-icon icon-sm"
>
</span>
</button>
</template>
<script>
export default {
name: 'FSButton',
props: {
icon: {
type: String,
default: () => { return '' }
},
white: {
type: Boolean,
default: () => { return false }
}
}
}
</script>
<style>
</style>

View File

@@ -91,6 +91,10 @@ export default {
id: uuidv4(),
title: 'Favori ajouté',
message: `${this.celestial.name} a été ajouté à la liste des favoris.`,
link: {
text: 'Consultez vos favoris.',
url: '/favoris'
},
category: 'valid',
timer: 3
})
@@ -99,11 +103,15 @@ export default {
id: uuidv4(),
title: 'Favori retiré',
message: `${this.celestial.name} a été retiré de la liste des favoris.`,
link: {
text: 'Consultez vos favoris.',
url: '/favoris'
},
category: 'valid',
timer: 3
})
}
this.$store.dispatch('toggleFav', this.celestial.id)
this.$store.dispatch('toggleFav', this.celestial)
}
}
}
@@ -155,6 +163,9 @@ export default {
will-change: font-size;
animation: toggleFavHeart 0.6s cubic-bezier(0.17, 0.89, 0.32, 1.49);
animation-fill-mode: forwards;
&:hover {
color: darken(#d01d35, 6%) !important
}
}
}
}

View File

@@ -2,31 +2,31 @@
<div class="card-icon">
<img
v-if="type === 'planète à lunes'"
src="/icons/saturn-and-other-planets.svg"
src="/icons/planet-moons.svg"
class="fs-icon"
alt="planet icon"
>
<img
v-else-if="type === 'planète'"
src="/icons/saturn-planet-shape.svg"
src="/icons/planet.svg"
class="fs-icon"
alt="planet icon"
>
<img
v-else-if="type === 'lune'"
src="/icons/moon-and-stars-in-a-cloud.svg"
src="/icons/moon.svg"
class="fs-icon"
alt="moon icon"
>
<img
v-else-if="type === 'étoile'"
src="/icons/sun-shape.svg"
src="/icons/sun.svg"
class="fs-icon"
alt="moon icon"
>
<img
v-else
src="/icons/stars-group.svg"
src="/icons/stars.svg"
alt="moon icon"
class="fs-icon"
>

View File

@@ -2,57 +2,44 @@
<div class="celestial-filters">
<ul class="no-style">
<li>
<button
class="btn btn-primary"
<AtomsFSButton
:class="[filters.all ? 'active' : '']"
@click="emitFilter('all')"
@click.native="emitFilter('all')"
>
Tous
</button>
<button
class="btn btn-primary btn-icon"
</AtomsFSButton>
<AtomsFSButton
:class="[filters.planets ? 'active' : '']"
@click="emitFilter('planets')"
icon="planet"
inverted
@click.native="emitFilter('planets')"
>
Planètes
<img
src="icons/saturn-planet-shape-white.svg"
alt=""
class="fs-icon icon-sm"
>
</button>
<button
class="btn btn-primary btn-icon"
</AtomsFSButton>
<AtomsFSButton
:class="[filters.moons ? 'active' : '']"
@click="emitFilter('moons')"
icon="moon"
inverted
@click.native="emitFilter('moons')"
>
Lunes
<img
src="icons/moon-and-stars-in-a-cloud-white.svg"
alt=""
class="fs-icon icon-sm"
>
</button>
<button
class="btn btn-primary btn-icon"
</AtomsFSButton>
<AtomsFSButton
:class="[filters.stars ? 'active' : '']"
@click="emitFilter('stars')"
icon="sun"
inverted
@click.native="emitFilter('stars')"
>
Etoiles
<img src="icons/sun-shape-white.svg" alt="" class="fs-icon icon-sm">
</button>
<button
class="btn btn-primary btn-icon"
</AtomsFSButton>
<AtomsFSButton
:class="[filters.others ? 'active' : '']"
@click="emitFilter('others')"
icon="stars"
inverted
@click.native="emitFilter('others')"
>
Autres
<img
src="icons/stars-group-white.svg"
alt=""
class="fs-icon icon-sm"
>
</button>
</AtomsFSButton>
</li>
</ul>
</div>

View File

@@ -1,9 +1,9 @@
<template>
<div class="celestial-list-wrapper">
<div v-if="celestials && celestials.length > 1">
<div v-if="celestials.length > 0">
<celestial-filters v-if="hasFilters" @filter:celestials="filterCelestials" />
<ul v-if="celestials" class="celestial-list grid no-style">
<ul class="celestial-list grid no-style">
<li
v-for="(celestial, index) in sortedCelestials"
:key="index"
@@ -84,11 +84,12 @@ export default defineComponent({
<style lang="scss" scoped>
.celestial-list {
display: flex;
justify-content: space-between;
justify-content: flex-start;
align-items: stretch;
flex-flow: row wrap;
.celestial-item {
width: calc(33% - 15px);
width: calc(33% - 20px);
margin-right: 20px;
margin-bottom: 20px;
}
}

View File

@@ -6,6 +6,9 @@
<div class="toast-message">
<slot name="message" />
</div>
<div class="toast-link">
<slot name="link" />
</div>
</div>
</template>
@@ -62,11 +65,23 @@ export default defineComponent({
animation: fadeIn 1s cubic-bezier(0.175, 1, 0.32, 1),
slideFromRight 1s cubic-bezier(0.175, 1, 0.32, 1);
overflow: hidden;
.toast-title {
margin-bottom: 5px;
font-size: 16px;
font-weight: $fw-bold;
}
.toast-link {
a {
color: $primary-xxlight;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
&:after {
position: absolute;
display: block;
@@ -78,6 +93,7 @@ export default defineComponent({
height: 6px;
background: rgba($fs-black, 33%);
}
&.info {
background-color: $info;
}
@@ -91,6 +107,7 @@ export default defineComponent({
&.danger {
background-color: $danger;
}
&.closing {
animation: fadeOut 1.2s cubic-bezier(0.175, 1, 0.32, 1),
slideFromLeft 1.2s cubic-bezier(0.175, 1, 0.32, 1);

View File

@@ -8,6 +8,11 @@
<template #message>
{{ toast.message }}
</template>
<template #link>
<nuxt-link :to="toast.link.url">
{{ toast.link.text }}
</nuxt-link>
</template>
</toast-card>
</div>
</div>

View File

@@ -1,7 +0,0 @@
# LAYOUTS
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your Application Layouts.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).

44
layouts/error.vue Normal file
View File

@@ -0,0 +1,44 @@
<template>
<section class="error bg-image">
<div class="splash">
<h2 class="heading-1">
<span v-if="error.statusCode === 404">Page non trouvée</span>
<span v-else>Une erreur est survenue</span>
<span>:(</span>
</h2>
<p>{{ error.message }}</p>
<div>
<nuxt-link :to="'/'">
<AtomsFSButton>Retourner à la page d'accueil</AtomsFSButton>
</nuxt-link>
</div>
</div>
</section>
</template>
<script>
export default {
layout: 'error',
props: {
error: {
type: Object,
default: () => { return {} }
}
}
}
</script>
<style lang="scss">
.error {
position: relative;
min-height: inherit;
padding: 0 10%;
display: flex;
align-items: center;
overflow: hidden;
&:after {
background-image: url("/celestials_bg-min.jpg");
}
}
</style>

View File

@@ -1,8 +0,0 @@
# MIDDLEWARE
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your application middleware.
Middleware let you define custom functions that can be run before rendering either a page or a group of pages.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).

24
package-lock.json generated
View File

@@ -6475,6 +6475,15 @@
}
}
},
"eslint-plugin-prettier": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.1.tgz",
"integrity": "sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ==",
"dev": true,
"requires": {
"prettier-linter-helpers": "^1.0.0"
}
},
"eslint-plugin-promise": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz",
@@ -7046,6 +7055,12 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"fast-diff": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
"dev": true
},
"fast-glob": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
@@ -12646,6 +12661,15 @@
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
"optional": true
},
"prettier-linter-helpers": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"requires": {
"fast-diff": "^1.1.2"
}
},
"pretty": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz",

View File

@@ -28,6 +28,7 @@
"babel-jest": "^26.6.3",
"eslint": "^7.18.0",
"eslint-plugin-nuxt": "^2.0.0",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^7.4.1",
"sass": "^1.32.8",
"sass-loader": "^10.1.1",

View File

@@ -1,6 +0,0 @@
# PAGES
This directory contains your Application Views and Routes.
The framework reads all the `*.vue` files inside this directory and creates the router of your application.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).

View File

@@ -1,42 +1,48 @@
<template>
<section class="celestial bg-image">
<header>
<h1 class="heading-1">
<span>{{ celestial.name }}</span>
<span v-if="celestial.name != celestial.englishName">/ {{ celestial.englishName }}</span>
<span class="txt-capitalize">- {{ celestial.type }}</span>
</h1>
</header>
<div class="section-content">
<main v-if="celestial" class="celestial-body">
<div>
<h3 class="heading-3">
Informations
</h3>
<p v-if="celestial.aroundPlanet">
Orbite autour de
<nuxt-link
:to="`/astres/${celestial.aroundPlanet.planet}`"
class="txt-capitalize"
>
{{ celestial.aroundPlanet.planet }}
</nuxt-link>
</p>
<p v-if="celestial.discoveredBy">
Découvert par {{ celestial.discoveredBy }} le {{ celestial.discoveryDate }}
</p>
<p>Facteur Gravité : {{ celestial.gravity }}</p>
<p>Facteur Densité : {{ celestial.density }}</p>
<p>Inclinaison : {{ celestial.inclination }}</p>
<main v-if="celestial">
<header>
<h1 class="heading-1">
<span>{{ celestial.name }}</span>
<span v-if="celestial.name != celestial.englishName">/ {{ celestial.englishName }}</span>
<span class="txt-capitalize">- {{ celestial.type }}</span>
</h1>
</header>
<div class="section-content">
<div class="celestial-body">
<div>
<h3 class="heading-3">
Informations
</h3>
<p v-if="celestial.aroundPlanet">
Orbite autour de
<nuxt-link
:to="`/astres/${celestial.aroundPlanet.planet}`"
class="txt-capitalize fs-link"
>
{{ celestial.aroundPlanet.planet }}
</nuxt-link>
</p>
<p v-if="celestial.discoveredBy">
Découvert par {{ celestial.discoveredBy }} le {{ celestial.discoveryDate }}
</p>
<p>Facteur Gravité : {{ celestial.gravity }}</p>
<p>Facteur Densité : {{ celestial.density }}</p>
<p>Inclinaison : {{ celestial.inclination }}</p>
</div>
<div v-if="celestial.moons" class="celestial-moons">
<h2 class="heading-2">
Astres orbitant {{ celestial.name }}
</h2>
<celestials-list :celestials="celestial.moons" :has-filters="false" />
</div>
</div>
<div v-if="celestial.moons" class="celestial-moons">
<h2 class="heading-2">
Astres orbitant {{ celestial.name }}
</h2>
<celestials-list :celestials="celestial.moons" :has-filters="false" />
</div>
</main>
</div>
</div>
</main>
</section>
</template>
@@ -47,22 +53,14 @@ import { fetchCelestial } from '@/api/le-systeme-solaire'
export default {
name: 'Celestial',
data () {
return {
celestial: {}
async asyncData ({ params, error }) {
const slug = params.slug
try {
const celestial = await fetchCelestial(slug)
return { celestial }
} catch (err) {
error(err)
}
},
mounted () {
// Fetches from API...
fetchCelestial(this.$route.params.slug)
.then((res) => {
this.celestial = res
return this.celestial
})
// .catch((err) => {
// console.error(err)
// })
}
}
</script>
@@ -76,15 +74,5 @@ export default {
&:after {
background-image: url("/celestials_bg-min.jpg");
}
.celestial-body {
a {
color: $primary-xxlight;
text-decoration: underline;
&:hover {
color: $primary-xlight;
}
}
}
}
</style>

View File

@@ -1,13 +1,15 @@
<template>
<section class="celestials bg-image">
<header>
<h1 class="heading-1">
Le système solaire
</h1>
</header>
<div class="section-content">
<celestials-list :celestials="celestials" />
</div>
<main>
<header>
<h1 class="heading-1">
Le système solaire
</h1>
</header>
<div class="section-content">
<celestials-list :celestials="celestials" />
</div>
</main>
</section>
</template>

View File

@@ -1,13 +1,22 @@
<template>
<section class="favourites bg-image">
<header>
<h1 class="heading-1">
Mes favoris
</h1>
</header>
<div class="section-content">
<celestials-list :celestials="favourites" />
</div>
<main>
<header>
<h1 class="heading-1">
Mes favoris
</h1>
</header>
<div class="section-content">
<div v-if="favourites && favourites.length >= 1">
<celestials-list :celestials="favourites" />
</div>
<div v-else>
<h3 class="heading-3">
Vous n'avez aucun favori pour le moment.
</h3>
</div>
</div>
</main>
</section>
</template>
@@ -15,14 +24,10 @@
export default {
name: 'Favourites',
data () {
return {
favourites: []
computed: {
favourites () {
return this.$store.state.user.favourites
}
},
created () {
// const favourites = this.$store.state.user.favourites
}
}
</script>

View File

@@ -1,7 +0,0 @@
# PLUGINS
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains Javascript plugins that you want to run before mounting the root Vue.js application.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).

View File

@@ -1,11 +0,0 @@
# STATIC
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your static files.
Each file inside this directory is mapped to `/`.
Thus you'd want to delete this README.md before deploying to production.
Example: `/static/robots.txt` is mapped as `/robots.txt`.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -17,23 +17,23 @@ export const getters = {
}
export const mutations = {
addFav: (state, celestialId) => {
state.user.favourites.push({ id: celestialId })
addFav: (state, celestial) => {
state.user.favourites.push(celestial)
},
removeFav: (state, celestialId) => {
removeFav: (state, celestial) => {
state.user.favourites = state.user.favourites.filter(
fav => fav.id !== celestialId
fav => fav.id !== celestial.id
)
}
}
export const actions = {
toggleFav: ({ commit, getters }, celestialId) => {
toggleFav: ({ commit, getters }, celestial) => {
// If the celestial is not faved
if (!getters.isFav(celestialId)) {
commit('addFav', celestialId)
if (!getters.isFav(celestial.id)) {
commit('addFav', celestial)
} else {
commit('removeFav', celestialId)
commit('removeFav', celestial)
}
}
}

View File

@@ -1,9 +0,0 @@
import { mount } from '@vue/test-utils'
import Logo from '@/components/Logo.vue'
describe('Logo', () => {
test('is a Vue instance', () => {
const wrapper = mount(Logo)
expect(wrapper.vm).toBeTruthy()
})
})