fix: impression PDF sans pagination custom
This commit is contained in:
BIN
LOGO-DEVIS.jpg
Normal file
BIN
LOGO-DEVIS.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
320
index.html
320
index.html
@@ -13,14 +13,43 @@
|
||||
<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>
|
||||
<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" />
|
||||
<input
|
||||
id="importJsonInput"
|
||||
type="file"
|
||||
accept="application/json"
|
||||
style="display: none"
|
||||
/>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
@@ -28,7 +57,8 @@
|
||||
<h2>Paramètres</h2>
|
||||
<div class="grid two">
|
||||
<div>
|
||||
<label>Devise
|
||||
<label
|
||||
>Devise
|
||||
<select id="currency">
|
||||
<option value="EUR">EUR €</option>
|
||||
<option value="USD">USD $</option>
|
||||
@@ -38,15 +68,23 @@
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>Taux de TVA (%)
|
||||
<input type="number" id="vatRate" min="0" step="0.01" value="20" />
|
||||
<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
|
||||
<label
|
||||
>Modèle d'impression
|
||||
<select id="printTemplate">
|
||||
<option value="standard">Standard</option>
|
||||
<option value="pro-minimal">Pro Minimal</option>
|
||||
@@ -59,66 +97,101 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid two">
|
||||
<div>
|
||||
<h3>Votre entreprise</h3>
|
||||
<label>Nom de l'entreprise
|
||||
<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
|
||||
>Rue et numéro
|
||||
<input
|
||||
id="myStreet"
|
||||
type="text"
|
||||
placeholder="Ex: 10 rue de la Paix"
|
||||
/>
|
||||
</label>
|
||||
<div class="grid two">
|
||||
<label>Code postal
|
||||
<label
|
||||
>Code postal
|
||||
<input id="myPostcode" type="text" placeholder="75002" />
|
||||
</label>
|
||||
<label>Ville
|
||||
<label
|
||||
>Ville
|
||||
<input id="myCity" type="text" placeholder="Paris" />
|
||||
</label>
|
||||
</div>
|
||||
<label>Pays
|
||||
<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
|
||||
>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
|
||||
>Téléphone
|
||||
<input
|
||||
id="myPhone"
|
||||
type="tel"
|
||||
placeholder="+33 6 12 34 56 78"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<label>Logo (URL ou data URI)
|
||||
<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
|
||||
>Numéro SIREN / TVA
|
||||
<input
|
||||
id="myLegal"
|
||||
type="text"
|
||||
placeholder="SIREN, TVA intracom..."
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Client</h3>
|
||||
<label>Nom / Société
|
||||
<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
|
||||
>Rue et numéro
|
||||
<input
|
||||
id="clientStreet"
|
||||
type="text"
|
||||
placeholder="Ex: 20 avenue Victor Hugo"
|
||||
/>
|
||||
</label>
|
||||
<div class="grid two">
|
||||
<label>Code postal
|
||||
<label
|
||||
>Code postal
|
||||
<input id="clientPostcode" type="text" placeholder="33000" />
|
||||
</label>
|
||||
<label>Ville
|
||||
<label
|
||||
>Ville
|
||||
<input id="clientCity" type="text" placeholder="Bordeaux" />
|
||||
</label>
|
||||
</div>
|
||||
<label>Pays
|
||||
<label
|
||||
>Pays
|
||||
<input id="clientCountry" type="text" placeholder="France" />
|
||||
</label>
|
||||
<div class="grid two">
|
||||
<label>Email
|
||||
<label
|
||||
>Email
|
||||
<input id="clientEmail" type="email" />
|
||||
</label>
|
||||
<label>Téléphone
|
||||
<label
|
||||
>Téléphone
|
||||
<input id="clientPhone" type="tel" />
|
||||
</label>
|
||||
</div>
|
||||
@@ -127,13 +200,16 @@
|
||||
|
||||
<h3>Détails du devis</h3>
|
||||
<div class="grid three">
|
||||
<label>Numéro de devis
|
||||
<label
|
||||
>Numéro de devis
|
||||
<input id="quoteNumber" type="text" />
|
||||
</label>
|
||||
<label>Date du devis
|
||||
<label
|
||||
>Date
|
||||
<input id="quoteDate" type="date" />
|
||||
</label>
|
||||
<label>Valable jusqu'au
|
||||
<label
|
||||
>Valable jusqu'au
|
||||
<input id="quoteValidUntil" type="date" />
|
||||
</label>
|
||||
</div>
|
||||
@@ -146,88 +222,162 @@
|
||||
<div>Temps (jours)</div>
|
||||
<div>PU HT</div>
|
||||
<div>Total HT</div>
|
||||
<div><input id="selectAllRows" type="checkbox" title="Tout sélectionner" /></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 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
|
||||
>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
|
||||
>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
|
||||
>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>
|
||||
<img id="p_myLogo" class="logo" src="LOGO-DEVIS.jpg" alt="Logo" />
|
||||
<div class="company-details">
|
||||
<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 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 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>N°</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 class="header-right">
|
||||
<div class="quote-dates">
|
||||
<div class="quote-date-value" id="p_quoteDate"></div>
|
||||
</div>
|
||||
<div class="client-block">
|
||||
<div class="muted">Destiné à</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>
|
||||
</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 class="quote-title-block">
|
||||
<div class="quote-title">DEVIS</div>
|
||||
<div class="quote-number">N° <span id="p_quoteNumber"></span></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 class="items-section-title">Détail de la prestation</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 id="printPages" class="print-pages" aria-hidden="true"></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 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="signature-block">
|
||||
Signature du client précédée de la mention "bon pour accord"
|
||||
</div>
|
||||
<div class="quote-valid-row">
|
||||
<span class="quote-date-label">Valable jusqu'au</span>
|
||||
<span class="quote-date-value" id="p_quoteValidUntil"></span>
|
||||
</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 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>
|
||||
<span class="page-counter" aria-hidden="true"></span>
|
||||
</footer>
|
||||
|
||||
<!-- Modal Bibliothèque de devis -->
|
||||
@@ -239,14 +389,14 @@
|
||||
<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 l’instant.</div>
|
||||
<div id="libraryEmpty" class="muted" style="display: none">
|
||||
Aucun devis enregistré pour l’instant.
|
||||
</div>
|
||||
<div id="libraryList" class="library-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
BIN
sample-devis-1.png
Normal file
BIN
sample-devis-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 170 KiB |
BIN
sample-devis.pdf
Normal file
BIN
sample-devis.pdf
Normal file
Binary file not shown.
1133
styles.css
1133
styles.css
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user