Extrait de Code
Extrait de Code
<div class="container">
<div style="text-align: center;">
<h1 class="page-title" style="color: green;">
<BookOpen class="icon" />
Recherche de Comptes par Prix
</h1>
</div>
<button type="submit">Rechercher</button>
</form>
</table>
<script setup>
import { ref, watch } from 'vue'
import { BookOpen } from 'lucide-vue-next'
import { useRoute } from 'vue-router'
import axios from 'axios'
import { getToken } from '../services/Token'
[Link] = [Link]['@[Link]'] || 0
[Link] = [Link]([Link] / pageSize)
const lignes = [Link] || []
if (journalId) {
const journalRes = await [Link](`${JOURNAL_ENDPOINT}/${journalId}`, {
headers: { Authorization: `Bearer ${token}` },
})
const journal = [Link]
reference = journal?.DocumentNo || reference
journalCode = journal?.DocumentStatus || 'OD'
}
} catch (err) {
[Link]('Erreur récupération journal:', [Link])
}
}
return {
id: [Link], // ID réel de Fact_Acct
journalId,
date: [Link],
reference,
journal: journalCode,
compte: ligne.Account_ID?.Value || '',
compteNom,
description: [Link] || '',
debit: Number([Link] || 0),
credit: Number([Link] || 0),
editing: false,
recordId: ligne.Record_ID, // 👈 Clé importante ici
}
})
)
[Link]((item) => {
const montant = [Link]([Link], [Link])
if (typeMontant === 'debit' && (prixMin === null || [Link] >= prixMin) && (prixMax === null || [Link] <=
prixMax)) {
[Link]([Link])
} else if (typeMontant === 'credit' && (prixMin === null || [Link] >= prixMin) && (prixMax === null || [Link]
<= prixMax)) {
[Link]([Link])
} else if (typeMontant === 'both' && (prixMin === null || montant >= prixMin) && (prixMax === null || montant <=
prixMax)) {
[Link]([Link])
}
})
if (libelle) {
const recherche = [Link]()
return [Link](
(item) =>
[Link]?.toLowerCase().includes(recherche) ||
[Link]?.toLowerCase().includes(recherche) ||
[Link]?.toLowerCase().includes(recherche) ||
[Link]?.toLowerCase().includes(recherche)
)
}
return lignesFiltrees
} catch (err) {
[Link]('Erreur chargement grand livre:', [Link]?.data || [Link])
throw new Error('Echec du chargement du grand livre')
}
}
} catch {
alert('Erreur lors du chargement des données')
}
[Link] = true
}
function pageSuivante() {
if ([Link] < [Link]) {
[Link]++
}
}
function pagePrecedente() {
if ([Link] > 1) {
[Link]--
}
}
function modifierLigne(index) {
[Link][index].editing = true
}
function annulerEdition(index) {
[Link][index].editing = false
chargerDonnees()
}
try {
[Link]('Enregistrement ligne:', ligne);
if ([Link] == null) {
throw new Error("recordId manquant ou invalide — impossible de mettre à jour.")
}
await [Link](`${FACT_ACCT_ENDPOINT}/${[Link]}`, {
headers: { Authorization: `Bearer ${token}` }
});
const factAcctPayload = {
DateAcct: [Link],
DateTrx: [Link],
Account_ID: { identifier: [Link] },
AmtAcctDr: parseFloat([Link] || 0),
AmtAcctCr: parseFloat([Link] || 0),
Description: [Link],
AD_Client_ID: 11,
AD_Org_ID: 11,
IsActive: 'Y',
C_Period_ID: 155,
C_AcctSchema_ID: 101,
AD_Table_ID: 224,
Record_ID: [Link], // Utilisation de recordId pour la mise à jour
PostingType: 'A',
C_Currency_ID: 108
};
[Link]("Envoi de la requête PUT avec payload:", factAcctPayload);
[Link] = false
alert('Montant mis à jour avec succès.')
} catch (err) {
[Link]('Erreur mise à jour :', [Link]?.data || [Link])
alert('Erreur lors de la mise à jour : ' + ([Link]?.data?.detail || [Link]))
}
}
watch(page, chargerDonnees)
</script>
<style scoped>
.container {
max-width: 900px;
margin: 2rem auto;
font-family: Arial, sans-serif;
color: #222;
}
.page-title {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.8rem;
margin-bottom: 1rem;
}
.icon {
width: 1.5rem;
height: 1.5rem;
color: #3182ce;
}
.filter-form {
display: flex;
flex-wrap: wrap;
gap: 1rem;
justify-content: center;
margin-bottom: 1rem;
}
.filter-form label {
font-weight: 600;
font-size: 1rem;
display: flex;
flex-direction: column;
color: #4a5568;
}
.filter-form input {
padding: 0.3rem 0.5rem;
border: 1px solid #cbd5e0;
border-radius: 4px;
margin-top: 0.3rem;
}
.filter-form button {
padding: 0.4rem 1.2rem;
background-color: #2b6cb0;
border: none;
color: white;
border-radius: 4px;
font-weight: 600;
cursor: pointer;
}
.filter-form button:hover {
background-color: #2c5282;
}
.ledger-table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
}
.ledger-table th,
.ledger-table td {
padding: 0.5rem;
border: 1px solid #e2e8f0;
text-align: center;
}
.ledger-table th {
background-color: #f7fafc;
font-weight: bold;
}
.pagination {
margin-top: 1rem;
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
}
.pagination button {
padding: 0.3rem 0.8rem;
font-weight: 600;
border-radius: 4px;
border: 1px solid #2b6cb0;
background-color: white;
color: #2b6cb0;
cursor: pointer;
}
.pagination button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
</style>
try {
if (!ligne.Record_ID) {
throw new Error("recordId manquant ou invalide — impossible de mettre à jour.")
}
const factAcctPayload = {
DateAcct: date,
DateTrx: date,
Account_ID: { identifier: [Link] },
AmtAcctDr: parseFloat([Link] || 0),
AmtAcctCr: parseFloat([Link] || 0),
Description: [Link],
AD_Client_ID: 11,
AD_Org_ID: 11,
IsActive: 'Y',
C_Period_ID: 155,
C_AcctSchema_ID: 101,
AD_Table_ID: 224,
Record_ID: journalId,
PostingType: 'A',
C_Currency_ID: 108
};
await [Link](`${FACT_ACCT_ENDPOINT}/${[Link]}`, {
factAcctPayload
}, {
headers: {
Authorization: `Bearer ${token}`,
},
})
[Link] = false
alert('Montant mis à jour avec succès.')
} catch (err) {
[Link]('Erreur mise à jour :', [Link]?.data || [Link])
alert('Erreur lors de la mise à jour : ' + ([Link]?.data?.detail || [Link]))
}
}
<template>
<div class="container">
<center>
<h1 class="page-title" style="color: green;">
<BookOpen class="icon" />
Recherche de Comptes par Prix
</h1>
</center>
<button type="submit">Rechercher</button>
</form>
<table v-if="[Link]" class="ledger-table">
<thead>
<tr>
<th>Date</th>
<th>Référence</th>
<th>Journal</th>
<th>Compte</th>
<th>Débit</th>
<th>Crédit</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-for="(ligne, index) in donnees" :key="index">
<td>{{ new Date([Link]).toLocaleDateString() }}</td>
<td>{{ [Link] }}</td>
<td>{{ [Link] }}</td>
<td>{{ [Link] }}</td>
<td>
<div v-if="[Link]">
<input type="number" [Link]="[Link]" />
</div>
<div v-else>
{{ formatMontant([Link]) }}
</div>
</td>
<td>
<div v-if="[Link]">
<input type="number" [Link]="[Link]" />
</div>
<div v-else>
{{ formatMontant([Link]) }}
</div>
</td>
<td>
<div v-if="[Link]">
<button @click="enregistrerLigne(index)">Enregistrer</button>
<button @click="annulerEdition(index)">Annuler</button>
</div>
<div v-else>
<button @click="modifierLigne(index)">Modifier</button>
</div>
</td>
</tr>
</tbody>
</table>
<p v-if="![Link] && dejaCharge">Aucun résultat trouvé.</p>
<script setup>
import { ref, watch } from 'vue'
import { BookOpen } from 'lucide-vue-next'
import { useRoute } from 'vue-router'
import axios from 'axios'
import { getToken } from '../services/Token'
async function fetchGrandLivre({ prixMin, prixMax, typeMontant, accountValue, libelle, skip, top }) {
try {
const token = await getToken()
const filters = []
if (accountValue) [Link](`Account_ID eq ${accountValue}`)
const filterString = [Link] > 0 ? [Link](' and ') : undefined
[Link] = [Link]['@[Link]'] || 0
[Link] = [Link]([Link] / pageSize)
const lignes = [Link] || []
if (journalId) {
const journalRes = await [Link](`${JOURNAL_ENDPOINT}/${journalId}`, {
headers: { Authorization: `Bearer ${token}` },
})
const journal = [Link]
reference = journal?.DocumentNo || reference
journalCode = journal?.DocumentStatus || 'OD'
}
} catch (err) {
[Link]('Erreur récupération journal:', [Link])
}
}
return {
id: [Link], // ID réel de Fact_Acct
journalId,
date: [Link],
reference,
journal: journalCode,
compte: ligne.Account_ID?.Value || '',
compteNom,
description: [Link] || '',
debit: Number([Link] || 0),
credit: Number([Link] || 0),
editing: false,
recordId: [Link], // 👈 Clé importante ici
}
})
)
[Link]((item) => {
const montant = [Link]([Link], [Link])
if (typeMontant === 'debit' && (prixMin === null || [Link] >= prixMin) && (prixMax === null || [Link] <=
prixMax)) {
[Link]([Link])
} else if (typeMontant === 'credit' && (prixMin === null || [Link] >= prixMin) && (prixMax === null || [Link]
<= prixMax)) {
[Link]([Link])
} else if (typeMontant === 'both' && (prixMin === null || montant >= prixMin) && (prixMax === null || montant <=
prixMax)) {
[Link]([Link])
}
})
if (libelle) {
const recherche = [Link]()
return [Link](
(item) =>
[Link]?.toLowerCase().includes(recherche) ||
[Link]?.toLowerCase().includes(recherche) ||
[Link]?.toLowerCase().includes(recherche) ||
[Link]?.toLowerCase().includes(recherche)
)
}
return lignesFiltrees
} catch (err) {
[Link]('Erreur chargement grand livre:', [Link]?.data || [Link])
throw new Error('Echec du chargement du grand livre')
}
}
} catch {
alert('Erreur lors du chargement des données')
}
[Link] = true
}
function pageSuivante() {
if ([Link] < [Link]) {
[Link]++
}
}
function pagePrecedente() {
if ([Link] > 1) {
[Link]--
}
}
function modifierLigne(index) {
[Link][index].editing = true
}
function annulerEdition(index) {
[Link][index].editing = false
chargerDonnees()
}
try {
if (![Link]) {
throw new Error("recordId manquant ou invalide — impossible de mettre à jour.")
}
await [Link](`${FACT_ACCT_ENDPOINT}/${[Link]}`, {
AmtAcctDr: [Link],
AmtAcctCr: [Link],
}, {
headers: {
Authorization: `Bearer ${token}`,
},
})
[Link] = false
alert('Montant mis à jour avec succès.')
} catch (err) {
[Link]('Erreur mise à jour :', [Link]?.data || [Link])
alert('Erreur lors de la mise à jour : ' + ([Link]?.data?.detail || [Link]))
}
}
watch(page, chargerDonnees)
</script>
<style scoped>
.container {
max-width: 900px;
margin: 2rem auto;
font-family: Arial, sans-serif;
color: #222;
}
.page-title {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.8rem;
margin-bottom: 1rem;
}
.icon {
width: 1.5rem;
height: 1.5rem;
color: #3182ce;
}
.filter-form {
display: flex;
flex-wrap: wrap;
gap: 1rem;
justify-content: center;
margin-bottom: 1rem;
}
.filter-form label {
font-weight: 600;
font-size: 1rem;
display: flex;
flex-direction: column;
color: #4a5568;
}
.filter-form input {
padding: 0.3rem 0.5rem;
border: 1px solid #cbd5e0;
border-radius: 4px;
margin-top: 0.3rem;
}
.filter-form button {
padding: 0.4rem 1.2rem;
background-color: #2b6cb0;
border: none;
color: white;
border-radius: 4px;
font-weight: 600;
cursor: pointer;
}
.filter-form button:hover {
background-color: #2c5282;
}
.ledger-table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
}
.ledger-table th,
.ledger-table td {
padding: 0.5rem;
border: 1px solid #e2e8f0;
text-align: center;
}
.ledger-table th {
background-color: #f7fafc;
font-
weight: bold;
}
.pagination {
margin-top: 1rem;
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
}
.pagination button {
padding: 0.3rem 0.8rem;
font-weight: 600;
border-radius: 4px;
border: 1px solid #2b6cb0;
background-color: white;
color: #2b6cb0;
cursor: pointer;
}
.pagination button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
</style>
<script setup>
import { ref, watch, onMounted } from 'vue'
import { BookOpen } from 'lucide-vue-next'
import { useRoute } from 'vue-router'
import axios from 'axios'
import { getToken } from '../services/Token'
if (accountValue !== null && accountValue !== undefined && accountValue !== '' && accountValue != 0) {
[Link](Account_ID eq ${accountValue})
}
[Link] = [Link]['@[Link]'] || 0
[Link] = [Link]([Link] / pageSize)
const lignes = [Link] || []
if (journalLine?.GL_Journal_ID?.id) {
const journalRes = await [Link](${JOURNAL_ENDPOINT}/${journalLine.GL_Journal_ID.id}, {
headers: { Authorization: Bearer ${token} },
})
const journal = [Link]
reference = journal?.DocumentNo || reference
journalCode = journal?.DocumentStatus || 'OD'
}
} catch (err) {
[Link]('Erreur récupération journal:', [Link])
}
}
return {
date: [Link],
reference,
journal: journalCode,
compte: ligne.Account_ID?.Value || '',
compteNom, // ✅ ajouté
description: [Link] || '',
debit: Number([Link] || 0),
credit: Number([Link] || 0),
}
})
)
let soldeCumul = 0
[Link]((ligne) => {
soldeCumul = [Link] - [Link]
[Link] = soldeCumul
})
return filtered
} catch (err) {
[Link]('Erreur chargement grand livre:', [Link]?.data || [Link])
throw new Error('Échec du chargement du grand livre')
}
}
function pageSuivante() {
if ([Link] < [Link]) {
[Link]++
}
}
function pagePrecedente() {
if ([Link] > 1) {
[Link]--
}
}
watch(page, () => {
chargerDonnees()
})
onMounted(() => {
chargerDonnees()
})
<style scoped>
.container {
max-width: 900px;
margin: 2rem auto;
font-family: Arial, sans-serif;
color: #222;
}
.page-title {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.8rem;
color: #2d3748;
margin-bottom: 1rem;
text-align: center;
}
.icon {
width: 1.5rem;
height: 1.5rem;
color: #3182ce;
}
.filter-form {
display: flex;
flex-wrap: wrap;
gap: 1rem;
justify-content: center;
margin-bottom: 1rem;
}
.filter-form label {
font-weight: 600;
font-size: 1rem;
display: flex;
flex-direction: column;
color: #4a5568;
}
.filter-form input {
padding: 0.3rem 0.5rem;
border: 1px solid #cbd5e0;
border-radius: 4px;
margin-top: 0.3rem;
}
.filter-form button {
padding: 0.4rem 1.2rem;
background-color: #2b6cb0;
border: none;
color: white;
border-radius: 4px;
font-weight: 600;
cursor: pointer;
}
.filter-form button:hover {
background-color: #2c5282;
}
.ledger-table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
}
.ledger-table th,
.ledger-table td {
padding: 0.5rem;
border: 1px solid #e2e8f0;
text-align: center;
}
.ledger-table th {
background-color: #f7fafc;
font-weight: bold;
}
.positif {
color: green;
font-weight: 600;
}
.negatif {
color: red;
font-weight: 600;
}
.pagination {
margin-top: 1rem;
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
}
.pagination button {
padding: 0.3rem 0.8rem;
font-weight: 600;
border-radius: 4px;
border: 1px solid #2b6cb0;
background-color: white;
color: #2b6cb0;
cursor: pointer;
}
.pagination button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
</style> peut tu mettre un colone ou il y a des boutons ou on peu supprimer une ligne , modifier et un autre bouton ajouter
en haut du tableau pour ajouter une nouvelle ligne
[10/06/2025 13:29] fenoantramanana: <template>
<div class="container">
<center>
<h1 class="page-title" style="color: green;">
<BookOpen class="icon" />
Grand Livre
</h1>
</center>
<script setup>
import { ref, watch, onMounted } from 'vue'
import { BookOpen } from 'lucide-vue-next'
import { useRoute } from 'vue-router'
import axios from 'axios'
import { getToken } from '../services/Token'
if (accountValue) {
[Link](`Account_ID eq ${accountValue}`)
}
if (dateDebut) [Link](`DateAcct ge '${dateDebut}'`)
if (dateFin) [Link](`DateAcct le '${dateFin}'`)
[Link] = [Link]['@[Link]'] || 0
[Link] = [Link]([Link] / pageSize)
const lignes = [Link] || []
if (journalLine?.GL_Journal_ID?.id) {
const journalRes = await [Link](`${JOURNAL_ENDPOINT}/${journalLine.GL_Journal_ID.id}`, {
headers: { Authorization: `Bearer ${token}` },
})
const journal = [Link]
reference = journal?.DocumentNo || reference
journalCode = journal?.DocumentStatus || 'OD'
}
} catch (err) {
[Link]('Erreur récupération journal:', [Link])
}
}
return {
date: [Link],
reference,
journal: journalCode,
compte: ligne.Account_ID?.Value || '',
compteNom,
description: [Link] || '',
debit: Number([Link] || 0),
credit: Number([Link] || 0),
}
})
)
let soldeCumul = 0
[Link]((ligne) => {
soldeCumul += [Link] - [Link]
[Link] = soldeCumul
})
return filtered
} catch (err) {
[Link]('Erreur chargement grand livre:', [Link]?.data || [Link])
throw new Error('Échec du chargement du grand livre')
}
}
function pageSuivante() {
if ([Link] < [Link]) [Link]++
}
function pagePrecedente() {
if ([Link] > 1) [Link]--
}
function formatMontant(montant) {
return Number(montant).toFixed(2)
}
function modifierLigne(index) {
alert(`Modifier la ligne ${index + 1} – fonctionnalité à implémenter`)
}
function supprimerLigne(index) {
if (confirm('Supprimer cette ligne ?')) {
[Link](index, 1)
}
}
watch(page, () => {
chargerDonnees()
})
onMounted(() => {
chargerDonnees()
})
</script>
<style scoped>
.container {
max-width: 900px;
margin: 2rem auto;
font-family: Arial, sans-serif;
color: #222;
}
.page-title {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.8rem;
color
[10/06/2025 13:56] Mon Amour ❤️🥺: <script setup>
import { ref, onMounted, computed } from 'vue'
import axios from 'axios'
import { getToken } from '../services/authService'
import { Calendar, ArrowDown } from 'lucide-vue-next'
import ApexChart from 'vue3-apexcharts'
import Header from './components/[Link]'
[Link](rawData);
[Link](entry => {
if ([Link]() === year) {
const idx = [Link]()
if ([Link]('6')) {
dataByMonth[idx].expense += [Link] // Charges : comptes 6, au débit
}
if ([Link]('7')) {
dataByMonth[idx].revenue += [Link] // Produits : comptes 7, au crédit
}
}
})
onMounted(fetchRawData)
</script>
<template>
<Header />
<main class="main-content">
<div class="table-container">
<form @[Link]="filterByYear" class="filter-form">
<label>
<!-- Année : -->
<select v-model="selectedYear">
<option v-for="year in years" :key="year" :value="year">
{{ year }}
</option>
</select>
</label>
<button type="submit">
<!-- <ArrowDown class="icon" /> -->
Filtrer
</button>
</form>
</main>
</template>
<style scoped>
@import url('[Link]
.container {
margin: 2rem auto;
padding: 1rem;
font-family: 'Inter', sans-serif;
color: #2d3748;
background-color: #f7fafc;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.table-container {
background-color: white;
border-radius: 8px;
padding: 2rem;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.05);
border: 1px solid #e5e7eb;
}
.main-content {
margin-left: 250px; /* décalage = largeur de la sidebar fixée */
padding: 2rem;
background-color: #f7f7fa;
min-height: 100vh;
width: 82%;
margin-top: -10px;
}
h1 {
text-align: center;
font-size: 1.8rem;
margin-bottom: 1.5rem;
color: #2b6cb0;
}
.filter-form {
display: flex;
gap: 1rem;
align-items: center;
justify-content: center;
margin-bottom: 1.5rem;
}
.filter-form label {
display: flex;
align-items: center;
gap: 0.5rem;
font-weight: 600;
color: #4a5568;
}
select {
padding: 0.4rem 0.6rem;
border: 1px solid #cbd5e0;
border-radius: 6px;
background-color: #fff;
cursor: pointer;
}
button {
display: flex;
align-items: center;
gap: 0.4rem;
padding: 0.45rem 1rem;
background-color: #3182ce;
border: none;
color: white;
font-weight: 600;
border-radius: 6px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.chart-container {
margin: 2rem 0;
background: white;
padding: 1rem;
border-radius: 8px;
/* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); */
}
.custom-table {
width: 100%;
border-collapse: collapse;
}
.custom-table th,
.custom-table td {
padding: 12px 16px;
text-align: left;
border-bottom: 1px solid #e0e0e0;
}
.custom-table th {
color: #3498db;
background-color: #edf8ff;
font-weight: 600;
}
[Link](rawData);
[Link](entry => {
if ([Link]() === year) {
const idx = [Link]()
if ([Link]('6')) {
dataByMonth[idx].expense += [Link] // Charges : comptes 6, au débit
if ([Link]('7')) {
dataByMonth[idx].revenue += [Link] // Produits : comptes 7, au crédit
[Link](`Débit pour ${[Link]}: ${[Link]} €`);
}
}
})
onMounted(fetchRawData)
</script>
[18/06/2025 08:46] Mon Amour ❤️🥺: import heapq
import networkx as nx
import [Link] as plt
while heap:
cost, node, path = [Link](heap)
if node in visited:
continue
[Link](node)
path = path + [node]
if node == end:
return cost, path
for neighbor, weight in [Link](node, {}).items():
if neighbor not in visited:
[Link](heap, (cost + weight, neighbor, path))
return float('inf'), []
# Affichage du graphe
pos = nx.spring_layout(G) # positions des noeuds
while heap:
cost, node, path = [Link](heap)
if node in visited:
continue
[Link](node)
path = path + [node]
if node == end:
return cost, path
return float('inf'), []
# Définition du graphe
graph = {
'A': {'B': 3, 'C': 4},
'B': {'C': 2, 'D': 5},
'C': {'D': 1, 'E': 7},
'D': {'E': 3},
}
# Résultat
print(f"Chemin le plus rapide de {start} à {end} : {' -> '.join(path)}")
print(f"Coût total : {cost}")
<script setup>
import { ref, computed, onMounted } from 'vue'
import axios from 'axios'
import { getToken } from '../services/Token'
const tempGrouped = {}
for (const record of [Link]) {
const id = record.Account_ID.id
if (!tempGrouped[id]) {
tempGrouped[id] = {
accountId: id,
totalDebit: 0,
totalCredit: 0,
description: [Link] || '',
dateAcct: [Link]
}
}
tempGrouped[id].totalDebit += Number([Link] || 0)
tempGrouped[id].totalCredit += Number([Link] || 0)
}
await [Link](promises)
[Link] = [Link](tempGrouped)
} catch (err) {
[Link](err)
alert("Erreur lors de la récupération de la balance")
}
}
if ([Link] || [Link]) {
const from = [Link] ? new Date([Link]) : null
const to = [Link] ? new Date([Link]) : null
onMounted(() => {
fetchBalance()
})
</script>
<style scoped>
.container {
max-width: 900px;
margin: 2rem auto;
padding: 0 1rem;
font-family: Arial, sans-serif;
color: #222;
}
h1 {
text-align: center;
margin-bottom: 1.5rem;
color: #1a202c;
}
.filter-form {
display: flex;
gap: 1rem;
justify-content: center;
margin-bottom: 1.5rem;
}
.filter-form label {
font-weight: 600;
font-size: 1rem;
display: flex;
flex-direction: column;
color: #4a5568;
}
.filter-form input {
padding: 0.3rem 0.5rem;
border: 1px solid #cbd5e0;
border-radius: 4px;
margin-top: 0.3rem;
}
.filter-form button {
padding: 0.4rem 1rem;
background-color: #2b6cb0;
border: none;
color: white;
border-radius: 4px;
cursor: pointer;
align-self: flex-end;
font-weight: 600;
transition: background-color 0.3s ease;
}
.filter-form button:hover {
background-color: #2c5282;
}
.balance-table {
width: 100%;
border-collapse: collapse;
text-align: center;
}
.balance-table th,
.balance-table td {
border: 1px solid #e2e8f0;
padding: 0.5rem;
}
.balance-table th {
background-color: #edf2f7;
font-weight: 700;
}
.positive {
color: green;
font-weight: 600;
}
.negative {
color: red;
font-weight: 600;
}
.pagination-controls {
display: flex;
justify-content: center;
margin-top: 1rem;
gap: 1rem;
align-items: center;
}
.pagination-controls button {
padding: 0.3rem 0.8rem;
background: #4a5568;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>