index-shop/site/plugins/shopify-refresh-button/src/components/ShopifyRefreshButton.vue
isUnknown ade0ed1a67 Add virtual pages from Shopify and panel refresh button
This simplifies product management by eliminating manual Kirby page creation. Products are now automatically loaded as virtual pages from the Shopify API.

Changes:
- Add virtual pages via page.children:after hook
- Create shopify.php helper with caching (60min TTL)
- Add shopify-refresh panel plugin for cache management
- Remove manual product content files (now virtual)
- Update site.yml blueprint to show refresh button
- Fix cache implementation to use get/set pattern

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-16 12:44:28 +01:00

97 lines
2.3 KiB
Vue

<template>
<div>
<k-info-field :label="infoLabel" :text="infoText" theme="info" />
<k-button
style="margin-top: 1rem"
:theme="theme"
variant="dimmed"
:icon="icon"
title="Synchroniser le cache des produits Shopify"
@click="refreshCache()"
:disabled="isProcessing"
>
{{ text }}
</k-button>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from "vue";
const props = defineProps({
products: {
type: Array,
default: () => [],
},
});
const text = ref("Synchroniser depuis Shopify");
const icon = ref("refresh");
const theme = ref("aqua-icon");
const isProcessing = ref(false);
const currentProducts = ref([]);
onMounted(() => {
currentProducts.value = props.products || [];
});
const infoLabel = computed(() => {
const count = currentProducts.value.length;
return `${count} produit${count > 1 ? "s" : ""} Shopify en cache`;
});
const infoText = computed(() => {
if (currentProducts.value.length === 0) {
return "Aucun produit trouvé. Cliquez sur 'Rafraîchir Shopify' pour récupérer les produits.";
}
return currentProducts.value.map((p) => `${p.title}<br/>`).join("\n");
});
async function refreshCache() {
isProcessing.value = true;
icon.value = "loader";
theme.value = "orange-icon";
text.value = "En cours…";
try {
const res = await fetch("/shopify/refresh-cache.json", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
const json = await res.json();
if (json.status === "error") {
throw new Error(json.message);
}
currentProducts.value = json.products || [];
text.value = `Terminé - ${json.count} produit${json.count > 1 ? "s" : ""}`;
icon.value = "check";
theme.value = "green-icon";
setTimeout(() => {
text.value = "Synchroniser depuis Shopify";
icon.value = "refresh";
theme.value = "aqua-icon";
isProcessing.value = false;
}, 3000);
} catch (error) {
console.error(error);
text.value = "Erreur";
icon.value = "alert";
theme.value = "red-icon";
setTimeout(() => {
text.value = "Synchroniser depuis Shopify";
icon.value = "refresh";
theme.value = "aqua-icon";
isProcessing.value = false;
}, 3000);
}
}
</script>