diff --git a/api/search.php b/api/search.php
new file mode 100644
index 0000000..81eb617
--- /dev/null
+++ b/api/search.php
@@ -0,0 +1,68 @@
+ 'Query cannot be empty.']);
+ http_response_code(400);
+ exit;
+}
+
+// New, more detailed mock data for "HuisWiki"
+$mock_data = [
+ // Basisgegevens
+ 'adres' => 'Coolsingel 40, 3011 AD Rotterdam',
+ 'postcode' => '3011 AD',
+ 'plaats' => 'Rotterdam',
+ 'gemeente' => 'Rotterdam',
+ 'provincie' => 'Zuid-Holland',
+ 'buurt' => 'Cool',
+ 'wijk' => 'Stadsdriehoek',
+
+ // WOZ Waarde
+ 'woz_waarde' => 2500000, // Current value in EUR
+ 'woz_ontwikkeling' => [
+ ['jaar' => 2019, 'waarde' => 2100000],
+ ['jaar' => 2020, 'waarde' => 2200000],
+ ['jaar' => 2021, 'waarde' => 2350000],
+ ['jaar' => 2022, 'waarde' => 2400000],
+ ['jaar' => 2023, 'waarde' => 2450000],
+ ['jaar' => 2024, 'waarde' => 2500000],
+ ],
+
+ // Kadastrale info
+ 'perceelnummer' => 'RTD01-A-1234',
+ 'eigendomssituatie' => 'Volledig eigendom',
+ 'type' => 'Winkelpand',
+ 'bouwjaar' => 1957,
+ 'oppervlakte' => 1573, // in m²
+
+ // Energielabel
+ 'energielabel' => 'A++',
+ 'geschatte_energiekosten' => 450, // per maand
+
+ // Verkoophistorie
+ 'verkoophistorie' => [
+ ['datum' => '2012-05-20', 'prijs' => 1800000, 'type' => 'Verkocht'],
+ ['datum' => '2005-11-15', 'prijs' => 1500000, 'type' => 'Verkocht'],
+ ['datum' => '1998-01-30', 'prijs' => 950000, 'type' => 'Verkocht'],
+ ],
+
+ // Buurtstatistieken
+ 'buurtstatistieken' => [
+ 'gemiddelde_woz' => 450000,
+ 'inwoners' => 8500,
+ 'gemiddelde_leeftijd' => 38,
+ 'groen_score' => 7.2, // out of 10
+ 'veiligheid_score' => 8.1, // out of 10
+ ]
+];
+
+// Simulate network delay
+sleep(1);
+
+echo json_encode($mock_data);
\ No newline at end of file
diff --git a/assets/css/custom.css b/assets/css/custom.css
new file mode 100644
index 0000000..b090507
--- /dev/null
+++ b/assets/css/custom.css
@@ -0,0 +1,250 @@
+/* --- Base & Variables --- */
+:root {
+ --bg-primary: #fefefe;
+ --bg-secondary: #f8f9fa;
+ --bg-accent: #e9ecef;
+ --text-primary: #212529;
+ --text-secondary: #495057;
+ --text-muted: #6c757d;
+ --accent-blue: #0066cc;
+ --accent-green: #059669;
+ --accent-orange: #ea580c;
+ --accent-purple: #7c3aed;
+ --border-color: #dee2e6;
+ --shadow: rgba(0, 0, 0, 0.07);
+ --gradient-1: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+}
+
+.dark {
+ /* Dark mode variables if needed */
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: 'Work Sans', sans-serif;
+ background: var(--bg-primary);
+ color: var(--text-primary);
+ line-height: 1.6;
+}
+
+.mono {
+ font-family: 'JetBrains Mono', monospace;
+}
+
+/* --- Layout & Header --- */
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2rem 1rem;
+}
+
+.header {
+ background: var(--bg-secondary);
+ border-bottom: 1px solid var(--border-color);
+ padding: 1.5rem 1rem;
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ box-shadow: 0 2px 10px var(--shadow);
+}
+
+.header-content {
+ max-width: 1200px;
+ margin: 0 auto;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.logo {
+ font-size: 1.5rem;
+ font-weight: 800;
+ background: var(--gradient-1);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.tagline {
+ color: var(--text-muted);
+ font-size: 0.85rem;
+}
+
+/* --- Hero & Search --- */
+.hero {
+ text-align: center;
+ padding: 3rem 1rem;
+ background: var(--bg-secondary);
+ border-radius: 16px;
+ margin-bottom: 2rem;
+ border: 1px solid var(--border-color);
+}
+
+.hero-title {
+ font-size: 2.5rem;
+ font-weight: 800;
+ margin-bottom: 1rem;
+}
+
+.hero-subtitle {
+ font-size: 1.1rem;
+ color: var(--text-secondary);
+ margin-bottom: 2rem;
+ max-width: 600px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.search-wrapper {
+ display: flex;
+ gap: 0.75rem;
+ max-width: 700px;
+ margin: 0 auto;
+}
+
+.search-input {
+ flex: 1;
+ padding: 1rem 1.5rem;
+ border: 2px solid var(--border-color);
+ background: var(--bg-primary);
+ border-radius: 12px;
+ font-size: 16px;
+}
+
+.search-btn {
+ padding: 1rem 2.5rem;
+ background: var(--gradient-1);
+ color: white;
+ border: none;
+ border-radius: 12px;
+ font-size: 1rem;
+ font-weight: 700;
+ cursor: pointer;
+ transition: transform 0.2s;
+}
+
+.search-btn:hover { transform: translateY(-2px); }
+
+.examples { margin-top: 1rem; color: var(--text-muted); }
+.example-link { color: var(--accent-blue); text-decoration: none; margin: 0 0.5rem; }
+
+/* --- Results --- */
+.results-container {
+ display: none;
+ animation: fadeIn 0.5s ease;
+}
+
+@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
+
+.results-header {
+ padding: 2rem;
+ border-radius: 16px;
+ margin-bottom: 2rem;
+ border: 1px solid var(--border-color);
+ background: var(--bg-secondary);
+}
+
+.address-title { font-size: 2rem; font-weight: 800; }
+.address-subtitle { font-size: 1.1rem; color: var(--text-secondary); }
+
+/* --- Info Grid & Cards --- */
+.info-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
+ gap: 1.5rem;
+}
+
+.info-card {
+ background: var(--bg-secondary);
+ padding: 1.5rem;
+ border-radius: 12px;
+ border: 1px solid var(--border-color);
+ grid-column: span 1;
+}
+
+.card-large {
+ grid-column: span 1;
+}
+
+@media (min-width: 992px) {
+ .card-large {
+ grid-column: span 2;
+ }
+}
+
+.card-header {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ margin-bottom: 1.5rem;
+ padding-bottom: 1rem;
+ border-bottom: 1px solid var(--border-color);
+}
+
+.card-icon { font-size: 1.5rem; }
+.card-title { font-size: 1.2rem; font-weight: 700; }
+
+.info-row {
+ display: flex;
+ justify-content: space-between;
+ padding: 0.75rem 0;
+ border-bottom: 1px solid var(--bg-accent);
+}
+.info-row:last-child { border-bottom: none; }
+
+.info-label { color: var(--text-muted); }
+.info-value { font-weight: 600; text-align: right; }
+
+/* --- Specific Cards --- */
+.woz-main {
+ text-align: center;
+ padding: 1rem 0 2rem;
+}
+
+.woz-label { color: var(--text-muted); margin-bottom: 0.5rem; }
+.woz-value { font-size: 2.5rem; font-weight: 800; color: var(--accent-blue); }
+
+.chart-container {
+ position: relative;
+ height: 250px;
+}
+
+.history-table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+.history-table th, .history-table td {
+ padding: 0.75rem;
+ text-align: left;
+ border-bottom: 1px solid var(--border-color);
+}
+
+.history-table th {
+ background-color: var(--bg-accent);
+ font-weight: 600;
+}
+
+.history-table td:last-child {
+ text-align: right;
+ font-weight: 600;
+ font-family: 'JetBrains Mono', monospace;
+}
+
+/* --- Loader --- */
+.loader {
+ width: 18px;
+ height: 18px;
+ border: 2px solid #FFF;
+ border-bottom-color: transparent;
+ border-radius: 50%;
+ display: inline-block;
+ animation: rotation 1s linear infinite;
+}
+
+@keyframes rotation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
\ No newline at end of file
diff --git a/assets/js/main.js b/assets/js/main.js
new file mode 100644
index 0000000..57ba996
--- /dev/null
+++ b/assets/js/main.js
@@ -0,0 +1,179 @@
+document.addEventListener('DOMContentLoaded', () => {
+ const searchForm = document.getElementById('search-form');
+ const searchInput = document.getElementById('search-input');
+ const searchBtn = document.getElementById('search-btn');
+ const resultsContainer = document.getElementById('results-container');
+ const examples = document.querySelectorAll('.example-link');
+
+ let wozChart = null; // To hold the chart instance
+
+ // Helper to format currency
+ const formatCurrency = (value) => new Intl.NumberFormat('nl-NL', { style: 'currency', currency: 'EUR', minimumFractionDigits: 0 }).format(value);
+
+ const handleSearch = async (query) => {
+ if (!query) return;
+
+ const originalBtnText = searchBtn.innerHTML;
+ searchBtn.innerHTML = '';
+ searchBtn.disabled = true;
+ resultsContainer.style.display = 'none';
+
+ try {
+ const response = await fetch(`/api/search.php?query=${encodeURIComponent(query)}`);
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ const data = await response.json();
+ displayResults(data);
+ } catch (error) {
+ console.error("Fetch error: ", error);
+ displayError('Er is een fout opgetreden. Probeer het later opnieuw.');
+ } finally {
+ searchBtn.innerHTML = originalBtnText;
+ searchBtn.disabled = false;
+ }
+ };
+
+ searchForm.addEventListener('submit', (e) => {
+ e.preventDefault();
+ handleSearch(searchInput.value);
+ });
+
+ examples.forEach(link => {
+ link.addEventListener('click', (e) => {
+ e.preventDefault();
+ const exampleQuery = e.target.textContent;
+ searchInput.value = exampleQuery;
+ handleSearch(exampleQuery);
+ });
+ });
+
+ const displayResults = (data) => {
+ if (data.error) {
+ displayError(data.error);
+ return;
+ }
+
+ // --- Main Header ---
+ document.getElementById('address-title').textContent = data.adres;
+ document.getElementById('address-subtitle').textContent = `Gegevens voor ${data.postcode}, ${data.plaats}`;
+
+ // --- Basisgegevens ---
+ document.getElementById('info-postcode').textContent = data.postcode;
+ document.getElementById('info-plaats').textContent = data.plaats;
+ document.getElementById('info-gemeente').textContent = data.gemeente;
+ document.getElementById('info-provincie').textContent = data.provincie;
+ document.getElementById('info-buurt').textContent = data.buurt;
+ document.getElementById('info-wijk').textContent = data.wijk;
+
+ // --- Kadastrale Info ---
+ document.getElementById('info-perceelnummer').textContent = data.perceelnummer;
+ document.getElementById('info-eigendomssituatie').textContent = data.eigendomssituatie;
+ document.getElementById('info-type').textContent = data.type;
+ document.getElementById('info-bouwjaar').textContent = data.bouwjaar;
+ document.getElementById('info-oppervlakte').textContent = `${data.oppervlakte} m²`;
+
+ // --- WOZ Waarde ---
+ document.getElementById('info-woz-waarde').textContent = formatCurrency(data.woz_waarde);
+ renderWozChart(data.woz_ontwikkeling);
+
+ // --- Energielabel ---
+ document.getElementById('info-energielabel').textContent = data.energielabel;
+ document.getElementById('info-energiekosten').textContent = `${formatCurrency(data.geschatte_energiekosten)}`;
+
+ // --- Buurtstatistieken ---
+ document.getElementById('info-gem-woz').textContent = formatCurrency(data.buurtstatistieken.gemiddelde_woz);
+ document.getElementById('info-inwoners').textContent = data.buurtstatistieken.inwoners.toLocaleString('nl-NL');
+ document.getElementById('info-gem-leeftijd').textContent = `${data.buurtstatistieken.gemiddelde_leeftijd} jaar`;
+ document.getElementById('info-groen-score').textContent = `${data.buurtstatistieken.groen_score} / 10`;
+ document.getElementById('info-veiligheid-score').textContent = `${data.buurtstatistieken.veiligheid_score} / 10`;
+
+ // --- Verkoophistorie ---
+ const historyBody = document.getElementById('verkoophistorie-body');
+ historyBody.innerHTML = ''; // Clear previous results
+ data.verkoophistorie.forEach(tx => {
+ const row = document.createElement('tr');
+ row.innerHTML = `
+
${new Date(tx.datum).toLocaleDateString('nl-NL')} |
+ ${tx.type} |
+ ${formatCurrency(tx.prijs)} |
+ `;
+ historyBody.appendChild(row);
+ });
+
+ resultsContainer.style.display = 'block';
+ resultsContainer.scrollIntoView({ behavior: 'smooth' });
+ };
+
+ const renderWozChart = (wozData) => {
+ const ctx = document.getElementById('woz-chart').getContext('2d');
+ const labels = wozData.map(d => d.jaar);
+ const values = wozData.map(d => d.waarde);
+
+ if (wozChart) {
+ wozChart.destroy(); // Destroy previous chart instance
+ }
+
+ wozChart = new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: labels,
+ datasets: [{
+ label: 'WOZ-Waarde',
+ data: values,
+ borderColor: '#0066cc',
+ backgroundColor: 'rgba(0, 102, 204, 0.1)',
+ fill: true,
+ tension: 0.4,
+ pointBackgroundColor: '#0066cc',
+ pointRadius: 4,
+ }]
+ },
+ options: {
+ responsive: true,
+ maintainAspectRatio: false,
+ scales: {
+ y: {
+ ticks: {
+ callback: (value) => formatCurrency(value)
+ }
+ }
+ },
+ plugins: {
+ legend: {
+ display: false
+ }
+ }
+ }
+ });
+ };
+
+ const displayError = (message) => {
+ alert(message);
+ };
+});
+
+// Add some CSS for the loader
+const style = document.createElement('style');
+style.innerHTML = `
+.loader {
+ width: 18px;
+ height: 18px;
+ border: 2px solid #FFF;
+ border-bottom-color: transparent;
+ border-radius: 50%;
+ display: inline-block;
+ box-sizing: border-box;
+ animation: rotation 1s linear infinite;
+}
+
+@keyframes rotation {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+`;
+document.head.appendChild(style);
\ No newline at end of file
diff --git a/index.php b/index.php
index 7205f3d..4808660 100644
--- a/index.php
+++ b/index.php
@@ -1,150 +1,166 @@
-
-
-
+
+
-
-
- New Style
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ HuisWiki - Complete adresinformatie Nederland
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
Analyzing your requirements and generating your website…
-
- Loading…
-
-
= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.
-
This page will update automatically as the plan is implemented.
-
Runtime: PHP = htmlspecialchars($phpVersion) ?> — UTC = htmlspecialchars($now) ?>
-
-
-
+
+
+
+
+
+ Vind alles over elk adres
+ Voer een postcode en huisnummer in en krijg direct toegang tot uitgebreide informatie over elk adres in Nederland.
+
+
+
+
+
+
+
+
+
+
+
+
Postcode
+
Plaats
+
Gemeente
+
Provincie
+
Buurt
+
Wijk
+
+
+
+
+
+
Perceel
+
Eigendom
+
Type
+
Bouwjaar
+
Oppervlakte
+
+
+
+
+
+
+
+
+
+ Label
+
+
+
+ Gechatte Kosten p/m
+
+
+
+
+
+
+
+
Gem. WOZ
+
Inwoners
+
Gem. Leeftijd
+
Groenscore
+
Veiligheidsscore
+
+
+
+
+
+
+
+
+ | Datum |
+ Type |
+ Prijs |
+
+
+
+
+
+
+
+
+
+
+
+
+