generated from pascalmartineau/wp-skeleton
feat: Initial Nuxt app
This commit is contained in:
3
wp-content/themes/ccat/.gitignore
vendored
3
wp-content/themes/ccat/.gitignore
vendored
@@ -4,6 +4,7 @@
|
|||||||
.nuxt
|
.nuxt
|
||||||
.nitro
|
.nitro
|
||||||
.cache
|
.cache
|
||||||
|
.wrangler
|
||||||
dist
|
dist
|
||||||
|
|
||||||
# Node dependencies
|
# Node dependencies
|
||||||
@@ -22,5 +23,3 @@ logs
|
|||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
!.env.example
|
!.env.example
|
||||||
|
|
||||||
.wrangler
|
|
||||||
1
wp-content/themes/ccat/.npmrc
Normal file
1
wp-content/themes/ccat/.npmrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
shamefully-hoist=true
|
||||||
3
wp-content/themes/ccat/README.md
Normal file
3
wp-content/themes/ccat/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# cultureat.ca
|
||||||
|
|
||||||
|
Site web du Conseil de la culture de l'Abitibi-Témiscamingue.
|
||||||
10
wp-content/themes/ccat/app/app.config.ts
Normal file
10
wp-content/themes/ccat/app/app.config.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { defineAppConfig } from "#imports";
|
||||||
|
|
||||||
|
export default defineAppConfig({
|
||||||
|
ui: {
|
||||||
|
colors: {
|
||||||
|
primary: "indigo",
|
||||||
|
neutral: "neutral",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
30
wp-content/themes/ccat/app/app.vue
Normal file
30
wp-content/themes/ccat/app/app.vue
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { fr } from "@nuxt/ui/locale";
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
htmlAttrs: {
|
||||||
|
lang: "fr-CA",
|
||||||
|
},
|
||||||
|
meta: [
|
||||||
|
{ charset: "utf-8" },
|
||||||
|
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
||||||
|
],
|
||||||
|
link: [
|
||||||
|
{ rel: "icon", href: "/favicon.ico" },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
useSeoMeta({
|
||||||
|
titleTemplate: "%s - Conseil de la culture de l'Abitibi-Témiscamingue",
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UApp :locale="fr">
|
||||||
|
<NuxtRouteAnnouncer />
|
||||||
|
<NuxtLoadingIndicator />
|
||||||
|
<NuxtLayout>
|
||||||
|
<NuxtPage />
|
||||||
|
</NuxtLayout>
|
||||||
|
</UApp>
|
||||||
|
</template>
|
||||||
9
wp-content/themes/ccat/app/assets/css/helpers.css
Normal file
9
wp-content/themes/ccat/app/assets/css/helpers.css
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
@layer components {
|
||||||
|
.container-fluid {
|
||||||
|
@apply w-full max-w-screen px-4 sm:px-6 lg:px-8;
|
||||||
|
}
|
||||||
|
.flex-break-words {
|
||||||
|
@apply min-w-0 break-words;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
7
wp-content/themes/ccat/app/assets/css/main.css
Normal file
7
wp-content/themes/ccat/app/assets/css/main.css
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
@import "@nuxt/ui";
|
||||||
|
@import "./helpers.css";
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--z-index-main: 10;
|
||||||
|
}
|
||||||
170
wp-content/themes/ccat/app/assets/svg/logo-ccat.svg
Normal file
170
wp-content/themes/ccat/app/assets/svg/logo-ccat.svg
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink" width="4.04in" height="1.52in" viewBox="0 0 290.92 109.68">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1 {
|
||||||
|
fill: url(#linear-gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-2 {
|
||||||
|
fill: url(#linear-gradient-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-3 {
|
||||||
|
fill: url(#linear-gradient-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-4 {
|
||||||
|
fill: url(#linear-gradient-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-5 {
|
||||||
|
fill: url(#linear-gradient-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-6 {
|
||||||
|
fill: url(#linear-gradient-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-7 {
|
||||||
|
fill: url(#linear-gradient-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-8 {
|
||||||
|
fill: url(#linear-gradient-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-9 {
|
||||||
|
fill: url(#linear-gradient-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-10 {
|
||||||
|
fill: url(#linear-gradient-15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-11 {
|
||||||
|
fill: url(#linear-gradient-16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-12 {
|
||||||
|
fill: url(#linear-gradient-22);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-13 {
|
||||||
|
fill: url(#linear-gradient-25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-14 {
|
||||||
|
fill: url(#linear-gradient-26);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-15 {
|
||||||
|
fill: url(#linear-gradient-33);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-16 {
|
||||||
|
fill: url(#linear-gradient-35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-17 {
|
||||||
|
fill: url(#linear-gradient-45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-18 {
|
||||||
|
fill: url(#linear-gradient-47);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-19 {
|
||||||
|
fill: url(#linear-gradient-49);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-20 {
|
||||||
|
fill: url(#linear-gradient-50);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<linearGradient id="linear-gradient" x1="-19.84" y1="71.96" x2="296.65" y2="71.96" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#cf8837"/>
|
||||||
|
<stop offset="0.41" stop-color="#bd4931"/>
|
||||||
|
<stop offset="1" stop-color="#2e3191"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linear-gradient-2" x1="-19.84" y1="32.09" x2="296.65" y2="32.09" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-3" x1="-19.84" y1="27.58" x2="296.65" y2="27.58" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-4" x1="-19.84" y1="20.21" x2="296.65" y2="20.21" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-5" x1="-19.84" y1="12.87" x2="296.65" y2="12.87" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-6" x1="-19.84" y1="12.38" x2="296.65" y2="12.38" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-7" x1="-19.84" y1="48.34" x2="296.65" y2="48.34" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-8" x1="-19.84" y1="31.96" x2="296.65" y2="31.96" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-12" x1="-19.84" y1="31.96" x2="296.65" y2="31.96" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-15" x1="-19.84" y1="71.7" x2="296.65" y2="71.7" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-16" x1="-19.84" y1="71.92" x2="296.65" y2="71.92" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-22" x1="-19.84" y1="103.92" x2="296.65" y2="103.92" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-25" x1="-19.84" y1="100.47" x2="296.65" y2="100.47" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-26" x1="-19.84" y1="103.85" x2="296.65" y2="103.85" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-33" x1="-19.84" y1="104.11" x2="296.65" y2="104.11" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-35" x1="-19.84" y1="102.27" x2="296.65" y2="102.27" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-45" x1="-19.84" y1="104" x2="296.65" y2="104" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-47" x1="-19.84" y1="63.12" x2="296.65" y2="63.12" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-49" x1="-19.84" y1="80.6" x2="296.65" y2="80.6" xlink:href="#linear-gradient"/>
|
||||||
|
<linearGradient id="linear-gradient-50" x1="-19.84" y1="80.51" x2="296.65" y2="80.51" xlink:href="#linear-gradient"/>
|
||||||
|
</defs>
|
||||||
|
<g>
|
||||||
|
<path class="cls-1" d="M49.39,34.25a1.09,1.09,0,0,0-1.09,1.09v.79a22.3,22.3,0,0,1-6.1,15.35L36,58.07V44.3a1.1,1.1,0,0,0-2.19,0V74.93l-.5-.32A22.26,22.26,0,0,1,22.94,55.74v-10a1.1,1.1,0,1,0-2.19,0v10A24.43,24.43,0,0,0,32.12,76.45l1.68,1.07v31.07a1.1,1.1,0,0,0,2.19,0V61.26L43.79,53a24.44,24.44,0,0,0,6.7-16.85v-.79A1.09,1.09,0,0,0,49.39,34.25Z"/>
|
||||||
|
<path class="cls-2" d="M22.41,41.52S20,31.13,15.85,26.94,0,22.63,0,22.63s1.53,8.89,6.3,14.11c4,4.4,12.28,4.8,15.12,4.8C22.05,41.54,22.41,41.52,22.41,41.52ZM7.1,36C3.69,32.26,2,26.4,1.36,23.78c3.14.18,10.75.91,13.71,3.93S20.2,37.56,21,40.44C18.17,40.4,10.67,39.91,7.1,36Z"/>
|
||||||
|
<path class="cls-3" d="M59.91,30c-2.12-1.29-5.25-.86-7-.44,1.67-.56,4.42-1.63,5.78-3,2-2.1,2-7.95,2-7.95s-4.4.88-7,3.32-2.23,7.61-2.21,8h0v0h0c.22.37,2.74,4.68,5.2,6.06s8.25-.13,8.25-.13S62.94,31.81,59.91,30Zm-5.47-7.31A13.21,13.21,0,0,1,59.49,20c-.14,2.08-.62,4.71-1.62,5.74s-3.6,2.17-5.32,2.75C52.62,26.65,53,24,54.44,22.65Z"/>
|
||||||
|
<path class="cls-4" d="M44.36,20.52C44.54,12.42,34.8,0,34.8,0s-8.65,9.47-9.18,19.2c-.55,10.1,9.3,21.22,9.3,21.22S44.17,28.94,44.36,20.52Z"/>
|
||||||
|
<path class="cls-5" d="M20,19s.41-5.24-.89-7.82-6.78-4.4-6.78-4.4-.61,4.39.83,7.56S20,19,20,19ZM13.32,8.3c1.89.8,4.19,2.09,4.83,3.35.71,1.43.85,4,.83,5.83-1.67-.65-4-1.89-4.81-3.62A13,13,0,0,1,13.32,8.3Z"/>
|
||||||
|
<path class="cls-6" d="M53.17,12.38a2,2,0,1,0-2,2A2,2,0,0,0,53.17,12.38Zm-2,.89a.89.89,0,1,1,.89-.89A.89.89,0,0,1,51.19,13.27Z"/>
|
||||||
|
<path class="cls-7" d="M10.25,47.25a1.55,1.55,0,1,0,2.19,0A1.55,1.55,0,0,0,10.25,47.25Z"/>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path class="cls-8" d="M88.15,17.82a13.85,13.85,0,0,1,9.5,3.65.77.77,0,0,1,0,1.1l-1.06,1.06c-.32.4-.63.36-1,0a11.93,11.93,0,0,0-7.5-2.94,11.29,11.29,0,0,0,0,22.58c3.41,0,5.42-1.38,7.5-2.95a.75.75,0,0,1,.94-.12l1.18,1.06a.76.76,0,0,1,0,1.06,13.45,13.45,0,0,1-9.54,3.81,14.14,14.14,0,1,1,0-28.27Z"/>
|
||||||
|
<path class="cls-8" d="M115.71,17.82A14.14,14.14,0,1,1,101.61,32,14.12,14.12,0,0,1,115.71,17.82Zm0,25.52A11.39,11.39,0,1,0,104.36,32,11.41,11.41,0,0,0,115.71,43.34Z"/>
|
||||||
|
<path class="cls-8" d="M135.85,18.53a.75.75,0,0,1,.75-.71h1l17.71,22.07h.08V19a.74.74,0,0,1,.74-.74h1.38a.77.77,0,0,1,.74.74V45.38a.73.73,0,0,1-.74.71h-.71l-18-22.5h0V45a.74.74,0,0,1-.75.75H136.6a.78.78,0,0,1-.75-.75Z"/>
|
||||||
|
<path class="cls-8" d="M164.48,41.58c.19-.24.39-.51.59-.75.39-.51.82-.82,1.37-.35.27.23,3.14,3,6.64,3,3.18,0,5.26-2,5.26-4.32,0-2.71-2.36-4.32-6.87-6.2-4.32-1.89-6.91-3.65-6.91-8.13,0-2.67,2.12-7,8.36-7a12.78,12.78,0,0,1,6.71,2,.86.86,0,0,1,.24,1.33c-.16.24-.32.51-.47.75a.9.9,0,0,1-1.38.35,10.93,10.93,0,0,0-5.14-1.81c-4.16,0-5.42,2.67-5.42,4.32,0,2.63,2,4.16,5.3,5.54,5.3,2.16,8.72,4.16,8.72,8.72,0,4.08-3.89,7.06-8.48,7.06a12.81,12.81,0,0,1-8.29-3.18A.86.86,0,0,1,164.48,41.58Z"/>
|
||||||
|
<path class="cls-9" d="M187.17,19a.74.74,0,0,1,.75-.74h15.47a.74.74,0,0,1,.74.74V20.1a.75.75,0,0,1-.74.75h-13.2v9.58h11.27a.77.77,0,0,1,.75.74v1.14a.75.75,0,0,1-.75.75H190.19v10h13.2a.74.74,0,0,1,.74.74V45a.74.74,0,0,1-.74.75H187.92a.74.74,0,0,1-.75-.75Z"/>
|
||||||
|
<path class="cls-9" d="M210.42,19a.77.77,0,0,1,.74-.74h1.57a.77.77,0,0,1,.75.74V45a.77.77,0,0,1-.75.75h-1.57a.77.77,0,0,1-.74-.75Z"/>
|
||||||
|
<path class="cls-9" d="M221.49,19a.74.74,0,0,1,.74-.74h1.53a.77.77,0,0,1,.75.74V43.07h11.31a.75.75,0,0,1,.75.74V45a.75.75,0,0,1-.75.75H222.23a.74.74,0,0,1-.74-.75Z"/>
|
||||||
|
<path class="cls-10" d="M124.62,56.16a15.13,15.13,0,0,1,10.44,4,.83.83,0,0,1,.05,1.2l-1.17,1.17c-.34.43-.69.39-1.12,0a13.05,13.05,0,0,0-8.25-3.24,12.42,12.42,0,0,0,0,24.82c3.76,0,6-1.51,8.25-3.24a.82.82,0,0,1,1-.13l1.3,1.17a.81.81,0,0,1,0,1.16,14.83,14.83,0,0,1-10.49,4.19,15.54,15.54,0,1,1,0-31.08Z"/>
|
||||||
|
<path class="cls-11" d="M141.37,57.41a.84.84,0,0,1,.82-.82h1.64a.82.82,0,0,1,.82.82v18c0,4.92,3.06,8.76,8.11,8.76s8.2-3.75,8.2-8.67V57.41a.82.82,0,0,1,.82-.82h1.64a.85.85,0,0,1,.82.82V75.67c0,6.56-4.66,11.57-11.48,11.57s-11.39-5-11.39-11.57Z"/>
|
||||||
|
<path class="cls-10" d="M172.66,57.41a.82.82,0,0,1,.82-.82h1.68a.85.85,0,0,1,.82.82V83.92h12.43a.81.81,0,0,1,.82.82V86a.82.82,0,0,1-.82.82H173.48a.82.82,0,0,1-.82-.82Z"/>
|
||||||
|
<path class="cls-10" d="M196.23,59.49h-7.51a.82.82,0,0,1-.82-.82V57.41a.82.82,0,0,1,.82-.82H207a.82.82,0,0,1,.82.82v1.26a.82.82,0,0,1-.82.82h-7.51V86a.85.85,0,0,1-.82.82h-1.64a.85.85,0,0,1-.82-.82Z"/>
|
||||||
|
<path class="cls-11" d="M212.2,57.41a.85.85,0,0,1,.82-.82h1.64a.82.82,0,0,1,.82.82v18c0,4.92,3.06,8.76,8.11,8.76s8.2-3.75,8.2-8.67V57.41a.82.82,0,0,1,.82-.82h1.64a.84.84,0,0,1,.82.82V75.67c0,6.56-4.66,11.57-11.48,11.57s-11.39-5-11.39-11.57Z"/>
|
||||||
|
<path class="cls-10" d="M243.49,57.41a.82.82,0,0,1,.82-.82h11.18a9.28,9.28,0,0,1,9.41,9.2,9.62,9.62,0,0,1-6.39,8.8l5.92,11a.82.82,0,0,1-.74,1.25h-2.2a.75.75,0,0,1-.69-.39L255.06,75h-8.25V86a.84.84,0,0,1-.82.82h-1.68a.82.82,0,0,1-.82-.82Zm11.79,14.72a6.2,6.2,0,1,0,0-12.39H246.9V72.13Z"/>
|
||||||
|
<path class="cls-10" d="M272,57.41a.82.82,0,0,1,.82-.82h17a.82.82,0,0,1,.82.82v1.26a.82.82,0,0,1-.82.82h-14.5V70h12.38a.84.84,0,0,1,.82.82v1.25a.82.82,0,0,1-.82.82H275.35v11h14.5a.82.82,0,0,1,.82.82V86a.82.82,0,0,1-.82.82h-17A.82.82,0,0,1,272,86Z"/>
|
||||||
|
<path class="cls-12" d="M75.27,98.73a.3.3,0,0,1,.28-.3h3.52a5.5,5.5,0,1,1,0,11H75.55a.3.3,0,0,1-.28-.3Zm3.55,9.61a4.42,4.42,0,1,0,0-8.84H76.46v8.84Z"/>
|
||||||
|
<path class="cls-12" d="M87,98.73a.3.3,0,0,1,.3-.3h6.19a.3.3,0,0,1,.3.3v.45a.3.3,0,0,1-.3.3H88.21v3.83h4.51a.31.31,0,0,1,.3.3v.46a.29.29,0,0,1-.3.29H88.21v4h5.28a.3.3,0,0,1,.3.3v.45a.3.3,0,0,1-.3.3H87.3a.3.3,0,0,1-.3-.3Z"/>
|
||||||
|
<path class="cls-12" d="M99.79,98.73a.3.3,0,0,1,.3-.3h.61a.31.31,0,0,1,.3.3v9.64h4.52a.3.3,0,0,1,.3.3v.45a.3.3,0,0,1-.3.3h-5.43a.3.3,0,0,1-.3-.3Z"/>
|
||||||
|
<path class="cls-13" d="M106.06,102.39c-.08-.08-.07-.24.09-.38a2.66,2.66,0,0,0,1-2,.55.55,0,0,1-.18,0,.91.91,0,0,1-.9-.9.89.89,0,0,1,.9-.89c.5,0,1,.28,1,1.41a4.32,4.32,0,0,1-1.32,2.9c-.15.15-.28.13-.37,0Z"/>
|
||||||
|
<path class="cls-14" d="M108.6,109l4.77-10.56a.29.29,0,0,1,.27-.18h.16a.26.26,0,0,1,.26.18L118.81,109a.28.28,0,0,1-.27.41h-.63a.3.3,0,0,1-.27-.17l-1.16-2.59h-5.57l-1.15,2.59a.27.27,0,0,1-.26.17h-.63A.28.28,0,0,1,108.6,109Zm7.46-3.33c-.77-1.71-1.52-3.44-2.29-5.15h-.13l-2.29,5.15Z"/>
|
||||||
|
<path class="cls-12" d="M120.52,98.73a.3.3,0,0,1,.3-.3h3.44a2.87,2.87,0,0,1,1.68,5.4,2.78,2.78,0,0,1,1.88,2.56,3.11,3.11,0,0,1-3.42,3h-3.58a.3.3,0,0,1-.3-.3Zm4,9.64a1.94,1.94,0,0,0,2-2,2.08,2.08,0,0,0-2.24-1.93h-2.59v3.93Zm-.27-5a1.81,1.81,0,0,0,1.88-2,1.74,1.74,0,0,0-1.88-1.89H121.7v3.85Z"/>
|
||||||
|
<path class="cls-12" d="M130.34,98.73a.31.31,0,0,1,.3-.3h.62a.31.31,0,0,1,.3.3v10.39a.31.31,0,0,1-.3.3h-.62a.31.31,0,0,1-.3-.3Z"/>
|
||||||
|
<path class="cls-12" d="M136.32,99.48h-2.73a.3.3,0,0,1-.3-.3v-.45a.3.3,0,0,1,.3-.3h6.66a.29.29,0,0,1,.29.3v.45a.29.29,0,0,1-.29.3h-2.74v9.64a.31.31,0,0,1-.29.3h-.6a.31.31,0,0,1-.3-.3Z"/>
|
||||||
|
<path class="cls-12" d="M142.27,98.73a.31.31,0,0,1,.3-.3h.63a.31.31,0,0,1,.3.3v10.39a.31.31,0,0,1-.3.3h-.63a.31.31,0,0,1-.3-.3Z"/>
|
||||||
|
<path class="cls-12" d="M146.7,98.73a.3.3,0,0,1,.3-.3h3.44a2.87,2.87,0,0,1,1.68,5.4,2.78,2.78,0,0,1,1.88,2.56,3.11,3.11,0,0,1-3.42,3H147a.3.3,0,0,1-.3-.3Zm4,9.64a2,2,0,0,0,2-2,2.09,2.09,0,0,0-2.25-1.93h-2.59v3.93Zm-.27-5a1.81,1.81,0,0,0,1.88-2,1.74,1.74,0,0,0-1.88-1.89h-2.56v3.85Z"/>
|
||||||
|
<path class="cls-12" d="M156.52,98.73a.31.31,0,0,1,.3-.3h.63a.31.31,0,0,1,.3.3v10.39a.31.31,0,0,1-.3.3h-.63a.31.31,0,0,1-.3-.3Z"/>
|
||||||
|
<path class="cls-15" d="M160.35,104.27V104a.29.29,0,0,1,.3-.3h3.28a.29.29,0,0,1,.3.3v.3a.28.28,0,0,1-.3.28h-3.28A.28.28,0,0,1,160.35,104.27Z"/>
|
||||||
|
<path class="cls-12" d="M168.16,99.48h-2.73a.29.29,0,0,1-.3-.3v-.45a.29.29,0,0,1,.3-.3h6.65a.29.29,0,0,1,.3.3v.45a.29.29,0,0,1-.3.3h-2.73v9.64a.31.31,0,0,1-.3.3h-.59a.31.31,0,0,1-.3-.3Z"/>
|
||||||
|
<path class="cls-16" d="M174.11,98.73a.3.3,0,0,1,.3-.3h6.19a.29.29,0,0,1,.29.3v.45a.29.29,0,0,1-.29.3h-5.28v3.83h4.51a.31.31,0,0,1,.3.3v.46a.3.3,0,0,1-.3.29h-4.51v4h5.28a.29.29,0,0,1,.29.3v.45a.29.29,0,0,1-.29.3h-6.19a.3.3,0,0,1-.3-.3Zm2-2a.22.22,0,0,1,.1-.3l2.35-1.32c.1-.06.33-.09.41,0l.28.57a.22.22,0,0,1-.09.33l-2.53,1c-.22.09-.3.09-.36,0Z"/>
|
||||||
|
<path class="cls-12" d="M184.65,98.49a.31.31,0,0,1,.28-.22h.25a.3.3,0,0,1,.27.18l3.11,8.65h.08l3.06-8.65a.3.3,0,0,1,.27-.18h.25a.31.31,0,0,1,.28.22l2,10.55c0,.22-.05.38-.29.38h-.62a.33.33,0,0,1-.29-.22l-1.39-8.09h-.07L189,109.4a.31.31,0,0,1-.26.18h-.29a.31.31,0,0,1-.26-.18l-2.92-8.29h-.07l-1.36,8.09a.31.31,0,0,1-.28.22h-.63c-.24,0-.33-.16-.29-.38Z"/>
|
||||||
|
<path class="cls-12" d="M197,98.73a.31.31,0,0,1,.3-.3h.62a.31.31,0,0,1,.3.3v10.39a.31.31,0,0,1-.3.3h-.62a.31.31,0,0,1-.3-.3Z"/>
|
||||||
|
<path class="cls-12" d="M200.67,107.77c.08-.09.16-.2.24-.3s.33-.33.55-.14a4.28,4.28,0,0,0,2.65,1.2,1.9,1.9,0,0,0,2.1-1.73c0-1.09-.94-1.73-2.74-2.48s-2.77-1.46-2.77-3.25c0-1.07.85-2.8,3.35-2.8a5.11,5.11,0,0,1,2.68.8.36.36,0,0,1,.1.54c-.07.09-.13.2-.19.29a.35.35,0,0,1-.55.15,4.3,4.3,0,0,0-2.06-.73c-1.66,0-2.17,1.07-2.17,1.73,0,1,.81,1.67,2.12,2.22,2.12.86,3.49,1.66,3.49,3.48a3.12,3.12,0,0,1-3.39,2.83,5.15,5.15,0,0,1-3.31-1.27A.35.35,0,0,1,200.67,107.77Z"/>
|
||||||
|
<path class="cls-12" d="M214.62,98.27a5.54,5.54,0,0,1,3.8,1.46.31.31,0,0,1,0,.44l-.42.43c-.13.15-.25.14-.41,0a4.75,4.75,0,0,0-3-1.18,4.52,4.52,0,0,0,0,9,4.55,4.55,0,0,0,3-1.18.3.3,0,0,1,.38,0l.47.42a.3.3,0,0,1,0,.42,5.38,5.38,0,0,1-3.81,1.53,5.66,5.66,0,1,1,0-11.31Z"/>
|
||||||
|
<path class="cls-14" d="M219.35,109l4.77-10.56a.29.29,0,0,1,.27-.18h.15a.29.29,0,0,1,.27.18L229.55,109a.28.28,0,0,1-.27.41h-.62a.29.29,0,0,1-.27-.17l-1.16-2.59h-5.58l-1.14,2.59a.29.29,0,0,1-.27.17h-.63A.27.27,0,0,1,219.35,109Zm7.45-3.33c-.77-1.71-1.52-3.44-2.29-5.15h-.12l-2.3,5.15Z"/>
|
||||||
|
<path class="cls-12" d="M232.51,98.49a.3.3,0,0,1,.28-.22H233a.3.3,0,0,1,.27.18l3.11,8.65h.07l3.07-8.65a.28.28,0,0,1,.26-.18h.25a.31.31,0,0,1,.29.22l2,10.55c.05.22,0,.38-.28.38h-.63a.32.32,0,0,1-.28-.22l-1.4-8.09h-.06l-2.89,8.29a.31.31,0,0,1-.27.18h-.28a.34.34,0,0,1-.27-.18l-2.92-8.29H233l-1.37,8.09a.29.29,0,0,1-.28.22h-.63c-.23,0-.33-.16-.28-.38Z"/>
|
||||||
|
<path class="cls-12" d="M244.81,98.73a.31.31,0,0,1,.29-.3h.63a.31.31,0,0,1,.3.3v10.39a.31.31,0,0,1-.3.3h-.63a.31.31,0,0,1-.29-.3Z"/>
|
||||||
|
<path class="cls-12" d="M249.24,98.56a.3.3,0,0,1,.29-.29h.4L257,107.1h0V98.73a.29.29,0,0,1,.3-.3h.55a.31.31,0,0,1,.29.3v10.56a.3.3,0,0,1-.29.29h-.29l-7.2-9h0v8.54a.29.29,0,0,1-.3.3h-.55a.31.31,0,0,1-.29-.3Z"/>
|
||||||
|
<path class="cls-12" d="M266.26,98.27a5.54,5.54,0,0,1,3.8,1.46.31.31,0,0,1,0,.44c-.14.14-.31.3-.44.44s-.23.14-.4,0a4.78,4.78,0,0,0-3-1.23,4.53,4.53,0,0,0,0,9,5.92,5.92,0,0,0,2.83-.66v-2.2h-1.81a.29.29,0,0,1-.3-.28v-.59a.29.29,0,0,1,.3-.29H270a.29.29,0,0,1,.28.29v3.6a.39.39,0,0,1-.12.25,7.73,7.73,0,0,1-3.88,1,5.66,5.66,0,1,1,0-11.31Z"/>
|
||||||
|
<path class="cls-17" d="M272.75,98.73a.31.31,0,0,1,.3-.3h.59a.3.3,0,0,1,.3.3v6.55a3,3,0,1,0,5.94,0V98.73a.29.29,0,0,1,.29-.3h.6a.31.31,0,0,1,.3.3v6.64a4.16,4.16,0,1,1-8.32,0Z"/>
|
||||||
|
<path class="cls-12" d="M284.13,98.73a.3.3,0,0,1,.3-.3h6.19a.3.3,0,0,1,.3.3v.45a.3.3,0,0,1-.3.3h-5.28v3.83h4.51a.31.31,0,0,1,.3.3v.46a.29.29,0,0,1-.3.29h-4.51v4h5.28a.3.3,0,0,1,.3.3v.45a.3.3,0,0,1-.3.3h-6.19a.3.3,0,0,1-.3-.3Z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="cls-18" d="M75.21,56.76a.35.35,0,0,1,.34-.36h4.31a6.73,6.73,0,1,1,0,13.45H75.55a.36.36,0,0,1-.34-.37Zm4.34,11.76a5.41,5.41,0,1,0,0-10.82H76.67V68.52Z"/>
|
||||||
|
<path class="cls-18" d="M89.55,56.76a.37.37,0,0,1,.37-.36h7.57a.37.37,0,0,1,.37.36v.56a.37.37,0,0,1-.37.36H91v4.69h5.52a.38.38,0,0,1,.36.37v.56a.36.36,0,0,1-.36.36H91v4.9h6.46a.37.37,0,0,1,.37.37v.55a.38.38,0,0,1-.37.37H89.92a.38.38,0,0,1-.37-.37Z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="cls-19" d="M75.29,74.75a.34.34,0,0,1,.34-.34h.69a.35.35,0,0,1,.33.34V85.6h5.09a.34.34,0,0,1,.34.33v.51a.34.34,0,0,1-.34.34H75.63a.34.34,0,0,1-.34-.34Z"/>
|
||||||
|
<path class="cls-20" d="M86.35,86.32l5.37-11.89a.3.3,0,0,1,.3-.19h.17a.33.33,0,0,1,.31.19l5.33,11.89a.31.31,0,0,1-.3.46h-.71a.35.35,0,0,1-.3-.19l-1.3-2.92H88.94l-1.29,2.92a.33.33,0,0,1-.3.19h-.7A.31.31,0,0,1,86.35,86.32Zm8.39-3.74c-.87-1.93-1.71-3.87-2.58-5.8H92l-2.58,5.8Z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 16 KiB |
15
wp-content/themes/ccat/app/components/auth/LoginForm.vue
Normal file
15
wp-content/themes/ccat/app/components/auth/LoginForm.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const { loginSchema, loginFields, onLoginSubmit } = useLogin();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UAuthForm
|
||||||
|
:schema="loginSchema"
|
||||||
|
:fields="loginFields"
|
||||||
|
title="Connexion"
|
||||||
|
description="Veuillez vous identifier."
|
||||||
|
icon="i-lucide-user"
|
||||||
|
loading-auto
|
||||||
|
@submit="onLoginSubmit"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const { loggedIn } = useUserSession();
|
||||||
|
defineProps<{ showLabels: boolean }>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AuthState>
|
||||||
|
<UButton
|
||||||
|
:icon="loggedIn ? 'i-lucide-log-out' : 'i-lucide-log-in'"
|
||||||
|
color="neutral"
|
||||||
|
to="/auth"
|
||||||
|
:label="showLabels ? (loggedIn ? 'Déconnexion' : 'Connexion') : undefined"
|
||||||
|
/>
|
||||||
|
</AuthState>
|
||||||
|
</template>
|
||||||
24
wp-content/themes/ccat/app/components/auth/LogoutForm.vue
Normal file
24
wp-content/themes/ccat/app/components/auth/LogoutForm.vue
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const { onLogoutClick } = useLogout();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="w-full space-y-6">
|
||||||
|
<div class="flex flex-col text-center">
|
||||||
|
<div class="text-xl text-pretty font-semibold text-highlighted">
|
||||||
|
Déconnexion
|
||||||
|
</div>
|
||||||
|
<div class="mt-1 text-base text-pretty text-muted">
|
||||||
|
Veuillez confirmer la déconnexion.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<UButton
|
||||||
|
icon="i-lucide-log-out"
|
||||||
|
block
|
||||||
|
loading-auto
|
||||||
|
to="/auth"
|
||||||
|
label="Déconnexion"
|
||||||
|
@click="onLogoutClick"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
12
wp-content/themes/ccat/app/components/auth/SignUpButton.vue
Normal file
12
wp-content/themes/ccat/app/components/auth/SignUpButton.vue
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{ showLabels: boolean }>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UButton
|
||||||
|
icon="i-lucide-user"
|
||||||
|
color="primary"
|
||||||
|
to="#"
|
||||||
|
:label="showLabels ? 'Devenir membre' : undefined"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<UFooter>
|
||||||
|
TODO
|
||||||
|
</UFooter>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container-fluid flex flex-col lg:flex-row justify-between items-center gap-x-6 gap-y-3 py-3 text-muted text-sm text-center">
|
||||||
|
<p class="flex-break-words">
|
||||||
|
© {{ new Date().getFullYear() }} Conseil de la culture de l'Abitibi-Témiscamingue.
|
||||||
|
</p>
|
||||||
|
<p class="flex items-center gap-1">
|
||||||
|
Fait avec <UIcon name="i-lucide-heart" /> par
|
||||||
|
<ULink href="https://websimple.com" target="_blank" external title="Site web développé par Websimple">Websimple</ULink>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
19
wp-content/themes/ccat/app/components/site/SiteHeader.vue
Normal file
19
wp-content/themes/ccat/app/components/site/SiteHeader.vue
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const { menuItems } = await useMenuItems("MAIN");
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UHeader title="CCAT" mode="slideover">
|
||||||
|
<template #left>
|
||||||
|
<NuxtLink to="/">
|
||||||
|
<SvgLogoCcat class="h-12 w-auto shrink-0" />
|
||||||
|
</NuxtLink>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<UNavigationMenu :items="menuItems" variant="link" content-orientation="vertical" class="hidden lg:block" :ui="{ list: '-mx-2.5', link: 'text-base', childLink: 'text-base' }" />
|
||||||
|
</template>
|
||||||
|
<template #body>
|
||||||
|
<UNavigationMenu :items="menuItems" orientation="vertical" />
|
||||||
|
</template>
|
||||||
|
</UHeader>
|
||||||
|
</template>
|
||||||
15
wp-content/themes/ccat/app/components/site/SiteHeaderTop.vue
Normal file
15
wp-content/themes/ccat/app/components/site/SiteHeaderTop.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const { profiles } = await useSiteOptions();
|
||||||
|
const { menuItems } = await useMenuItems("TOP");
|
||||||
|
const { breakpoints } = useResponsive();
|
||||||
|
const showLabels = breakpoints.greaterOrEqual("sm");
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UContainer class="flex items-center gap-1.5">
|
||||||
|
<UiSocialProfiles :profiles="profiles" class="mr-auto" />
|
||||||
|
<UNavigationMenu :items="menuItems" variant="link" content-orientation="vertical" />
|
||||||
|
<LoginLogoutButton :show-labels="showLabels" />
|
||||||
|
<SignUpButton :show-labels="showLabels" />
|
||||||
|
</UContainer>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { SiteOptionsFragment } from "#graphql-operations";
|
||||||
|
|
||||||
|
defineProps<{ profiles: SiteOptionsFragment["profiles"] }>();
|
||||||
|
|
||||||
|
const socialIconMap = {
|
||||||
|
"facebook.com": "i-cib-facebook-f",
|
||||||
|
"twitter.com": "i-cib-twitter",
|
||||||
|
"x.com": "i-cib-twitter",
|
||||||
|
"instagram.com": "i-cib-instagram",
|
||||||
|
"youtube.com": "i-cib-youtube",
|
||||||
|
"linkedin.com": "i-cib-linkedin",
|
||||||
|
"tiktok.com": "i-cib-tiktok",
|
||||||
|
};
|
||||||
|
|
||||||
|
function getIconFromUrl(url: string): string {
|
||||||
|
try {
|
||||||
|
const domain = new URL(url).hostname.toLowerCase().replace(/^www\./, "");
|
||||||
|
return socialIconMap[domain as keyof typeof socialIconMap] || "i-lucide-globe";
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return "i-lucide-globe";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex gap-1">
|
||||||
|
<UButton
|
||||||
|
v-for="(profile, key) in profiles" :key="key"
|
||||||
|
:icon="getIconFromUrl(profile!.url)"
|
||||||
|
:to="profile!.url"
|
||||||
|
variant="link"
|
||||||
|
color="neutral"
|
||||||
|
external
|
||||||
|
target="_blank"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
48
wp-content/themes/ccat/app/composables/useLogin.ts
Normal file
48
wp-content/themes/ccat/app/composables/useLogin.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
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 };
|
||||||
|
}
|
||||||
23
wp-content/themes/ccat/app/composables/useLogout.ts
Normal file
23
wp-content/themes/ccat/app/composables/useLogout.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
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 };
|
||||||
|
}
|
||||||
19
wp-content/themes/ccat/app/composables/useMenuItems.gql
Normal file
19
wp-content/themes/ccat/app/composables/useMenuItems.gql
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
fragment MenuItem on MenuItem {
|
||||||
|
id
|
||||||
|
label
|
||||||
|
to: path
|
||||||
|
target
|
||||||
|
}
|
||||||
|
|
||||||
|
query menuItems($location: MenuLocationEnum!) {
|
||||||
|
menuItems(where: {location: $location, parentDatabaseId: 0}) {
|
||||||
|
nodes {
|
||||||
|
...MenuItem
|
||||||
|
childItems {
|
||||||
|
nodes {
|
||||||
|
...MenuItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
wp-content/themes/ccat/app/composables/useMenuItems.ts
Normal file
14
wp-content/themes/ccat/app/composables/useMenuItems.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import type { MenuLocationEnum } from "#graphql-operations";
|
||||||
|
import type { NavigationMenuItem } from "@nuxt/ui";
|
||||||
|
|
||||||
|
export async function useMenuItems(location: MenuLocationEnum) {
|
||||||
|
const { data } = await useAsyncGraphqlQuery("menuItems", { location }, { graphqlCaching: { client: true } });
|
||||||
|
if (data.value?.errors?.length) {
|
||||||
|
throw createError({ statusCode: 500, message: "Erreur lors de la récupération des éléments de menu" });
|
||||||
|
}
|
||||||
|
const menuItems: NavigationMenuItem[] = (data.value?.data.menuItems?.nodes || []).map(({ childItems, ...menuItem }) => ({
|
||||||
|
...menuItem,
|
||||||
|
children: childItems?.nodes || [],
|
||||||
|
}));
|
||||||
|
return { menuItems };
|
||||||
|
}
|
||||||
11
wp-content/themes/ccat/app/composables/useResponsive.ts
Normal file
11
wp-content/themes/ccat/app/composables/useResponsive.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core";
|
||||||
|
|
||||||
|
export function useResponsive() {
|
||||||
|
const { isMobileOrTablet } = useDevice();
|
||||||
|
const breakpoints = useBreakpoints(breakpointsTailwind, { ssrWidth: isMobileOrTablet ? 375 : 1024 });
|
||||||
|
|
||||||
|
return {
|
||||||
|
breakpoints,
|
||||||
|
isDesktop: breakpoints.greaterOrEqual("lg"),
|
||||||
|
};
|
||||||
|
}
|
||||||
13
wp-content/themes/ccat/app/composables/useSiteOptions.gql
Normal file
13
wp-content/themes/ccat/app/composables/useSiteOptions.gql
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
fragment SiteOptions on Ccat {
|
||||||
|
profiles {
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query siteOptions {
|
||||||
|
siteOptions {
|
||||||
|
ccat {
|
||||||
|
...SiteOptions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
wp-content/themes/ccat/app/composables/useSiteOptions.ts
Normal file
7
wp-content/themes/ccat/app/composables/useSiteOptions.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export async function useSiteOptions() {
|
||||||
|
const { data } = await useAsyncGraphqlQuery("siteOptions", {}, { graphqlCaching: { client: true } });
|
||||||
|
if (data.value?.errors?.length || !data.value?.data.siteOptions?.ccat) {
|
||||||
|
throw createError({ statusCode: 500, message: "Erreur lors de la récupération des options du site" });
|
||||||
|
}
|
||||||
|
return { ...data.value?.data.siteOptions?.ccat };
|
||||||
|
}
|
||||||
11
wp-content/themes/ccat/app/error.vue
Normal file
11
wp-content/themes/ccat/app/error.vue
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { NuxtError } from "#app";
|
||||||
|
|
||||||
|
defineProps<{ error: NuxtError }>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UApp>
|
||||||
|
<UError :error="error" />
|
||||||
|
</UApp>
|
||||||
|
</template>
|
||||||
19
wp-content/themes/ccat/app/layouts/auth.vue
Normal file
19
wp-content/themes/ccat/app/layouts/auth.vue
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<template>
|
||||||
|
<div class="h-screen flex items-center justify-center px-4">
|
||||||
|
<UButton
|
||||||
|
icon="i-lucide-chevron-left"
|
||||||
|
to="/"
|
||||||
|
size="xl"
|
||||||
|
color="neutral"
|
||||||
|
variant="subtle"
|
||||||
|
class="absolute left-8 top-8 rounded-full z-10"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<UPageCard
|
||||||
|
variant="subtle"
|
||||||
|
class="max-w-sm w-full"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</UPageCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
23
wp-content/themes/ccat/app/layouts/default.vue
Normal file
23
wp-content/themes/ccat/app/layouts/default.vue
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const refSiteFooterBottom = useTemplateRef("refSiteFooterBottom");
|
||||||
|
const { height } = useElementSize(refSiteFooterBottom);
|
||||||
|
watch(height, (h) => {
|
||||||
|
document.documentElement.style.setProperty("--footer-bottom-height", `${h}px`);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<SiteHeaderTop />
|
||||||
|
<SiteHeader />
|
||||||
|
<div class="relative z-main bg-white border-b border-muted mb-[var(--footer-bottom-height)]">
|
||||||
|
<UMain>
|
||||||
|
<slot />
|
||||||
|
</UMain>
|
||||||
|
<SiteFooter />
|
||||||
|
</div>
|
||||||
|
<div ref="refSiteFooterBottom" class="fixed bottom-0 w-full bg-muted">
|
||||||
|
<SiteFooterBottom />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
12
wp-content/themes/ccat/app/pages/auth.vue
Normal file
12
wp-content/themes/ccat/app/pages/auth.vue
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({ layout: "auth" });
|
||||||
|
|
||||||
|
const { loggedIn } = useUserSession();
|
||||||
|
|
||||||
|
useSeoMeta({ title: loggedIn.value ? "Déconnexion" : "Connexion" });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<LogoutForm v-if="loggedIn" />
|
||||||
|
<LoginForm v-else />
|
||||||
|
</template>
|
||||||
9
wp-content/themes/ccat/app/pages/index.vue
Normal file
9
wp-content/themes/ccat/app/pages/index.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
useSeoMeta({ title: "Accueil" });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UPage>
|
||||||
|
<UPageHero title="Nuxt UI rocks" />
|
||||||
|
</UPage>
|
||||||
|
</template>
|
||||||
8
wp-content/themes/ccat/eslint.config.mjs
Normal file
8
wp-content/themes/ccat/eslint.config.mjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// @ts-check
|
||||||
|
import withNuxt from "./.nuxt/eslint.config.mjs";
|
||||||
|
|
||||||
|
export default withNuxt({
|
||||||
|
rules: {
|
||||||
|
"vue/max-attributes-per-line": "off",
|
||||||
|
},
|
||||||
|
});
|
||||||
3
wp-content/themes/ccat/graphql.config.ts
Normal file
3
wp-content/themes/ccat/graphql.config.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import config from "./.nuxt/nuxt-graphql-middleware/graphql.config";
|
||||||
|
|
||||||
|
export default config;
|
||||||
81
wp-content/themes/ccat/nuxt.config.ts
Normal file
81
wp-content/themes/ccat/nuxt.config.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
const isDev = process.env.NODE_ENV === "development";
|
||||||
|
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
modules: [
|
||||||
|
"@nuxt/eslint",
|
||||||
|
"@nuxt/ui",
|
||||||
|
"@nuxthub/core",
|
||||||
|
"@nuxtjs/device",
|
||||||
|
"@nuxtjs/robots",
|
||||||
|
"@nuxtjs/sitemap",
|
||||||
|
"@vueuse/nuxt",
|
||||||
|
"nuxt-auth-utils",
|
||||||
|
"nuxt-graphql-middleware",
|
||||||
|
"nuxt-svgo",
|
||||||
|
],
|
||||||
|
|
||||||
|
components: {
|
||||||
|
dirs: [
|
||||||
|
{ path: "~/components", pathPrefix: false },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
devtools: { enabled: true },
|
||||||
|
css: ["~/assets/css/main.css"],
|
||||||
|
|
||||||
|
site: {
|
||||||
|
indexable: true,
|
||||||
|
url: "https://cultureat.ca",
|
||||||
|
name: "Conseil de la culture de l'Abitibi-Témiscamingue",
|
||||||
|
},
|
||||||
|
|
||||||
|
ui: {
|
||||||
|
colorMode: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
runtimeConfig: {
|
||||||
|
public: {
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
future: { compatibilityVersion: 4 },
|
||||||
|
compatibilityDate: "2025-03-01",
|
||||||
|
|
||||||
|
nitro: {
|
||||||
|
preset: "cloudflare_module",
|
||||||
|
},
|
||||||
|
|
||||||
|
hub: {},
|
||||||
|
|
||||||
|
eslint: {
|
||||||
|
config: {
|
||||||
|
stylistic: {
|
||||||
|
arrowParens: true,
|
||||||
|
commaDangle: "always-multiline",
|
||||||
|
indent: 2,
|
||||||
|
quotes: "double",
|
||||||
|
semi: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
graphqlMiddleware: {
|
||||||
|
graphqlEndpoint: process.env.NUXT_GRAPHQL_ENDPOINT || "https://wp.cultureat.ca/graphql",
|
||||||
|
downloadSchema: isDev,
|
||||||
|
schemaPath: "server/graphql/schema.graphql",
|
||||||
|
},
|
||||||
|
|
||||||
|
robots: {
|
||||||
|
sitemap: [
|
||||||
|
"/sitemap.xml",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
sitemap: {},
|
||||||
|
|
||||||
|
svgo: {
|
||||||
|
autoImportPath: "~/assets/svg/",
|
||||||
|
componentPrefix: "svg",
|
||||||
|
defaultImport: "component",
|
||||||
|
},
|
||||||
|
});
|
||||||
54
wp-content/themes/ccat/package.json
Normal file
54
wp-content/themes/ccat/package.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"name": "@lewebsimple/cultureat.ca",
|
||||||
|
"version": "0.2.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "pnpm --sequential /build:.*/",
|
||||||
|
"build:typecheck": "nuxi typecheck",
|
||||||
|
"build:nuxt": "nuxt build",
|
||||||
|
"deploy": "pnpx nuxthub deploy",
|
||||||
|
"dev": "pnpm /dev:.*/",
|
||||||
|
"dev:nuxt": "nuxt dev --host",
|
||||||
|
"lint": "eslint --fix .",
|
||||||
|
"postinstall": "pnpm --sequential /postinstall:.*/",
|
||||||
|
"postinstall:nuxt": "nuxt prepare",
|
||||||
|
"preview": "pnpx nuxthub preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@iconify-json/cib": "^1.2.3",
|
||||||
|
"@iconify-json/lucide": "^1.2.63",
|
||||||
|
"@nuxt/eslint": "^1.9.0",
|
||||||
|
"@nuxt/ui": "4.0.0-alpha.0",
|
||||||
|
"@nuxthub/core": "^0.9.0",
|
||||||
|
"@nuxtjs/device": "3.2.4",
|
||||||
|
"@nuxtjs/robots": "5.5.0",
|
||||||
|
"@nuxtjs/sitemap": "7.4.3",
|
||||||
|
"@vueuse/nuxt": "13.7.0",
|
||||||
|
"nuxt": "^4.0.3",
|
||||||
|
"nuxt-auth-utils": "0.5.23",
|
||||||
|
"nuxt-graphql-middleware": "5.2.0",
|
||||||
|
"nuxt-svgo": "4.2.6",
|
||||||
|
"vue": "^3.5.19",
|
||||||
|
"vue-router": "^4.5.1",
|
||||||
|
"zod": "^4.0.17"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^9.33.0",
|
||||||
|
"typescript": "^5.9.2",
|
||||||
|
"vue-tsc": "^3.0.6",
|
||||||
|
"wrangler": "^4.32.0"
|
||||||
|
},
|
||||||
|
"packageManager": "pnpm@10.15.0",
|
||||||
|
"pnpm": {
|
||||||
|
"onlyBuiltDependencies": [
|
||||||
|
"@parcel/watcher",
|
||||||
|
"@tailwindcss/oxide",
|
||||||
|
"esbuild",
|
||||||
|
"sharp",
|
||||||
|
"unrs-resolver",
|
||||||
|
"vue-demi",
|
||||||
|
"workerd"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
13939
wp-content/themes/ccat/pnpm-lock.yaml
generated
Normal file
13939
wp-content/themes/ccat/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
BIN
wp-content/themes/ccat/public/favicon.ico
Normal file
BIN
wp-content/themes/ccat/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
9
wp-content/themes/ccat/server/api/login.gql
Normal file
9
wp-content/themes/ccat/server/api/login.gql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
mutation login($email: String!, $password: String!) {
|
||||||
|
login(input: { username: $email, password: $password }) {
|
||||||
|
authToken
|
||||||
|
refreshToken
|
||||||
|
user {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
wp-content/themes/ccat/server/api/login.post.ts
Normal file
29
wp-content/themes/ccat/server/api/login.post.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { defineEventHandler, readBody } from "h3";
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { email, password } = await readBody(event);
|
||||||
|
try {
|
||||||
|
const response = await useGraphqlMutation("login", { email, password });
|
||||||
|
if (response.errors.length) {
|
||||||
|
throw new Error(response.errors[0]?.message);
|
||||||
|
}
|
||||||
|
if (!response.data.login) {
|
||||||
|
throw new Error("Login failed: Invalid credentials");
|
||||||
|
}
|
||||||
|
const { authToken, refreshToken, user } = response.data.login;
|
||||||
|
await setUserSession(event, {
|
||||||
|
user,
|
||||||
|
secure: { authToken, refreshToken },
|
||||||
|
loggedInAt: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
const messages: Record<string, string> = {
|
||||||
|
invalid_email: "Courriel et/ou mot de passe invalide(s).",
|
||||||
|
incorrect_password: "Courriel et/ou mot de passe invalide(s).",
|
||||||
|
};
|
||||||
|
const message = error instanceof Error && messages[error.message] ? messages[error.message] : "Une erreur est survenue.";
|
||||||
|
return { success: false, message };
|
||||||
|
}
|
||||||
|
});
|
||||||
6
wp-content/themes/ccat/server/api/logout.post.ts
Normal file
6
wp-content/themes/ccat/server/api/logout.post.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { defineEventHandler } from "h3";
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
await clearUserSession(event);
|
||||||
|
return { success: true };
|
||||||
|
});
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
mutation refreshJwtAuthToken($refreshToken: String!) {
|
||||||
|
refreshJwtAuthToken(input: { jwtRefreshToken: $refreshToken }) {
|
||||||
|
authToken
|
||||||
|
}
|
||||||
|
}
|
||||||
25771
wp-content/themes/ccat/server/graphql/schema.graphql
Normal file
25771
wp-content/themes/ccat/server/graphql/schema.graphql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
|||||||
|
import { defineGraphqlServerOptions } from "nuxt-graphql-middleware/server-options";
|
||||||
|
import { jwtDecode } from "jwt-decode";
|
||||||
|
|
||||||
|
interface DecodedToken {
|
||||||
|
exp: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refreshAuthToken(refreshToken: string): Promise<string | null> {
|
||||||
|
const refreshResponse = await useGraphqlMutation("refreshJwtAuthToken", { refreshToken });
|
||||||
|
return refreshResponse.data?.refreshJwtAuthToken?.authToken || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineGraphqlServerOptions({
|
||||||
|
async serverFetchOptions(event) {
|
||||||
|
const session = await getUserSession(event);
|
||||||
|
if (!session?.secure?.authToken) return {};
|
||||||
|
|
||||||
|
const decoded = jwtDecode<DecodedToken>(session.secure.authToken);
|
||||||
|
const isExpired = decoded.exp * 1000 < Date.now();
|
||||||
|
if (isExpired) {
|
||||||
|
const newToken = await refreshAuthToken(session.secure.authToken);
|
||||||
|
if (newToken) {
|
||||||
|
session.secure.authToken = newToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { headers: { Authorization: `Bearer ${session.secure.authToken}` } };
|
||||||
|
},
|
||||||
|
});
|
||||||
17
wp-content/themes/ccat/shared/auth.d.ts
vendored
Normal file
17
wp-content/themes/ccat/shared/auth.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// auth.d.ts
|
||||||
|
declare module "#auth-utils" {
|
||||||
|
interface User {
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UserSession {
|
||||||
|
loggedInAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SecureSessionData {
|
||||||
|
authToken: string;
|
||||||
|
refreshToken: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { };
|
||||||
4
wp-content/themes/ccat/tsconfig.json
Normal file
4
wp-content/themes/ccat/tsconfig.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
// https://nuxt.com/docs/guide/concepts/typescript
|
||||||
|
"extends": "./.nuxt/tsconfig.json"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user