diff --git a/app.vue b/app.vue index d8579390aef33fc0353d3ada8a8de73d3bbac406..8e56977dd192e05f2818161be23fa714cc22d351 100644 --- a/app.vue +++ b/app.vue @@ -6,6 +6,13 @@ useHead({ }) </script> +<style> +@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&family=Open+Sans:ital,wdth,wght@0,75..100,300..800;1,75..100,300..800&family=Oswald:wght@200..700&display=swap'); +body { + margin: 0; +} +</style> + <template> <div> <NuxtLayout> diff --git a/assets/css/fonts.css b/assets/css/fonts.css new file mode 100644 index 0000000000000000000000000000000000000000..bd03fb381a0c2ea24dcdff0b7fee4400ca5e9d26 --- /dev/null +++ b/assets/css/fonts.css @@ -0,0 +1,35 @@ +/*source : https://fonts.google.com/selection/embed*/ +:root { + --montserrat-width: 700; /* Use a value from 100 to 900 */ + --open-sans-width: 400; /* Use a value from 300 to 800 */ + --oswald-width: 400; /* Use a value from 200 to 700 */ +} + +h1, h2, h3, h4, h5, h6, .header { + font-family: "Montserrat", serif; + font-optical-sizing: auto; + font-weight: var(--montserrat-width); + font-style: normal; +} + +h1 { font-size: clamp(32px, 6vw, 36px); } +h2 { font-size: clamp(24px, 5vw, 28px); } +h3 { font-size: clamp(18px, 4vw, 22px); } +p { font-size: clamp(14px, 3vw, 16px); } +p p { font-size: clamp(12px, 2vw, 14px); } + +div, p, a, .open-sans { + font-family: "Open Sans", serif; + font-optical-sizing: auto; + font-weight: var(--open-sans-width); + font-style: normal; + font-variation-settings: "wdth" 100; /* Use a value from 75 to 100 */ +} + +.number { + font-family: "Oswald", serif; + font-optical-sizing: auto; + font-weight: var(--oswald-width); + font-style: normal; + font-size: clamp(18px, 4vw, 22px); +} \ No newline at end of file diff --git a/assets/css/transitions.css b/assets/css/transitions.css new file mode 100644 index 0000000000000000000000000000000000000000..6a362a7a8bd18d9a785d2c93689b9f516f67c2bd --- /dev/null +++ b/assets/css/transitions.css @@ -0,0 +1,24 @@ +/* Style transitions for page transitions */ +.page-enter-active, .page-leave-active { + transition: all 0.4s; +} +.page-enter-from, .page-leave-to { + opacity: 0; + filter: blur(1rem); +} + +.rotate-enter-active, .rotate-leave-active { + transition: all 0.4s; +} +.rotate-enter-from, .rotate-leave-to { + opacity: 0; + transform: rotate3d(1, 1, 1, 15deg); +} + +.layout-enter-active, .layout-leave-active { + transition: all 0.4s; +} +.layout-enter-from, .layout-leave-to { + opacity: 0; + filter: blur(1rem); +} \ No newline at end of file diff --git a/components/AppFooter.vue b/components/AppFooter.vue index 81db4d3354f47abc8eb6f1dc54fbbc88700863fc..eeee7b9014c0ee72fc53dbe7b72cc793d77ae087 100644 --- a/components/AppFooter.vue +++ b/components/AppFooter.vue @@ -1,5 +1,25 @@ +<script setup lang="ts"> +const appConfig = useAppConfig() +</script> + +<style> +footer { + position: fixed; + bottom: 0; + padding-left: 8px; + width: 100%; + + display: flex; + background-color: v-bind(appConfig.theme.dark.colors.background); +} +footer > p { + margin: 1vh; + color: v-bind(appConfig.theme.dark.colors.primary); +} +</style> + <template> <footer> - <p>© 2024 3SPA</p> + <p>© 2025 3SPA</p> </footer> </template> \ No newline at end of file diff --git a/components/AppHeader.vue b/components/AppHeader.vue index 848b86a29e32354cf12c4acd680dd783494da11d..b21062ff27f63698049d19b7c8e075de1f6bedfd 100644 --- a/components/AppHeader.vue +++ b/components/AppHeader.vue @@ -2,8 +2,24 @@ const appConfig = useAppConfig() </script> +<style> +header { + position: sticky; + top: 0; + padding-left: 8px; + + display: flex; + justify-content: center; + background-color: v-bind(appConfig.theme.dark.colors.background); +} +.header { + margin: 1vh; + color: v-bind(appConfig.theme.dark.colors.secondary); +} +</style> + <template> <header> - <h1>{{appConfig.title}}</h1> + <h1 class="header">{{appConfig.title}}</h1> </header> </template> diff --git a/data/mock/exercices.json b/data/mock/exercices.json new file mode 100644 index 0000000000000000000000000000000000000000..bdd45ebe38ec65c174a7d9af913d6220ad8b6a82 --- /dev/null +++ b/data/mock/exercices.json @@ -0,0 +1,38 @@ +[ + { + "id": 1, + "name": "Push-up", + "description": "The push-up is a basic exercise used in athletic training or physical therapy. It is a type of resistance training that develops the pectoral muscles and triceps, as well as the deltoids, serratus anterior, coracobrachialis and the midsection as a whole. Push-ups are a basic exercise used in civilian athletic training or physical education and commonly in military physical training.", + "category": "Renforcement", + "subCategory": "Upper Body", + "safetyInstructions": [ + "Keep your body in a straight line from head to heels.", + "Keep your elbows close to your body." + ], + "generalInstructions": [ + "Start in a plank position with your hands shoulder-width apart.", + "Lower your body until your chest nearly touches the floor.", + "Push yourself back up to the starting position." + ], + "diagram": "https://upload.wikimedia.org/wikipedia/commons/b/b8/Liegestuetz02_ani_fcm.gif", + "video": "https://www.youtube.com/watch?v=IODxDxX7oi4" + }, + { + "id": 2, + "name": "Squat", + "description": "The squat is a lower body exercise. It primarily targets the quadriceps and the glutes, but also involves the hamstrings, the calves, and the lower back. The squat is often called 'the king of exercises' because it works many muscles at the same time.", + "category": "Renforcement" + }, + { + "id": 3, + "name": "Running", + "description": "Running is a method of terrestrial locomotion allowing humans and other animals to move rapidly on foot. It is simply defined in athletics terms as a gait in which at regular points during the running cycle both feet are off the ground.", + "category": "Cardio" + }, + { + "id": 4, + "name": "Stretching exercises", + "description": "Stretching is a form of physical exercise in which a specific muscle or tendon (or muscle group) is deliberately flexed or stretched in order to improve the muscle's felt elasticity and achieve comfortable muscle tone. The result is a feeling of increased muscle control, flexibility, and range of motion.", + "category": "Stretching" + } +] \ No newline at end of file diff --git a/layouts/default.vue b/layouts/default.vue index 0d69f14ead36b357bdbfe58c5246c468903b6241..2b99b6214dc37b43e4866f9878a18fc8f22c115b 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -1,7 +1,13 @@ +<style> +body { + margin-bottom: 6vh; +} +</style> + <template> <div> <AppHeader /> <slot /> <AppFooter /> </div> -</template> +</template> \ No newline at end of file diff --git a/layouts/login.vue b/layouts/login.vue new file mode 100644 index 0000000000000000000000000000000000000000..4dff124468f1c0f9d1b09e7e762b46d7c7e9cd91 --- /dev/null +++ b/layouts/login.vue @@ -0,0 +1,5 @@ +<template> + <div> + <slot /> + </div> +</template> \ No newline at end of file diff --git a/middleware/auth.ts b/middleware/auth.ts new file mode 100644 index 0000000000000000000000000000000000000000..bb7f74ce6ade3e3f5cc486618797d48fe5ce6d65 --- /dev/null +++ b/middleware/auth.ts @@ -0,0 +1,6 @@ +function isAuthenticated(): boolean { return true } +export default defineNuxtRouteMiddleware((to, from) => { + if (!isAuthenticated()) { + return navigateTo('/login') + } +}) diff --git a/nuxt.config.ts b/nuxt.config.ts index c86f4246c1dc76759e6a2be9a7205f0e72e8f211..940648b8c6189f5c1aa8a242b7955f1cb0e004f2 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -31,12 +31,26 @@ export default defineNuxtConfig({ head: { charset: 'utf-8', viewport: 'width=device-width, initial-scale=1', - } + }, + pageTransition: { name: 'page', mode: 'out-in' }, + layoutTransition: { name: 'layout', mode: 'out-in' } }, + + /** Les feuilles de style */ + css: [ + '~/assets/css/fonts.css', + '~/assets/css/transitions.css', + ], + components: [ { path: '~/components', pathPrefix: true, }, ], + imports: { + dirs: [ + 'types/**' + ] + } }) diff --git a/package.json b/package.json index c9c523fa7480e01836adbe5312cf6d1723bad5a3..b19fa8a876fd52fa81e751ec52f3cc8ac6995cd9 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,9 @@ "dev": "node_modules/.bin/nuxt dev", "generate": "node_modules/.bin/nuxt generate", "preview": "node_modules/.bin/nuxt preview", - "postinstall": "node_modules/.bin/nuxt prepare" + "postinstall": "node_modules/.bin/nuxt prepare", + "start": "node_modules/.bin/nuxt start", + "prod": " node .output/server/index.mjs" }, "dependencies": { "nuxt": "^3.15.1", diff --git a/pages/about.vue b/pages/about.vue index 2b2de16861a4936e6f537822163cd7147820b0dc..52467d3e15fbd6f677a2f546f44e62cdbb719763 100644 --- a/pages/about.vue +++ b/pages/about.vue @@ -5,6 +5,11 @@ useHead({ { name: 'description', content: 'Page d\'accueil de l\'interface administrateur du projet.' } ] }) +definePageMeta({ + pageTransition: { + name: 'rotate' + } +}) </script> <template> diff --git a/pages/exercices.vue b/pages/exercices.vue new file mode 100644 index 0000000000000000000000000000000000000000..371b856f2dcee520ede47b03c7b30c23e681837f --- /dev/null +++ b/pages/exercices.vue @@ -0,0 +1,25 @@ +<script setup lang="ts"> +import myData from '../data/mock/exercices.json'; + +const router = useRouter() + +const exercices = ref(myData) +</script> + +<template> + <div> + <h2>Exercices</h2> + <p v-for="exercice in exercices"> + {{ exercice.name }} <br> + <p>{{ exercice.description }}</p> + </p> + <p v-for="exercice in exercices"> + {{ exercice.name }} <br> + <p>{{ exercice.description }}</p> + </p> + </div> +</template> + +<style scoped> + +</style> \ No newline at end of file diff --git a/pages/exercices/[id].vue b/pages/exercices/[id].vue new file mode 100644 index 0000000000000000000000000000000000000000..96c0baf2962af764a8ee54b135a5bb33402f69c8 --- /dev/null +++ b/pages/exercices/[id].vue @@ -0,0 +1,11 @@ +<script setup lang="ts"> + +</script> + +<template> + +</template> + +<style scoped> + +</style> \ No newline at end of file diff --git a/pages/index.vue b/pages/index.vue index 1b10de4ee5446de2c6067e8b34e04039f295d60f..b6d994cb50c5d8e1c43353f7a681e252845248cc 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -4,10 +4,15 @@ useHead({ { name: 'description', content: 'Page d\'accueil de l\'interface administrateur du projet.' } ] }) +definePageMeta({ + middleware: 'auth' +}) </script> <template> <div> <h2>Index vue</h2> + <NuxtLink to="/about">About page</NuxtLink><br> + <NuxtLink to="/login">Log in</NuxtLink> </div> </template> \ No newline at end of file diff --git a/pages/login.vue b/pages/login.vue new file mode 100644 index 0000000000000000000000000000000000000000..334f535c2f9a7152ea09e52f5e3a34eeda41b7a3 --- /dev/null +++ b/pages/login.vue @@ -0,0 +1,21 @@ +<script setup lang="ts"> +definePageMeta({ + layout: 'login' +}) + +import { useRouter } from 'vue-router' +const router = useRouter() +</script> + +<template> + <div> + <h2>Login</h2><br> + username: <input type="text" /><br> + password: <input type="password" /><br> + <button @click="router.push('/')">Log in</button> + </div> +</template> + +<style scoped> + +</style> \ No newline at end of file diff --git a/types/Exercice.ts b/types/Exercice.ts new file mode 100644 index 0000000000000000000000000000000000000000..80fc46f11078c517c083963b6b6dc3f85b7e1980 --- /dev/null +++ b/types/Exercice.ts @@ -0,0 +1,14 @@ +import type {ExerciseCategory} from "~/types/enum/ExerciseCategory"; +import type {ExerciseSubCategory} from "~/types/enum/ExerciseSubCategory"; + +export interface Exercise { + id: number; + name: string; + description: string; + category: ExerciseCategory; + subCategory?: ExerciseSubCategory; + safetyInstructions?: string[]; + generalInstructions?: string[]; + diagram?: string; + video?: string; +} \ No newline at end of file diff --git a/types/enum/ExerciseCategory.ts b/types/enum/ExerciseCategory.ts new file mode 100644 index 0000000000000000000000000000000000000000..760928e8767928f1620015adc7a3755afccf16cd --- /dev/null +++ b/types/enum/ExerciseCategory.ts @@ -0,0 +1,5 @@ +export enum ExerciseCategory { + Renforcement = 'Renforcement', + Cardio = 'Cardio', + Stretching = 'Stretching', +} \ No newline at end of file diff --git a/types/enum/ExerciseSubCategory.ts b/types/enum/ExerciseSubCategory.ts new file mode 100644 index 0000000000000000000000000000000000000000..2dd536e68b4a3cac3f5d29fde31aced1c3e835d4 --- /dev/null +++ b/types/enum/ExerciseSubCategory.ts @@ -0,0 +1,8 @@ +export enum ExerciseSubCategory { + Chest = "Chest", + Back = "Back", + Legs = "Legs", + Shoulders = "Shoulders", + Arms = "Arms", + Other = "Other" +} \ No newline at end of file