Compare commits
5 Commits
v0.1.11
...
ab563a7b37
| Author | SHA1 | Date | |
|---|---|---|---|
| ab563a7b37 | |||
| 2cfc1a0047 | |||
| 98e8d971e8 | |||
| 87be06ecea | |||
| 28f6e1ae7c |
@@ -1,9 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { fr } from "@nuxt/ui/locale";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<UApp :locale="fr">
|
||||
<NuxtRouteAnnouncer />
|
||||
<NuxtLoadingIndicator />
|
||||
<NuxtLayout>
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
</div>
|
||||
</UApp>
|
||||
</template>
|
||||
|
||||
@@ -4,9 +4,10 @@ import type { ButtonProps } from "@nuxt/ui";
|
||||
|
||||
type AcfLinkButtonProps = & Omit<ButtonProps, "to" | "target" | "href"> & {
|
||||
link?: AcfLinkFragment;
|
||||
showLabel?: boolean;
|
||||
};
|
||||
|
||||
const { link, ...buttonProps } = defineProps<AcfLinkButtonProps>();
|
||||
const { link, showLabel, ...buttonProps } = defineProps<AcfLinkButtonProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -18,6 +19,6 @@ const { link, ...buttonProps } = defineProps<AcfLinkButtonProps>();
|
||||
:external="link.target === '_blank'"
|
||||
:rel="link.target === '_blank' ? 'noopener noreferrer' : undefined"
|
||||
>
|
||||
<slot>{{ link.title }}</slot>
|
||||
<slot>{{ showLabel ? link.title : "" }}</slot>
|
||||
</UButton>
|
||||
</template>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
fragment AcfMedia on GroupAbstractMedia_Fields {
|
||||
image {
|
||||
node {
|
||||
...AcfImage
|
||||
}
|
||||
}
|
||||
image { node { ... AcfImage } }
|
||||
aspectRatio
|
||||
objectFit
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
const { isLoggedIn } = useAuth();
|
||||
const attrs = computed(() => {
|
||||
return isLoggedIn.value
|
||||
? {
|
||||
label: "Déconnexion",
|
||||
icon: "i-lucide-log-out",
|
||||
}
|
||||
: {
|
||||
label: "Connexion",
|
||||
icon: "i-lucide-log-in",
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthState>
|
||||
<UButton to="/connexion" v-bind="attrs" color="neutral" />
|
||||
</AuthState>
|
||||
</template>
|
||||
@@ -34,7 +34,7 @@ const classes = tvSectionHeroSplit({
|
||||
<section :class="classes.base()">
|
||||
<div :class="classes.container()">
|
||||
<UiProse :content="content" :class="classes.content()" />
|
||||
<AcfMedia :media="$props" :class="classes.media()" />
|
||||
<AcfMedia :media="parseAcfMedia(props)" :class="classes.media()" />
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
const { connexionButton } = useAuthConnexion();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-inverted text-inverted py-1.5">
|
||||
<div class="container flex flex-col sm:flex-row items-center gap-3">
|
||||
<SiteFooterCopyright class="sm:mr-auto" />
|
||||
<AuthConnexionButton color="neutral" variant="link" />
|
||||
<UButton v-bind="connexionButton" color="neutral" variant="link" />
|
||||
<SiteFooterCredits />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,8 +8,5 @@
|
||||
<SvgSiteLogo class="h-12 w-auto" />
|
||||
</NuxtLink>
|
||||
</template>
|
||||
<template #right>
|
||||
<AuthConnexionButton />
|
||||
</template>
|
||||
</UHeader>
|
||||
</template>
|
||||
|
||||
@@ -2,5 +2,6 @@ export function useAuth() {
|
||||
const { loggedIn: isLoggedIn, session } = useUserSession();
|
||||
const hasRole = (role: string) => session.value?.user?.roles?.includes(role) || false;
|
||||
const isAdmin = computed(() => hasRole("administrator"));
|
||||
|
||||
return { isLoggedIn, hasRole, isAdmin };
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { FormSubmitEvent } from "@nuxt/ui";
|
||||
const isRedirecting = ref(false);
|
||||
|
||||
export function useAuthConnexion() {
|
||||
const { isLoggedIn } = useAuth();
|
||||
const toast = useToast();
|
||||
const { fetch: refreshUserSession } = useUserSession();
|
||||
const routeRedirect = useRoute().query.redirect as string || undefined;
|
||||
@@ -67,5 +68,12 @@ export function useAuthConnexion() {
|
||||
}
|
||||
}
|
||||
|
||||
return { isRedirecting, login, logout };
|
||||
// Dynamic connexion link
|
||||
const connexionButton = computed(() => ({
|
||||
label: isLoggedIn.value ? "Déconnexion" : "Connexion",
|
||||
icon: isLoggedIn.value ? "i-lucide-log-out" : "i-lucide-log-in",
|
||||
to: "/connexion",
|
||||
}));
|
||||
|
||||
return { isRedirecting, login, logout, connexionButton };
|
||||
}
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { fr } from "@nuxt/ui/locale";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UApp id="layout-default" :locale="fr">
|
||||
<div id="layout-default">
|
||||
<SiteHeader />
|
||||
<UMain>
|
||||
<slot />
|
||||
</UMain>
|
||||
<SiteFooter />
|
||||
</UApp>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
18
wp-content/themes/moonshine/app/utils/acf-link.ts
Normal file
18
wp-content/themes/moonshine/app/utils/acf-link.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import * as z from "zod";
|
||||
import type { AcfLinkFragment } from "#graphql/operations";
|
||||
|
||||
const acfLinkSchema = z.object({
|
||||
title: z.string(),
|
||||
url: z.string(),
|
||||
target: z.string().optional().default(""),
|
||||
});
|
||||
export type AcfLinkOutput = z.infer<typeof acfLinkSchema>;
|
||||
|
||||
export function parseAcfLink(data?: Partial<AcfLinkFragment>) {
|
||||
try {
|
||||
return acfLinkSchema.parse(data);
|
||||
}
|
||||
catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
29
wp-content/themes/moonshine/app/utils/acf-media.ts
Normal file
29
wp-content/themes/moonshine/app/utils/acf-media.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import type { AcfMediaFragment } from "#graphql/operations";
|
||||
import * as z from "zod";
|
||||
|
||||
export const acfImageSchema = z.object({
|
||||
src: z.url(),
|
||||
alt: z.string(),
|
||||
mediaDetails: z.object({
|
||||
width: z.number(),
|
||||
height: z.number(),
|
||||
}),
|
||||
objectPosition: z.string().optional().default("center"),
|
||||
});
|
||||
|
||||
export const acfMediaSchema = z.object({
|
||||
image: z.object({
|
||||
node: acfImageSchema,
|
||||
}),
|
||||
aspectRatio: z.enum(["square", "video", "portrait", "auto"]).optional().default("auto"),
|
||||
objectFit: z.enum(["cover", "contain"]).optional().default("cover"),
|
||||
});
|
||||
|
||||
export function parseAcfMedia(data?: Partial<AcfMediaFragment>) {
|
||||
try {
|
||||
return acfMediaSchema.parse(data);
|
||||
}
|
||||
catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -119,4 +119,5 @@ export default defineNuxtConfig({
|
||||
componentPrefix: "Svg",
|
||||
defaultImport: "component",
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user