From 967be9e750221ab2ab783f95df79bb26d290a45e Mon Sep 17 00:00:00 2001 From: Martial Simon Date: Mon, 15 Sep 2025 01:07:58 +0200 Subject: add: added projects --- ping/frontend/src/app.css | 58 +++ ping/frontend/src/app.d.ts | 13 + ping/frontend/src/app.html | 13 + ping/frontend/src/lib/components/Avatar.svelte | 48 ++ ping/frontend/src/lib/components/Button.svelte | 17 + ping/frontend/src/lib/components/NavBar.svelte | 44 ++ .../src/lib/components/NumberStatList.svelte | 55 ++ ping/frontend/src/lib/components/SideBar.svelte | 61 +++ .../src/lib/components/SteppedLineChart.svelte | 76 +++ ping/frontend/src/lib/components/ToastList.svelte | 67 +++ ping/frontend/src/lib/components/UserItem.svelte | 42 ++ .../lib/components/dashboard/RiskAnalysis.svelte | 10 + .../src/lib/components/dashboard/StockGraph.svelte | 136 +++++ .../components/dashboard/TrendingSymbols.svelte | 85 +++ .../dashboard/transactions/TransactionModal.svelte | 165 ++++++ .../src/lib/components/input/StockSelector.svelte | 231 +++++++++ .../src/lib/components/input/UserSelector.svelte | 35 ++ ping/frontend/src/lib/pages.ts | 54 ++ ping/frontend/src/lib/stores/auth.ts | 66 +++ ping/frontend/src/lib/stores/toast.ts | 22 + ping/frontend/src/routes/+layout.svelte | 9 + ping/frontend/src/routes/+page.svelte | 59 +++ ping/frontend/src/routes/dashboard/+layout.svelte | 44 ++ ping/frontend/src/routes/dashboard/+page.svelte | 81 +++ .../src/routes/dashboard/analyses/+page.svelte | 409 +++++++++++++++ .../src/routes/dashboard/messages/+page.svelte | 403 +++++++++++++++ .../src/routes/dashboard/models/+page.svelte | 568 +++++++++++++++++++++ .../src/routes/dashboard/personnel/+page.svelte | 290 +++++++++++ .../src/routes/dashboard/settings/+page.svelte | 452 ++++++++++++++++ .../src/routes/dashboard/transactions/+page.svelte | 360 +++++++++++++ ping/frontend/src/routes/login/+page.svelte | 149 ++++++ .../frontend/src/routes/stocksapi/chart/+server.ts | 21 + .../src/routes/stocksapi/insights/+server.ts | 19 + .../frontend/src/routes/stocksapi/quote/+server.ts | 18 + .../src/routes/stocksapi/search/+server.ts | 18 + .../routes/stocksapi/trendingSymbols/+server.ts | 16 + 36 files changed, 4214 insertions(+) create mode 100644 ping/frontend/src/app.css create mode 100644 ping/frontend/src/app.d.ts create mode 100644 ping/frontend/src/app.html create mode 100644 ping/frontend/src/lib/components/Avatar.svelte create mode 100644 ping/frontend/src/lib/components/Button.svelte create mode 100644 ping/frontend/src/lib/components/NavBar.svelte create mode 100644 ping/frontend/src/lib/components/NumberStatList.svelte create mode 100644 ping/frontend/src/lib/components/SideBar.svelte create mode 100644 ping/frontend/src/lib/components/SteppedLineChart.svelte create mode 100644 ping/frontend/src/lib/components/ToastList.svelte create mode 100644 ping/frontend/src/lib/components/UserItem.svelte create mode 100644 ping/frontend/src/lib/components/dashboard/RiskAnalysis.svelte create mode 100644 ping/frontend/src/lib/components/dashboard/StockGraph.svelte create mode 100644 ping/frontend/src/lib/components/dashboard/TrendingSymbols.svelte create mode 100644 ping/frontend/src/lib/components/dashboard/transactions/TransactionModal.svelte create mode 100644 ping/frontend/src/lib/components/input/StockSelector.svelte create mode 100644 ping/frontend/src/lib/components/input/UserSelector.svelte create mode 100644 ping/frontend/src/lib/pages.ts create mode 100644 ping/frontend/src/lib/stores/auth.ts create mode 100644 ping/frontend/src/lib/stores/toast.ts create mode 100644 ping/frontend/src/routes/+layout.svelte create mode 100644 ping/frontend/src/routes/+page.svelte create mode 100644 ping/frontend/src/routes/dashboard/+layout.svelte create mode 100644 ping/frontend/src/routes/dashboard/+page.svelte create mode 100644 ping/frontend/src/routes/dashboard/analyses/+page.svelte create mode 100644 ping/frontend/src/routes/dashboard/messages/+page.svelte create mode 100644 ping/frontend/src/routes/dashboard/models/+page.svelte create mode 100644 ping/frontend/src/routes/dashboard/personnel/+page.svelte create mode 100644 ping/frontend/src/routes/dashboard/settings/+page.svelte create mode 100644 ping/frontend/src/routes/dashboard/transactions/+page.svelte create mode 100644 ping/frontend/src/routes/login/+page.svelte create mode 100644 ping/frontend/src/routes/stocksapi/chart/+server.ts create mode 100644 ping/frontend/src/routes/stocksapi/insights/+server.ts create mode 100644 ping/frontend/src/routes/stocksapi/quote/+server.ts create mode 100644 ping/frontend/src/routes/stocksapi/search/+server.ts create mode 100644 ping/frontend/src/routes/stocksapi/trendingSymbols/+server.ts (limited to 'ping/frontend/src') diff --git a/ping/frontend/src/app.css b/ping/frontend/src/app.css new file mode 100644 index 0000000..42e2b32 --- /dev/null +++ b/ping/frontend/src/app.css @@ -0,0 +1,58 @@ +@import 'tailwindcss'; +@plugin '@tailwindcss/forms'; +@plugin '@tailwindcss/typography'; + +:root { + --bg-primary: #1A1C22; + --bg-secondary: #282C35; + --btn-primary: #343844; + --btn-primary-hover: #2d8f3a; + --btn-secondary: #454b5a; + --text-lime: #00FF77; +} + +body { + background-color: var(--bg-secondary); +} + +input,select,textarea { + background-color: var(--bg-secondary); + border:none; + border-bottom: 2px solid var(--text-lime); + padding: 8px; + border-radius: 8px 8px 0 0; +} + +input[type="checkbox"], +input[type="radio"] { + accent-color: var(--text-lime); + border-radius: 8px; + border:none; +} + +.btn { + background-color: var(--btn-primary); + color: white; + border: none; + padding: 8px 16px; + border-radius: 4px; + cursor: pointer; + text-decoration: none; + transition-duration: 0.2s; + font-weight: 600; +} + +.btn:hover { + background-color: var(--btn-primary-hover); + transform: scale(1.025); +} + +.card { + background-color: var(--bg-primary); + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + padding: 16px; + margin: 16px; + color: white; + width: 100%; +} \ No newline at end of file diff --git a/ping/frontend/src/app.d.ts b/ping/frontend/src/app.d.ts new file mode 100644 index 0000000..da08e6d --- /dev/null +++ b/ping/frontend/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://svelte.dev/docs/kit/types#app.d.ts +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/ping/frontend/src/app.html b/ping/frontend/src/app.html new file mode 100644 index 0000000..e37ecf4 --- /dev/null +++ b/ping/frontend/src/app.html @@ -0,0 +1,13 @@ + + + + + + Patapimvest + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/ping/frontend/src/lib/components/Avatar.svelte b/ping/frontend/src/lib/components/Avatar.svelte new file mode 100644 index 0000000..c04b563 --- /dev/null +++ b/ping/frontend/src/lib/components/Avatar.svelte @@ -0,0 +1,48 @@ + + + +
+ + (showTooltip = true)} + onmouseleave={() => (showTooltip = false)} + {onclick} + alt="User Avatar" + /> + {#if showTooltip} +
{username}
+ {/if} +
+ + diff --git a/ping/frontend/src/lib/components/Button.svelte b/ping/frontend/src/lib/components/Button.svelte new file mode 100644 index 0000000..54b26ab --- /dev/null +++ b/ping/frontend/src/lib/components/Button.svelte @@ -0,0 +1,17 @@ + + +{#if href} + {@render children?.()} +{:else} + +{/if} diff --git a/ping/frontend/src/lib/components/NavBar.svelte b/ping/frontend/src/lib/components/NavBar.svelte new file mode 100644 index 0000000..1a76876 --- /dev/null +++ b/ping/frontend/src/lib/components/NavBar.svelte @@ -0,0 +1,44 @@ + + + + + diff --git a/ping/frontend/src/lib/components/NumberStatList.svelte b/ping/frontend/src/lib/components/NumberStatList.svelte new file mode 100644 index 0000000..b6444e8 --- /dev/null +++ b/ping/frontend/src/lib/components/NumberStatList.svelte @@ -0,0 +1,55 @@ + + +
+ {#each statsList as stat} +
+ + {stat.name} + {stat.value} +
+ {/each} +
+ + diff --git a/ping/frontend/src/lib/components/SideBar.svelte b/ping/frontend/src/lib/components/SideBar.svelte new file mode 100644 index 0000000..9ea8a04 --- /dev/null +++ b/ping/frontend/src/lib/components/SideBar.svelte @@ -0,0 +1,61 @@ + + + + + diff --git a/ping/frontend/src/lib/components/SteppedLineChart.svelte b/ping/frontend/src/lib/components/SteppedLineChart.svelte new file mode 100644 index 0000000..d393b44 --- /dev/null +++ b/ping/frontend/src/lib/components/SteppedLineChart.svelte @@ -0,0 +1,76 @@ + + +
+ +
diff --git a/ping/frontend/src/lib/components/ToastList.svelte b/ping/frontend/src/lib/components/ToastList.svelte new file mode 100644 index 0000000..5351ef7 --- /dev/null +++ b/ping/frontend/src/lib/components/ToastList.svelte @@ -0,0 +1,67 @@ + + +
+ {#each $toastList as toast} +
+

{toast.title}

+

{toast.message}

+
+ {/each} +
+ + diff --git a/ping/frontend/src/lib/components/UserItem.svelte b/ping/frontend/src/lib/components/UserItem.svelte new file mode 100644 index 0000000..44add60 --- /dev/null +++ b/ping/frontend/src/lib/components/UserItem.svelte @@ -0,0 +1,42 @@ + + +
+
+ + + +
+
+

Nom: {user.displayName}

+

Login: {user.login}

+

Role: {user.isAdmin ? 'ADMIN' : 'USER'}

+

Id: {user.id}

+
+
+ + diff --git a/ping/frontend/src/lib/components/dashboard/RiskAnalysis.svelte b/ping/frontend/src/lib/components/dashboard/RiskAnalysis.svelte new file mode 100644 index 0000000..3844abc --- /dev/null +++ b/ping/frontend/src/lib/components/dashboard/RiskAnalysis.svelte @@ -0,0 +1,10 @@ +

Analyse de risque

+tkt t safe c hardcodé chef + + diff --git a/ping/frontend/src/lib/components/dashboard/StockGraph.svelte b/ping/frontend/src/lib/components/dashboard/StockGraph.svelte new file mode 100644 index 0000000..beefed9 --- /dev/null +++ b/ping/frontend/src/lib/components/dashboard/StockGraph.svelte @@ -0,0 +1,136 @@ + + +
+
+

Vue d'ensemble : {selectedStock}

+
+ + + + + +
+
+ +
+ + diff --git a/ping/frontend/src/lib/components/dashboard/TrendingSymbols.svelte b/ping/frontend/src/lib/components/dashboard/TrendingSymbols.svelte new file mode 100644 index 0000000..3d947ad --- /dev/null +++ b/ping/frontend/src/lib/components/dashboard/TrendingSymbols.svelte @@ -0,0 +1,85 @@ + + +

Tendances

+ + + diff --git a/ping/frontend/src/lib/components/dashboard/transactions/TransactionModal.svelte b/ping/frontend/src/lib/components/dashboard/transactions/TransactionModal.svelte new file mode 100644 index 0000000..b9f0224 --- /dev/null +++ b/ping/frontend/src/lib/components/dashboard/transactions/TransactionModal.svelte @@ -0,0 +1,165 @@ + + + + +{#if isOpen} +
+ e.stopPropagation()}> +

Créer une nouvelle transaction

+
+ + + + + + + +
+
+
+{/if} + + diff --git a/ping/frontend/src/lib/components/input/StockSelector.svelte b/ping/frontend/src/lib/components/input/StockSelector.svelte new file mode 100644 index 0000000..1237128 --- /dev/null +++ b/ping/frontend/src/lib/components/input/StockSelector.svelte @@ -0,0 +1,231 @@ + + + + + +
+ + +
+
+
+ {#if stocks.length === 0} +

Aucune action, ETFs trouvés.

+ {:else} +

{stocks.length} actions, ETFs trouvés

+ {#each stocks as stock} + + {/each} + {/if} +
+
+ {#if news.length === 0} +

Pas de news trouvés.

+ {:else} +

{news.length} news trouvées

+ {#each news as newsItem} + + {#if newsItem.thumbnail?.resolutions?.length > 0} + News Thumbnail + {/if} +

{newsItem.title}

+ {/each} + {/if} +
+
+
+ + +
+ + diff --git a/ping/frontend/src/lib/components/input/UserSelector.svelte b/ping/frontend/src/lib/components/input/UserSelector.svelte new file mode 100644 index 0000000..a0c80c7 --- /dev/null +++ b/ping/frontend/src/lib/components/input/UserSelector.svelte @@ -0,0 +1,35 @@ + + +
+ {#each users as u, i} + { + users = users.filter((_, index) => index !== i); + }} + /> + {/each} + { + let userId = prompt("Entrez l'ID de l'utilisateur à ajouter :"); + if (userId === null || userId.trim() === '') { + addToast({ title: 'ID utilisateur invalide.' }); + return; + } + if (users.map((u) => u.displayName).includes(userId)) { + addToast({ title: 'Cet utilisateur est déjà ajouté.' }); + return; + } + users = [...users, { displayName: userId, avatar: '/img/default-avatar.png' } as IUser]; + }} + /> +
diff --git a/ping/frontend/src/lib/pages.ts b/ping/frontend/src/lib/pages.ts new file mode 100644 index 0000000..e5d424e --- /dev/null +++ b/ping/frontend/src/lib/pages.ts @@ -0,0 +1,54 @@ +interface SideBarItem { + icon: string; + name: string; + href: string; +} + +export const pages: SideBarItem[] = [ + { + name: 'Dashboard', + icon: '/icons/dashboard.svg', + href: '/dashboard' + }, + { + name: 'Transactions', + icon: '/icons/credit-card.svg', + href: '/dashboard/transactions' + }, + { + name: 'Modèles', + icon: '/icons/floppy-disk.svg', + href: '/dashboard/models' + }, + { + name: 'Analyses', + icon: '/icons/magnifying_glass_icon.svg', + href: '/dashboard/analyses' + }, + { + name: 'Personnel', + icon: '/icons/people.svg', + href: '/dashboard/personnel' + }, + { + name: 'Messages', + icon: '/icons/msg.svg', + href: '/dashboard/messages' + }, + { + name: 'Paramètres', + icon: '/icons/settings.svg', + href: '/dashboard/settings' + } +]; + +export function getPageIndex(pathname: string) { + if (pathname === '/dashboard') return 0; + if (pathname.startsWith('/dashboard/transactions')) return 1; + if (pathname.startsWith('/dashboard/models')) return 2; + if (pathname.startsWith('/dashboard/analyses')) return 3; + if (pathname.startsWith('/dashboard/personnel')) return 4; + if (pathname.startsWith('/dashboard/messages')) return 5; + if (pathname.startsWith('/dashboard/settings')) return 6; + return -1; // Not found +} \ No newline at end of file diff --git a/ping/frontend/src/lib/stores/auth.ts b/ping/frontend/src/lib/stores/auth.ts new file mode 100644 index 0000000..97acaf2 --- /dev/null +++ b/ping/frontend/src/lib/stores/auth.ts @@ -0,0 +1,66 @@ +import { error } from "@sveltejs/kit"; +import { get, writable } from "svelte/store"; + +export interface IUser { + id: string; + login: string; + displayName: string; + avatar: string; + isAdmin: boolean; +} + +export const user = writable(null); + +export async function getUser() { + const userVal = get(user); + if (userVal) { + return userVal; + } + return getUpdatedUser(); +} + +export async function getUpdatedUser() { + const token = localStorage.getItem("token"); + if (!token) { + localStorage.clear(); + window.location.replace("/login"); + throw new Error("Pas de token"); + } + try { + const userId = JSON.parse(atob(token.split(".")[1])).sub; + + const res = await authFetch(`/api/user/${userId}`); + if (!res.ok) { + throw error(res.status, "Erreur lors de la récupération de l'utilisateur"); + } + const data = await res.json(); + user.set({ ...data }); + return data; + } + catch (e) { + console.error("Erreur lors de la récupération de l'ID utilisateur depuis le token", e); + localStorage.clear(); + window.location.replace("/login"); + throw new Error("Token invalide " + e); + } +} + +// place files you want to import through the `$lib` alias in this folder. +export function authFetch(url: string | URL, options: RequestInit = {}) { + const token = localStorage.getItem("token"); + if (!token) { + localStorage.clear(); + window.location.replace("/login"); + throw new Error("Pas de token"); + } + + const mergedOptions: RequestInit = { + ...options, + headers: { + Authorization: `Bearer ${token}`, + ...(options.headers ?? {}) + } + }; + + return fetch(url, mergedOptions); +} \ No newline at end of file diff --git a/ping/frontend/src/lib/stores/toast.ts b/ping/frontend/src/lib/stores/toast.ts new file mode 100644 index 0000000..454461b --- /dev/null +++ b/ping/frontend/src/lib/stores/toast.ts @@ -0,0 +1,22 @@ +import { writable } from "svelte/store"; + +export interface Toast { + color?: string | undefined; + title?: string | undefined; + message?: string | undefined; +} + +export const toastList = writable([]); + +export function addToast(toast: Toast) { + toast ??= { color: "red", title: "Error", message: "An error occurred" }; + toast.color ??= "red"; + toast.title ??= "Error"; + toast.message ??= "An error occurred"; + + toastList.update((list) => [...list, toast]); + + setTimeout(() => { + toastList.update((list) => list.filter((t) => t !== toast)); + }, 5000); +} \ No newline at end of file diff --git a/ping/frontend/src/routes/+layout.svelte b/ping/frontend/src/routes/+layout.svelte new file mode 100644 index 0000000..ba995cc --- /dev/null +++ b/ping/frontend/src/routes/+layout.svelte @@ -0,0 +1,9 @@ + + +{@render children()} + diff --git a/ping/frontend/src/routes/+page.svelte b/ping/frontend/src/routes/+page.svelte new file mode 100644 index 0000000..7088945 --- /dev/null +++ b/ping/frontend/src/routes/+page.svelte @@ -0,0 +1,59 @@ + + + + + {#snippet rightComponent()} + + {/snippet} + +
+
+
+
+

Investissons plus mieux et plus vert

+
    +
  • Investissez facilement
  • +
  • Analysez les risques et les performances
  • +
  • Soulagez votre éco-conscience
  • +
+
+
+ + diff --git a/ping/frontend/src/routes/dashboard/+layout.svelte b/ping/frontend/src/routes/dashboard/+layout.svelte new file mode 100644 index 0000000..a2f7efe --- /dev/null +++ b/ping/frontend/src/routes/dashboard/+layout.svelte @@ -0,0 +1,44 @@ + + + + + {#snippet rightComponent()} +
+
+ +
+ +
+ {/snippet} +
+ +
{@render children()}
+ + diff --git a/ping/frontend/src/routes/dashboard/+page.svelte b/ping/frontend/src/routes/dashboard/+page.svelte new file mode 100644 index 0000000..c38e281 --- /dev/null +++ b/ping/frontend/src/routes/dashboard/+page.svelte @@ -0,0 +1,81 @@ + + +
+ +
+
+ +
+ + +
+ +
+ +
+
+ + diff --git a/ping/frontend/src/routes/dashboard/analyses/+page.svelte b/ping/frontend/src/routes/dashboard/analyses/+page.svelte new file mode 100644 index 0000000..1a8ed47 --- /dev/null +++ b/ping/frontend/src/routes/dashboard/analyses/+page.svelte @@ -0,0 +1,409 @@ + + +
+
+

Analyses des Transactions

+
+ + +
+
+ + + + {#if analysisData.thresholdAlerts} +
+ {#if analysisData.thresholdAlerts.dailySpending} +
+ ⚠️ Dépenses quotidiennes élevées ({(Math.abs(analysisData.totalAmount) / selectedPeriod).toFixed(0)}€/jour) +
+ {/if} + {#if analysisData.thresholdAlerts.co2Impact} +
+ 🌍 Impact CO2 élevé ({analysisData.totalCO2}g) +
+ {/if} + {#if analysisData.thresholdAlerts.profitTarget} +
+ 🎯 Objectif de profit atteint ({analysisData.totalAmount.toFixed(0)}€) +
+ {/if} +
+ {/if} + +
+
+

Transactions dans le temps

+ {#if analysisData.chartData?.length > 0} + + {:else} +

Aucune donnée

+ {/if} +
+ +
+

Top destinataires

+
+ {#each (analysisData.recipientChartData || []).slice(0, 5) as recipient} +
+ {recipient.x} +
+ {#if analysisData.recipientChartData?.length > 0} + {@const maxValue = Math.max(...analysisData.recipientChartData.map(r => r.y))} +
+ {:else} +
+ {/if} + {recipient.y.toFixed(0)}€ +
+
+ {/each} +
+
+ +
+

Répartition des transactions

+
+
+ Achats: + + {(analysisData.filteredTransactions || []).filter((t: Transaction) => t.type === 'buy').length} + +
+
+ Ventes: + + {(analysisData.filteredTransactions || []).filter((t: Transaction) => t.type === 'sell').length} + +
+
+ Volume total: + + {Math.abs(analysisData.totalAmount || 0).toFixed(0)}€ + +
+
+
+ +
+

Métriques CO2

+
+
+ Impact total: + + {analysisData.totalCO2 || 0}g CO2 + +
+
+ Par transaction: + + {(analysisData.filteredTransactions?.length ? analysisData.totalCO2 / analysisData.filteredTransactions.length : 0).toFixed(1)}g + +
+
+
+
+
+ + diff --git a/ping/frontend/src/routes/dashboard/messages/+page.svelte b/ping/frontend/src/routes/dashboard/messages/+page.svelte new file mode 100644 index 0000000..52869e4 --- /dev/null +++ b/ping/frontend/src/routes/dashboard/messages/+page.svelte @@ -0,0 +1,403 @@ + + +
+
+ +
+

Messages

+ +
+ +
+ +
+

Boîte de réception

+
+ {#each messages as message} +
selectMessage(message)} + > +
+ {message.sender} + {message.date.toLocaleDateString()} +
+
{message.subject}
+
{message.content.substring(0, 80)}...
+ {#if message.unread} +
+ {/if} +
+ {/each} +
+
+ + +
+ {#if selectedMessage} +
+

{selectedMessage.subject}

+
+ +
+
+
+ De: {selectedMessage.sender} + Date: {selectedMessage.date.toLocaleDateString()} +
+
+ {selectedMessage.content} +
+ + +
+

Répondre

+ + +
+ {:else} +
+

Sélectionnez un message

+

Choisissez un message dans la liste pour le lire

+
+ {/if} +
+
+
+
+ + diff --git a/ping/frontend/src/routes/dashboard/models/+page.svelte b/ping/frontend/src/routes/dashboard/models/+page.svelte new file mode 100644 index 0000000..3be6f00 --- /dev/null +++ b/ping/frontend/src/routes/dashboard/models/+page.svelte @@ -0,0 +1,568 @@ + + +
+
+
+

Modèles actifs

+
+ {#each models as m, i} +
+
+ {m.name}
+ {m.id} +
+
+
+ Eco score + {69} % +
+
+ Efficacité + {69} % +
+
+ + +
+ {/each} +
+
+ +
+
+
+ {#if modelToEdit !== null} +

Modifier un modèle

+ {:else} +

Nouveau modèle

+ {/if} + +
+
+ + +
+ {#if modelToEdit !== null} + + {:else if currentUser} + + {:else} + Chargement en cours... + {/if} + +
+
+ +
+
+ Sources de données + +
+ + {#each sources as source, index} +
+ + +
+ + +
+
+ {/each} +
+
+
+
+
+ + diff --git a/ping/frontend/src/routes/dashboard/personnel/+page.svelte b/ping/frontend/src/routes/dashboard/personnel/+page.svelte new file mode 100644 index 0000000..a1722c1 --- /dev/null +++ b/ping/frontend/src/routes/dashboard/personnel/+page.svelte @@ -0,0 +1,290 @@ + + +{#if user} +
+
+
+

Mon compte

+ +

Nom: {user.displayName}

+

Login: {user.login}

+

Role: {user.isAdmin ? 'ADMIN' : 'USER'}

+

Id: {user.id}

+
+
+

Modifier

+ Laisser vide pour ne pas modifier
+ {#if user.isAdmin} +

Vous pouvez modifier les informations de n'importe quel utilisateur.

+ {:else} +

Vous ne pouvez modifier que vos propres informations.

+ {/if} +

+
+ {#if user.isAdmin} + + + {/if} + + + + + + + +
+
+
+ + {#if user.isAdmin} +
+
+

Créer un nouvel utilisateur

+
+ + + + + + + + + +
+
+
+

Liste des utilisateurs

+
+ {#each allUsers as u} + { + idValue = u.id; + urlValue = u.avatar || ''; + nameValue = u.displayName || ''; + }} + onDelete={() => { + authFetch(`/api/user/${u.id}`, { + method: 'DELETE' + }) + .then(async (res) => { + if (!res.ok) { + addToast({ + title: 'Erreur', + message: "Impossible de supprimer l'utilisateur." + }); + throw new Error("Erreur lors de la suppression de l'utilisateur"); + } + allUsers = allUsers.filter((user) => user.id !== u.id); + addToast({ + title: 'Succès', + message: 'Utilisateur supprimé avec succès.', + color: 'green' + }); + }) + .catch(() => { + addToast({ + title: 'Erreur', + message: "Impossible de supprimer l'utilisateur." + }); + }); + }} + /> + {/each} +
+
+
+ {/if} +
+{:else} +

Chargement des informations utilisateur...

+{/if} + + diff --git a/ping/frontend/src/routes/dashboard/settings/+page.svelte b/ping/frontend/src/routes/dashboard/settings/+page.svelte new file mode 100644 index 0000000..99c5d8f --- /dev/null +++ b/ping/frontend/src/routes/dashboard/settings/+page.svelte @@ -0,0 +1,452 @@ + + +
+
+
+

Paramètres

+
+ +
+
+

👤 Profil utilisateur

+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ +
+
+ +
+

🔔 Notifications

+
+
+ + + + + +
+ +
+
+ +
+

🔒 Sécurité

+
+
+ +
+
+ + +
+
+ +
+ +
+ +
+

Changer le mot de passe

+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ +
+

🎨 Affichage

+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ +
+
+ +
+

📊 Gestion des données

+
+
+
+

Exporter mes données

+

Téléchargez toutes vos données personnelles dans un fichier JSON

+
+ +
+
+
+

Supprimer mon compte

+

Supprimez définitivement votre compte et toutes vos données

+
+ +
+
+
+
+
+
+ + diff --git a/ping/frontend/src/routes/dashboard/transactions/+page.svelte b/ping/frontend/src/routes/dashboard/transactions/+page.svelte new file mode 100644 index 0000000..86f9292 --- /dev/null +++ b/ping/frontend/src/routes/dashboard/transactions/+page.svelte @@ -0,0 +1,360 @@ + + +
+
+
+

Transactions

+ +
+ +
+
+ Trier +
+ + +
+
+
+ + +
+
+ +
+ {#each visibleTransactions as transaction} +
+
+
+

{transaction.label}

+

+ {transaction.receiverIban} • {transaction.receiverLabel} +

+
+
+
+ CO2 + {transaction.eco_score} +
+
+ {transaction.currency} + {transaction.amount} +
+
+ +
+
+ {/each} +
+
+
+ + + diff --git a/ping/frontend/src/routes/login/+page.svelte b/ping/frontend/src/routes/login/+page.svelte new file mode 100644 index 0000000..0d66f8d --- /dev/null +++ b/ping/frontend/src/routes/login/+page.svelte @@ -0,0 +1,149 @@ + + +
+
+

Connectez-vous

+
+ + + + + +
+
+
+ + + diff --git a/ping/frontend/src/routes/stocksapi/chart/+server.ts b/ping/frontend/src/routes/stocksapi/chart/+server.ts new file mode 100644 index 0000000..3271e83 --- /dev/null +++ b/ping/frontend/src/routes/stocksapi/chart/+server.ts @@ -0,0 +1,21 @@ +import type { RequestHandler } from '@sveltejs/kit'; +import yahooFinance from 'yahoo-finance2'; + +/** + * Example request : GET /stocksapi/chart?query=AAPL&startDate=2025-01-01& + */ +export const GET: RequestHandler = async ({ request }) => { + const sp = new URL(request.url).searchParams; + const query = sp.get('query') || 'AAPL'; + const startDate = sp.get('startDate') || '2025-01-01'; + const endDate = sp.get('endDate') || new Date().toISOString().split('T')[0]; + const interval = sp.get('interval') || '1d'; + + const data = await yahooFinance.chart(query, { period1: startDate, period2: endDate, interval: interval }); + return new Response(JSON.stringify(data), { + headers: { + 'Content-Type': 'application/json', + 'Cache-Control': 'no-cache', + }, + }); +}; \ No newline at end of file diff --git a/ping/frontend/src/routes/stocksapi/insights/+server.ts b/ping/frontend/src/routes/stocksapi/insights/+server.ts new file mode 100644 index 0000000..6be76e9 --- /dev/null +++ b/ping/frontend/src/routes/stocksapi/insights/+server.ts @@ -0,0 +1,19 @@ +import type { RequestHandler } from '@sveltejs/kit'; +import yahooFinance from 'yahoo-finance2'; + +/** + * Example request : GET /stocksapi/insights?query=AAPL + */ +export const GET: RequestHandler = async ({ request }) => { + const sp = new URL(request.url).searchParams; + const query = sp.get('query') || 'AAPL'; + + const queryOptions = { lang: 'en-US', reportsCount: 2, region: 'US' }; + const data = await yahooFinance.insights(query, queryOptions); + return new Response(JSON.stringify(data), { + headers: { + 'Content-Type': 'application/json', + 'Cache-Control': 'no-cache', + }, + }); +}; \ No newline at end of file diff --git a/ping/frontend/src/routes/stocksapi/quote/+server.ts b/ping/frontend/src/routes/stocksapi/quote/+server.ts new file mode 100644 index 0000000..96619fc --- /dev/null +++ b/ping/frontend/src/routes/stocksapi/quote/+server.ts @@ -0,0 +1,18 @@ +import type { RequestHandler } from '@sveltejs/kit'; +import yahooFinance from 'yahoo-finance2'; + +/** + * Example request : GET /stocksapi/quote?query=AAPL + */ +export const GET: RequestHandler = async ({ request }) => { + const sp = new URL(request.url).searchParams; + const query = sp.get('query') || 'AAPL'; + + const data = await yahooFinance.quote(query); + return new Response(JSON.stringify(data), { + headers: { + 'Content-Type': 'application/json', + 'Cache-Control': 'no-cache', + }, + }); +}; \ No newline at end of file diff --git a/ping/frontend/src/routes/stocksapi/search/+server.ts b/ping/frontend/src/routes/stocksapi/search/+server.ts new file mode 100644 index 0000000..e58fc6b --- /dev/null +++ b/ping/frontend/src/routes/stocksapi/search/+server.ts @@ -0,0 +1,18 @@ +import type { RequestHandler } from '@sveltejs/kit'; +import yahooFinance from 'yahoo-finance2'; + +/** + * Example request : GET /stocksapi/search?query=AAPL + */ +export const GET: RequestHandler = async ({ request }) => { + const sp = new URL(request.url).searchParams; + const query = sp.get('query') || 'AAPL'; + + const data = await yahooFinance.search(query, { region: 'US' }) + return new Response(JSON.stringify(data), { + headers: { + 'Content-Type': 'application/json', + 'Cache-Control': 'no-cache', + }, + }); +}; \ No newline at end of file diff --git a/ping/frontend/src/routes/stocksapi/trendingSymbols/+server.ts b/ping/frontend/src/routes/stocksapi/trendingSymbols/+server.ts new file mode 100644 index 0000000..3dac574 --- /dev/null +++ b/ping/frontend/src/routes/stocksapi/trendingSymbols/+server.ts @@ -0,0 +1,16 @@ +import type { RequestHandler } from '@sveltejs/kit'; +import yahooFinance from 'yahoo-finance2'; + +/** + * Example request : GET /stocksapi/trendingSymbols + */ +export const GET: RequestHandler = async () => { + const queryOptions = { count: 5, lang: 'en-US' }; + const data = await yahooFinance.trendingSymbols('US', queryOptions); + return new Response(JSON.stringify(data), { + headers: { + 'Content-Type': 'application/json', + 'Cache-Control': 'no-cache', + }, + }); +}; \ No newline at end of file -- cgit v1.2.3