// S’assure que le DOM est complĂštement chargĂ© avant d’exĂ©cuter le script document.addEventListener(‘DOMContentLoaded’, () => { // Configuration des champs de saisie du calculateur, basĂ©e sur les donnĂ©es fournies. // Des ‘id’ et ‘unit’ ont Ă©tĂ© ajoutĂ©s pour faciliter la manipulation DOM et l’affichage. const dataConfig = [ {‘label’: ‘Surface du logement (mÂČ)’, ‘id’: ‘surface’, ‘type’: ‘number’, ‘min’: 15, ‘max’: 200, ‘step’: 5, ‘default’: 50, ‘unit’: ‘mÂČ’}, {‘label’: ‘Nombre de chambres’, ‘id’: ‘bedrooms’, ‘type’: ‘number’, ‘min’: 1, ‘max’: 5, ‘step’: 1, ‘default’: 2, ‘unit’: ‘chambre(s)’}, {‘label’: ‘Nombre de salles de bain’, ‘id’: ‘bathrooms’, ‘type’: ‘number’, ‘min’: 1, ‘max’: 3, ‘step’: 1, ‘default’: 1, ‘unit’: ‘salle(s) de bain’}, {‘label’: ‘Linge inclus’, ‘id’: ‘linen’, ‘type’: ‘boolean’, ‘default’: true, ‘description’: ‘(lavage, sĂ©chage, pliage, mise en place)’}, {‘label’: ‘Consommables (savons, papier toilette…)’, ‘id’: ‘consumables’, ‘type’: ‘boolean’, ‘default’: true, ‘description’: ‘(rĂ©approvisionnement)’}, {‘label’: ‘Temps estimĂ© (heures)’, ‘id’: ‘userTimeOverride’, ‘type’: ‘number’, ‘min’: 1, ‘max’: 8, ‘step’: 0.5, ‘default’: 3, ‘unit’: ‘heures’} // Ce champ sera d’abord calculĂ©, puis ajustable par l’utilisateur ]; // RĂ©fĂ©rences aux Ă©lĂ©ments DOM oĂč les inputs seront gĂ©nĂ©rĂ©s et oĂč les rĂ©sultats seront affichĂ©s const calculatorInputsDiv = document.getElementById(‘calculatorInputs’); const hourlyRateInput = document.getElementById(‘hourlyRate’); const estimatedTimeSpan = document.getElementById(‘estimatedTime’); const consumablesCostSpan = document.getElementById(‘consumablesCost’); const estimatedPriceSpan = document.getElementById(‘estimatedPrice’); // — ParamĂštres de calcul de base (ajustables selon le marchĂ© et l’expĂ©rience) — const CALC_PARAMS = { BASE_TIME_PER_SQM: 0.04, // Temps de nettoyage de base par mĂštre carrĂ© (ex: 0.04h = 2.4 minutes/mÂČ) TIME_PER_ADDITIONAL_BEDROOM: 0.25, // Temps additionnel par chambre au-delĂ  de la premiĂšre (ex: 0.25h = 15 minutes) TIME_PER_ADDITIONAL_BATHROOM: 0.5, // Temps additionnel par salle de bain au-delĂ  de la premiĂšre (ex: 0.5h = 30 minutes) TIME_FOR_LINEN: 0.75, // Temps additionnel si le service de linge est inclus (ex: 0.75h = 45 minutes) COST_FOR_CONSUMABLES: 5 // CoĂ»t fixe pour les consommables si inclus (en euros) }; /** * GĂ©nĂšre dynamiquement les champs de saisie (inputs) dans le DOM * basĂ©s sur la configuration `dataConfig`. */ function generateInputs() { dataConfig.forEach(config => { const div = document.createElement(‘div’); div.className = ‘flex flex-col’; const label = document.createElement(‘label’); label.htmlFor = config.id; label.className = ‘block text-sm font-medium text-gray-700 mb-1’; label.textContent = config.label; div.appendChild(label); // Ajoute une description si spĂ©cifiĂ©e dans la configuration if (config.description) { const desc = document.createElement(‘p’); desc.className = ‘text-xs text-gray-500 mb-1’; desc.textContent = config.description; div.appendChild(desc); } // CrĂ©e un champ de type ‘number’ if (config.type === ‘number’) { const input = document.createElement(‘input’); input.type = ‘number’; input.id = config.id; input.min = config.min; input.max = config.max; input.step = config.step; input.value = config.default; input.className = ‘p-3 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500 text-gray-900’; input.setAttribute(‘aria-label’, config.label); input.addEventListener(‘input’, calculateEstimation); // Écoute les changements pour recalculer const inputWrapper = document.createElement(‘div’); inputWrapper.className = ‘relative flex items-center’; inputWrapper.appendChild(input); // Ajoute l’unitĂ© si spĂ©cifiĂ©e (ex: mÂČ, heures) if (config.unit) { const unitSpan = document.createElement(‘span’); unitSpan.className = ‘absolute right-3 text-gray-500 text-sm’; unitSpan.textContent = config.unit; inputWrapper.appendChild(unitSpan); input.style.paddingRight = ’50px’; // Ajuste le padding pour Ă©viter que le texte ne chevauche l’unitĂ© } div.appendChild(inputWrapper); } else if (config.type === ‘boolean’) { // CrĂ©e un champ de type ‘checkbox’ (toggle visuel) const toggleContainer = document.createElement(‘div’); toggleContainer.className = ‘relative inline-flex items-center cursor-pointer’; const input = document.createElement(‘input’); input.type = ‘checkbox’; input.id = config.id; input.checked = config.default; input.className = ‘sr-only peer’; // Masque l’input original input.setAttribute(‘aria-label’, config.label); input.addEventListener(‘change’, calculateEstimation); // Écoute les changements // CrĂ©e la piste visuelle du toggle const track = document.createElement(‘div’); track.className = ‘w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[”] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600’; toggleContainer.appendChild(input); toggleContainer.appendChild(track); div.appendChild(toggleContainer); } calculatorInputsDiv.appendChild(div); }); } /** * Effectue le calcul de l’estimation du temps et du coĂ»t de la prestation. * Cette fonction est appelĂ©e Ă  chaque modification d’un champ de saisie. */ function calculateEstimation() { // RĂ©cupĂšre les valeurs actuelles de tous les champs de saisie const surface = parseFloat(document.getElementById(‘surface’).value) || 0; const bedrooms = parseInt(document.getElementById(‘bedrooms’).value) || 0; const bathrooms = parseInt(document.getElementById(‘bathrooms’).value) || 0; const linenIncluded = document.getElementById(‘linen’).checked; const consumablesIncluded = document.getElementById(‘consumables’).checked; const hourlyRate = parseFloat(hourlyRateInput.value) || 0; // 1. Calcul du temps de base en fonction de la surface let calculatedSuggestedTime = surface * CALC_PARAMS.BASE_TIME_PER_SQM; // 2. Temps additionnel pour les chambres (si plus d’une) if (bedrooms > 1) { calculatedSuggestedTime += (bedrooms – 1) * CALC_PARAMS.TIME_PER_ADDITIONAL_BEDROOM; } // 3. Temps additionnel pour les salles de bain (si plus d’une) if (bathrooms > 1) { calculatedSuggestedTime += (bathrooms – 1) * CALC_PARAMS.TIME_PER_ADDITIONAL_BATHROOM; } // 4. Temps additionnel si le service de linge est inclus if (linenIncluded) { calculatedSuggestedTime += CALC_PARAMS.TIME_FOR_LINEN; } // Assure que le temps suggĂ©rĂ© respecte les limites min/max du champ ‘userTimeOverride’ const userTimeOverrideConfig = dataConfig.find(config => config.id === ‘userTimeOverride’); if (userTimeOverrideConfig) { calculatedSuggestedTime = Math.max(userTimeOverrideConfig.min, Math.min(calculatedSuggestedTime, userTimeOverrideConfig.max)); } // 5. GĂšre le champ “Temps estimĂ© (heures)” qui peut ĂȘtre override par l’utilisateur const userTimeInput = document.getElementById(‘userTimeOverride’); let finalEstimatedTimeForPrice = calculatedSuggestedTime; // Par dĂ©faut, utilise le temps calculĂ© const currentInputValue = parseFloat(userTimeInput.value); // Si la valeur saisie par l’utilisateur est trĂšs proche du temps calculĂ©, // ou si l’input est vide/invalide, on met Ă  jour l’input avec notre suggestion. // Sinon (l’utilisateur a explicitement modifiĂ© l’input), on respecte sa valeur. const tolerance = 0.1; // TolĂ©rance pour la comparaison des nombres flottants if (isNaN(currentInputValue) || Math.abs(currentInputValue – calculatedSuggestedTime) < tolerance) { userTimeInput.value = calculatedSuggestedTime.toFixed(2); } else { finalEstimatedTimeForPrice = currentInputValue; // Utilise la valeur override de l'utilisateur } // 6. Calcul du coĂ»t des consommables const currentConsumablesCost = consumablesIncluded ? CALC_PARAMS.COST_FOR_CONSUMABLES : 0; // 7. Calcul du prix total de la prestation const estimatedTotalPrice = (finalEstimatedTimeForPrice * hourlyRate) + currentConsumablesCost; // Affichage des rĂ©sultats dans le DOM estimatedTimeSpan.textContent = finalEstimatedTimeForPrice.toFixed(2); consumablesCostSpan.textContent = currentConsumablesCost.toFixed(2); estimatedPriceSpan.textContent = estimatedTotalPrice.toFixed(2); } // — Initialisation du calculateur — // 1. GĂ©nĂšre tous les champs de saisie generateInputs(); // 2. Ajoute un Ă©couteur sur le champ du taux horaire pour dĂ©clencher le recalcul hourlyRateInput.addEventListener('input', calculateEstimation); // 3. Effectue un premier calcul pour afficher les valeurs par dĂ©faut au chargement calculateEstimation(); });

