2 Commits

Author SHA1 Message Date
3199835e83 feat: AcfSocial / parseAcfSocial 2026-01-30 11:45:39 -05:00
6dd13ead91 feat: mapSocialIcon 2026-01-30 11:18:10 -05:00
12 changed files with 264 additions and 20 deletions

View File

@@ -0,0 +1,86 @@
{
"key": "group_abstract_social",
"title": "Abstract - Social",
"fields": [
{
"key": "field_6855a1d643408",
"label": "Médias sociaux",
"name": "profiles",
"aria-label": "",
"type": "repeater",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"acfe_repeater_stylised_button": 0,
"layout": "table",
"pagination": 0,
"min": 0,
"max": 0,
"collapsed": "",
"button_label": "Ajouter un élément",
"show_in_graphql": 1,
"graphql_description": "",
"graphql_field_name": "profiles",
"graphql_non_null": 1,
"rows_per_page": 20,
"sub_fields": [
{
"key": "field_6855a7e143409",
"label": "URL",
"name": "url",
"aria-label": "",
"type": "url",
"instructions": "",
"required": 1,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"allow_in_bindings": 0,
"placeholder": "",
"show_in_graphql": 1,
"graphql_description": "",
"graphql_field_name": "url",
"graphql_non_null": 1,
"parent_repeater": "field_6855a1d643408"
}
]
}
],
"location": [
[
{
"param": "abstract"
}
]
],
"menu_order": 0,
"position": "normal",
"style": "seamless",
"label_placement": "top",
"instruction_placement": "label",
"hide_on_screen": "",
"active": true,
"description": "",
"show_in_rest": 0,
"display_title": "",
"acfe_autosync": [
"json"
],
"acfe_form": 0,
"show_in_graphql": 1,
"graphql_field_name": "GroupAbstractSocial",
"map_graphql_types_from_location_rules": 0,
"graphql_types": "",
"acfe_meta": "",
"acfe_note": "",
"modified": 1769788591
}

View File

@@ -48,6 +48,34 @@
"graphql_field_name": "phoneNumber", "graphql_field_name": "phoneNumber",
"graphql_non_null": 1 "graphql_non_null": 1
}, },
{
"key": "field_697cd4c5fc56a",
"label": "Médias sociaux",
"name": "social",
"aria-label": "",
"type": "clone",
"instructions": "",
"required": 1,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"graphql_field_name": "social",
"clone": [
"group_abstract_social"
],
"display": "seamless",
"layout": "block",
"prefix_label": 0,
"prefix_name": 0,
"acfe_seamless_style": 0,
"acfe_clone_modal": 0,
"acfe_clone_modal_close": 0,
"acfe_clone_modal_button": "",
"acfe_clone_modal_size": "large"
},
{ {
"key": "field_697cc921234cc", "key": "field_697cc921234cc",
"label": "Liens globaux", "label": "Liens globaux",
@@ -126,5 +154,5 @@
"graphql_types": "", "graphql_types": "",
"acfe_meta": "", "acfe_meta": "",
"acfe_note": "", "acfe_note": "",
"modified": 1769785750 "modified": 1769788698
} }

View File

@@ -0,0 +1,5 @@
fragment AcfSocial on GroupAbstractSocial_Fields {
profiles {
url
}
}

View File

@@ -0,0 +1,11 @@
<script setup lang="ts">
defineProps<{ social?: AcfSocialOutput }>();
</script>
<template>
<div v-if="social?.profiles" class="flex gap-1.5">
<a v-for="({ url, icon }, key) in social.profiles" :key="key" :href="url" target="_blank" rel="noopener noreferrer" class="flex">
<UIcon :name="icon" />
</a>
</div>
</template>

View File

@@ -1,13 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
const { data: siteOptions } = await useSiteOptions();
</script> </script>
<template> <template>
<UFooter id="site-footer"> <footer class="bg-accented links:link-prose">
<template #left> <div class="container py-6">
<SiteFooterCopyright /> <AcfSocialProfiles :social="parseAcfSocial(siteOptions)" />
</template> </div>
<template #right> <SiteFooterBottom />
<SiteFooterCredits /> </footer>
</template>
</UFooter>
</template> </template>

View File

@@ -0,0 +1,9 @@
<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" />
<SiteFooterCredits />
</div>
</div>
</template>

View File

