/* Styles personnalisés pour le tableau et les éléments interactifs */
/* Utilisez des noms de classe uniques pour éviter les conflits CSS */
.airbnb-cleaning-comparator {
font-family: ‘Segoe UI’, Tahoma, Geneva, Verdana, sans-serif; /* Police moderne et lisible */
max-width: 100%; /* S’adapte Ă la largeur du conteneur parent */
margin: 2rem auto; /* Centrage et espacement vertical */
padding: 1.5rem;
border-radius: 0.75rem; /* Coins arrondis */
background-color: #ffffff;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* Ombre douce */
max-height: 2000px; /* Contrainte de hauteur maximale */
overflow-y: auto; /* Permet le défilement si le contenu dépasse la hauteur maximale */
color: #333;
line-height: 1.6;
}
.airbnb-cleaning-comparator h2 {
font-size: 2.25rem; /* Taille de titre plus grande */
font-weight: 700; /* Gras */
color: #2c3e50; /* Couleur de titre plus sombre */
margin-bottom: 2rem;
text-align: center;
letter-spacing: -0.025em; /* Léger espacement pour le titre */
}
.airbnb-cleaning-comparator input[type=”text”] {
padding: 0.75rem 1rem;
border: 1px solid #cbd5e0; /* Couleur de bordure plus neutre */
border-radius: 0.5rem;
width: 100%;
max-width: 400px; /* Limiter la largeur de l’input */
display: block; /* S’assure que l’input prend une nouvelle ligne */
margin: 0 auto 1.5rem auto; /* Centrer l’input */
font-size: 1rem;
color: #4a5568;
outline: none;
transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
}
.airbnb-cleaning-comparator input[type=”text”]:focus {
border-color: #6a40df; /* Une couleur violette plus profonde */
box-shadow: 0 0 0 3px rgba(106, 64, 223, 0.2);
}
.airbnb-cleaning-comparator .table-container {
overflow-x: auto; /* Permet le défilement horizontal sur petits écrans */
border-radius: 0.5rem;
border: 1px solid #e2e8f0; /* Bordure de conteneur de tableau */
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
}
.airbnb-cleaning-comparator table {
width: 100%;
border-collapse: collapse;
text-align: left;
min-width: 768px; /* Assure que le tableau reste lisible sur des écrans plus petits */
}
.airbnb-cleaning-comparator th, .airbnb-cleaning-comparator td {
padding: 1rem 1.25rem;
border-bottom: 1px solid #edf2f7; /* Bordure plus claire */
}
.airbnb-cleaning-comparator th {
background-color: #f8f9fa; /* Fond d’en-tĂȘte trĂšs clair */
font-weight: 600;
color: #4a5568;
cursor: pointer;
user-select: none;
white-space: nowrap;
transition: background-color 0.2s ease-in-out;
}
.airbnb-cleaning-comparator th:hover {
background-color: #f1f3f5; /* Léger changement au survol */
}
.airbnb-cleaning-comparator th.sort-asc::after {
content: ‘ âČ’;
font-size: 0.7em; /* Plus petit */
vertical-align: super;
color: #6a40df; /* Couleur accentuĂ©e pour l’indicateur */
}
.airbnb-cleaning-comparator th.sort-desc::after {
content: ‘ ⌒;
font-size: 0.7em;
vertical-align: super;
color: #6a40df;
}
.airbnb-cleaning-comparator tbody tr:hover {
background-color: #fbfdff; /* Effet de survol trĂšs subtil pour les lignes du tableau */
}
.airbnb-cleaning-comparator tbody tr:nth-child(even) {
background-color: #fdfdfe; /* LégÚre alternance de couleur de ligne */
}
.airbnb-cleaning-comparator tbody tr:last-child td {
border-bottom: none;
}
.airbnb-cleaning-comparator td {
color: #4a5568;
}
/* Styles spécifiques pour Description et Avantages clés pour permettre le retour à la ligne */
.airbnb-cleaning-comparator td:nth-child(2),
.airbnb-cleaning-comparator td:nth-child(4) {
white-space: normal;
word-wrap: break-word; /* Assure le retour Ă la ligne pour les mots longs */
max-width: 250px; /* Limite la largeur de ces colonnes pour ne pas trop étirer le tableau */
}
/* Ajustement de la largeur des colonnes pour un meilleur équilibre */
.airbnb-cleaning-comparator th:nth-child(1), .airbnb-cleaning-comparator td:nth-child(1) { width: 15%; } /* Service */
.airbnb-cleaning-comparator th:nth-child(2), .airbnb-cleaning-comparator td:nth-child(2) { width: 35%; } /* Description */
.airbnb-cleaning-comparator th:nth-child(3), .airbnb-cleaning-comparator td:nth-child(3) { width: 15%; } /* Tarif */
.airbnb-cleaning-comparator th:nth-child(4), .airbnb-cleaning-comparator td:nth-child(4) { width: 35%; } /* Avantages */
// Bloc de données JSON pour le tableau comparatif
// Aucune API externe n’est utilisĂ©e, les donnĂ©es sont directement intĂ©grĂ©es dans le code.
// URL API/Exemple JSON: N/A – DonnĂ©es statiques locales.
const tableData = {
“title”: “Comparaison DĂ©taillĂ©e des Services de MĂ©nage Airbnb Ă Strasbourg ”,
“headers”: [“Service”, “Description”, “Tarif Indicatif”, “Avantages clĂ©s”],
“rows”: [
[“Nettoyage Standard”, “Aspiration/lavage des sols, nettoyage des surfaces , dĂ©sinfection des sanitaires, nettoyage de la cuisine (hors vaisselle spĂ©cifique), vidage des poubelles. Convient pour les sĂ©jours courts avec peu d’entretien .”, “Ă partir de 40⏔, “â
Essentiel, rapide, Ă©conomique. IdĂ©al pour une remise en Ă©tat basique avant ou aprĂšs un court sĂ©jour.”],
[“Nettoyage Complet”, “Inclut tous les services du Nettoyage Standard + nettoyage des placards et tiroirs, intĂ©rieur/extĂ©rieur de l’Ă©lectromĂ©nager, gestion et mise en place du linge de maison frais (lavĂ© et repassĂ©), rĂ©approvisionnement des consommables de base (papier toilette, savon, etc.), et un contrĂŽle inventaire simple.”, “Ă partir de 60⏔, “âš SĂ©rĂ©nitĂ© totale pour l’hĂŽte. Garantit une expĂ©rience premium pour les voyageurs. PrĂ©pare le logement pour le prochain arrivant sans intervention de votre part.”],
[“Nettoyage Express”, “Conçu pour les turnovers trĂšs rapides. Nettoyage ciblĂ© des zones visibles, lits faits (avec linge fourni par l’hĂŽte), sanitaires rafraĂźchis, poubelles vidĂ©es. Pour un dĂ©part et une arrivĂ©e le mĂȘme jour avec peu de temps entre les deux.”, “Ă partir de 30⏔, “âĄïž IdĂ©al pour maximiser le taux d’occupation. RĂ©duit le temps d’attente entre deux rĂ©servations . Parfait pour les sĂ©jours d’une nuit.”],
[“Nettoyage Approfondi”, “Comprend le Nettoyage Complet + nettoyage des vitres intĂ©rieures, dĂ©poussiĂ©rage mĂ©ticuleux des plinthes et luminaires, nettoyage en profondeur du four, du rĂ©frigĂ©rateur et des micro-ondes, nettoyage des murs (tĂąches localisĂ©es), et entretien des terrasses/balcons si applicables.”, “Ă partir de 90⏔, “đ Maintient le logement impeccable sur le long terme. PrĂ©vient l’usure prĂ©maturĂ©e et garantit un logement toujours au top. RecommandĂ© trimestriellement ou semestriellement.”],
[“Service PersonnalisĂ©”, “CrĂ©ation d’une liste de tĂąches sur mesure selon vos besoins spĂ©cifiques (ex: arrosage des plantes, gestion de clĂ©s, courses spĂ©cifiques, vĂ©rification d’Ă©quipement particulier ). Le tarif est basĂ© sur le temps passĂ© ou un devis spĂ©cifique.”, “Sur devis”, “âïž FlexibilitĂ© maximale. RĂ©ponse Ă des besoins uniques et spĂ©cifiques Ă votre propriĂ©tĂ© ou Ă vos voyageurs. Un vrai partenaire de confiance.”]
]
};
// Références aux éléments DOM
const comparatorTitle = document.getElementById(‘comparator-title’);
const searchInput = document.getElementById(‘search-input’);
const tableHeadRow = document.querySelector(‘#comparison-table thead tr’);
const tableBody = document.getElementById(‘comparison-table-body’);
// Ătat du tri
let currentSortColumnIndex = -1; // -1 pour aucun tri initial
let sortDirection = ‘asc’; // ‘asc’ ou ‘desc’
// Copie des donnĂ©es initiales pour pouvoir filtrer/trier sans modifier l’original
let currentRows = […tableData.rows];
/**
* Extrait le prix numĂ©rique d’une chaĂźne de caractĂšres de tarif.
* GĂšre les formats comme “Ă partir de 40⏔ ou “Sur devis”.
* @param {string} priceString – La chaĂźne de caractĂšres du tarif.
* @returns {number|null} Le prix numĂ©rique ou null si non chiffrable (ex: “Sur devis”).
*/
function extractPrice(priceString) {
const match = priceString.match(/d+/); // Recherche un ou plusieurs chiffres
return match ? parseInt(match[0], 10) : null;
}
/**
* Affiche ou met à jour les lignes du tableau avec les données fournies.
* @param {Array<Array>} rows – Les donnĂ©es des lignes Ă afficher.
*/
function renderTable(rows) {
tableBody.innerHTML = ”; // Vide le corps du tableau actuel
if (rows.length === 0) {
const noResultsRow = document.createElement(‘tr’);
noResultsRow.innerHTML = `Aucun résultat trouvé pour votre recherche.`;
tableBody.appendChild(noResultsRow);
return;
}
rows.forEach(rowData => {
const tr = document.createElement(‘tr’);
rowData.forEach(cellData => {
const td = document.createElement(‘td’);
td.textContent = cellData;
tr.appendChild(td);
});
tableBody.appendChild(tr);
});
}
/**
* CrĂ©e et affiche les en-tĂȘtes du tableau avec les fonctions de tri.
* @param {Array} headers – Les noms des en-tĂȘtes.
*/
function renderHeaders(headers) {
tableHeadRow.innerHTML = ”; // Vide les en-tĂȘtes actuels
headers.forEach((headerText, index) => {
const th = document.createElement(‘th’);
th.textContent = headerText;
th.setAttribute(‘data-column-index’, index);
// Ajout de classes Tailwind pour un style cohérent, bien que le style.css prenne le dessus pour les rÚgles spécifiques
th.classList.add(‘px-4’, ‘py-2’, ‘text-left’, ‘font-medium’, ‘text-gray-700’, ‘uppercase’, ‘tracking-wider’);
// Ajoute l’icĂŽne de tri si c’est la colonne actuellement triĂ©e
if (index === currentSortColumnIndex) {
th.classList.add(`sort-${sortDirection}`);
}
th.addEventListener(‘click’, () => sortData(index));
tableHeadRow.appendChild(th);
});
}
/**
* Trie les données du tableau en fonction de la colonne et de la direction spécifiées.
* @param {number} columnIndex – L’index de la colonne Ă trier.
*/
function sortData(columnIndex) {
// Si la mĂȘme colonne est cliquĂ©e, inverse la direction du tri
if (currentSortColumnIndex === columnIndex) {
sortDirection = sortDirection === ‘asc’ ? ‘desc’ : ‘asc’;
} else {
// Sinon, dĂ©finit la nouvelle colonne de tri et rĂ©initialise la direction Ă ‘asc’
currentSortColumnIndex = columnIndex;
sortDirection = ‘asc’;
}
// Identifie si la colonne est la colonne “Tarif Indicatif” pour un tri numĂ©rique
const isPriceColumn = tableData.headers[columnIndex] === “Tarif Indicatif”;
currentRows.sort((a, b) => {
let valA = a[columnIndex];
let valB = b[columnIndex];
if (isPriceColumn) {
valA = extractPrice(valA);
valB = extractPrice(valB);
// GĂšre les valeurs null (ex: “Sur devis”) en les plaçant Ă la fin pour le tri ascendant,
// et au début pour le tri descendant, pour une meilleure UX.
if (valA === null && valB === null) return 0;
if (valA === null) return sortDirection === ‘asc’ ? 1 : -1; // null va aprĂšs les nombres en asc, avant en desc
if (valB === null) return sortDirection === ‘asc’ ? -1 : 1; // null va aprĂšs les nombres en asc, avant en desc
} else {
// Pour un tri alphabétique, assure que les valeurs sont des chaßnes de caractÚres
valA = String(valA).toLowerCase();
valB = String(valB).toLowerCase();
}
if (valA valB) {
return sortDirection === ‘asc’ ? 1 : -1;
}
return 0;
});
renderTable(currentRows); // Met à jour le tableau avec les données triées
renderHeaders(tableData.headers); // Met Ă jour les en-tĂȘtes pour afficher l’icĂŽne de tri
}
/**
* Filtre les données du tableau en fonction du terme de recherche.
* @param {string} searchTerm – Le terme Ă rechercher.
*/
function filterData(searchTerm) {
const lowerCaseSearchTerm = searchTerm.toLowerCase().trim();
if (!lowerCaseSearchTerm) {
currentRows = […tableData.rows]; // RĂ©initialise Ă toutes les donnĂ©es si la recherche est vide
} else {
currentRows = tableData.rows.filter(row =>
row.some(cell => String(cell).toLowerCase().includes(lowerCaseSearchTerm))
);
}
// Applique le tri existant aprÚs le filtrage si une colonne est déjà triée
if (currentSortColumnIndex !== -1) {
// Pour rĂ©appliquer le tri, nous appelons simplement sortData avec l’index actuel.
// La fonction sortData contient déjà la logique pour gérer la direction et ré-afficher le tableau.
sortData(currentSortColumnIndex);
} else {
renderTable(currentRows); // Sinon, affiche juste les données filtrées
}
}
// Initialisation du tableau aprĂšs le chargement du DOM
document.addEventListener(‘DOMContentLoaded’, () => {
comparatorTitle.textContent = tableData.title; // Définit le titre
renderHeaders(tableData.headers); // Affiche les en-tĂȘtes
renderTable(currentRows); // Affiche les données initiales
// Ăcoute l’Ă©vĂ©nement de saisie pour la recherche
searchInput.addEventListener(‘keyup’, (event) => {
filterData(event.target.value);
});
});
{“@context”:”https://schema.org”,”@type”:”FAQPage”,”mainEntity”:[{“@type”:”Question”,”name”:”Comment trouver mes premiu00e8res missions de nettoyage Airbnb u00e0 Strasbourg ? (Question fru00e9quente sur les missions ru00e9guliu00e8res)”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Pour trouver vos premiu00e8res missions de nettoyage Airbnb u00e0 Strasbourg, il est conseillu00e9 de commencer par le ru00e9seau de co-hu00f4tes Airbnb. Cette plateforme met en relation les propriu00e9taires avec des professionnels locaux. Inscrivez-vous, cru00e9ez un profil du00e9taillu00e9 mettant en avant vos compu00e9tences, votre fiabilitu00e9 et votre connaissance de la ville. Contactez u00e9galement les conciergeries locales spu00e9cialisu00e9es dans la gestion de locations courte duru00e9e u00e0 Strasbourg. Elles ont un besoin constant de prestataires et peuvent vous fournir des missions ru00e9guliu00e8res. Le bouche-u00e0-oreille reste u00e9galement tru00e8s efficace : parlez de votre activitu00e9 autour de vous, notamment aupru00e8s des propriu00e9taires ou des agences immobiliu00e8res. La clu00e9 est de du00e9montrer votre professionnalisme et votre ru00e9activitu00e9 du00e8s les premiu00e8res interactions.”}},{“@type”:”Question”,”name”:”Quelles sont les ru00e9glementations spu00e9cifiques u00e0 Strasbourg pour le mu00e9nage Airbnb que je dois connau00eetre ?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”En tant que prestataire de mu00e9nage, il est essentiel de comprendre les ru00e9glementations Airbnb u00e0 Strasbourg. La principale distinction concerne les ru00e9sidences principales (limitu00e9es u00e0 120 jours de location par an et nu00e9cessitant une du00e9claration en mairie avec un numu00e9ro d’enregistrement) et les ru00e9sidences secondaires (soumises u00e0 des ru00e8gles plus strictes, incluant souvent une autorisation de changement d’usage et une compensation). Bien que ces ru00e8gles concernent directement les hu00f4tes, votre connaissance de ces aspects vous permettra de mieux comprendre leurs contraintes et d’adapter votre service. Par exemple, un hu00f4te de ru00e9sidence principale aura des missions plus espacu00e9es. Travailler avec des conciergeries assure souvent que les logements sont en conformitu00e9, vous offrant ainsi un cadre de travail su00e9curisu00e9.”}},{“@type”:”Question”,”name”:”Quels sont les avantages de travailler avec une conciergerie locale pour le nettoyage Airbnb ?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Travailler avec une conciergerie locale pru00e9sente de nombreux avantages pour un prestataire de mu00e9nage. Elles offrent une ru00e9munu00e9ration attractive avec des tarifs fixes et des paiements rapides, ainsi qu’une flexibilitu00e9 totale pour accepter ou refuser les missions selon vos disponibilitu00e9s. La proximitu00e9 des missions, souvent situu00e9es dans vos quartiers pru00e9fu00e9ru00e9s de Strasbourg, ru00e9duit les temps de trajet. De plus, les conciergeries locales gu00e8rent l’interface avec les hu00f4tes, les plannings complexes et les impru00e9vus, vous permettant de vous concentrer pleinement sur la qualitu00e9 du nettoyage. Elles sont une source stable de missions ru00e9guliu00e8res et peuvent vous aider u00e0 du00e9velopper votre ru00e9putation et votre expertise dans la gu00e9rance Airbnb.”}},{“@type”:”Question”,”name”:”Comment puis-je augmenter mes revenus en tant que prestataire de mu00e9nage Airbnb u00e0 Strasbourg ?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Pour augmenter vos revenus, plusieurs stratu00e9gies peuvent u00eatre mises en place. Premiu00e8rement, u00e9largissez votre gamme de services au-delu00e0 du simple nettoyage : proposez la gestion du linge, le ru00e9approvisionnement des consommables, des services de petite maintenance, ou mu00eame le check-in/check-out des voyageurs. Ces services additionnels sont souvent tru00e8s demandu00e9s et mieux ru00e9munu00e9ru00e9s. Deuxiu00e8mement, optimisez votre temps en utilisant des techniques de nettoyage efficaces et des outils de planification. Troisiu00e8mement, bu00e2tissez une excellente ru00e9putation gru00e2ce u00e0 la qualitu00e9 constante de votre travail et aux retours positifs des clients, ce qui vous permettra d’attirer plus de missions et potentiellement de nu00e9gocier de meilleurs tarifs. Enfin, explorez des partenariats avec d’autres prestataires ou agences immobiliu00e8res pour diversifier vos sources de missions en plus de la gu00e9rance Airbnb.”}}]}
Pour offrir les meilleures expériences, nous utilisons des technologies telles que les cookies pour stocker et/ou accéder aux informations des appareils. Le fait de consentir à ces technologies nous permettra de traiter des données telles que le comportement de navigation ou les ID uniques sur ce site. Le fait de ne pas consentir ou de retirer son consentement peut avoir un effet négatif sur certaines caractéristiques et fonctions.
LâaccĂšs ou le stockage technique est strictement nĂ©cessaire dans la finalitĂ© dâintĂ©rĂȘt lĂ©gitime de permettre lâutilisation dâun service spĂ©cifique explicitement demandĂ© par lâabonnĂ© ou lâutilisateur, ou dans le seul but dâeffectuer la transmission dâune communication sur un rĂ©seau de communications Ă©lectroniques.
LâaccĂšs ou le stockage technique est nĂ©cessaire dans la finalitĂ© dâintĂ©rĂȘt lĂ©gitime de stocker des prĂ©fĂ©rences qui ne sont pas demandĂ©es par lâabonnĂ© ou lâinternaute.
Le stockage ou lâaccĂšs technique qui est utilisĂ© exclusivement Ă des fins statistiques.
Le stockage ou lâaccĂšs technique qui est utilisĂ© exclusivement dans des finalitĂ©s statistiques anonymes. En lâabsence dâune assignation Ă comparaĂźtre, dâune conformitĂ© volontaire de la part de votre fournisseur dâaccĂšs Ă internet ou dâenregistrements supplĂ©mentaires provenant dâune tierce partie, les informations stockĂ©es ou extraites Ă cette seule fin ne peuvent gĂ©nĂ©ralement pas ĂȘtre utilisĂ©es pour vous identifier.
LâaccĂšs ou le stockage technique est nĂ©cessaire pour crĂ©er des profils dâinternautes afin dâenvoyer des publicitĂ©s, ou pour suivre lâutilisateur sur un site web ou sur plusieurs sites web ayant des finalitĂ©s marketing similaires.
Gérer le consentement