-
-
- Le mot de passe est faible
+
+
+ force de ton mot de passe :
+
+
+
+
+
+
+
+ Le mot de passe est faible
+
+
+ Le mot de passe est moyen
+
+
+ Le mot de passe est bon
+
+
+ Le mot de passe est fort
+
+
-
- Le mot de passe est moyen
+
+
+
+
+
+ Un mot bon mot de passe est souvent lié au nombres de charactères (une phrase est un bon mot de
+ passe) et à sa complexité à deviner (non, votre code postal et le nom de votre lapin n'est pas un bon motde
+ passe)
+
-
- Le mot de passe est bon
-
-
- Le mot de passe est fort
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/modules/app/components/WIPNotif.vue b/modules/app/components/WIPNotif.vue
new file mode 100644
index 0000000..c0ea943
--- /dev/null
+++ b/modules/app/components/WIPNotif.vue
@@ -0,0 +1,4 @@
+
+
+
\ No newline at end of file
diff --git a/modules/app/components/profile/EmailUpdateForm.vue b/modules/app/components/profile/EmailUpdateForm.vue
new file mode 100644
index 0000000..eb65faa
--- /dev/null
+++ b/modules/app/components/profile/EmailUpdateForm.vue
@@ -0,0 +1,77 @@
+
+
+
+ Modification de votre adresse de couriel
+
+
+
+
+
+
+
+
+
+
+ Sauvegarder la nouvelle adresse
+
+
+
+
\ No newline at end of file
diff --git a/modules/app/components/profile/PasswordUpdateForm.vue b/modules/app/components/profile/PasswordUpdateForm.vue
new file mode 100644
index 0000000..bf2bd43
--- /dev/null
+++ b/modules/app/components/profile/PasswordUpdateForm.vue
@@ -0,0 +1,88 @@
+
+
+
+ Réinitialiser votre mot de passe
+ Nous pouvons envoyer un lien de récupération à l’adresse courriel associé à votre compte.
+
+
+
+
+
+
+
+
+
+
+
+ Sauvegarder le nouveau mot de passe
+
+
+
+
\ No newline at end of file
diff --git a/modules/app/composables/auth.ts b/modules/app/composables/auth.ts
new file mode 100644
index 0000000..50f48d6
--- /dev/null
+++ b/modules/app/composables/auth.ts
@@ -0,0 +1,13 @@
+export const useAuth = () => {
+ const user = useSupabaseUser()
+ const { auth } = useSupabaseClient()
+
+ auth.onAuthStateChange(async (event) => {
+ if (event === 'SIGNED_OUT')
+ navigateTo('/')
+ })
+
+ return {
+ user
+ }
+}
\ No newline at end of file
diff --git a/modules/app/composables/foStyle.ts b/modules/app/composables/foStyle.ts
new file mode 100644
index 0000000..b3ae324
--- /dev/null
+++ b/modules/app/composables/foStyle.ts
@@ -0,0 +1,20 @@
+export const useFoStyle = () => {
+ return {
+ inputStyle: {
+ ui: {
+ placeholder: 'placeholder-transparent',
+ },
+ attrs: {
+ variant: 'none'
+ }
+ },
+ formGroupStyle: {
+ ui: {
+ wrapper: 'flex flex-col md:flex-row rounded-lg py-1 px-4 border-b-2 border-orange-500 has-[:focus]:bg-orange-100 has-[:focus]:border-t-2 has-[:focus]:border-x-2 has-[:focus]:border-b-0 mb-6',
+ inner: 'flex-2 content-center',
+ container: 'flex-1 mt-auto relative',
+ error: 'text-red-500 text-sm absolute top[-100%] left-0 mt-2 pointer-events-none',
+ },
+ },
+ }
+}
\ No newline at end of file
diff --git a/modules/app/composables/passwordStrength.ts b/modules/app/composables/passwordStrength.ts
index 128f941..0a783bf 100644
--- a/modules/app/composables/passwordStrength.ts
+++ b/modules/app/composables/passwordStrength.ts
@@ -2,7 +2,7 @@ import { zxcvbn, zxcvbnOptions, type ZxcvbnResult } from '@zxcvbn-ts/core'
import * as zxcvbnCommonPackage from '@zxcvbn-ts/language-common'
import * as zxcvbnEnPackage from '@zxcvbn-ts/language-fr'
-export const usePasswordStrength = (password: Ref) => {
+export const usePasswordStrength = (password?: Ref) => {
// 0 # too guessable: risky password. (guesses < 10 ^ 3)
// 1 # very guessable: protection from throttled online attacks. (guesses < 10 ^ 6)
@@ -25,18 +25,25 @@ export const usePasswordStrength = (password: Ref) => {
zxcvbnOptions.setOptions(options)
- watchDebounced(password, (newPassword) => {
- if (!newPassword) {
- strength.value = {
- score: 0,
- }
- return
- }
+ function testPassword(password: string) {
+ return zxcvbn(password.trim())
+ }
- strength.value = zxcvbn(newPassword.trim())
- }, { immediate: true, debounce: 500 })
+ if (password) {
+ watchDebounced(password, (newPassword) => {
+ if (!newPassword) {
+ strength.value = {
+ score: 0,
+ }
+ return
+ }
+
+ strength.value = zxcvbn(newPassword.trim())
+ }, { immediate: true, debounce: 500 })
+ }
return {
strength,
+ testPassword,
}
}
\ No newline at end of file
diff --git a/modules/app/composables/profile.ts b/modules/app/composables/profile.ts
new file mode 100644
index 0000000..02cbeef
--- /dev/null
+++ b/modules/app/composables/profile.ts
@@ -0,0 +1,66 @@
+export const useProfile = () => {
+ const user = useSupabaseUser()
+ const client = useSupabaseClient()
+ const toast = useToast()
+
+ const loading = ref(false)
+ const profile = ref<{
+ firstname: string
+ lastname: string
+ displayname?: string
+ } | null>(null)
+
+ const displayName = computed(() => {
+ if (!profile.value) {
+ return '...'
+ }
+
+ const { firstname, lastname, displayname } = profile.value || {}
+
+ if (!displayname) {
+ return `${firstname || ''} ${lastname || ''}`.trim()
+ }
+
+ return displayname
+ })
+
+ const waitingMailValidation = computed(() => {
+ return user.value && !user.value?.email_confirmed_at
+ })
+
+
+ async function getProfile() {
+ loading.value = true
+
+ const { data, error } = await useAsyncData('profiles', async () => {
+ if (!user.value) {
+ return
+ }
+
+ const { data, error } = await client.from('profiles').select('id,firstname,lastname,displayname,mail').eq('id', user.value.id).single()
+ return data
+ })
+
+ if (error.value) {
+ toast.add({ color: 'red', description: error.value?.message, title: 'Error' })
+ } else {
+ profile.value = data.value
+ }
+
+ loading.value = false
+ }
+
+ watch(user, (user) => {
+ if (user && !loading.value) {
+ getProfile()
+ }
+ }, { immediate: true })
+
+ return {
+ user,
+ loading,
+ profile,
+ displayName,
+ waitingMailValidation,
+ }
+}
\ No newline at end of file
diff --git a/modules/app/nuxt.config.ts b/modules/app/nuxt.config.ts
index 22e3f60..fb2c0c6 100644
--- a/modules/app/nuxt.config.ts
+++ b/modules/app/nuxt.config.ts
@@ -6,6 +6,7 @@ export default defineNuxtConfig({
runtimeConfig: {
public: {
env: '',
+ baseUrl: process.env.NUXT_PUBLIC_BASE_URL || 'http://localhost:3000',
},
},
@@ -33,7 +34,7 @@ export default defineNuxtConfig({
redirectOptions: {
login: '/signin',
callback: '/signin/confirm',
- exclude: ['/signin/*', '/join', '/public/*'],
+ exclude: ['/profile/auth/reset', '/signin/*', '/join', '/join/*', '/public/*'],
},
cookieName: 'fo-cookies',
cookieOptions: {
diff --git a/modules/app/pages/index.vue b/modules/app/pages/index.vue
index 72b1f92..04b1324 100644
--- a/modules/app/pages/index.vue
+++ b/modules/app/pages/index.vue
@@ -5,7 +5,12 @@ definePageMeta({
-
-
Home
-
+
+
+ Bienvenue sur Force Orange
+
+ Tu retrouveras toutes les informations nécessaires pour t'accompagner dans la préparation du festival Paris Est
+ Ludique 2025.
+
+
\ No newline at end of file
diff --git a/modules/app/pages/join/index.vue b/modules/app/pages/join/index.vue
index 0afc771..6debae8 100644
--- a/modules/app/pages/join/index.vue
+++ b/modules/app/pages/join/index.vue
@@ -1,27 +1,41 @@
-
- Rejoindre Paris est Ludique!
+
+ Rejoindre Paris est Ludique!
Pour rejoindre la Force orange de Paris est Ludique!, il est nécessaire de compléter le
formulaire ci-dessous:
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
-
S'inscrire
+
+
+
+
+
+
+
+
+
+
+
+
+
+
S'inscrire
\ No newline at end of file
diff --git a/modules/app/pages/join/valid.vue b/modules/app/pages/join/valid.vue
new file mode 100644
index 0000000..13a62b3
--- /dev/null
+++ b/modules/app/pages/join/valid.vue
@@ -0,0 +1,27 @@
+
+
+
+
+ Bravo ! Tu as vaillament réussi à valider ton compte Force Orange
+
+ Tu peux maintenant te connecter à ton compte et profiter de toutes les fonctionnalités de Force Orange.
+
+
+
+ Retour à l'accueil
+
+
+
+ Se connecter
+
+
+
\ No newline at end of file
diff --git a/modules/app/pages/join/waiting.vue b/modules/app/pages/join/waiting.vue
new file mode 100644
index 0000000..2b83946
--- /dev/null
+++ b/modules/app/pages/join/waiting.vue
@@ -0,0 +1,25 @@
+
+
+
+
+ En attente de validation
+
+ Un email de validation t'a été envoyé à ton adresse de courriel.
+ Merci de cliquer sur le lien pour valider ton inscription sur Force Orange.
+
+
+
+ Retour à l'accueil
+
+
+
+ Se connecter
+
+
+
\ No newline at end of file
diff --git a/modules/app/pages/news.vue b/modules/app/pages/news.vue
new file mode 100644
index 0000000..d0445e6
--- /dev/null
+++ b/modules/app/pages/news.vue
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Les actus ça sera ici !
+
+
\ No newline at end of file
diff --git a/modules/app/pages/profile/auth/reset.vue b/modules/app/pages/profile/auth/reset.vue
new file mode 100644
index 0000000..d464349
--- /dev/null
+++ b/modules/app/pages/profile/auth/reset.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/app/pages/profile/index.vue b/modules/app/pages/profile/index.vue
new file mode 100644
index 0000000..1dca4c1
--- /dev/null
+++ b/modules/app/pages/profile/index.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ {{ displayName }}
+
+
+
+ Authentification
+ Gérer mes manières de me connecter au site de Force Orange.
+
+ {{ profile.mail }}
+
+
+ Modifier mon adresse de couriel
+
+ Modifier mon mot
+ de passe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/app/pages/signin/confirm.vue b/modules/app/pages/signin/confirm.vue
index 0d64016..4c3450a 100644
--- a/modules/app/pages/signin/confirm.vue
+++ b/modules/app/pages/signin/confirm.vue
@@ -1,6 +1,10 @@
-
+
diff --git a/modules/app/pages/signin/forgot.vue b/modules/app/pages/signin/forgot.vue
new file mode 100644
index 0000000..7b9613d
--- /dev/null
+++ b/modules/app/pages/signin/forgot.vue
@@ -0,0 +1,88 @@
+
+
+
+
+ Réinitialiser votre mot de passe
+ Nous pouvons envoyer un lien de récupération à l’adresse courriel associé à votre compte.
+
+
+
+
+
+
+
+ Récupérer mon compte
+
+
+
+
+
+ C’est partit
+
+ Si nous avons connaissance de cette adresse, vous devriez recevoir un courriel contenant les instructions pour
+ récupérer votre compte Force Orange.
+
+
+
+ Fermer cette page
+
+
+
+
\ No newline at end of file
diff --git a/modules/app/pages/signin/index.vue b/modules/app/pages/signin/index.vue
index 5e1f71f..0c6f2e3 100644
--- a/modules/app/pages/signin/index.vue
+++ b/modules/app/pages/signin/index.vue
@@ -7,26 +7,32 @@ definePageMeta({
name: 'Signin',
})
-const user = useSupabaseUser()
+const router = useRouter()
+const toast = useToast()
+
+const loading = ref(false)
const { auth } = useSupabaseClient
()
+const { inputStyle, formGroupStyle } = useFoStyle()
+
const schema = object({
- mail: string().email('Invalid email').required('Required'),
- password: string().required('Required'),
+ email: string().lowercase().trim().email('Invalid email').required('Required'),
+ password: string().lowercase().trim().required('Required'),
})
type Schema = InferType
const state = reactive({
- mail: undefined,
+ email: undefined,
password: undefined,
})
async function onSignin(event: FormSubmitEvent) {
+ loading.value = true
const formSubmit = event.data
const { data, error } = await auth.signInWithPassword({
- email: formSubmit.mail,
+ email: formSubmit.email,
password: formSubmit.password
})
@@ -36,41 +42,56 @@ async function onSignin(event: FormSubmitEvent) {
// options: {
// // set this to false if you do not want the user to be automatically signed up
// shouldCreateUser: false,
- // emailRedirectTo: 'https://example.com/welcome',
+ // emailRedirectTo: 'https://example.com/waiting',
// },
// })
- // TODO confirm signin
+ if (error) {
+ console.log(error)
+ toast.add({
+ title: 'Erreur',
+ description: 'Une erreur est survenue lors de ton inscription',
+ color: 'red',
+ })
+ } else {
+ console.log(data)
- if (error) console.log(error)
+ toast.add({
+ title: 'Connecté(e)',
+ description: 'Que la force Orange soit avec toi !',
+ color: 'orange',
+ })
+
+ router.push('/')
+ }
+ loading.value = false
}
+
+ Qui êtes-vous ?
-
- Qui êtes-vous ?
-
-
-
-
+
+
+
-
-
+
+
- Se Connecter
- Mot de passe oublié ?
+
+ Se Connecter
+ Mot de passe oublié ?
+
-
-
- ou bien
+
\ No newline at end of file
diff --git a/modules/shared/app.config.ts b/modules/shared/app.config.ts
index 9abea16..20eba1f 100644
--- a/modules/shared/app.config.ts
+++ b/modules/shared/app.config.ts
@@ -7,17 +7,13 @@ export default defineAppConfig({
},
},
input: {
- placeholder: 'placeholder-transparent',
+ base: 'focus:bg-orange-100',
default: {
size: 'md',
color: 'primary',
- variant: 'none'
},
},
formGroup: {
- wrapper: 'flex flex-col md:flex-row rounded-lg py-1 px-4 border-b-2 border-orange-500',
- inner: 'flex-2 content-center',
- container: 'flex-1 mt-auto',
label: {
base: 'font-thin'
},