refactor: better project structure
All checks were successful
Deploy WordPress and Nuxt / deploy (push) Successful in 6m3s

This commit is contained in:
2025-09-17 08:41:42 -04:00
parent ba42386645
commit 346890c088
19 changed files with 90 additions and 124 deletions

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
const { loginSchema, loginFields, onLoginSubmit } = useLogin();
const { loginFields, onLoginSubmit } = useAuth();
</script>
<template>

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
const { onLogoutClick } = useLogout();
const { onLogoutClick } = useAuth();
</script>
<template>

View File

@@ -1,12 +0,0 @@
<script setup lang="ts">
defineProps<{ showLabels: boolean }>();
</script>
<template>
<UButton
icon="i-lucide-user"
color="primary"
to="#"
:label="showLabels ? 'Devenir membre' : undefined"
/>
</template>

View File

@@ -1,13 +0,0 @@
<script setup lang="ts">
defineProps<{ userId: number }>();
const { isUserSwitched, userSwitchBack, userSwitchTo } = useUserSwitching();
</script>
<template>
<UButton v-if="isUserSwitched" variant="outline" @click="userSwitchBack()">
Switch back
</UButton>
<UButton v-else @click="userSwitchTo(userId)">
Switch to
</UButton>
</template>

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
defineProps<{ showLabels: boolean }>();
const props = defineProps<{ showLabels: boolean }>();
const { loggedIn } = useUserSession();
const label = computed(() => props.showLabels ? (loggedIn ? "Déconnexion" : "Connexion") : undefined);
</script>
<template>
@@ -9,7 +10,7 @@ const { loggedIn } = useUserSession();
:icon="loggedIn ? 'i-lucide-log-out' : 'i-lucide-log-in'"
color="neutral"
to="/connexion"
:label="showLabels ? (loggedIn ? 'Déconnexion' : 'Connexion') : undefined"
:label="label"
/>
</AuthState>
</template>

View File

@@ -5,9 +5,11 @@ const link = computed(() => (loggedIn.value ? { label: "Espace membre", to: "/es
</script>
<template>
<AuthState>
<UButton
icon="i-lucide-user"
color="primary"
v-bind="link"
/>
</AuthState>
</template>

View File

@@ -0,0 +1,57 @@
import type { FormSubmitEvent } from "@nuxt/ui";
export function useAuth() {
const toast = useToast();
const redirect = useRoute().query.redirect as string || "/";
const router = useRouter();
const { fetch: refreshUserSession } = useUserSession();
// Login form
const loginFields = [
{
name: "email",
type: "text" as const,
label: "Courriel",
placeholder: "Entrez votre courriel",
required: true,
}, {
name: "password",
label: "Mot de passe",
type: "password" as const,
placeholder: "Entrez votre mot de passe",
required: true,
},
];
async function onLoginSubmit({ data }: FormSubmitEvent<LoginOutput>) {
try {
const result = await $fetch<{ success: boolean; message?: string }>("/api/login", { method: "POST", body: data });
if (!result.success) {
throw new Error(result.message || "Une erreur est survenue.");
}
await router.push(redirect);
await refreshUserSession();
}
catch (error) {
const message = error instanceof Error ? error.message : "Une erreur est survenue.";
toast.add({ title: "Échec de la connexion", description: message, color: "error" });
}
}
// Logout action
async function onLogoutClick() {
try {
const result = await $fetch("/api/logout", { method: "POST" });
if (!result.success) {
throw new Error("Une erreur est survenue.");
}
await router.push(redirect);
await refreshUserSession();
}
catch (error) {
const message = error instanceof Error ? error.message : "Une erreur est survenue.";
toast.add({ title: "Échec de la déconnexion", description: message, color: "error" });
}
}
return { loginFields, onLoginSubmit, onLogoutClick };
}

View File

@@ -1,48 +0,0 @@
import type { FormSubmitEvent } from "@nuxt/ui";
import * as z from "zod";
const loginSchema = z.object({
email: z.email("Courriel invalide"),
password: z.string("Veuillez saisir votre mot de passe"),
});
type LoginSchema = z.infer<typeof loginSchema>;
const loginFields = [
{
name: "email",
type: "text" as const,
label: "Courriel",
placeholder: "Entrez votre courriel",
required: true,
}, {
name: "password",
label: "Mot de passe",
type: "password" as const,
placeholder: "Entrez votre mot de passe",
required: true,
},
];
export function useLogin() {
const toast = useToast();
const redirect = useRoute().query.redirect as string || "/";
const router = useRouter();
const { fetch: refreshUserSession } = useUserSession();
async function onLoginSubmit({ data }: FormSubmitEvent<LoginSchema>) {
try {
const result = await $fetch<{ success: boolean; message?: string }>("/api/login", { method: "POST", body: data });
if (!result.success) {
throw new Error(result.message || "Une erreur est survenue.");
}
await router.push(redirect);
await refreshUserSession();
}
catch (error) {
const message = error instanceof Error ? error.message : "Une erreur est survenue.";
toast.add({ title: "Échec de la connexion", description: message, color: "error" });
}
}
return { loginSchema, loginFields, onLoginSubmit };
}

View File

@@ -1,23 +0,0 @@
export function useLogout() {
const toast = useToast();
const redirect = useRoute().query.redirect as string || "/";
const router = useRouter();
const { fetch: refreshUserSession } = useUserSession();
async function onLogoutClick() {
try {
const result = await $fetch("/api/logout", { method: "POST" });
if (!result.success) {
throw new Error("Une erreur est survenue.");
}
await router.push(redirect);
await refreshUserSession();
}
catch (error) {
const message = error instanceof Error ? error.message : "Une erreur est survenue.";
toast.add({ title: "Échec de la déconnexion", description: message, color: "error" });
}
}
return { onLogoutClick };
}

View File

@@ -0,0 +1,3 @@
export function useMemberArea() {
return {};
}

View File

@@ -0,0 +1,3 @@
export function useMemberSignup() {
return {};
}

View File

@@ -1,21 +1,5 @@
import type {
ThePageFragment,
TheArticleFragment,
TheEventFragment,
TheLocationFragment,
TheMembershipFragment,
TheProjectFragment,
TheResourceFragment,
} from "#graphql-operations";
import {
ThePage,
TheArticle,
TheEvent,
TheLocation,
TheMembership,
TheProject,
TheResource,
} from "#components";
import type { ThePageFragment, TheArticleFragment, TheEventFragment, TheLocationFragment, TheMembershipFragment, TheProjectFragment, TheResourceFragment } from "#graphql-operations";
import { ThePage, TheArticle, TheEvent, TheLocation, TheMembership, TheProject, TheResource } from "#components";
export async function useNodeByUri() {
const route = useRoute();

View File

@@ -20,6 +20,10 @@ export default defineNuxtConfig({
],
},
imports: {
dirs: ["~~/shared/schemas"],
},
devtools: { enabled: true },
css: ["~/assets/css/main.css"],
@@ -64,7 +68,7 @@ export default defineNuxtConfig({
graphqlMiddleware: {
graphqlEndpoint: process.env.NUXT_GRAPHQL_ENDPOINT || "https://wp.cultureat.ca/graphql",
downloadSchema: isDev,
schemaPath: "server/graphql/schema.graphql",
schemaPath: "server/schema.graphql",
},
robots: {

View File

@@ -0,0 +1,8 @@
import * as z from "zod";
export const loginSchema = z.object({
email: z.email("Courriel invalide"),
password: z.string("Veuillez saisir votre mot de passe"),
});
export type LoginInput = z.input<typeof loginSchema>;
export type LoginOutput = z.output<typeof loginSchema>;