{“@context”:”https://schema.org”,”@type”:”FAQPage”,”mainEntity”:[{“@type”:”Question”,”name”:”Quelles sont les compu00e9tences essentielles pour devenir prestataire de mu00e9nage Airbnb u00e0 Poligny ? “,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Pour ru00e9ussir, un prestataire de mu00e9nage Airbnb u00e0 Poligny doit faire preuve d’un sens aigu du du00e9tail, u00eatre capable de respecter des du00e9lais courts entre les locations, connau00eetre les standards de propretu00e9 spu00e9cifiques u00e0 Airbnb, et mau00eetriser la gestion de l’entretien du linge (draps, serviettes, etc.). La fiabilitu00e9 et la proactivitu00e9 sont u00e9galement cruciales.”}},{“@type”:”Question”,”name”:”Comment trouver des missions ru00e9guliu00e8res de nettoyage Airbnb u00e0 Poligny ? “,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Il existe plusieurs stratu00e9gies : s’inscrire sur des plateformes spu00e9cialisu00e9es, contacter directement des agences de conciergerie Airbnb locales comme Manasteos, du00e9velopper son ru00e9seau par le bouche-u00e0-oreille aupru00e8s des propriu00e9taires, et promouvoir ses services sur les ru00e9seaux sociaux ou via des annonces locales.”}},{“@type”:”Question”,”name”:”Est-il nu00e9cessaire d’avoir un statut lu00e9gal pour u00eatre prestataire de mu00e9nage Airbnb ? “,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Oui, il est fortement recommandu00e9 de cru00e9er un statut lu00e9gal, comme celui d’auto-entrepreneur. Ce statut simplifie les du00e9marches administratives, permet de facturer lu00e9galement les prestations, de cotiser pour sa protection sociale et de bu00e9nu00e9ficier d’un ru00e9gime fiscal simplifiu00e9. Cela inspire u00e9galement confiance aux propriu00e9taires.”}},{“@type”:”Question”,”name”:”Comment optimiser sa ru00e9munu00e9ration en tant que prestataire de mu00e9nage Airbnb ? “,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Pour optimiser sa ru00e9munu00e9ration, il convient d’u00e9tablir des tarifs fixes transparents, d’offrir des services additionnels (gestion complu00e8te du linge, ru00e9approvisionnement des consommables, petites ru00e9parations), de fidu00e9liser sa clientu00e8le par la qualitu00e9 et la communication, et d’optimiser sa logistique et ses du00e9placements.”}}]}