Pharmacies De Garde Tanger
Phardegarde est un site qui fournit des informations sur les pharmacies de garde tanger. Il aide les habitants et les visiteurs à trouver rapidement les pharmacies de garde tanger ouvertes la nuit, les week-ends et les jours fériés.
https://smmstores1.blogspot.com
#pharmacies-widget-fr * {
box-sizing: border-box;
}
#pharmacies-widget-fr {
font-family: Arial, sans-serif;
background: #f4f6fb;
padding: 20px 14px 35px;
direction: ltr;
}
#pharmacies-widget-fr .pw-wrap {
max-width: 1100px;
margin: 0 auto;
}
#pharmacies-widget-fr .pw-header {
text-align: center;
margin-bottom: 20px;
}
#pharmacies-widget-fr .pw-header h2 {
margin: 0;
font-size: 30px;
font-weight: 800;
color: #1a1a2e;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
#pharmacies-widget-fr .pw-date {
margin-top: 8px;
color: #666;
font-size: 14px;
}
#pharmacies-widget-fr .pw-notice {
background: #fff8e1;
border-left: 4px solid #f5a623;
border-radius: 10px;
padding: 12px 16px;
margin-bottom: 22px;
color: #7a5c00;
font-size: 14px;
line-height: 1.7;
}
#pharmacies-widget-fr .pw-status {
background: #ffffff;
border-radius: 12px;
padding: 14px 16px;
margin-bottom: 18px;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
color: #444;
font-size: 14px;
}
#pharmacies-widget-fr .pw-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 18px;
}
@media (max-width: 900px) {
#pharmacies-widget-fr .pw-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 560px) {
#pharmacies-widget-fr .pw-grid {
grid-template-columns: 1fr;
}
}
#pharmacies-widget-fr .pw-card {
background: #fff;
border-radius: 18px;
padding: 18px 16px 16px;
box-shadow: 0 4px 18px rgba(0,0,0,0.07);
display: flex;
flex-direction: column;
gap: 10px;
position: relative;
overflow: hidden;
transition: transform 0.2s, box-shadow 0.2s;
min-height: 250px;
}
#pharmacies-widget-fr .pw-card:hover {
transform: translateY(-3px);
box-shadow: 0 8px 28px rgba(0,0,0,0.12);
}
#pharmacies-widget-fr .pw-card::before {
content: '';
position: absolute;
top: -12px;
left: -12px;
width: 60px;
height: 60px;
border-radius: 50%;
opacity: 0.08;
}
#pharmacies-widget-fr .c1::before { background: #e53935; }
#pharmacies-widget-fr .c2::before { background: #1e88e5; }
#pharmacies-widget-fr .c3::before { background: #43a047; }
#pharmacies-widget-fr .c4::before { background: #fb8c00; }
#pharmacies-widget-fr .c5::before { background: #8e24aa; }
#pharmacies-widget-fr .c6::before { background: #00897b; }
#pharmacies-widget-fr .pw-badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border-radius: 20px;
font-size: 12px;
font-weight: 700;
width: fit-content;
}
#pharmacies-widget-fr .pw-badge.ok {
background: #e8f5e9;
color: #2e7d32;
}
#pharmacies-widget-fr .pw-badge.partial {
background: #fff3e0;
color: #ef6c00;
}
#pharmacies-widget-fr .pw-badge.unknown {
background: #eceff1;
color: #455a64;
}
#pharmacies-widget-fr .pw-title {
font-size: 18px;
font-weight: 800;
color: #1a1a2e;
line-height: 1.5;
padding-right: 50px;
}
#pharmacies-widget-fr .pw-pill {
position: absolute;
top: 14px;
right: 14px;
width: 42px;
height: 42px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 18px;
font-weight: bold;
}
#pharmacies-widget-fr .c1 .pw-pill { background: #e53935; }
#pharmacies-widget-fr .c2 .pw-pill { background: #1e88e5; }
#pharmacies-widget-fr .c3 .pw-pill { background: #43a047; }
#pharmacies-widget-fr .c4 .pw-pill { background: #fb8c00; }
#pharmacies-widget-fr .c5 .pw-pill { background: #8e24aa; }
#pharmacies-widget-fr .c6 .pw-pill { background: #00897b; }
#pharmacies-widget-fr .pw-info {
display: flex;
flex-direction: column;
gap: 8px;
}
#pharmacies-widget-fr .pw-row {
display: flex;
align-items: flex-start;
gap: 9px;
font-size: 14px;
color: #444;
line-height: 1.6;
word-break: break-word;
}
#pharmacies-widget-fr .pw-row .pw-ico {
width: 16px;
flex-shrink: 0;
text-align: center;
margin-top: 2px;
}
#pharmacies-widget-fr .pw-row a {
color: #1976d2;
font-weight: 700;
text-decoration: none;
}
#pharmacies-widget-fr .pw-row a:hover {
text-decoration: underline;
}
#pharmacies-widget-fr .pw-map-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 10px 14px;
border-radius: 10px;
font-size: 14px;
font-weight: 700;
text-decoration: none;
color: #fff;
margin-top: auto;
transition: opacity 0.2s, transform 0.15s;
}
#pharmacies-widget-fr .pw-map-btn:hover {
opacity: 0.9;
transform: scale(0.98);
}
#pharmacies-widget-fr .c1 .pw-map-btn { background: linear-gradient(135deg, #e53935, #ef9a9a); }
#pharmacies-widget-fr .c2 .pw-map-btn { background: linear-gradient(135deg, #1e88e5, #90caf9); }
#pharmacies-widget-fr .c3 .pw-map-btn { background: linear-gradient(135deg, #43a047, #a5d6a7); }
#pharmacies-widget-fr .c4 .pw-map-btn { background: linear-gradient(135deg, #fb8c00, #ffcc80); }
#pharmacies-widget-fr .c5 .pw-map-btn { background: linear-gradient(135deg, #8e24aa, #ce93d8); }
#pharmacies-widget-fr .c6 .pw-map-btn { background: linear-gradient(135deg, #00897b, #80cbc4); }
#pharmacies-widget-fr .pw-footer {
margin-top: 28px;
background: #fff;
border-radius: 14px;
padding: 18px 20px;
font-size: 14px;
color: #555;
line-height: 1.8;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
#pharmacies-widget-fr .pw-footer strong {
display: block;
font-size: 15px;
color: #1a1a2e;
margin-bottom: 8px;
}
#pharmacies-widget-fr .pw-loading,
#pharmacies-widget-fr .pw-empty,
#pharmacies-widget-fr .pw-error {
background: #fff;
border-radius: 16px;
padding: 30px 20px;
text-align: center;
box-shadow: 0 4px 18px rgba(0,0,0,0.07);
grid-column: 1 / -1;
}
#pharmacies-widget-fr .pw-spinner {
width: 42px;
height: 42px;
border: 4px solid #e3f2fd;
border-top-color: #1e88e5;
border-radius: 50%;
margin: 0 auto 12px;
animation: pw-spin 1s linear infinite;
}
@keyframes pw-spin {
to { transform: rotate(360deg); }
}
(function () {
const CONFIG = {
city: "Tangier",
country: "Morocco",
limit: 6,
radius: 6000
};
const root = document.getElementById("pharmacies-widget-fr");
if (!root) return;
root.innerHTML = `
`;
const statusBox = root.querySelector("#pw-status");
const grid = root.querySelector("#pw-grid");
const dateBox = root.querySelector("#pw-date");
const colors = ["c1", "c2", "c3", "c4", "c5", "c6"];
function escapeHtml(str) {
return String(str || "")
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function formatDateFr() {
const now = new Date();
dateBox.textContent = now.toLocaleDateString("fr-FR", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
});
}
function buildMapUrl(lat, lon) {
return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(lat + "," + lon)}`;
}
function normalizePhone(phone) {
return String(phone || "").replace(/[^\d+]/g, "");
}
function getBadge(item) {
if (item.opening_hours) {
return { cls: "ok", label: "Horaires disponibles" };
}
if (item.phone) {
return { cls: "partial", label: "Infos partielles" };
}
return { cls: "unknown", label: "Infos limitées" };
}
function haversine(lat1, lon1, lat2, lon2) {
const R = 6371;
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLon = (lon2 - lon1) * Math.PI / 180;
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1 * Math.PI / 180) *
Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
return R * (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)));
}
async function geocodeCity(city, country) {
const url = `https://nominatim.openstreetmap.org/search?format=jsonv2&limit=1&city=${encodeURIComponent(city)}&country=${encodeURIComponent(country)}`;
const res = await fetch(url, {
headers: {
"Accept": "application/json"
}
});
if (!res.ok) throw new Error("Impossible de localiser la ville.");
const data = await res.json();
if (!Array.isArray(data) || !data.length) {
throw new Error("Ville introuvable.");
}
return {
lat: parseFloat(data[0].lat),
lon: parseFloat(data[0].lon),
name: data[0].display_name || city
};
}
async function fetchPharmacies(lat, lon, radius) {
const query = `
[out:json][timeout:25];
(
node["amenity"="pharmacy"](around:${radius},${lat},${lon});
way["amenity"="pharmacy"](around:${radius},${lat},${lon});
relation["amenity"="pharmacy"](around:${radius},${lat},${lon});
);
out center tags;
`.trim();
const res = await fetch("https://overpass-api.de/api/interpreter", {
method: "POST",
headers: {
"Content-Type": "text/plain;charset=UTF-8"
},
body: query
});
if (!res.ok) {
throw new Error("Erreur lors du chargement des pharmacies.");
}
const data = await res.json();
return Array.isArray(data.elements) ? data.elements : [];
}
function normalizeItem(item, centerLat, centerLon) {
const tags = item.tags || {};
const lat = item.lat || (item.center && item.center.lat);
const lon = item.lon || (item.center && item.center.lon);
if (!lat || !lon) return null;
const name = tags.name || "Pharmacie";
const phone = tags.phone || tags["contact:phone"] || "";
const opening_hours = tags.opening_hours || "";
const website = tags.website || tags["contact:website"] || "";
const parts = [];
if (tags["addr:housenumber"]) parts.push(tags["addr:housenumber"]);
if (tags["addr:street"]) parts.push(tags["addr:street"]);
const street = parts.join(" ").trim();
const city = tags["addr:city"] || tags["addr:town"] || tags["addr:village"] || CONFIG.city;
const full_address = [street, city].filter(Boolean).join(", ") || "Adresse non disponible";
return {
name,
phone,
opening_hours,
website,
city,
full_address,
lat: parseFloat(lat),
lon: parseFloat(lon),
distance: haversine(centerLat, centerLon, parseFloat(lat), parseFloat(lon)).toFixed(2),
map_url: buildMapUrl(lat, lon)
};
}
function renderItems(items) {
if (!items.length) {
grid.innerHTML = `
${
item.website
? `
`
: ""
}
Voir sur la carte
`;
}).join("");
}
async function init() {
try {
formatDateFr();
statusBox.textContent = "Recherche de la ville configurée...";
const cityData = await geocodeCity(CONFIG.city, CONFIG.country);
statusBox.textContent = `Chargement des pharmacies autour de ${CONFIG.city}...`;
const rawItems = await fetchPharmacies(cityData.lat, cityData.lon, CONFIG.radius);
const items = rawItems
.map(item => normalizeItem(item, cityData.lat, cityData.lon))
.filter(Boolean)
.sort((a, b) => parseFloat(a.distance) - parseFloat(b.distance))
.slice(0, CONFIG.limit);
renderItems(items);
statusBox.textContent = `${items.length} pharmacie(s) chargée(s) automatiquement pour ${CONFIG.city}.`;
} catch (err) {
grid.innerHTML = `
💊 Pharmacies proches
Les pharmacies sont chargées automatiquement selon la ville configurée dans le code.
Les horaires, téléphones et autres informations dépendent de la disponibilité des données publiques.
Initialisation du chargement...
Chargement des pharmacies...
Information importante
Cette version fonctionne automatiquement sans intervention.
Pour afficher uniquement les pharmacies de garde officielles.
Aucune pharmacie trouvée dans cette zone.
`;
return;
}
grid.innerHTML = items.map((item, i) => {
const color = colors[i % colors.length];
const badge = getBadge(item);
return `
💊
${escapeHtml(badge.label)}
${escapeHtml(item.name)}
📍
${escapeHtml(item.city)}
🏠
${escapeHtml(item.full_address)}
📏
${escapeHtml(item.distance)} km
📞
${item.phone ? `${escapeHtml(item.phone)}` : "Téléphone non disponible"}
🕒
${item.opening_hours ? escapeHtml(item.opening_hours) : "Horaires non disponibles"}
🌐
${escapeHtml(err.message || "Erreur de chargement.")}
`;
statusBox.textContent = "Impossible de charger les données.";
}
}
init();
})();