From 4f65fbcbf3b0afbe62aecc14af10a8a995c1a055 Mon Sep 17 00:00:00 2001 From: MiloKow Date: Wed, 20 Aug 2025 20:46:39 +0200 Subject: [PATCH 1/4] :ambulance: [FIX] Fixing conflit --- crypto-pilot-builder/src/acceuil/Accueil.vue | 2545 +++++++++++++++-- .../src/services/cryptoService.js | 314 ++ 2 files changed, 2694 insertions(+), 165 deletions(-) create mode 100644 crypto-pilot-builder/src/services/cryptoService.js diff --git a/crypto-pilot-builder/src/acceuil/Accueil.vue b/crypto-pilot-builder/src/acceuil/Accueil.vue index 28f2aed..e2a52ff 100644 --- a/crypto-pilot-builder/src/acceuil/Accueil.vue +++ b/crypto-pilot-builder/src/acceuil/Accueil.vue @@ -5,27 +5,59 @@ + + @@ -46,7 +84,9 @@
- -
-
-
-
-
- 📰 - {{ - cryptoNews[2].source - }} -
-

{{ cryptoNews[2].title }}

-
{{ cryptoNews[2].time }}
-
-
-
-
@@ -346,27 +382,6 @@
- - -
-
-
-
-
- 📰 - {{ - cryptoNews[3].source - }} -
-

{{ cryptoNews[3].title }}

