Spaces:
Running
Running
Add 2 files
Browse files- README.md +6 -4
- index.html +695 -19
README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
colorTo: pink
|
6 |
sdk: static
|
7 |
pinned: false
|
|
|
|
|
8 |
---
|
9 |
|
10 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: easyloc
|
3 |
+
emoji: 🐳
|
4 |
+
colorFrom: yellow
|
5 |
colorTo: pink
|
6 |
sdk: static
|
7 |
pinned: false
|
8 |
+
tags:
|
9 |
+
- deepsite
|
10 |
---
|
11 |
|
12 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
index.html
CHANGED
@@ -1,19 +1,695 @@
|
|
1 |
-
<!
|
2 |
-
<html>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="fr">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>EasyLoc - Gestion des locations saisonnières</title>
|
7 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
8 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
9 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
10 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
11 |
+
<style>
|
12 |
+
.tab-active {
|
13 |
+
border-bottom: 3px solid #f97316;
|
14 |
+
color: #f97316;
|
15 |
+
font-weight: 600;
|
16 |
+
}
|
17 |
+
.datepicker {
|
18 |
+
z-index: 1000;
|
19 |
+
}
|
20 |
+
.contract-section {
|
21 |
+
margin-bottom: 1.5rem;
|
22 |
+
}
|
23 |
+
.signature-placeholder {
|
24 |
+
border-bottom: 1px dashed #000;
|
25 |
+
display: inline-block;
|
26 |
+
min-width: 200px;
|
27 |
+
}
|
28 |
+
.bold-text {
|
29 |
+
font-weight: bold;
|
30 |
+
}
|
31 |
+
.account-modal {
|
32 |
+
display: none;
|
33 |
+
position: fixed;
|
34 |
+
top: 0;
|
35 |
+
left: 0;
|
36 |
+
width: 100%;
|
37 |
+
height: 100%;
|
38 |
+
background-color: rgba(0,0,0,0.5);
|
39 |
+
z-index: 1000;
|
40 |
+
justify-content: center;
|
41 |
+
align-items: center;
|
42 |
+
}
|
43 |
+
.account-modal-content {
|
44 |
+
background-color: white;
|
45 |
+
padding: 2rem;
|
46 |
+
border-radius: 0.5rem;
|
47 |
+
width: 90%;
|
48 |
+
max-width: 600px;
|
49 |
+
max-height: 90vh;
|
50 |
+
overflow-y: auto;
|
51 |
+
}
|
52 |
+
</style>
|
53 |
+
</head>
|
54 |
+
<body class="bg-gray-50">
|
55 |
+
<div class="container mx-auto px-4 py-8 max-w-6xl">
|
56 |
+
<header class="mb-10">
|
57 |
+
<div class="flex justify-between items-center">
|
58 |
+
<div class="flex items-center">
|
59 |
+
<i class="fas fa-home text-orange-500 text-4xl mr-3"></i>
|
60 |
+
<h1 class="text-3xl font-bold text-gray-800">Easy<span class="text-orange-500">Loc</span></h1>
|
61 |
+
</div>
|
62 |
+
<div id="account-btn" class="bg-orange-100 text-orange-800 px-4 py-2 rounded-full text-sm font-medium cursor-pointer hover:bg-orange-200 transition">
|
63 |
+
<i class="fas fa-user-circle mr-2"></i>
|
64 |
+
<span id="user-name">Mon compte</span>
|
65 |
+
</div>
|
66 |
+
</div>
|
67 |
+
<p class="text-gray-600 mt-2">Gérez vos contrats de location saisonnière en toute simplicité</p>
|
68 |
+
</header>
|
69 |
+
|
70 |
+
<!-- Account Modal -->
|
71 |
+
<div id="account-modal" class="account-modal">
|
72 |
+
<div class="account-modal-content">
|
73 |
+
<div class="flex justify-between items-center mb-6">
|
74 |
+
<h2 class="text-2xl font-bold text-gray-800">Mon compte</h2>
|
75 |
+
<button id="close-modal" class="text-gray-500 hover:text-gray-700">
|
76 |
+
<i class="fas fa-times"></i>
|
77 |
+
</button>
|
78 |
+
</div>
|
79 |
+
|
80 |
+
<div class="mb-8">
|
81 |
+
<h3 class="text-lg font-semibold text-gray-800 mb-4">Informations de connexion</h3>
|
82 |
+
<div class="space-y-4">
|
83 |
+
<div>
|
84 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Email*</label>
|
85 |
+
<input type="email" id="account-email" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500" required>
|
86 |
+
</div>
|
87 |
+
<div>
|
88 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Mot de passe*</label>
|
89 |
+
<input type="password" id="account-password" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500" required>
|
90 |
+
</div>
|
91 |
+
</div>
|
92 |
+
</div>
|
93 |
+
|
94 |
+
<div class="mb-8">
|
95 |
+
<h3 class="text-lg font-semibold text-gray-800 mb-4">Informations du propriétaire</h3>
|
96 |
+
<div class="space-y-4">
|
97 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
98 |
+
<div>
|
99 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Nom*</label>
|
100 |
+
<input type="text" id="account-owner-lastname" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500" required>
|
101 |
+
</div>
|
102 |
+
<div>
|
103 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Prénom*</label>
|
104 |
+
<input type="text" id="account-owner-firstname" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500" required>
|
105 |
+
</div>
|
106 |
+
</div>
|
107 |
+
<div>
|
108 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Adresse*</label>
|
109 |
+
<input type="text" id="account-owner-address" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500" required>
|
110 |
+
</div>
|
111 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
112 |
+
<div>
|
113 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Téléphone*</label>
|
114 |
+
<input type="tel" id="account-owner-phone" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500" required>
|
115 |
+
</div>
|
116 |
+
<div>
|
117 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Email*</label>
|
118 |
+
<input type="email" id="account-owner-email" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500" required>
|
119 |
+
</div>
|
120 |
+
</div>
|
121 |
+
</div>
|
122 |
+
</div>
|
123 |
+
|
124 |
+
<div class="mb-8">
|
125 |
+
<h3 class="text-lg font-semibold text-gray-800 mb-4">Informations sur le logement</h3>
|
126 |
+
<div class="space-y-4">
|
127 |
+
<div>
|
128 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Adresse du logement*</label>
|
129 |
+
<input type="text" id="account-property-address" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500" required>
|
130 |
+
</div>
|
131 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
132 |
+
<div>
|
133 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Tarif journalier (€)*</label>
|
134 |
+
<input type="number" id="account-daily-rate" min="0" step="0.01" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500" required>
|
135 |
+
</div>
|
136 |
+
<div>
|
137 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Frais de ménage (€)*</label>
|
138 |
+
<input type="number" id="account-cleaning-fee" min="0" step="0.01" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500" required>
|
139 |
+
</div>
|
140 |
+
</div>
|
141 |
+
</div>
|
142 |
+
</div>
|
143 |
+
|
144 |
+
<div class="flex justify-between pt-4">
|
145 |
+
<button id="logout-btn" class="px-4 py-2 text-gray-700 font-medium rounded-md hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500 hidden">
|
146 |
+
<i class="fas fa-sign-out-alt mr-2"></i> Déconnexion
|
147 |
+
</button>
|
148 |
+
<div>
|
149 |
+
<button id="cancel-account" class="px-4 py-2 border border-gray-300 text-gray-700 font-medium rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500 mr-2">
|
150 |
+
Annuler
|
151 |
+
</button>
|
152 |
+
<button id="save-account" class="px-6 py-2 bg-orange-600 text-white font-medium rounded-md hover:bg-orange-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500">
|
153 |
+
Enregistrer
|
154 |
+
</button>
|
155 |
+
</div>
|
156 |
+
</div>
|
157 |
+
</div>
|
158 |
+
</div>
|
159 |
+
|
160 |
+
<div class="bg-white rounded-xl shadow-md overflow-hidden">
|
161 |
+
<!-- Navigation tabs -->
|
162 |
+
<div class="border-b border-gray-200">
|
163 |
+
<nav class="flex">
|
164 |
+
<button id="tab1-btn" class="tab-active px-6 py-4 text-center focus:outline-none">
|
165 |
+
<i class="fas fa-user-tie mr-2"></i>Propriétaire
|
166 |
+
</button>
|
167 |
+
<button id="tab2-btn" class="px-6 py-4 text-center text-gray-500 focus:outline-none">
|
168 |
+
<i class="fas fa-users mr-2"></i>Locataire
|
169 |
+
</button>
|
170 |
+
<button id="tab3-btn" class="px-6 py-4 text-center text-gray-500 focus:outline-none">
|
171 |
+
<i class="fas fa-file-contract mr-2"></i>Contrat
|
172 |
+
</button>
|
173 |
+
</nav>
|
174 |
+
</div>
|
175 |
+
|
176 |
+
<!-- Tab content -->
|
177 |
+
<div class="p-8">
|
178 |
+
<!-- Propriétaire Tab -->
|
179 |
+
<div id="tab1-content" class="tab-content">
|
180 |
+
<h2 class="text-2xl font-bold text-gray-800 mb-6">Informations du propriétaire</h2>
|
181 |
+
|
182 |
+
<form id="owner-form" class="space-y-6">
|
183 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
184 |
+
<div>
|
185 |
+
<label for="owner-lastname" class="block text-sm font-medium text-gray-700 mb-1">Nom*</label>
|
186 |
+
<input type="text" id="owner-lastname" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
187 |
+
</div>
|
188 |
+
<div>
|
189 |
+
<label for="owner-firstname" class="block text-sm font-medium text-gray-700 mb-1">Prénom*</label>
|
190 |
+
<input type="text" id="owner-firstname" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
191 |
+
</div>
|
192 |
+
</div>
|
193 |
+
|
194 |
+
<div>
|
195 |
+
<label for="owner-address" class="block text-sm font-medium text-gray-700 mb-1">Adresse*</label>
|
196 |
+
<input type="text" id="owner-address" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
197 |
+
</div>
|
198 |
+
|
199 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
200 |
+
<div>
|
201 |
+
<label for="owner-phone" class="block text-sm font-medium text-gray-700 mb-1">Téléphone*</label>
|
202 |
+
<input type="tel" id="owner-phone" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
203 |
+
</div>
|
204 |
+
<div>
|
205 |
+
<label for="owner-email" class="block text-sm font-medium text-gray-700 mb-1">Email*</label>
|
206 |
+
<input type="email" id="owner-email" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
207 |
+
</div>
|
208 |
+
</div>
|
209 |
+
|
210 |
+
<div class="pt-6 border-t border-gray-200">
|
211 |
+
<h3 class="text-lg font-medium text-gray-800 mb-4">Informations sur le logement</h3>
|
212 |
+
|
213 |
+
<div class="mb-6">
|
214 |
+
<label for="property-address" class="block text-sm font-medium text-gray-700 mb-1">Adresse du logement*</label>
|
215 |
+
<input type="text" id="property-address" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
216 |
+
</div>
|
217 |
+
|
218 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
|
219 |
+
<div>
|
220 |
+
<label for="rental-start" class="block text-sm font-medium text-gray-700 mb-1">Date de début*</label>
|
221 |
+
<input type="date" id="rental-start" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
222 |
+
</div>
|
223 |
+
<div>
|
224 |
+
<label for="rental-end" class="block text-sm font-medium text-gray-700 mb-1">Date de fin*</label>
|
225 |
+
<input type="date" id="rental-end" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
226 |
+
</div>
|
227 |
+
</div>
|
228 |
+
|
229 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
230 |
+
<div>
|
231 |
+
<label for="daily-rate" class="block text-sm font-medium text-gray-700 mb-1">Tarif journalier (€)*</label>
|
232 |
+
<input type="number" id="daily-rate" min="0" step="0.01" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
233 |
+
</div>
|
234 |
+
<div>
|
235 |
+
<label for="cleaning-fee" class="block text-sm font-medium text-gray-700 mb-1">Frais de ménage (€)*</label>
|
236 |
+
<input type="number" id="cleaning-fee" min="0" step="0.01" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
237 |
+
</div>
|
238 |
+
</div>
|
239 |
+
</div>
|
240 |
+
|
241 |
+
<div class="pt-6 border-t border-gray-200">
|
242 |
+
<div class="bg-orange-50 p-4 rounded-lg">
|
243 |
+
<h4 class="font-medium text-orange-800 mb-2">Récapitulatif financier</h4>
|
244 |
+
<div class="grid grid-cols-2 gap-4">
|
245 |
+
<div>
|
246 |
+
<p class="text-sm text-gray-600">Durée du séjour</p>
|
247 |
+
<p id="stay-duration" class="font-medium">-</p>
|
248 |
+
</div>
|
249 |
+
<div>
|
250 |
+
<p class="text-sm text-gray-600">Prix location</p>
|
251 |
+
<p id="rental-price" class="font-medium">-</p>
|
252 |
+
</div>
|
253 |
+
<div>
|
254 |
+
<p class="text-sm text-gray-600">Frais de ménage</p>
|
255 |
+
<p id="cleaning-fee-display" class="font-medium">-</p>
|
256 |
+
</div>
|
257 |
+
<div>
|
258 |
+
<p class="text-sm text-gray-600">Total</p>
|
259 |
+
<p id="total-price" class="font-bold text-orange-600 text-lg">-</p>
|
260 |
+
</div>
|
261 |
+
</div>
|
262 |
+
</div>
|
263 |
+
</div>
|
264 |
+
|
265 |
+
<div class="flex justify-end pt-6">
|
266 |
+
<button type="button" id="next-to-tenant" class="px-6 py-2 bg-orange-600 text-white font-medium rounded-md hover:bg-orange-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500">
|
267 |
+
Suivant <i class="fas fa-arrow-right ml-2"></i>
|
268 |
+
</button>
|
269 |
+
</div>
|
270 |
+
</form>
|
271 |
+
</div>
|
272 |
+
|
273 |
+
<!-- Locataire Tab -->
|
274 |
+
<div id="tab2-content" class="tab-content hidden">
|
275 |
+
<h2 class="text-2xl font-bold text-gray-800 mb-6">Informations du locataire</h2>
|
276 |
+
|
277 |
+
<form id="tenant-form" class="space-y-6">
|
278 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
279 |
+
<div>
|
280 |
+
<label class="block text-sm font-medium text-gray-700 mb-2">Civilité*</label>
|
281 |
+
<div class="flex space-x-4">
|
282 |
+
<label class="inline-flex items-center">
|
283 |
+
<input type="radio" name="tenant-civility" value="Madame" class="h-4 w-4 text-orange-600 focus:ring-orange-500 border-gray-300" checked>
|
284 |
+
<span class="ml-2 text-gray-700">Madame</span>
|
285 |
+
</label>
|
286 |
+
<label class="inline-flex items-center">
|
287 |
+
<input type="radio" name="tenant-civility" value="Monsieur" class="h-4 w-4 text-orange-600 focus:ring-orange-500 border-gray-300">
|
288 |
+
<span class="ml-2 text-gray-700">Monsieur</span>
|
289 |
+
</label>
|
290 |
+
</div>
|
291 |
+
</div>
|
292 |
+
<div></div>
|
293 |
+
</div>
|
294 |
+
|
295 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
296 |
+
<div>
|
297 |
+
<label for="tenant-lastname" class="block text-sm font-medium text-gray-700 mb-1">Nom*</label>
|
298 |
+
<input type="text" id="tenant-lastname" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
299 |
+
</div>
|
300 |
+
<div>
|
301 |
+
<label for="tenant-firstname" class="block text-sm font-medium text-gray-700 mb-1">Prénom*</label>
|
302 |
+
<input type="text" id="tenant-firstname" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
303 |
+
</div>
|
304 |
+
</div>
|
305 |
+
|
306 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
307 |
+
<div>
|
308 |
+
<label for="tenant-phone" class="block text-sm font-medium text-gray-700 mb-1">Téléphone*</label>
|
309 |
+
<input type="tel" id="tenant-phone" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
310 |
+
</div>
|
311 |
+
<div>
|
312 |
+
<label for="tenant-email" class="block text-sm font-medium text-gray-700 mb-1">Email*</label>
|
313 |
+
<input type="email" id="tenant-email" required class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-orange-500 focus:border-orange-500">
|
314 |
+
</div>
|
315 |
+
</div>
|
316 |
+
|
317 |
+
<div class="pt-6 border-t border-gray-200">
|
318 |
+
<h3 class="text-lg font-medium text-gray-800 mb-4">Paiement</h3>
|
319 |
+
|
320 |
+
<div class="mb-6">
|
321 |
+
<label for="deposit-amount" class="block text-sm font-medium text-gray-700 mb-1">Montant de l'acompte (30% du total, arrondi à la dizaine supérieure)</label>
|
322 |
+
<input type="number" id="deposit-amount" min="0" step="10" readonly class="w-full px-4 py-2 border border-gray-300 rounded-md bg-gray-100">
|
323 |
+
</div>
|
324 |
+
|
325 |
+
<div class="bg-orange-50 p-4 rounded-lg">
|
326 |
+
<h4 class="font-medium text-orange-800 mb-2">Récapitulatif financier</h4>
|
327 |
+
<div class="grid grid-cols-2 gap-4">
|
328 |
+
<div>
|
329 |
+
<p class="text-sm text-gray-600">Total à payer</p>
|
330 |
+
<p id="total-price-display" class="font-medium">-</p>
|
331 |
+
</div>
|
332 |
+
<div>
|
333 |
+
<p class="text-sm text-gray-600">Acompte (30%)</p>
|
334 |
+
<p id="deposit-display" class="font-medium">-</p>
|
335 |
+
</div>
|
336 |
+
<div>
|
337 |
+
<p class="text-sm text-gray-600">Solde à payer</p>
|
338 |
+
<p id="balance-due" class="font-bold text-orange-600 text-lg">-</p>
|
339 |
+
</div>
|
340 |
+
</div>
|
341 |
+
</div>
|
342 |
+
</div>
|
343 |
+
|
344 |
+
<div class="flex justify-between pt-6">
|
345 |
+
<button type="button" id="back-to-owner" class="px-6 py-2 border border-gray-300 text-gray-700 font-medium rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500">
|
346 |
+
<i class="fas fa-arrow-left mr-2"></i> Retour
|
347 |
+
</button>
|
348 |
+
<button type="button" id="next-to-contract" class="px-6 py-2 bg-orange-600 text-white font-medium rounded-md hover:bg-orange-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500">
|
349 |
+
Générer le contrat <i class="fas fa-file-contract ml-2"></i>
|
350 |
+
</button>
|
351 |
+
</div>
|
352 |
+
</form>
|
353 |
+
</div>
|
354 |
+
|
355 |
+
<!-- Contrat Tab -->
|
356 |
+
<div id="tab3-content" class="tab-content hidden">
|
357 |
+
<div class="flex justify-between items-center mb-6">
|
358 |
+
<h2 class="text-2xl font-bold text-gray-800">Contrat de location</h2>
|
359 |
+
<div class="space-x-2">
|
360 |
+
<button id="export-word" class="px-4 py-2 bg-blue-600 text-white font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
361 |
+
<i class="fas fa-file-word mr-2"></i>Exporter en Word
|
362 |
+
</button>
|
363 |
+
<button id="export-pdf" class="px-4 py-2 bg-orange-600 text-white font-medium rounded-md hover:bg-orange-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500">
|
364 |
+
<i class="fas fa-file-pdf mr-2"></i>Exporter en PDF
|
365 |
+
</button>
|
366 |
+
</div>
|
367 |
+
</div>
|
368 |
+
|
369 |
+
<div id="contract-content" class="bg-white p-8 border border-gray-200 rounded-lg">
|
370 |
+
<div class="text-center mb-8">
|
371 |
+
<h1 class="text-2xl font-bold">CONTRAT DE LOCATION SAISONNIÈRE</h1>
|
372 |
+
</div>
|
373 |
+
|
374 |
+
<div class="contract-section">
|
375 |
+
<p>ENTRE LES SOUSSIGNÉS,</p>
|
376 |
+
<p id="contract-owner-info" class="ml-8 my-2">
|
377 |
+
<span id="owner-civility">Madame</span> <span class="signature-placeholder" id="owner-name">[NOM Prénom]</span>, demeurant <span id="owner-address-display">[adresse]</span><br>
|
378 |
+
Numéro de téléphone portable: <span id="owner-phone-display">[téléphone]</span><br>
|
379 |
+
Email: <span id="owner-email-display">[email]</span><br>
|
380 |
+
ci-après dénommé(e) « Le Bailleur »
|
381 |
+
</p>
|
382 |
+
<p>D'UNE PART</p>
|
383 |
+
<p>ET</p>
|
384 |
+
<p id="contract-tenant-info" class="ml-8 my-2">
|
385 |
+
<span id="tenant-civility-display">Madame</span> <span class="signature-placeholder" id="tenant-name">[NOM Prénom]</span><br>
|
386 |
+
Numéro de téléphone portable: <span id="tenant-phone-display">[téléphone]</span><br>
|
387 |
+
Email: <span id="tenant-email-display">[email]</span><br>
|
388 |
+
ci-après dénommé(e) « Le Preneur »
|
389 |
+
</p>
|
390 |
+
<p>D'AUTRE PART</p>
|
391 |
+
<p class="mt-4">Il a été convenu entre les parties que le Bailleur loue au Preneur le logement tel que décrit ci-dessous aux conditions suivantes :</p>
|
392 |
+
</div>
|
393 |
+
|
394 |
+
<div class="contract-section">
|
395 |
+
<h3 class="font-bold">1. OBJET DU CONTRAT DE LOCATION</h3>
|
396 |
+
<p>Les locaux objet du présent contrat sont loués meublés à titre saisonnier.</p>
|
397 |
+
</div>
|
398 |
+
|
399 |
+
<div class="contract-section">
|
400 |
+
<h3 class="font-bold">2. DÉSIGNATION DU LOGEMENT</h3>
|
401 |
+
<h4 class="font-bold mt-2">2.1. Adresse du logement :</h4>
|
402 |
+
<p id="property-address-display" class="ml-8">[adresse du logement]</p>
|
403 |
+
</div>
|
404 |
+
|
405 |
+
<div class="contract-section">
|
406 |
+
<h3 class="font-bold">3. DURÉE DE LA LOCATION SAISONNIÈRE</h3>
|
407 |
+
<p>Le Bailleur loue au Preneur le logement du <span id="rental-start-display" class="bold-text">[date début]</span> au <span id="rental-end-display" class="bold-text">[date fin]</span>, soit une durée maximum de <span id="stay-duration-display" class="bold-text">[X]</span> nuitées.</p>
|
408 |
+
<p class="mt-2">Lors du début de la location, le Bailleur ou son représentant remettra au Preneur les clefs et les instructions relative au logement.</p>
|
409 |
+
</div>
|
410 |
+
|
411 |
+
<div class="contract-section">
|
412 |
+
<h3 class="font-bold">4. PRIX DE LOCATION AND CHARGES</h3>
|
413 |
+
<p>Les Parties ont convenu de fixer le loyer à <span id="total-price-contract" class="bold-text">[montant]</span> Euros pour l'intégralité de la durée de la location décrite au paragraphe 3.</p>
|
414 |
+
<p class="mt-2">Le loyer ci-dessus comprend, pour toute la durée de la location, le paiement des charges locatives et des fournitures disponibles rappelées ci-après :</p>
|
415 |
+
<ul class="list-disc ml-8 mt-2">
|
416 |
+
<li>Eau de ville</li>
|
417 |
+
<li>Electricité</li>
|
418 |
+
<li>Chauffage</li>
|
419 |
+
<li>Internet</li>
|
420 |
+
<li>Forfait ménage avant le séjour</li>
|
421 |
+
<li>Taxes de séjour</li>
|
422 |
+
</ul>
|
423 |
+
<p class="mt-2">Le Bailleur remettra au Preneur sur demande une quittance pour tout versement effectué.</p>
|
424 |
+
</div>
|
425 |
+
|
426 |
+
<div class="contract-section">
|
427 |
+
<h3 class="font-bold">5. RÉSERVATION</h3>
|
428 |
+
<p>Afin de procéder à la réservation du logement, le Preneur retourne le présent contrat paraphé à chaque page et signé accompagné du versement d'acompte à hauteur de <span id="deposit-amount-display" class="bold-text">[montant]</span> euros.</p>
|
429 |
+
</div>
|
430 |
+
|
431 |
+
<div class="contract-section">
|
432 |
+
<h3 class="font-bold">6. RÈGLEMENT DU PRIX</h3>
|
433 |
+
<p>Le solde du montant du loyer indiqué au paragraphe 4, soit <span id="balance-due-display" class="bold-text">[montant]</span> Euros, sera versé par le Preneur au plus tard lors de l'entrée dans le logement. Les chèques ne sont plus acceptés.</p>
|
434 |
+
</div>
|
435 |
+
|
436 |
+
<div class="contract-section">
|
437 |
+
<h3 class="font-bold">7. ÉTAT DES LIEUX ET INVENTAIRES</h3>
|
438 |
+
<p>Un état des lieux et un inventaire du mobilier mis à disposition du Preneur est effectué lors de l'entrée dans le logement.</p>
|
439 |
+
<p class="mt-2">Un état des lieux et un inventaire seront établis après le départ des preneurs.</p>
|
440 |
+
</div>
|
441 |
+
|
442 |
+
<div class="contract-section">
|
443 |
+
<h3 class="font-bold">8. DÉCLARATION DU BAILLEUR</h3>
|
444 |
+
<p>Le Bailleur déclare être propriétaire du logement et en avoir la libre disposition et la pleine jouissance durant la période définie au paragraphe 3.</p>
|
445 |
+
</div>
|
446 |
+
|
447 |
+
<div class="contract-section">
|
448 |
+
<h3 class="font-bold">9. OBLIGATIONS DU PRENEUR</h3>
|
449 |
+
<ul class="list-disc ml-8 space-y-2">
|
450 |
+
<li>Le Preneur usera paisiblement du logement loué et du mobilier et équipements suivant la destination qui leur a été donnée par le bail et répondra des dégradations et pertes qui pourraient survenir pendant la durée du contrat dans les locaux dont il a la jouissance exclusive.</li>
|
451 |
+
<li>Le Preneur entretiendra le logement loué et le rendra en bon état de propreté et de réparations locatives en fin de contrat. Si des objets figurant à l'inventaire sont brisés ou détériorés, le Bailleur pourra réclamer leur valeur de remplacement.</li>
|
452 |
+
<li>Il devra éviter tout bruit de nature à gêner les voisins, notamment ceux émis par les appareils de radio, télévision et autres.</li>
|
453 |
+
<li>Le Preneur ne pourra exercer aucun recours contre le Bailleur en cas de vol et déprédations dans les lieux loués.</li>
|
454 |
+
<li>Il respectera le nombre de personnes maximum pouvant entrer dans les lieux, conformément au descriptif qui lui a été remis.</li>
|
455 |
+
<li>Le preneur ne pourra s'opposer à la visite des locaux si le Bailleur ou son mandataire en font la demande.</li>
|
456 |
+
</ul>
|
457 |
+
</div>
|
458 |
+
|
459 |
+
<div class="contract-section">
|
460 |
+
<h3 class="font-bold">10. ANNULATION</h3>
|
461 |
+
<p>La signature du contrat engage les deux parties de manière irrévocable. Aucune résiliation n'est possible sauf accord écrit des parties. Si le Preneur renonce à la location, il reste redevable de la totalité du loyer.</p>
|
462 |
+
</div>
|
463 |
+
|
464 |
+
<div class="contract-section">
|
465 |
+
<h3 class="font-bold">11. RÉSILIATION DE PLEIN DROIT</h3>
|
466 |
+
<p>En cas de manquement par le Preneur à l'une des obligations contractuelles, le présent bail sera résilié de plein droit. Cette résiliation prendra effet après un délai de 48 heures après une simple sommation par lettre recommandée ou lettre remise en main propre restée infructueuse.</p>
|
467 |
+
</div>
|
468 |
+
|
469 |
+
<div class="contract-section mt-12">
|
470 |
+
<div class="text-center italic mb-8">"Lu et approuvé"</div>
|
471 |
+
|
472 |
+
<div class="flex justify-between">
|
473 |
+
<div class="text-center">
|
474 |
+
<p id="owner-signature-name" class="font-medium">[NOM Prénom]</p>
|
475 |
+
<div class="mt-8 mb-2">……………………………………</div>
|
476 |
+
<p>Le Bailleur</p>
|
477 |
+
<p class="mt-2">Date : <span id="contract-date">[date]</span></p>
|
478 |
+
</div>
|
479 |
+
|
480 |
+
<div class="text-center">
|
481 |
+
<p id="tenant-signature-name" class="font-medium">[NOM Prénom]</p>
|
482 |
+
<div class="mt-8 mb-2">……………………………………</div>
|
483 |
+
<p>Le Preneur</p>
|
484 |
+
<p class="mt-2">Date : …………………</p>
|
485 |
+
</div>
|
486 |
+
</div>
|
487 |
+
</div>
|
488 |
+
</div>
|
489 |
+
|
490 |
+
<div class="flex justify-between pt-6">
|
491 |
+
<button type="button" id="back-to-tenant" class="px-6 py-2 border border-gray-300 text-gray-700 font-medium rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500">
|
492 |
+
<i class="fas fa-arrow-left mr-2"></i> Retour
|
493 |
+
</button>
|
494 |
+
<button type="button" id="save-contract" class="px-6 py-2 bg-orange-600 text-white font-medium rounded-md hover:bg-orange-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500">
|
495 |
+
<i class="fas fa-save mr-2"></i> Enregistrer le contrat
|
496 |
+
</button>
|
497 |
+
</div>
|
498 |
+
</div>
|
499 |
+
</div>
|
500 |
+
</div>
|
501 |
+
</div>
|
502 |
+
|
503 |
+
<script>
|
504 |
+
// Tab navigation
|
505 |
+
document.getElementById('tab1-btn').addEventListener('click', () => {
|
506 |
+
showTab('tab1');
|
507 |
+
});
|
508 |
+
|
509 |
+
document.getElementById('tab2-btn').addEventListener('click', () => {
|
510 |
+
showTab('tab2');
|
511 |
+
});
|
512 |
+
|
513 |
+
document.getElementById('tab3-btn').addEventListener('click', () => {
|
514 |
+
showTab('tab3');
|
515 |
+
});
|
516 |
+
|
517 |
+
document.getElementById('next-to-tenant').addEventListener('click', () => {
|
518 |
+
if (document.getElementById('owner-form').checkValidity()) {
|
519 |
+
calculatePrices();
|
520 |
+
showTab('tab2');
|
521 |
+
} else {
|
522 |
+
alert('Veuillez remplir tous les champs obligatoires.');
|
523 |
+
}
|
524 |
+
});
|
525 |
+
|
526 |
+
document.getElementById('back-to-owner').addEventListener('click', () => {
|
527 |
+
showTab('tab1');
|
528 |
+
});
|
529 |
+
|
530 |
+
document.getElementById('next-to-contract').addEventListener('click', () => {
|
531 |
+
if (document.getElementById('tenant-form').checkValidity()) {
|
532 |
+
calculateBalance();
|
533 |
+
generateContract();
|
534 |
+
showTab('tab3');
|
535 |
+
} else {
|
536 |
+
alert('Veuillez remplir tous les champs obligatoires.');
|
537 |
+
}
|
538 |
+
});
|
539 |
+
|
540 |
+
document.getElementById('back-to-tenant').addEventListener('click', () => {
|
541 |
+
showTab('tab2');
|
542 |
+
});
|
543 |
+
|
544 |
+
function showTab(tabName) {
|
545 |
+
// Hide all tab contents
|
546 |
+
document.querySelectorAll('.tab-content').forEach(tab => {
|
547 |
+
tab.classList.add('hidden');
|
548 |
+
});
|
549 |
+
|
550 |
+
// Show selected tab content
|
551 |
+
document.getElementById(`${tabName}-content`).classList.remove('hidden');
|
552 |
+
|
553 |
+
// Update tab navigation styling
|
554 |
+
document.querySelectorAll('nav button').forEach(btn => {
|
555 |
+
btn.classList.remove('tab-active', 'text-orange-500');
|
556 |
+
btn.classList.add('text-gray-500');
|
557 |
+
});
|
558 |
+
|
559 |
+
document.getElementById(`${tabName}-btn`).classList.add('tab-active', 'text-orange-500');
|
560 |
+
document.getElementById(`${tabName}-btn`).classList.remove('text-gray-500');
|
561 |
+
}
|
562 |
+
|
563 |
+
// Calculate rental prices when dates or rates change
|
564 |
+
document.getElementById('rental-start').addEventListener('change', calculatePrices);
|
565 |
+
document.getElementById('rental-end').addEventListener('change', calculatePrices);
|
566 |
+
document.getElementById('daily-rate').addEventListener('input', calculatePrices);
|
567 |
+
document.getElementById('cleaning-fee').addEventListener('input', calculatePrices);
|
568 |
+
|
569 |
+
// Calculate rental prices
|
570 |
+
function calculatePrices() {
|
571 |
+
const startDate = new Date(document.getElementById('rental-start').value);
|
572 |
+
const endDate = new Date(document.getElementById('rental-end').value);
|
573 |
+
|
574 |
+
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) return;
|
575 |
+
|
576 |
+
// Calculate duration in days
|
577 |
+
const timeDiff = endDate.getTime() - startDate.getTime();
|
578 |
+
const dayDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
579 |
+
|
580 |
+
if (dayDiff <= 0) {
|
581 |
+
alert('La date de fin doit être postérieure à la date de début.');
|
582 |
+
return;
|
583 |
+
}
|
584 |
+
|
585 |
+
const dailyRate = parseFloat(document.getElementById('daily-rate').value) || 0;
|
586 |
+
const cleaningFee = parseFloat(document.getElementById('cleaning-fee').value) || 0;
|
587 |
+
const rentalPrice = dayDiff * dailyRate;
|
588 |
+
const totalPrice = rentalPrice + cleaningFee;
|
589 |
+
|
590 |
+
// Calculate deposit (30% rounded up to nearest 10)
|
591 |
+
const depositAmount = Math.ceil(totalPrice * 0.3 / 10) * 10;
|
592 |
+
|
593 |
+
// Update display
|
594 |
+
document.getElementById('stay-duration').textContent = `${dayDiff} nuitée${dayDiff > 1 ? 's' : ''}`;
|
595 |
+
document.getElementById('rental-price').textContent = `${rentalPrice.toFixed(2)} €`;
|
596 |
+
document.getElementById('cleaning-fee-display').textContent = `${cleaningFee.toFixed(2)} €`;
|
597 |
+
document.getElementById('total-price').textContent = `${totalPrice.toFixed(2)} €`;
|
598 |
+
|
599 |
+
// Update tenant tab display
|
600 |
+
document.getElementById('total-price-display').textContent = `${totalPrice.toFixed(2)} €`;
|
601 |
+
document.getElementById('deposit-amount').value = depositAmount;
|
602 |
+
document.getElementById('deposit-display').textContent = `${depositAmount.toFixed(2)} €`;
|
603 |
+
document.getElementById('balance-due').textContent = `${(totalPrice - depositAmount).toFixed(2)} €`;
|
604 |
+
}
|
605 |
+
|
606 |
+
// Calculate balance due
|
607 |
+
function calculateBalance() {
|
608 |
+
const totalPrice = parseFloat(document.getElementById('total-price').textContent) || 0;
|
609 |
+
const depositAmount = parseFloat(document.getElementById('deposit-amount').value) || 0;
|
610 |
+
const balanceDue = totalPrice - depositAmount;
|
611 |
+
|
612 |
+
document.getElementById('deposit-display').textContent = `${depositAmount.toFixed(2)} €`;
|
613 |
+
document.getElementById('balance-due').textContent = `${balanceDue.toFixed(2)} €`;
|
614 |
+
}
|
615 |
+
|
616 |
+
// Generate contract content
|
617 |
+
function generateContract() {
|
618 |
+
// Owner info
|
619 |
+
document.getElementById('owner-name').textContent = `${document.getElementById('owner-lastname').value} ${document.getElementById('owner-firstname').value}`;
|
620 |
+
document.getElementById('owner-address-display').textContent = document.getElementById('owner-address').value;
|
621 |
+
document.getElementById('owner-phone-display').textContent = document.getElementById('owner-phone').value;
|
622 |
+
document.getElementById('owner-email-display').textContent = document.getElementById('owner-email').value;
|
623 |
+
document.getElementById('owner-signature-name').textContent = `${document.getElementById('owner-lastname').value} ${document.getElementById('owner-firstname').value}`;
|
624 |
+
|
625 |
+
// Tenant info
|
626 |
+
const tenantCivility = document.querySelector('input[name="tenant-civility"]:checked').value;
|
627 |
+
document.getElementById('tenant-civility-display').textContent = tenantCivility;
|
628 |
+
document.getElementById('tenant-name').textContent = `${document.getElementById('tenant-lastname').value} ${document.getElementById('tenant-firstname').value}`;
|
629 |
+
document.getElementById('tenant-phone-display').textContent = document.getElementById('tenant-phone').value;
|
630 |
+
document.getElementById('tenant-email-display').textContent = document.getElementById('tenant-email').value;
|
631 |
+
document.getElementById('tenant-signature-name').textContent = `${document.getElementById('tenant-lastname').value} ${document.getElementById('tenant-firstname').value}`;
|
632 |
+
|
633 |
+
// Property info
|
634 |
+
document.getElementById('property-address-display').textContent = document.getElementById('property-address').value;
|
635 |
+
|
636 |
+
// Rental dates
|
637 |
+
const startDate = new Date(document.getElementById('rental-start').value);
|
638 |
+
const endDate = new Date(document.getElementById('rental-end').value);
|
639 |
+
const timeDiff = endDate.getTime() - startDate.getTime();
|
640 |
+
const dayDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
641 |
+
|
642 |
+
const options = { day: 'numeric', month: 'long', year: 'numeric' };
|
643 |
+
document.getElementById('rental-start-display').textContent = startDate.toLocaleDateString('fr-FR', options);
|
644 |
+
document.getElementById('rental-end-display').textContent = endDate.toLocaleDateString('fr-FR', options);
|
645 |
+
document.getElementById('stay-duration-display').textContent = dayDiff;
|
646 |
+
|
647 |
+
// Prices
|
648 |
+
document.getElementById('total-price-contract').textContent = document.getElementById('total-price').textContent;
|
649 |
+
document.getElementById('deposit-amount-display').textContent = document.getElementById('deposit-amount').value;
|
650 |
+
|
651 |
+
document.getElementById('balance-due-display').textContent = document.getElementById('balance-due').textContent.split(' ')[0];
|
652 |
+
|
653 |
+
// Contract date
|
654 |
+
const today = new Date();
|
655 |
+
document.getElementById('contract-date').textContent = today.toLocaleDateString('fr-FR', options);
|
656 |
+
}
|
657 |
+
|
658 |
+
// Export to PDF
|
659 |
+
document.getElementById('export-pdf').addEventListener('click', () => {
|
660 |
+
const { jsPDF } = window.jspdf;
|
661 |
+
const element = document.getElementById('contract-content');
|
662 |
+
|
663 |
+
html2canvas(element, {
|
664 |
+
scale: 2,
|
665 |
+
logging: false,
|
666 |
+
useCORS: true
|
667 |
+
}).then(canvas => {
|
668 |
+
const imgData = canvas.toDataURL('image/png');
|
669 |
+
const pdf = new jsPDF('p', 'mm', 'a4');
|
670 |
+
const imgWidth = 210; // A4 width in mm
|
671 |
+
const pageHeight = 295; // A4 height in mm
|
672 |
+
const imgHeight = canvas.height * imgWidth / canvas.width;
|
673 |
+
let heightLeft = imgHeight;
|
674 |
+
let position = 0;
|
675 |
+
|
676 |
+
pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
|
677 |
+
heightLeft -= pageHeight;
|
678 |
+
|
679 |
+
while (heightLeft >= 0) {
|
680 |
+
position = heightLeft - imgHeight;
|
681 |
+
pdf.addPage();
|
682 |
+
pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
|
683 |
+
heightLeft -= pageHeight;
|
684 |
+
}
|
685 |
+
|
686 |
+
const fileName = `contrat_location_${document.getElementById('tenant-lastname').value}_${document.getElementById('rental-start').value}.pdf`;
|
687 |
+
pdf.save(fileName);
|
688 |
+
});
|
689 |
+
});
|
690 |
+
|
691 |
+
// Export to Word
|
692 |
+
document.getElementById('export-word').addEventListener('click', () => {
|
693 |
+
const contractContent = document.getElementById('contract-content').innerHTML;
|
694 |
+
const preHtml = `<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'><head><meta charset='utf-8'><title>Contrat de location</title></head><body>`;
|
695 |
+
const postHtml = `<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=pointvirgule/easyloc" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body></html>
|