@@ -1,6 +1,7 @@
fragment SiteOptions on GroupSiteOptions { fragment SiteOptions on GroupSiteOptions {
email email
phoneNumber { ... AcfPhone } phoneNumber { ... AcfPhone }
...AcfSocial
links { links {
contact { ... AcfLink} contact { ... AcfLink}
} }

View File

@@ -0,0 +1,32 @@
import * as z from "zod";
import type { AcfSocialFragment } from "#graphql/operations";
const socialProfile = z.object({ url: z.url() }).transform(({ url }) => ({ url, icon: getSocialIcon(url) }));
const acfSocialSchema = z.object({
profiles: z.array(socialProfile),
});
export type AcfSocialOutput = z.infer<typeof acfSocialSchema>;
export function parseAcfSocial(data?: AcfSocialFragment) {
try {
return acfSocialSchema.parse(data);
}
catch {
return undefined;
}
}
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 getSocialIcon(url: string): string {
const domain = new URL(url).hostname.toLowerCase().replace(/^www\./, "");
return socialIconMap[domain as keyof typeof socialIconMap] ?? "i-lucide-globe";
}

View File

@@ -1,6 +1,6 @@
<?php <?php
// Override TermConnection query args // Override term connection query args
add_filter( 'graphql_term_object_connection_query_args', 'moonshine_graphql_term_object_connection_query_args', 10, 3 ); add_filter( 'graphql_term_object_connection_query_args', 'moonshine_graphql_term_object_connection_query_args', 10, 3 );
function moonshine_graphql_term_object_connection_query_args( $query_args, $source, $args ) { function moonshine_graphql_term_object_connection_query_args( $query_args, $source, $args ) {
// Sort by 'order' meta value instead of legacy 'term_order' field // Sort by 'order' meta value instead of legacy 'term_order' field

View File

@@ -15,8 +15,9 @@
"typecheck": "nuxt typecheck" "typecheck": "nuxt typecheck"
}, },
"dependencies": { "dependencies": {
"@iconify-json/cib": "^1.2.3",
"@iconify-json/lucide": "^1.2.87", "@iconify-json/lucide": "^1.2.87",
"@lewebsimple/nuxt-graphql": "^0.6.7", "@lewebsimple/nuxt-graphql": "^0.6.8",
"@nuxt/image": "^2.0.0", "@nuxt/image": "^2.0.0",
"@nuxt/ui": "4.3.0", "@nuxt/ui": "4.3.0",
"@nuxtjs/device": "4.0.0", "@nuxtjs/device": "4.0.0",

View File

@@ -12,12 +12,15 @@ importers:
.: .:
dependencies: dependencies:
'@iconify-json/cib':
specifier: ^1.2.3
version: 1.2.3
'@iconify-json/lucide': '@iconify-json/lucide':
specifier: ^1.2.87 specifier: ^1.2.87
version: 1.2.87 version: 1.2.87
'@lewebsimple/nuxt-graphql': '@lewebsimple/nuxt-graphql':
specifier: ^0.6.7 specifier: ^0.6.8
version: 0.6.7(db0@0.3.4)(ioredis@5.9.2)(magicast@0.5.1) version: 0.6.8(db0@0.3.4)(ioredis@5.9.2)(magicast@0.5.1)
'@nuxt/image': '@nuxt/image':
specifier: ^2.0.0 specifier: ^2.0.0
version: 2.0.0(db0@0.3.4)(ioredis@5.9.2)(magicast@0.5.1) version: 2.0.0(db0@0.3.4)(ioredis@5.9.2)(magicast@0.5.1)
@@ -1060,6 +1063,9 @@ packages:
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
engines: {node: '>=18.18'} engines: {node: '>=18.18'}
'@iconify-json/cib@1.2.3':
resolution: {integrity: sha512-MMvRXVTHt82z3bYN19JDAjv/X8OBNC/1B3I334SV/1nyhdPeeyvJZVoI1cGuNqYznBjMnWxKPtIhhiVgGQ1CzQ==}
'@iconify-json/lucide@1.2.87': '@iconify-json/lucide@1.2.87':
resolution: {integrity: sha512-wxYIAp0f8Uw0rJa6BMWMaRbiHk3yV4XczA38GKXFlqyZtTdmHM1QOF4NZw5xpMlRDzbh2MnB7wjteLeFnn/ciQ==} resolution: {integrity: sha512-wxYIAp0f8Uw0rJa6BMWMaRbiHk3yV4XczA38GKXFlqyZtTdmHM1QOF4NZw5xpMlRDzbh2MnB7wjteLeFnn/ciQ==}
@@ -1267,8 +1273,8 @@ packages:
'@kwsites/promise-deferred@1.1.1': '@kwsites/promise-deferred@1.1.1':
resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==}
'@lewebsimple/nuxt-graphql@0.6.7': '@lewebsimple/nuxt-graphql@0.6.8':
resolution: {integrity: sha512-/7jol50YtpKdUlVIliDI0IH9z9D8Gk0pm6Jc1q7CL6TTOKlJKnCmLw0KsjmmmniUgtBQjyh/G+VqXu60iRgRYg==} resolution: {integrity: sha512-b7QYVQx4OeiWmO8qY5CDxFC+Vnafn92ak8ApijA4C4t1lrJ/QjFl5avdATOWeTsskHBvq0QI3rGE2O144iBZGA==}
'@mapbox/node-pre-gyp@2.0.3': '@mapbox/node-pre-gyp@2.0.3':
resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==} resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==}
@@ -7426,6 +7432,10 @@ snapshots:
'@humanwhocodes/retry@0.4.3': {} '@humanwhocodes/retry@0.4.3': {}
'@iconify-json/cib@1.2.3':
dependencies:
'@iconify/types': 2.0.0
'@iconify-json/lucide@1.2.87': '@iconify-json/lucide@1.2.87':
dependencies: dependencies:
'@iconify/types': 2.0.0 '@iconify/types': 2.0.0
@@ -7609,7 +7619,7 @@ snapshots:
'@kwsites/promise-deferred@1.1.1': {} '@kwsites/promise-deferred@1.1.1': {}
'@lewebsimple/nuxt-graphql@0.6.7(db0@0.3.4)(ioredis@5.9.2)(magicast@0.5.1)': '@lewebsimple/nuxt-graphql@0.6.8(db0@0.3.4)(ioredis@5.9.2)(magicast@0.5.1)':
dependencies: dependencies:
'@graphql-codegen/core': 5.0.0(graphql@16.12.0) '@graphql-codegen/core': 5.0.0(graphql@16.12.0)
'@graphql-codegen/typed-document-node': 6.1.5(graphql@16.12.0) '@graphql-codegen/typed-document-node': 6.1.5(graphql@16.12.0)
@@ -11514,7 +11524,7 @@ snapshots:
lower-case@2.0.2: lower-case@2.0.2:
dependencies: dependencies:
tslib: 2.6.3 tslib: 2.8.1
lru-cache@10.4.3: {} lru-cache@10.4.3: {}
@@ -13461,7 +13471,7 @@ snapshots:
upper-case@2.0.2: upper-case@2.0.2:
dependencies: dependencies:
tslib: 2.6.3 tslib: 2.8.1
uqr@0.1.2: {} uqr@0.1.2: {}

View File

@@ -3639,6 +3639,58 @@ interface GroupAbstractMedia_Fields implements AcfFieldGroup & AcfFieldGroupFiel
objectFit: String! objectFit: String!
} }
"""
The &quot;GroupAbstractSocial&quot; Field Group. Added to the Schema by &quot;WPGraphQL for ACF&quot;.
"""
type GroupAbstractSocial implements AcfFieldGroup & AcfFieldGroupFields & GroupAbstractSocial_Fields {
"""The name of the field group"""
fieldGroupName: String @deprecated(reason: "Use __typename instead")
"""
Field of the &quot;repeater&quot; Field Type added to the schema as part of the &quot;GroupAbstractSocial&quot; Field Group
"""
profiles: [GroupAbstractSocialProfiles]!
}
"""
The &quot;GroupAbstractSocialProfiles&quot; Field Group. Added to the Schema by &quot;WPGraphQL for ACF&quot;.
"""
type GroupAbstractSocialProfiles implements AcfFieldGroup & AcfFieldGroupFields & GroupAbstractSocialProfiles_Fields {
"""The name of the field group"""
fieldGroupName: String @deprecated(reason: "Use __typename instead")
"""
Field of the &quot;url&quot; Field Type added to the schema as part of the &quot;GroupAbstractSocialProfiles&quot; Field Group
"""
url: String!
}
"""
Interface representing fields of the ACF &quot;GroupAbstractSocialProfiles&quot; Field Group
"""
interface GroupAbstractSocialProfiles_Fields implements AcfFieldGroup & AcfFieldGroupFields {
"""The name of the field group"""
fieldGroupName: String @deprecated(reason: "Use __typename instead")
"""
Field of the &quot;url&quot; Field Type added to the schema as part of the &quot;GroupAbstractSocialProfiles&quot; Field Group
"""
url: String!
}
"""
Interface representing fields of the ACF &quot;GroupAbstractSocial&quot; Field Group
"""
interface GroupAbstractSocial_Fields implements AcfFieldGroup & AcfFieldGroupFields {
"""The name of the field group"""
fieldGroupName: String @deprecated(reason: "Use __typename instead")
"""
Field of the &quot;repeater&quot; Field Type added to the schema as part of the &quot;GroupAbstractSocial&quot; Field Group
"""
profiles: [GroupAbstractSocialProfiles]!
}
""" """
The &quot;GroupLayoutContained&quot; Field Group. Added to the Schema by &quot;WPGraphQL for ACF&quot;. The &quot;GroupLayoutContained&quot; Field Group. Added to the Schema by &quot;WPGraphQL for ACF&quot;.
""" """
@@ -3714,7 +3766,7 @@ interface GroupPostPage_Fields implements AcfFieldGroup & AcfFieldGroupFields &
""" """
The &quot;GroupSiteOptions&quot; Field Group. Added to the Schema by &quot;WPGraphQL for ACF&quot;. The &quot;GroupSiteOptions&quot; Field Group. Added to the Schema by &quot;WPGraphQL for ACF&quot;.
""" """
type GroupSiteOptions implements AcfFieldGroup & AcfFieldGroupFields & GroupSiteOptions_Fields { type GroupSiteOptions implements AcfFieldGroup & AcfFieldGroupFields & GroupAbstractSocial_Fields & GroupSiteOptions_Fields {
""" """
Field of the &quot;email&quot; Field Type added to the schema as part of the &quot;GroupSiteOptions&quot; Field Group Field of the &quot;email&quot; Field Type added to the schema as part of the &quot;GroupSiteOptions&quot; Field Group
""" """
@@ -3732,6 +3784,11 @@ type GroupSiteOptions implements AcfFieldGroup & AcfFieldGroupFields & GroupSite
Field of the &quot;phone&quot; Field Type added to the schema as part of the &quot;GroupSiteOptions&quot; Field Group Field of the &quot;phone&quot; Field Type added to the schema as part of the &quot;GroupSiteOptions&quot; Field Group
""" """
phoneNumber: AcfPhone! phoneNumber: AcfPhone!
"""
Field of the &quot;repeater&quot; Field Type added to the schema as part of the &quot;GroupAbstractSocial&quot; Field Group
"""
profiles: [GroupAbstractSocialProfiles]!
} }
""" """
@@ -3763,7 +3820,7 @@ interface GroupSiteOptionsLinks_Fields implements AcfFieldGroup & AcfFieldGroupF
""" """
Interface representing fields of the ACF &quot;GroupSiteOptions&quot; Field Group Interface representing fields of the ACF &quot;GroupSiteOptions&quot; Field Group
""" """
interface GroupSiteOptions_Fields implements AcfFieldGroup & AcfFieldGroupFields { interface GroupSiteOptions_Fields implements AcfFieldGroup & AcfFieldGroupFields & GroupAbstractSocial_Fields {
""" """
Field of the &quot;email&quot; Field Type added to the schema as part of the &quot;GroupSiteOptions&quot; Field Group Field of the &quot;email&quot; Field Type added to the schema as part of the &quot;GroupSiteOptions&quot; Field Group
""" """
@@ -3781,6 +3838,11 @@ interface GroupSiteOptions_Fields implements AcfFieldGroup & AcfFieldGroupFields
Field of the &quot;phone&quot; Field Type added to the schema as part of the &quot;GroupSiteOptions&quot; Field Group Field of the &quot;phone&quot; Field Type added to the schema as part of the &quot;GroupSiteOptions&quot; Field Group
""" """
phoneNumber: AcfPhone! phoneNumber: AcfPhone!
"""
Field of the &quot;repeater&quot; Field Type added to the schema as part of the &quot;GroupAbstractSocial&quot; Field Group
"""
profiles: [GroupAbstractSocialProfiles]!
} }
""" """