-
{{ cryptoNews[3].time }}
-
-
-
@@ -492,6 +507,11 @@ export default { trendingCurrentIndex: 0, trendingScrollInterval: null, trendingScrollOffset: 0, + // Préférences utilisateur personnalisées + userPreferences: null, + preferredCrypto: null, + preferredCryptoData: null, + personalizedNews: [], }; }, computed: { @@ -546,12 +566,226 @@ export default { extendedTrendingCoins() { return [...this.trendingCoins, ...this.trendingCoins]; }, + // Propriétés personnalisées basées sur les préférences utilisateur + mainCryptoData() { + // Utiliser la crypto préférée si disponible, sinon Bitcoin par défaut + return this.preferredCryptoData || this.bitcoinData; + }, + mainCryptoName() { + return this.mainCryptoData?.name || "Bitcoin"; + }, + mainCryptoSymbol() { + return this.mainCryptoData?.symbol?.toUpperCase() || "BTC"; + }, + mainCryptoIcon() { + return ( + this.mainCryptoData?.image || + "https://assets.coingecko.com/coins/images/1/large/bitcoin.png" + ); + }, + displayNews() { + // Utiliser les nouvelles personnalisées si disponibles, sinon les nouvelles générales + return this.personalizedNews.length > 0 + ? this.personalizedNews + : this.cryptoNews; + }, + isPersonalized() { + return this.userPreferences && this.preferredCrypto; + }, }, methods: { ...mapActions("auth", ["logout"]), ...mapActions(["loadAgentConfig"]), - // Méthodes crypto + // Méthodes pour la personnalisation basée sur la mémoire IA + async loadUserPreferences() { + if (!this.isAuthenticated) return; + + try { + console.log("🧠 Chargement des préférences utilisateur..."); + const response = await apiService.getUserMemory(); + + if (response && response.memories) { + this.userPreferences = response.memories; + this.processUserPreferences(); + console.log( + "✅ Préférences utilisateur chargées:", + this.userPreferences + ); + } + } catch (error) { + console.error("❌ Erreur lors du chargement des préférences:", error); + } + }, + + processUserPreferences() { + if (!this.userPreferences) return; + + console.log( + "🧠 Traitement des préférences utilisateur:", + this.userPreferences + ); + + // Chercher la blockchain/crypto préférée avec plus de critères + const cryptoPreferences = this.userPreferences.filter((memory) => { + const memoryType = memory.memory_type?.toLowerCase() || ""; + const keyInfo = memory.key_info?.toLowerCase() || ""; + const valueInfo = memory.value_info?.toLowerCase() || ""; + + return ( + memoryType === "preferences_crypto" || + memoryType === "preferences" || + keyInfo.includes("blockchain") || + keyInfo.includes("crypto") || + keyInfo.includes("preferee") || + keyInfo.includes("favori") || + keyInfo.includes("coin") || + keyInfo.includes("token") || + // Vérifier aussi dans la valeur + valueInfo.includes("bitcoin") || + valueInfo.includes("ethereum") || + valueInfo.includes("solana") || + valueInfo.includes("cardano") || + valueInfo.includes("polkadot") || + valueInfo.includes("avalanche") || + valueInfo.includes("chainlink") || + valueInfo.includes("ripple") || + valueInfo.includes("binance") || + valueInfo.includes("dogecoin") + ); + }); + + console.log("🎯 Préférences crypto trouvées:", cryptoPreferences); + + if (cryptoPreferences.length > 0) { + // Prendre la préférence avec le score de confiance le plus élevé + const bestPreference = cryptoPreferences.reduce((prev, current) => + current.confidence_score > prev.confidence_score ? current : prev + ); + + this.preferredCrypto = bestPreference.value_info.toLowerCase(); + console.log( + "🎯 Crypto préférée détectée:", + this.preferredCrypto, + "avec un score de confiance:", + bestPreference.confidence_score + ); + + // Mettre à jour les données de la crypto préférée + this.updatePreferredCryptoData(); + } else { + console.log( + "⚠️ Aucune préférence crypto trouvée dans la mémoire utilisateur" + ); + } + }, + + updatePreferredCryptoData() { + if (!this.preferredCrypto || !this.topCryptos.length) return; + + console.log( + "🔍 Recherche de la crypto préférée dans les données:", + this.preferredCrypto + ); + + // Mapping des noms de crypto vers les IDs CoinGecko + const cryptoMapping = { + bitcoin: "bitcoin", + btc: "bitcoin", + ethereum: "ethereum", + eth: "ethereum", + solana: "solana", + sol: "solana", + cardano: "cardano", + ada: "cardano", + polkadot: "polkadot", + dot: "polkadot", + avalanche: "avalanche-2", + avax: "avalanche-2", + chainlink: "chainlink", + link: "chainlink", + ripple: "ripple", + xrp: "ripple", + binance: "binancecoin", + bnb: "binancecoin", + dogecoin: "dogecoin", + doge: "dogecoin", + }; + + // Chercher d'abord par mapping exact + const mappedId = cryptoMapping[this.preferredCrypto.toLowerCase()]; + let preferredData = null; + + if (mappedId) { + preferredData = this.topCryptos.find( + (crypto) => crypto.id === mappedId + ); + console.log( + "🎯 Trouvé par mapping:", + mappedId, + preferredData ? preferredData.name : "non trouvé" + ); + } + + // Si pas trouvé par mapping, chercher par nom/symbole + if (!preferredData) { + preferredData = this.topCryptos.find( + (crypto) => + crypto.name.toLowerCase().includes(this.preferredCrypto) || + crypto.symbol.toLowerCase().includes(this.preferredCrypto) || + crypto.id.toLowerCase().includes(this.preferredCrypto) + ); + console.log( + "🔍 Recherche par nom/symbole:", + preferredData ? preferredData.name : "non trouvé" + ); + } + + if (preferredData) { + this.preferredCryptoData = preferredData; + console.log( + "✅ Données de la crypto préférée mises à jour:", + preferredData.name, + "(${preferredData.symbol.toUpperCase()})" + ); + } else { + console.log( + "⚠️ Crypto préférée non trouvée dans les données disponibles. Cryptos disponibles:", + this.topCryptos.map((c) => c.name) + ); + this.preferredCryptoData = null; + } + }, + + async loadPersonalizedNews() { + if (!this.preferredCrypto) return; + + try { + console.log( + "📰 Chargement des nouvelles personnalisées pour:", + this.preferredCrypto + ); + + // Utiliser le service cryptoService pour récupérer les nouvelles personnalisées + this.personalizedNews = await cryptoService.getPersonalizedNews( + this.preferredCrypto + ); + + console.log( + "✅ Nouvelles personnalisées chargées:", + this.personalizedNews.length + ); + } catch (error) { + console.error( + "❌ Erreur lors du chargement des nouvelles personnalisées:", + error + ); + // Fallback avec des nouvelles génériques + this.personalizedNews = []; + } + }, + + // Méthodes crypto existantes async loadCryptoData() { try { console.log("🔄 Chargement des données crypto..."); @@ -621,12 +855,22 @@ export default { newsCount: this.cryptoNews.length, }); - // Dessiner le sparkline pour Bitcoin + // Mettre à jour les données de la crypto préférée si elle existe + this.updatePreferredCryptoData(); + + // Charger les nouvelles personnalisées si l'utilisateur a des préférences + if (this.preferredCrypto) { + await this.loadPersonalizedNews(); + } + + // Dessiner le sparkline pour la crypto principale (préférée ou Bitcoin) this.$nextTick(() => { - if (this.bitcoinData?.sparkline_in_7d?.price) { + if (this.mainCryptoData?.sparkline_in_7d?.price) { this.drawSparkline(); } else { - console.warn("⚠️ Pas de données sparkline pour Bitcoin"); + console.warn( + "⚠️ Pas de données sparkline pour la crypto principale" + ); } }); } catch (error) { @@ -797,12 +1041,15 @@ export default { }, drawSparkline() { - if (!this.bitcoinData?.sparkline_in_7d?.price || !this.$refs.bitcoinChart) + if ( + !this.mainCryptoData?.sparkline_in_7d?.price || + !this.$refs.bitcoinChart + ) return; const canvas = this.$refs.bitcoinChart; const ctx = canvas.getContext("2d"); - const prices = this.bitcoinData.sparkline_in_7d.price; + const prices = this.mainCryptoData.sparkline_in_7d.price; // Définir les dimensions du canvas pour qu'il prenne toute la largeur disponible const dpr = window.devicePixelRatio || 1; @@ -831,7 +1078,7 @@ export default { const chartHeight = containerHeight - margin * 2; // Couleur selon la tendance - const isPositive = this.bitcoinData.price_change_percentage_24h >= 0; + const isPositive = this.mainCryptoData.price_change_percentage_24h >= 0; const lineColor = isPositive ? "#22C55E" : "#EF4444"; const gradientColorStart = isPositive ? "rgba(34, 197, 94, 0.4)" @@ -1096,7 +1343,7 @@ export default { this.redrawChart(); // Dessiner le point en surbrillance - const isPositive = this.bitcoinData.price_change_percentage_24h >= 0; + const isPositive = this.mainCryptoData.price_change_percentage_24h >= 0; const lineColor = isPositive ? "#22C55E" : "#EF4444"; ctx.shadowColor = lineColor; @@ -1134,7 +1381,8 @@ export default { if (animationFrame < 20) { this.redrawChart(); - const isPositive = this.bitcoinData.price_change_percentage_24h >= 0; + const isPositive = + this.mainCryptoData.price_change_percentage_24h >= 0; const lineColor = isPositive ? "#22C55E" : "#EF4444"; // Effet de pulsation @@ -1547,6 +1795,7 @@ export default { handleAuthenticated() { this.loadAgentConfig(); + this.loadUserPreferences(); // Charger les préférences après authentification if (this.redirectAfterAuth) { this.$router.push(this.redirectAfterAuth); this.redirectAfterAuth = null; @@ -1630,6 +1879,8 @@ export default { if (this.isAuthenticated) { await this.loadAgentConfig(); await this.loadChatsFromApi(); + // Charger les préférences utilisateur pour la personnalisation + await this.loadUserPreferences(); } // Charger les données crypto @@ -3684,4 +3935,36 @@ export default { width: 100%; } } + +/* Badge de personnalisation */ +.personalization-badge { + font-size: 12px; + color: #fbbf24; + animation: sparkle 2s ease-in-out infinite; + margin-left: 4px; +} + +@keyframes sparkle { + 0%, + 100% { + opacity: 1; + transform: scale(1); + } + 50% { + opacity: 0.7; + transform: scale(1.1); + } +} + +/* Indicateur de personnalisation pour le widget principal */ +.crypto-compact-name .personalization-badge { + font-size: 14px; + margin-left: 6px; +} + +/* Indicateur de personnalisation pour les nouvelles */ +.news-single-header .personalization-badge { + font-size: 10px; + margin-left: 4px; +} diff --git a/crypto-pilot-builder/src/services/cryptoService.js b/crypto-pilot-builder/src/services/cryptoService.js index 144c97c..0cd7d3d 100644 --- a/crypto-pilot-builder/src/services/cryptoService.js +++ b/crypto-pilot-builder/src/services/cryptoService.js @@ -213,7 +213,7 @@ class CryptoService { try { // Utilisation de l'API CryptoCompare pour récupérer de vraies actualités crypto const response = await fetch( - "https://min-api.cryptocompare.com/data/v2/news/?lang=EN&limit=8" + "https://min-api.cryptocompare.com/data/v2/news/?lang=EN&limit=20" ); const data = await response.json(); @@ -227,6 +227,7 @@ class CryptoService { url: article.url, categories: article.categories || "General", lang: article.lang || "EN", + body: article.body || "", })); } @@ -243,23 +244,211 @@ class CryptoService { source: "CoinTelegraph", time: "2h", url: "https://cointelegraph.com/news/bitcoin-reaches-new-all-time-high", + categories: "Bitcoin", + body: "Bitcoin continue sa progression avec de nouveaux records...", }, { title: "Ethereum 2.0 : La mise à jour révolutionnaire", - source: "CryptoNews", + source: "CoinDesk", time: "4h", - url: "https://cryptonews.com/news/ethereum-2-0-revolutionary-update", + url: "https://coindesk.com/news/ethereum-2-0-revolutionary-update", + categories: "Ethereum", + body: "Ethereum lance sa mise à jour majeure...", }, { title: "Nouvelle réglementation DeFi en Europe", source: "DeFi Pulse", time: "6h", url: "https://defipulse.com/blog/new-defi-regulation-europe", + categories: "DeFi", + body: "L'Europe annonce de nouvelles règles pour la DeFi...", }, ]; } } + async getPersonalizedNews(cryptoName) { + try { + console.log("🔍 Recherche de nouvelles personnalisées pour:", cryptoName); + + // Récupérer toutes les nouvelles + const allNews = await this.getCryptoNews(); + + if (!allNews || allNews.length === 0) { + console.log("⚠️ Aucune nouvelle disponible, utilisation du fallback"); + return this.getPersonalizedNewsFallback(cryptoName); + } + + // Créer des mots-clés de recherche pour la crypto + const searchKeywords = this.generateSearchKeywords(cryptoName); + console.log("🔑 Mots-clés de recherche:", searchKeywords); + + // Filtrer les nouvelles par mots-clés + const personalizedNews = allNews.filter((article) => { + const searchText = + `${article.title} ${article.body} ${article.categories}`.toLowerCase(); + return searchKeywords.some((keyword) => + searchText.includes(keyword.toLowerCase()) + ); + }); + + console.log( + `📰 Trouvé ${personalizedNews.length} nouvelles personnalisées sur ${allNews.length} totales` + ); + + // Si pas assez de nouvelles personnalisées, ajouter des nouvelles générales + if (personalizedNews.length < 4) { + const remainingSlots = 4 - personalizedNews.length; + const generalNews = allNews + .filter((article) => !personalizedNews.includes(article)) + .slice(0, remainingSlots); + + personalizedNews.push(...generalNews); + console.log(`➕ Ajouté ${generalNews.length} nouvelles générales`); + } + + // Limiter à 4 nouvelles maximum + return personalizedNews.slice(0, 4); + } catch (error) { + console.error( + "❌ Erreur lors de la récupération des nouvelles personnalisées:", + error + ); + return this.getPersonalizedNewsFallback(cryptoName); + } + } + + generateSearchKeywords(cryptoName) { + // Mapping des noms de crypto vers des mots-clés de recherche + const keywordMapping = { + bitcoin: [ + "bitcoin", + "btc", + "bitcoin price", + "bitcoin news", + "crypto king", + ], + ethereum: [ + "ethereum", + "eth", + "ethereum price", + "ethereum news", + "defi", + "smart contracts", + ], + solana: [ + "solana", + "sol", + "solana price", + "solana news", + "fast blockchain", + ], + cardano: [ + "cardano", + "ada", + "cardano price", + "cardano news", + "proof of stake", + ], + polkadot: [ + "polkadot", + "dot", + "polkadot price", + "polkadot news", + "parachain", + ], + avalanche: [ + "avalanche", + "avax", + "avalanche price", + "avalanche news", + "subnet", + ], + chainlink: [ + "chainlink", + "link", + "chainlink price", + "chainlink news", + "oracle", + ], + ripple: ["ripple", "xrp", "ripple price", "ripple news", "xrp ledger"], + binance: [ + "binance", + "bnb", + "binance coin", + "binance price", + "binance news", + ], + dogecoin: [ + "dogecoin", + "doge", + "dogecoin price", + "dogecoin news", + "meme coin", + ], + }; + + const normalizedName = cryptoName.toLowerCase(); + + // Chercher dans le mapping + for (const [key, keywords] of Object.entries(keywordMapping)) { + if (normalizedName.includes(key) || key.includes(normalizedName)) { + return keywords; + } + } + + // Fallback : utiliser le nom de la crypto et des mots-clés génériques + return [ + cryptoName.toLowerCase(), + cryptoName, + cryptoName.toUpperCase(), + "crypto", + "blockchain", + "digital currency", + ]; + } + + getPersonalizedNewsFallback(cryptoName) { + // Fallback avec des nouvelles simulées si l'API échoue + const cryptoDisplayName = + cryptoName.charAt(0).toUpperCase() + cryptoName.slice(1); + + return [ + { + title: `${cryptoDisplayName} : Nouvelles avancées technologiques et adoption croissante`, + source: "CryptoDaily", + time: "1h", + url: "#", + categories: cryptoDisplayName, + body: `Les dernières nouvelles sur ${cryptoDisplayName} montrent une adoption croissante...`, + }, + { + title: `Développements majeurs pour ${cryptoDisplayName} : Mise à jour du protocole`, + source: "CoinDesk", + time: "3h", + url: "#", + categories: cryptoDisplayName, + body: `${cryptoDisplayName} annonce de nouveaux développements majeurs...`, + }, + { + title: `Analyse technique : ${cryptoDisplayName} en 2024 - Perspectives et tendances`, + source: "The Block", + time: "5h", + url: "#", + categories: cryptoDisplayName, + body: `Analyse approfondie des perspectives pour ${cryptoDisplayName}...`, + }, + { + title: `Écosystème ${cryptoDisplayName} : Nouveaux partenariats et intégrations`, + source: "CryptoNews", + time: "8h", + url: "#", + categories: cryptoDisplayName, + body: `L'écosystème ${cryptoDisplayName} continue de s'étendre...`, + }, + ]; + } + formatTimeAgo(timestamp) { const now = Math.floor(Date.now() / 1000); const diff = now - timestamp; From 719429a8a156c7f086787553292930d6dff59635 Mon Sep 17 00:00:00 2001 From: MiloKow Date: Wed, 20 Aug 2025 17:12:23 +0200 Subject: [PATCH 4/4] :ambulance: [FIX] Putting bento into component --- crypto-pilot-builder/src/acceuil/Accueil.vue | 326 +--------- .../src/components/bento/BentoGrid.vue | 509 +++++++++++++++ .../src/components/bento/CryptoWidget.vue | 137 ++++ .../src/components/bento/MainCryptoWidget.vue | 598 ++++++++++++++++++ .../src/components/bento/NewsWidget.vue | 174 +++++ .../src/components/bento/StatsWidget.vue | 163 +++++ .../src/components/bento/TrendingWidget.vue | 246 +++++++ .../src/components/bento/index.js | 7 + 8 files changed, 1855 insertions(+), 305 deletions(-) create mode 100644 crypto-pilot-builder/src/components/bento/BentoGrid.vue create mode 100644 crypto-pilot-builder/src/components/bento/CryptoWidget.vue create mode 100644 crypto-pilot-builder/src/components/bento/MainCryptoWidget.vue create mode 100644 crypto-pilot-builder/src/components/bento/NewsWidget.vue create mode 100644 crypto-pilot-builder/src/components/bento/StatsWidget.vue create mode 100644 crypto-pilot-builder/src/components/bento/TrendingWidget.vue create mode 100644 crypto-pilot-builder/src/components/bento/index.js diff --git a/crypto-pilot-builder/src/acceuil/Accueil.vue b/crypto-pilot-builder/src/acceuil/Accueil.vue index daf1398..2b165be 100644 --- a/crypto-pilot-builder/src/acceuil/Accueil.vue +++ b/crypto-pilot-builder/src/acceuil/Accueil.vue @@ -99,290 +99,17 @@
-
- -
-
-
-
- -
-

- {{ mainCryptoName }} - -

- {{ - mainCryptoSymbol - }} -
-
-
-
- {{ formatPrice(mainCryptoData?.current_price || 0) }} -
-
- {{ - formatPercentage( - mainCryptoData?.price_change_percentage_24h || 0 - ) - }} -
-
-
-
-
7 jours
- -
-
-
- - -
-
-
- Ethereum - {{ - ethereumData?.symbol?.toUpperCase() || "ETH" - }} -
-
- {{ formatPrice(ethereumData?.current_price || 0) }} -
-
- {{ - formatPercentage( - ethereumData?.price_change_percentage_24h || 0 - ) - }} -
-
-
- - -
-
-
- 🌍 - Market Cap -
-
- {{ formatMarketCap(globalStats?.total_market_cap?.usd || 0) }} -
-
- {{ - formatPercentage( - globalStats?.market_cap_change_percentage_24h_usd || 0 - ) - }} -
-
-
- - -
-
-
- 📈 - Top Gainer -
-
-
- {{ topGainer.symbol?.toUpperCase() }} -
-
- {{ formatPercentage(topGainer.price_change_percentage_24h) }} -
-
-
-
- - -
-
-
-
-
- 📰 - {{ - displayNews[0].source - }} - -
-

{{ displayNews[0].title }}

-
{{ displayNews[0].time }}
-
-
-
- - -
-
-
-
-
- 📰 - {{ - displayNews[1].source - }} - -
-

{{ displayNews[1].title }}

-
{{ displayNews[1].time }}
-
-
-
- - -
-
-
-
-
- 📰 - {{ - displayNews[2].source - }} - -
-

{{ displayNews[2].title }}

-
{{ displayNews[2].time }}
-
-
-
- - -
-
-
-
-
- 📰 - {{ - displayNews[3].source - }} - -
-

{{ displayNews[3].title }}

-
{{ displayNews[3].time }}
-
-
-
- - -
- -
- - -
-
-
- Fear & Greed -
-
-
{{ fearGreedIndex }}
-
{{ fearGreedLabel }}
-
-
-
- - -
-
-
- 💰 - 24h Volume -
-
- {{ formatMarketCap(globalStats?.total_volume?.usd || 0) }} -
-
-
-
+
@@ -466,6 +193,7 @@ import Wallet from "../components/wallet.vue"; import { useSessionManager } from "../composables/useSessionManager.js"; import apiService from "../services/apiService"; import cryptoService from "../services/cryptoService"; +import BentoGrid from "../components/bento/BentoGrid.vue"; export default { name: "Accueil", @@ -473,6 +201,7 @@ export default { AuthModal, Chatbot, Wallet, + BentoGrid, }, setup() { const sessionManager = useSessionManager(); @@ -501,12 +230,6 @@ export default { cryptoNews: [], fearGreedIndex: 75, updateInterval: null, - chartPoints: null, - chartBounds: null, - // Défilement trending - trendingCurrentIndex: 0, - trendingScrollInterval: null, - trendingScrollOffset: 0, // Préférences utilisateur personnalisées userPreferences: null, preferredCrypto: null, @@ -863,16 +586,7 @@ export default { await this.loadPersonalizedNews(); } - // Dessiner le sparkline pour la crypto principale (préférée ou Bitcoin) - this.$nextTick(() => { - if (this.mainCryptoData?.sparkline_in_7d?.price) { - this.drawSparkline(); - } else { - console.warn( - "⚠️ Pas de données sparkline pour la crypto principale" - ); - } - }); + console.log("✅ Données crypto chargées avec succès"); } catch (error) { console.error( "❌ Erreur générale lors du chargement des données crypto:", @@ -1033,11 +747,6 @@ export default { this.fearGreedIndex = 67; console.log("✅ Données de fallback chargées"); - - // Dessiner le sparkline avec les données de fallback - this.$nextTick(() => { - this.drawSparkline(); - }); }, drawSparkline() { @@ -3623,6 +3332,13 @@ export default { backdrop-filter: blur(20px); } +.auth-message { + color: rgba(255, 255, 255, 0.7); + text-align: center; + margin-top: 12px; + font-size: 14px; +} + /* Responsive Design Apple Style */ @media (max-width: 1024px) { .bento-grid { diff --git a/crypto-pilot-builder/src/components/bento/BentoGrid.vue b/crypto-pilot-builder/src/components/bento/BentoGrid.vue new file mode 100644 index 0000000..dcee332 --- /dev/null +++ b/crypto-pilot-builder/src/components/bento/BentoGrid.vue @@ -0,0 +1,509 @@ + + + + + diff --git a/crypto-pilot-builder/src/components/bento/CryptoWidget.vue b/crypto-pilot-builder/src/components/bento/CryptoWidget.vue new file mode 100644 index 0000000..b5455dc --- /dev/null +++ b/crypto-pilot-builder/src/components/bento/CryptoWidget.vue @@ -0,0 +1,137 @@ + + + + + diff --git a/crypto-pilot-builder/src/components/bento/MainCryptoWidget.vue b/crypto-pilot-builder/src/components/bento/MainCryptoWidget.vue new file mode 100644 index 0000000..a27976c --- /dev/null +++ b/crypto-pilot-builder/src/components/bento/MainCryptoWidget.vue @@ -0,0 +1,598 @@ + + + + + diff --git a/crypto-pilot-builder/src/components/bento/NewsWidget.vue b/crypto-pilot-builder/src/components/bento/NewsWidget.vue new file mode 100644 index 0000000..60493d6 --- /dev/null +++ b/crypto-pilot-builder/src/components/bento/NewsWidget.vue @@ -0,0 +1,174 @@ + + + + + diff --git a/crypto-pilot-builder/src/components/bento/StatsWidget.vue b/crypto-pilot-builder/src/components/bento/StatsWidget.vue new file mode 100644 index 0000000..9c50f01 --- /dev/null +++ b/crypto-pilot-builder/src/components/bento/StatsWidget.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/crypto-pilot-builder/src/components/bento/TrendingWidget.vue b/crypto-pilot-builder/src/components/bento/TrendingWidget.vue new file mode 100644 index 0000000..6816efc --- /dev/null +++ b/crypto-pilot-builder/src/components/bento/TrendingWidget.vue @@ -0,0 +1,246 @@ + + + + + diff --git a/crypto-pilot-builder/src/components/bento/index.js b/crypto-pilot-builder/src/components/bento/index.js new file mode 100644 index 0000000..e17beb3 --- /dev/null +++ b/crypto-pilot-builder/src/components/bento/index.js @@ -0,0 +1,7 @@ +// Export de tous les composants Bento +export { default as BentoGrid } from "./BentoGrid.vue"; +export { default as MainCryptoWidget } from "./MainCryptoWidget.vue"; +export { default as NewsWidget } from "./NewsWidget.vue"; +export { default as StatsWidget } from "./StatsWidget.vue"; +export { default as CryptoWidget } from "./CryptoWidget.vue"; +export { default as TrendingWidget } from "./TrendingWidget.vue";