diff --git a/package-lock.json b/package-lock.json index d8410b7..9a5e866 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1377,6 +1377,12 @@ } } }, + "@types/uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==", + "dev": true + }, "@types/webpack": { "version": "4.41.26", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.26.tgz", @@ -9959,6 +9965,14 @@ "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "require-directory": { @@ -10604,6 +10618,14 @@ "faye-websocket": "^0.11.3", "uuid": "^3.4.0", "websocket-driver": "^0.7.4" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "sockjs-client": { @@ -11838,10 +11860,9 @@ "dev": true }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache": { "version": "2.2.0", @@ -12666,6 +12687,14 @@ "requires": { "ansi-colors": "^3.0.0", "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "webpack-merge": { diff --git a/package.json b/package.json index 279f571..055df93 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,13 @@ "dependencies": { "axios": "^0.21.1", "core-js": "^3.6.5", + "uuid": "^8.3.2", "vue": "^3.0.0", "vue-router": "^4.0.0-0", "vuex": "^4.0.0-0" }, "devDependencies": { + "@types/uuid": "^8.3.0", "@typescript-eslint/eslint-plugin": "^2.33.0", "@typescript-eslint/parser": "^2.33.0", "@vue/cli-plugin-babel": "~4.5.0", diff --git a/src/App.vue b/src/App.vue index d10ed83..c289db1 100644 --- a/src/App.vue +++ b/src/App.vue @@ -4,16 +4,19 @@
+ diff --git a/src/api/le-systeme-solaire/index.ts b/src/api/le-systeme-solaire/index.ts new file mode 100644 index 0000000..c5e29ba --- /dev/null +++ b/src/api/le-systeme-solaire/index.ts @@ -0,0 +1,30 @@ +import axios from "axios"; + +/** + * Fetches the API for all celestial bodies + * @returns Array of celestials in the API + */ +export const fetchCelestials = (): Promise => { + return axios + .get("https://api.le-systeme-solaire.net/rest/bodies/") + .then(res => { + return res.data.bodies; + }); +}; + +/** + * Fetches the API for all celestial bodies + * @returns Array of celestials in the API + */ +export const fetchCelestial = (slug: string): Promise => { + return axios + .get(`https://api.le-systeme-solaire.net/rest/bodies/${slug}`) + .then(res => { + return res.data; + }); +}; + +export default { + fetchCelestials, + fetchCelestial +}; diff --git a/src/api/wikipedia/index.ts b/src/api/wikipedia/index.ts new file mode 100644 index 0000000..05c5d77 --- /dev/null +++ b/src/api/wikipedia/index.ts @@ -0,0 +1,36 @@ +import axios from "axios"; + +/** + * Get the excerpt of the wikipedia (fr) article for the specific celestial object + * @param celestial A celestial object + */ +export const fetchWikipediaExcerpt = async (celestial: any): Promise => { + let query = 'https://fr.wikipedia.org/w/api.php?action=opensearch'; + + switch (celestial.id) { + case "soleil": + case "lune": + query += `&search=${celestial.id}`; + break; + + case "planète à lunes": + query += `&search=${celestial.id}%20planète`; + break; + + default: + query += `&search=${celestial.id}%20${celestial.type}`; + break; + } + + query += "&limit=1&namespace=0&format=json"; + + console.log(query); + + + const req = await axios.get(query); + return; +}; + +export default { + fetchWikipediaExcerpt +} \ No newline at end of file diff --git a/src/assets/scss/_animations.scss b/src/assets/scss/_animations.scss index 601de22..26372b3 100644 --- a/src/assets/scss/_animations.scss +++ b/src/assets/scss/_animations.scss @@ -1,3 +1,14 @@ +@keyframes toggleFavHeart { + 0%, 20% { + color: #d01d35; + transform: scale(1.2); + } + 100% { + color: #d01d35; + transform: scale(1); + } +} + @keyframes fadeInBg { from { opacity: 0; @@ -16,6 +27,15 @@ } } +@keyframes fadeOut { + from { + opacity: 100%; + } + to { + opacity: 0; + } +} + @keyframes fromBottom { from { transform: translateY(20px); @@ -25,6 +45,24 @@ } } +@keyframes slideFromRight { + from { + transform: translateX(100%); + } + to { + transform: translateX(0); + } +} + +@keyframes slideFromLeft { + from { + transform: translateX(0); + } + to { + transform: translateX(100%); + } +} + @keyframes paneBgAround { 0% { background-position: -10vw 0%; diff --git a/src/assets/scss/_fonts.scss b/src/assets/scss/_fonts.scss index 2e45106..0f8698c 100644 --- a/src/assets/scss/_fonts.scss +++ b/src/assets/scss/_fonts.scss @@ -1 +1,2 @@ +@import url('https://fonts.googleapis.com/icon?family=Material+Icons|Material+Icons+Round'); @import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,700;1,400;1,700&family=Poppins:wght@400;600;700;800;900&display=swap'); \ No newline at end of file diff --git a/src/assets/scss/_global.scss b/src/assets/scss/_global.scss index c55b6cb..8da6a8e 100644 --- a/src/assets/scss/_global.scss +++ b/src/assets/scss/_global.scss @@ -66,6 +66,18 @@ a { } } +button { + &.no-style { + padding: 0; + background: none; + border: none; + cursor: pointer; + &:focus { + outline: none; + } + } +} + hr { border-color: rgba($white, .2); } @@ -140,13 +152,14 @@ hr { width: 100%; background-size: cover; background-attachment: fixed; + background-repeat: no-repeat; z-index: -1; opacity: 33%; pointer-events: none; } &.bg-fade-in { &:after { - width: 120vw; + background-size: 120vw; opacity: 0; animation: fadeInBg 2s ease-out 0s 1 forwards, paneBgAround 35s ease-in-out 0s infinite forwards; diff --git a/src/assets/scss/_variables.scss b/src/assets/scss/_variables.scss index 12c47f9..bec6060 100644 --- a/src/assets/scss/_variables.scss +++ b/src/assets/scss/_variables.scss @@ -8,6 +8,16 @@ $space-blue-600: #234e69; $space-blue-500: #457b9d; $space-blue-300: #a8dadc; +$blue: #306BAC; +$green: #1c8267; +$orange: #ff9844; +$red: #9f2042; + +$info: $blue; +$valid: $green; +$warning: $orange; +$danger: $red; + $primary: $space-blue-700; $primary-light: $space-blue-600; diff --git a/src/components/Navbar.vue b/src/components/Navbar.vue index 7eeee35..aaada17 100644 --- a/src/components/Navbar.vue +++ b/src/components/Navbar.vue @@ -23,8 +23,8 @@ export default defineComponent({ link: "/" }, { - text: "Célestes", - link: "/celestes" + text: "Astres", + link: "/astres" }, { text: "À propos", diff --git a/src/components/celestials/CelestialCard.vue b/src/components/celestials/CelestialCard.vue index 4d61454..4a950a5 100644 --- a/src/components/celestials/CelestialCard.vue +++ b/src/components/celestials/CelestialCard.vue @@ -42,6 +42,15 @@

+
+ + info + +
+

@@ -75,12 +84,13 @@

- - Détails - + favorite +
@@ -88,6 +98,9 @@ @@ -121,8 +164,18 @@ export default defineComponent({ .card-icon { display: block; position: absolute; - top: 0; + top: 20px; + bottom: 20px; + left: 0; right: 0; + user-select: none; + pointer-events: none; + opacity: 4%; + img { + height: 100%; + width: 100%; + z-index: -1; + } } > * { @@ -135,6 +188,30 @@ export default defineComponent({ flex: 1 1 auto; min-height: 30px; } + + .card-info { + position: absolute; + top: 0; + right: 0; + } + + .card-actions { + color: #afafaf; + .favourite { + .icon { + color: #afafaf; + } + &.active { + .icon { + position: relative; + display: inline-block; + will-change: font-size; + animation: toggleFavHeart 0.6s cubic-bezier(0.17, 0.89, 0.32, 1.49); + animation-fill-mode: forwards; + } + } + } + } } } diff --git a/src/components/celestials/CelestialFilters.vue b/src/components/celestials/CelestialFilters.vue index 0b2bc00..d3f3050 100644 --- a/src/components/celestials/CelestialFilters.vue +++ b/src/components/celestials/CelestialFilters.vue @@ -71,7 +71,7 @@ export default defineComponent({ data() { return { filters: { - all: false, + all: true, planets: false, moons: false, stars: false, diff --git a/src/components/toast/ToastCard.vue b/src/components/toast/ToastCard.vue new file mode 100644 index 0000000..a9b3d68 --- /dev/null +++ b/src/components/toast/ToastCard.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/src/components/toast/ToastsList.vue b/src/components/toast/ToastsList.vue new file mode 100644 index 0000000..bdbb3e7 --- /dev/null +++ b/src/components/toast/ToastsList.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/src/plugins/methods/index.ts b/src/plugins/methods/index.ts index cad386a..acdde32 100644 --- a/src/plugins/methods/index.ts +++ b/src/plugins/methods/index.ts @@ -21,6 +21,11 @@ export const addCelestialType = (celestial: any) => { return celestial; }; -export default { - addCelestialType +export const addCelestialsType = (celestials: any) => { + return celestials.map((e: any) => addCelestialType(e)); +}; + +export default { + addCelestialType, + addCelestialsType }; diff --git a/src/router/index.ts b/src/router/index.ts index 7087f20..d6f1be3 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -19,12 +19,12 @@ const routes: Array = [ component: About }, { - path: "/celestes", + path: "/astres", name: "CelesteAll", component: Celestials }, { - path: "/celestes/:slug", + path: "/astres/:slug", name: "CelesteSingle", component: Celestial, props: true diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts index 3804a43..f001839 100644 --- a/src/shims-vue.d.ts +++ b/src/shims-vue.d.ts @@ -4,3 +4,5 @@ declare module '*.vue' { const component: DefineComponent<{}, {}, any> export default component } + +declare module 'uuid'; \ No newline at end of file diff --git a/src/store/index.ts b/src/store/index.ts index 187b4cb..76ae223 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,8 +1,52 @@ import { createStore } from "vuex"; +import toastStore from "./toasts"; + export default createStore({ - state: {}, - mutations: {}, - actions: {}, - modules: {} + state: () => ({ + user: { + avatarUrl: "", + favourites: Array<{ id: string }>() + } + }), + getters: { + // Returns the number of favs for the user + favCount: (state): number => { + return state.user.favourites.length; + }, + // Returns true if celestial is fav + isFav: state => (celestialId: string) => { + return state.user.favourites.find(fav => fav.id === celestialId); + } + }, + mutations: { + addFav: (state, celestialId: string) => { + state.user.favourites.push({ id: celestialId }); + }, + removeFav: (state, celestialId: string) => { + state.user.favourites = state.user.favourites.filter( + fav => fav.id != celestialId + ); + } + }, + actions: { + toggleFav: ({ commit, getters }, celestialId: string) => { + // If the celestial is not faved + if (!getters.isFav(celestialId)) { + // ... favs it + commit("addFav", celestialId); + } else { + // ...else unfavs + commit("removeFav", celestialId); + } + } + }, + modules: { + toasts: { + namespaced: true, + state: toastStore.state, + mutations: toastStore.mutations, + actions: toastStore.actions + } + } }); diff --git a/src/store/toasts/index.ts b/src/store/toasts/index.ts new file mode 100644 index 0000000..e3e229b --- /dev/null +++ b/src/store/toasts/index.ts @@ -0,0 +1,27 @@ +export default { + state: { + queue: Array<{ + id: string; + title: string; + message: string; + category: string; + timer: number; + }>() + }, + mutations: { + pushToast: (state: any, toast: any) => { + state.queue.push(toast); + }, + purgeToast: (state: any, toastId: string) => { + state.queue = state.queue.filter((toast: any) => toast.id != toastId); + } + }, + actions: { + pushToast: ({ commit }: any, toast: any) => { + commit("pushToast", toast); + }, + purgeToast: ({ commit }: any, toastId: string) => { + commit("purgeToast", toastId); + } + } +}; diff --git a/src/views/Home.vue b/src/views/Home.vue index f6e4435..42970ba 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -3,11 +3,11 @@

Full Skies

- L'application Full Skies explore les cieux à votre place ! + Explorez les cieux et le système solaire avec Full Skies !

Embarquez pour un voyage stellaire ; destination : le système solaire et - ses astres. + ses astres si proches.

diff --git a/src/views/celestials/Celestial.vue b/src/views/celestials/Celestial.vue index 332d796..02c8dda 100644 --- a/src/views/celestials/Celestial.vue +++ b/src/views/celestials/Celestial.vue @@ -1,6 +1,6 @@