const appTerritoryCardStyles = new CSSStyleSheet(); appTerritoryCardStyles.replaceSync(` :host { display: inline-block; box-sizing: border-box; width: 300px; height: 200px; } @media (max-width: 2300px) { :host { width: calc((100% / 5) - 40px); } } @media (max-width: 1960px) { :host { width: calc((100% / 4) - 40px); } } @media (max-width: 1640px) { :host { width: calc((100% / 3) - 40px); } } @media (max-width: 1280px) { :host { width: calc((100% / 2) - 40px); } } @media (max-width: 650px) { :host { width: 100%; } } .card { position: relative; width: 100%; height: 200px; background-color: var(--ColorThemes2, #525151); overflow: hidden; cursor: pointer; border-radius: calc(var(--border-radius, 15px) - 5px); } @media(hover: hover) { .card:hover { opacity: 0.8; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } } img { width: 100%; height: 100%; object-fit: cover; position: absolute; top: 0; left: 0; z-index: 1; filter: blur(3px); } .contents { position: relative; z-index: 2; background: rgb(64 64 64 / 0.7); width: 100%; height: 100%; display: flex; flex-direction: column; align-items: stretch; justify-content: space-between; border-radius: calc(var(--border-radius, 15px) - 5px); } .address { margin: 10px; height: 35px; display: flex; background: var(--ColorThemes0, #1c1c19); align-items: center; justify-content: center; font-size: var(--FontSize3, 14px); color: var(--ColorThemes3, #f3f3f3); border-radius: calc(var(--border-radius, 15px) - 5px - 4px); position: relative; overflow: hidden; font-weight: 400; } /* Стили для режима 'sheep' */ .sheep { margin: 10px; max-height: 50px; border-radius: calc(var(--border-radius, 15px) - 5px - 4px); padding: 10px 0; margin-top: 10px; display: flex; background: var(--PrimaryColor, #cb9e44); align-items: center; flex-direction: column; justify-content: space-around; } .sheep span { color: var(--PrimaryColorText, #2e2e2e); font-size: var(--FontSize3, 14px); font-weight: 400; opacity: 0.8; } .sheep p { color: var(--PrimaryColorText, #2e2e2e); font-size: var(--FontSize4, 15px); font-weight: 400; margin: 5px 0 0 0; } /* Стили для режима 'info' (прогресс) */ .info { margin: 10px; } .info > div { position: relative; background-color: var(--ColorThemes0, #1c1c19);; border-radius: calc(var(--border-radius, 15px) - 5px - 4px); overflow: hidden; padding: 5px 10px; display: flex; justify-content: space-between; align-items: center; min-height: 25px; } .info span { z-index: 2; font-size: var(--FontSize1, 12px); color: var(--ColorThemes3, #f3f3f3); } .info p { z-index: 2; margin: 0; font-weight: 500; font-size: var(--FontSize3, 14px); color: var(--ColorThemes3, #f3f3f3); } .progress { position: absolute; top: 0; left: 0; height: 100%; background-color: var(--PrimaryColor, #cb9e44); transition: width 0.3s ease; } a { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 10; } `); class AppTerritoryCard extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); if (this.shadowRoot.adoptedStyleSheets) { this.shadowRoot.adoptedStyleSheets = [appTerritoryCardStyles]; } } // Определяем, какие атрибуты будем отслеживать static get observedAttributes() { return ['image', 'address', 'sheep', 'link', 'atWork', 'quantity']; } get image() { return this.getAttribute('image'); } set image(newValue) { if (newValue === null) { this.removeAttribute('image'); } else { this.setAttribute('image', newValue); } } get address() { return this.getAttribute('address'); } set address(newValue) { if (newValue === null) { this.removeAttribute('address'); } else { this.setAttribute('address', newValue); } } get sheep() { return this.getAttribute('sheep'); } set sheep(newValue) { if (newValue === null) { this.removeAttribute('sheep'); } else { this.setAttribute('sheep', newValue); } } get link() { return this.getAttribute('link'); } set link(newValue) { if (newValue === null) { this.removeAttribute('link'); } else { this.setAttribute('link', newValue); } } get atWork() { return this.getAttribute('atWork'); } set atWork(newValue) { if (newValue === null) { this.removeAttribute('atWork'); } else { this.setAttribute('atWork', String(newValue)); } } get quantity() { return this.getAttribute('quantity'); } set quantity(newValue) { if (newValue === null) { this.removeAttribute('quantity'); } else { this.setAttribute('quantity', String(newValue)); } } // Вызывается при добавлении элемента в DOM connectedCallback() { this.render(); } // Вызывается при изменении одного из отслеживаемых атрибутов attributeChangedCallback(name, oldValue, newValue) { if (oldValue !== newValue) { this.render(); } } render() { const image = this.getAttribute('image') || ''; const address = this.getAttribute('address') || ''; const sheep = this.getAttribute('sheep'); // Может быть null или "" const link = this.getAttribute('link') || '#'; const atWork = this.getAttribute('atWork'); // Может быть null const quantity = this.getAttribute('quantity'); // Может быть null // --- Логика определения контента --- let contentHTML = ''; const isProgressMode = atWork !== null && quantity !== null && !isNaN(parseInt(atWork)) && !isNaN(parseInt(quantity)); const hasSheep = sheep !== null && sheep !== ''; if (isProgressMode) { // Режим прогресса (свободные подъезды) const atWorkNum = parseInt(atWork); const quantityNum = parseInt(quantity); const free = quantityNum - atWorkNum; const progressPercent = quantityNum > 0 ? (atWorkNum / quantityNum) * 100 : 100; contentHTML = `
${free} / ${quantityNum}
${sheep}