Bransjesjekk bygg og anlegg
by SvennMats
HTML
<div id="iframe-wrapper">
<div id="compliance-app">
<header>
<h2>Bransjekrav & Godkjenninger</h2>
<p>Søk på firmanavn eller org.nr...</p>
</header>
<div class="search-container">
<div class="input-wrapper">
<input type="text" id="searchInput" placeholder="Søk etter firma..." autocomplete="off">
<div id="app-loader" class="spinner hidden"></div>
</div>
<div id="search-results" class="hidden"></div>
</div>
<div id="main-content" class="hidden">
<div class="company-header">
<h1 id="disp-navn"></h1>
<span id="disp-bransje"></span>
<div id="dibk-status-container" class="dibk-box">
<span id="dibk-icon"></span>
<span id="dibk-text">Sjekker sentral godkjenning...</span>
</div>
<div class="law-tag">
<a id="lovdata-link" href="#" target="_blank">🔗 Sentralt regelverk i Lovdata</a>
</div>
</div>
<div class="krav-grid">
<div class="krav-card ks">
<div class="krav-header"><h4>🛠 Kvalitetssikring</h4></div>
<p id="txt-ks"></p>
</div>
<div class="krav-card hms">
<div class="krav-header"><h4>🛡 HMS & Internkontroll</h4></div>
<p id="txt-hms"></p>
</div>
<div class="krav-card time">
<div class="krav-header"><h4>⏳ Timeføring & Logg</h4></div>
<p id="txt-time"></p>
</div>
</div>
</div>
</div>
</div>
CSS
/* 1. GLOBAL RESET
Sikrer at padding og border ikke dytter elementer ut av beholderen.
*/
* {
box-sizing: border-box;
}
:root {
--primary: #2563eb;
--success: #10b981;
--success-bg: #ecfdf5;
--success-text: #065f46;
--danger: #ef4444;
--danger-bg: #fef2f2;
--danger-text: #991b1b;
--text-main: #1e293b;
--text-muted: #64748b;
--bg-app: #ffffff;
--bg-muted: #f8fafc;
--border: #e2e8f0;
}
/* 2. BASE STYLING
Tilpasset for bruk i iFrame/JSFiddle.
*/
body {
margin: 0;
padding: 10px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background-color: transparent;
color: var(--text-main);
line-height: 1.5;
}
#compliance-app {
max-width: 550px;
width: 100%;
margin: 0 auto;
background: var(--bg-app);
border: 1px solid var(--border);
border-radius: 12px;
padding: 24px;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}
header h2 { margin: 0 0 5px 0; font-size: 1.4rem; }
header p { margin: 0 0 20px 0; font-size: 0.9rem; color: var(--text-muted); }
/* 3. SØKEFELT & AUTOCOMPLETE
*/
.search-container {
position: relative;
width: 100%;
margin-bottom: 25px;
}
input#searchInput {
width: 100%;
padding: 14px 16px;
border: 2px solid var(--border);
border-radius: 8px;
font-size: 16px; /* Hindrer auto-zoom på iPhone */
outline: none;
transition: border-color 0.2s;
}
input#searchInput:focus {
border-color: var(--primary);
}
#search-results {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: white;
border: 1px solid var(--border);
border-radius: 0 0 8px 8px;
z-index: 1000;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
max-height: 250px;
overflow-y: auto;
}
.res-item {
padding: 12px 16px;
border-bottom: 1px solid #f1f5f9;
...
JavaScript
const db = {
"41": { n: "Bygg", ks: "PBL-dokumentasjon og uavhengig kontroll.", hms: "HMS-kort og SHA-plan er påkrevd.", time: "Mannskapslister skal føres daglig.", link: "https://lovdata.no/dokument/NL/lov/2008-06-27-71" },
"62": { n: "IT/Konsulent", ks: "GDPR og databehandleravtaler.", hms: "Fokus på ergonomi og psykososialt miljø.", time: "Dokumentasjon for fakturerbar tid.", link: "https://lovdata.no/dokument/NL/lov/2018-06-15-38" },
"47": { n: "Handel", ks: "Forbrukerkjøpsloven og produktkontroll.", hms: "Brannsikkerhet og tunge løft.", time: "Vaktlister tilgjengelig 2 uker før.", link: "https://lovdata.no/dokument/NL/lov/2002-06-21-34" },
"default": { n: "Generell", ks: "Rutiner for god forretningsskikk.", hms: "Lovpålagt internkontroll (HMS).", time: "Oversikt over faktisk arbeidstid.", link: "https://lovdata.no/dokument/NL/lov/2005-06-17-62" }
};
let debounceTimer;
document.getElementById('searchInput').addEventListener('input', (e) => {
const query = e.target.value;
clearTimeout(debounceTimer);
if (query.length < 3) return document.getElementById('search-results').classList.add('hidden');
debounceTimer = setTimeout(() => utforSok(query), 300);
});
async function utforSok(query) {
const resDiv = document.getElementById('search-results');
const loader = document.getElementById('app-loader');
loader.classList.remove('hidden');
try {
const url = isNaN(query) ? `https://data.brreg.no/enhetsregisteret/api/enheter?navn=${encodeURIComponent(query)}&size=8` : `https://data.brreg.no/enhetsregisteret/api/enheter/${query}`;
const response = await fetch(url);
const data = await response.json();
let enheter = data._embedded ? data._embedded.enheter : (data.navn ? [data] : []);
resDiv.innerHTML = enheter.map(e => `<div class="res-item"...