This commit is contained in:
Matthieu
2025-10-30 10:30:27 +01:00
commit 952a43059b
3 changed files with 1752 additions and 0 deletions

252
index.html Normal file
View File

@@ -0,0 +1,252 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Générateur de Devis</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="app-header">
<div class="brand">
<span class="logo-circle"></span>
<h1>Générateur de Devis</h1>
</div>
<div class="actions">
<button id="saveQuoteBtn" class="btn" title="Enregistrer ce devis">Enregistrer</button>
<button id="openLibraryBtn" class="btn" title="Voir les devis enregistrés">Devis enregistrés</button>
<button id="importJsonBtn" class="btn" title="Importer un JSON">Importer JSON</button>
<button id="exportJsonBtn" class="btn" title="Exporter en JSON">Exporter JSON</button>
<button id="resetBtn" class="btn btn-secondary" title="Réinitialiser les champs">Réinitialiser</button>
<button id="printBtn" class="btn btn-primary" title="Télécharger en PDF">Télécharger PDF</button>
</div>
<input id="importJsonInput" type="file" accept="application/json" style="display:none" />
</header>
<main class="container">
<section class="panel form-panel">
<h2>Paramètres</h2>
<div class="grid two">
<div>
<label>Devise
<select id="currency">
<option value="EUR">EUR €</option>
<option value="USD">USD $</option>
<option value="GBP">GBP £</option>
<option value="CHF">CHF Fr.</option>
</select>
</label>
</div>
<div>
<label>Taux de TVA (%)
<input type="number" id="vatRate" min="0" step="0.01" value="20" />
</label>
</div>
</div>
<h3>Apparence</h3>
<div class="grid two">
<label>Modèle d'impression
<select id="printTemplate">
<option value="standard">Standard</option>
<option value="pro-minimal">Pro Minimal</option>
<option value="pro-striped">Pro Bandes</option>
<option value="compact">Compact</option>
<option value="pro-borders">Pro Bordures</option>
<option value="sidebar-accent">Bandeau Latéral</option>
<option value="centered-minimal">Minimal Centré</option>
</select>
</label>
</div>
<div class="grid two">
<div>
<h3>Votre entreprise</h3>
<label>Nom de l'entreprise
<input id="myName" type="text" placeholder="Ex: ACME SAS" />
</label>
<label>Rue et numéro
<input id="myStreet" type="text" placeholder="Ex: 10 rue de la Paix" />
</label>
<div class="grid two">
<label>Code postal
<input id="myPostcode" type="text" placeholder="75002" />
</label>
<label>Ville
<input id="myCity" type="text" placeholder="Paris" />
</label>
</div>
<label>Pays
<input id="myCountry" type="text" placeholder="France" />
</label>
<div class="grid two">
<label>Email
<input id="myEmail" type="email" placeholder="contact@exemple.com" />
</label>
<label>Téléphone
<input id="myPhone" type="tel" placeholder="+33 6 12 34 56 78" />
</label>
</div>
<label>Logo (URL ou data URI)
<input id="myLogo" type="text" placeholder="https://..." />
</label>
<label>Numéro SIREN / TVA
<input id="myLegal" type="text" placeholder="SIREN, TVA intracom..." />
</label>
</div>
<div>
<h3>Client</h3>
<label>Nom / Société
<input id="clientName" type="text" placeholder="Nom du client" />
</label>
<label>Rue et numéro
<input id="clientStreet" type="text" placeholder="Ex: 20 avenue Victor Hugo" />
</label>
<div class="grid two">
<label>Code postal
<input id="clientPostcode" type="text" placeholder="33000" />
</label>
<label>Ville
<input id="clientCity" type="text" placeholder="Bordeaux" />
</label>
</div>
<label>Pays
<input id="clientCountry" type="text" placeholder="France" />
</label>
<div class="grid two">
<label>Email
<input id="clientEmail" type="email" />
</label>
<label>Téléphone
<input id="clientPhone" type="tel" />
</label>
</div>
</div>
</div>
<h3>Détails du devis</h3>
<div class="grid three">
<label>Numéro de devis
<input id="quoteNumber" type="text" />
</label>
<label>Date du devis
<input id="quoteDate" type="date" />
</label>
<label>Valable jusqu'au
<input id="quoteValidUntil" type="date" />
</label>
</div>
<h3>Lignes</h3>
<div class="table">
<div class="table-head">
<div></div>
<div>Description</div>
<div>Temps (jours)</div>
<div>PU HT</div>
<div>Total HT</div>
<div><input id="selectAllRows" type="checkbox" title="Tout sélectionner" /></div>
</div>
<div id="items" class="table-body"></div>
</div>
<div class="actions" style="margin-top:8px; gap:8px; flex-wrap: wrap;">
<button id="addItemBtn" class="btn btn-outline">+ Ajouter une ligne</button>
<button id="addGroupBtn" class="btn btn-outline">+ Ajouter un groupe</button>
<button id="duplicateSelectedBtn" class="btn">Dupliquer sélection</button>
<button id="deleteSelectedBtn" class="btn btn-danger">Supprimer sélection</button>
</div>
<div class="grid two mt">
<label>Remise (%)
<input id="discountRate" type="number" min="0" step="0.01" value="0" />
</label>
<label>Conditions de paiement
<input id="paymentTerms" type="text" placeholder="30 jours, virement..." />
</label>
</div>
<label>Notes
<textarea id="notes" rows="3" placeholder="Informations complémentaires"></textarea>
</label>
</section>
<section class="panel preview-panel" id="printArea">
<div class="quote-header">
<div class="company">
<img id="p_myLogo" class="logo" alt="Logo" />
<div>
<div class="company-name" id="p_myName"></div>
<div class="icon-text"><span class="ico">📍</span><span class="company-address" id="p_myAddress"></span></div>
<div class="company-contact stack">
<div class="icon-text"><span class="ico">✉️</span><span id="p_myEmail"></span></div>
<div class="icon-text"><span class="ico">📞</span><span id="p_myPhone"></span></div>
</div>
<div class="icon-text"><span class="ico">🧾</span><span class="company-legal" id="p_myLegal"></span></div>
</div>
</div>
<div class="quote-meta">
<div class="quote-title">DEVIS</div>
<div class="icon-text right"><span class="ico">#</span><span><strong></strong> <span id="p_quoteNumber"></span></span></div>
<div class="icon-text right"><span class="ico">📅</span><span><strong>Date</strong> <span id="p_quoteDate"></span></span></div>
<div class="icon-text right"><span class="ico"></span><span><strong>Valide jusqu'au</strong> <span id="p_quoteValidUntil"></span></span></div>
</div>
</div>
<div class="client-block">
<div class="muted">Destinataire</div>
<div class="client-name" id="p_clientName"></div>
<div class="icon-text"><span class="ico">📍</span><span class="client-address" id="p_clientAddress"></span></div>
<div class="client-contact stack">
<div class="icon-text"><span class="ico">✉️</span><span id="p_clientEmail"></span></div>
<div class="icon-text"><span class="ico">📞</span><span id="p_clientPhone"></span></div>
</div>
</div>
<div class="items original">
<div class="items-head">
<div>Description</div><div>Temps (jours)</div><div>PU HT</div><div>Total HT</div>
</div>
<div id="p_items" class="items-body"></div>
</div>
<!-- Conteneur des pages imprimées, construit dynamiquement -->
<div id="printPages" class="print-pages"></div>
<div class="totals">
<div class="row"><span>Total jours</span><span id="p_totalDays"></span></div>
<div class="row"><span>Sous-total</span><span id="p_subtotal"></span></div>
<div class="row"><span>Remise</span><span id="p_discount"></span></div>
<div class="row"><span>TVA (<span id="p_vatRate"></span>%)</span><span id="p_vat"></span></div>
<div class="row grand"><span>Total TTC</span><span id="p_total"></span></div>
</div>
<div class="notes">
<div class="icon-text"><span class="ico">💳</span><span><strong>Conditions de paiement:</strong> <span id="p_paymentTerms"></span></span></div>
<div class="icon-text"><span class="ico">📝</span><span id="p_notes"></span></div>
</div>
</section>
</main>
<footer class="app-footer">
<span>Fait avec ❤️ — export PDF via impression</span>
</footer>
<!-- Modal Bibliothèque de devis -->
<div id="libraryModal" class="modal" aria-hidden="true">
<div class="modal-backdrop" data-close="1"></div>
<div class="modal-content">
<div class="modal-header">
<h3>Devis enregistrés</h3>
<button class="btn" id="closeLibraryBtn" title="Fermer"></button>
</div>
<div class="modal-body">
<div id="libraryEmpty" class="muted" style="display:none">Aucun devis enregistré pour linstant.</div>
<div id="libraryList" class="library-list"></div>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>