{"id":436,"date":"2026-08-28T07:32:09","date_gmt":"2026-08-28T07:32:09","guid":{"rendered":"https:\/\/drakensbergtech.solutions\/?page_id=436"},"modified":"2026-08-31T09:28:16","modified_gmt":"2026-08-31T09:28:16","slug":"elementor-436","status":"publish","type":"page","link":"https:\/\/drakensbergtech.solutions\/?page_id=436","title":{"rendered":"Check Fibre Availability"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"436\" class=\"elementor elementor-436\">\n\t\t\t\t<div class=\"elementor-element elementor-element-76d464d e-flex e-con-boxed e-con e-parent\" data-id=\"76d464d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0b81170 elementor-widget elementor-widget-html\" data-id=\"0b81170\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<link\n  href=\"https:\/\/api.mapbox.com\/mapbox-gl-js\/v3.28.0\/mapbox-gl.css\"\n  rel=\"stylesheet\"\n\/>\n\n<script src=\"https:\/\/api.mapbox.com\/mapbox-gl-js\/v3.28.0\/mapbox-gl.js\"><\/script>\n\n<div id=\"afrinet-checker\" style=\"max-width:900px;margin:auto;\">\n\n    <h3>Check Fibre Availability<\/h3>\n\n    <input\n        id=\"afrinet-address\"\n        type=\"text\"\n        placeholder=\"Enter your South African address\"\n        autocomplete=\"off\"\n        style=\"width:100%;box-sizing:border-box;padding:14px;font-size:16px;border:1px solid #ccc;border-radius:6px;\"\n    >\n\n    <div\n        id=\"afrinet-suggestions\"\n        style=\"display:none;background:white;border:1px solid #ddd;position:relative;z-index:9999;\"\n    ><\/div>\n\n    <button\n        id=\"afrinet-check\"\n        type=\"button\"\n        style=\"margin-top:15px;padding:14px 25px;border:0;border-radius:6px;cursor:pointer;\"\n    >\n        Check Fibre Availability\n    <\/button>\n\n    <div\n        id=\"afrinet-result\"\n        style=\"margin-top:20px;\"\n    ><\/div>\n\n    <div\n        id=\"afrinet-map\"\n        style=\"\n            width:100%;\n            height:450px;\n            margin-top:25px;\n            border-radius:10px;\n            overflow:hidden;\n            display:none;\n        \"\n    ><\/div>\n\n<\/div>\n\n\n<script>\n\n(function () {\n\n    var mapboxToken =\n        'pk.eyJ1IjoiZGJlcnRlY2gtMjMiLCJhIjoiY210YmJvMWxjMDdhdTJ2c2U1NnRlNHF6ayJ9.HykP0vYak8hGI84j_9MAtA';\n\n    var ajaxUrl =\n        window.location.origin +\n        '\/wp-admin\/admin-ajax.php';\n\n    var addressInput =\n        document.getElementById('afrinet-address');\n\n    var suggestions =\n        document.getElementById('afrinet-suggestions');\n\n    var checkButton =\n        document.getElementById('afrinet-check');\n\n    var resultBox =\n        document.getElementById('afrinet-result');\n\n    var mapContainer =\n        document.getElementById('afrinet-map');\n\n    var latitude = null;\n    var longitude = null;\n\n    var map = null;\n\n    var marker = null;\n\n\n    \/*\n     * ADDRESS SEARCH\n     *\/\n\n    addressInput.addEventListener(\n        'input',\n        function () {\n\n            var query =\n                addressInput.value.trim();\n\n            latitude = null;\n            longitude = null;\n\n            if (query.length < 3) {\n\n                suggestions.style.display =\n                    'none';\n\n                return;\n\n            }\n\n            fetch(\n                'https:\/\/api.mapbox.com\/geocoding\/v5\/mapbox.places\/' +\n                encodeURIComponent(query) +\n                '.json?access_token=' +\n                encodeURIComponent(mapboxToken) +\n                '&country=ZA&limit=5'\n            )\n\n            .then(function (response) {\n                return response.json();\n            })\n\n            .then(function (data) {\n\n                suggestions.innerHTML = '';\n\n                if (\n                    !data.features ||\n                    !data.features.length\n                ) {\n\n                    suggestions.style.display =\n                        'none';\n\n                    return;\n\n                }\n\n                data.features.forEach(\n                    function (place) {\n\n                        var option =\n                            document.createElement('div');\n\n                        option.textContent =\n                            place.place_name;\n\n                        option.style.padding =\n                            '12px';\n\n                        option.style.cursor =\n                            'pointer';\n\n                        option.style.borderBottom =\n                            '1px solid #eee';\n\n                        option.onclick =\n                            function () {\n\n                                addressInput.value =\n                                    place.place_name;\n\n                                longitude =\n                                    place.center[0];\n\n                                latitude =\n                                    place.center[1];\n\n                                suggestions.style.display =\n                                    'none';\n\n                                resultBox.innerHTML =\n                                    'Address selected. Click <strong>Check Fibre Availability<\/strong>.';\n\n                                showMap();\n\n                            };\n\n                        suggestions.appendChild(\n                            option\n                        );\n\n                    }\n                );\n\n                suggestions.style.display =\n                    'block';\n\n            })\n\n            .catch(function () {\n\n                resultBox.innerHTML =\n                    'Unable to search for this address.';\n\n            });\n\n        }\n    );\n\n\n    \/*\n     * SHOW MAP\n     *\/\n\n    function showMap() {\n\n        mapContainer.style.display =\n            'block';\n\n        if (!map) {\n\n            mapboxgl.accessToken =\n                mapboxToken;\n\n            map =\n                new mapboxgl.Map({\n\n                    container:\n                        'afrinet-map',\n\n                    style:\n                        'mapbox:\/\/styles\/mapbox\/streets-v12',\n\n                    center:\n                        [\n                            longitude,\n                            latitude\n                        ],\n\n                    zoom:\n                        15\n\n                });\n\n            map.addControl(\n                new mapboxgl.NavigationControl()\n            );\n\n        } else {\n\n            map.setCenter([\n                longitude,\n                latitude\n            ]);\n\n            map.setZoom(15);\n\n        }\n\n\n        if (marker) {\n\n            marker.remove();\n\n        }\n\n        marker =\n            new mapboxgl.Marker()\n                .setLngLat([\n                    longitude,\n                    latitude\n                ])\n                .addTo(map);\n\n    }\n\n\n    \/*\n     * CHECK AFRINET\n     *\/\n\n    checkButton.addEventListener(\n        'click',\n        function () {\n\n            if (\n                latitude === null ||\n                longitude === null\n            ) {\n\n                resultBox.innerHTML =\n                    'Please select your address from the suggestions first.';\n\n                return;\n\n            }\n\n            resultBox.innerHTML =\n                '\ud83d\udd04 Checking fibre availability...';\n\n\n            var formData =\n                new FormData();\n\n            formData.append(\n                'action',\n                'drakensberg_test_afrinet'\n            );\n\n            formData.append(\n                'latitude',\n                latitude\n            );\n\n            formData.append(\n                'longitude',\n                longitude\n            );\n\n\n            fetch(\n                ajaxUrl,\n                {\n                    method:\n                        'POST',\n\n                    body:\n                        formData\n                }\n            )\n\n            .then(function (response) {\n                return response.json();\n            })\n\n            .then(function (data) {\n\n                console.log(\n                    'AfriNet:',\n                    data\n                );\n\n\n                if (\n                    !data.success ||\n                    !data.data ||\n                    !data.data.afrinet_response\n                ) {\n\n                    resultBox.innerHTML =\n                        '\u26a0\ufe0f Fibre availability check failed.';\n\n                    return;\n\n                }\n\n\n                var fibre =\n                    data.data.afrinet_response;\n\n                if (\n                    fibre.available === true\n                ) {\n\n                    resultBox.innerHTML =\n                        '<div style=\"padding:20px;border-radius:8px;\">' +\n\n                        '<strong style=\"font-size:22px;\">\ud83d\udfe2 Fibre Available!<\/strong>' +\n\n                        '<p>Vumatel fibre appears to be available at this address.<\/p>' +\n\n                        '<\/div>';\n\n                } else {\n\n                    resultBox.innerHTML =\n                        '<div style=\"padding:20px;border-radius:8px;\">' +\n\n                        '<strong style=\"font-size:22px;\">\ud83d\udd34 Fibre Not Available<\/strong>' +\n\n                        '<p>Vumatel fibre is not currently showing as available at this address.<\/p>' +\n\n                        '<\/div>';\n\n                }\n\n\n                \/*\n                 * ADD COVERAGE\n                 *\/\n\n                if (\n                    fibre.map_tile_url\n                ) {\n\n                    addCoverage(\n                        fibre.map_tile_url\n                    );\n\n                }\n\n            })\n\n            .catch(function () {\n\n                resultBox.innerHTML =\n                    '\u26a0\ufe0f Something went wrong. Please try again.';\n\n            });\n\n        }\n    );\n\n\n    \/*\n     * ADD AFRINET COVERAGE\n     *\/\n\n    function addCoverage(\n        tileUrl\n    ) {\n\n        if (!map) {\n            return;\n        }\n\n\n        \/*\n         * Get current map bounds\n         *\/\n\n        var bounds =\n            map.getBounds();\n\n\n        var west =\n            bounds.getWest();\n\n        var south =\n            bounds.getSouth();\n\n        var east =\n            bounds.getEast();\n\n        var north =\n            bounds.getNorth();\n\n\n        \/*\n         * Convert geographic\n         * coordinates to Web Mercator\n         *\/\n\n        function mercatorX(lng) {\n\n            return (\n                lng + 180\n            ) \/ 360 * 40075016.68557849;\n\n        }\n\n\n        function mercatorY(lat) {\n\n            var rad =\n                lat *\n                Math.PI \/\n                180;\n\n            return (\n                Math.log(\n                    Math.tan(\n                        Math.PI \/ 4 +\n                        rad \/ 2\n                    )\n                )\n            ) *\n            -40075016.68557849 \/\n            (2 * Math.PI);\n\n        }\n\n\n        var minX =\n            mercatorX(west);\n\n        var maxX =\n            mercatorX(east);\n\n        var minY =\n            mercatorY(north);\n\n        var maxY =\n            mercatorY(south);\n\n\n        \/*\n         * Replace AfriNet\n         * bbox placeholder\n         *\/\n\n        var bbox =\n            minX + ',' +\n            minY + ',' +\n            maxX + ',' +\n            maxY;\n\n\n        var imageUrl =\n            tileUrl.replace(\n                '{bbox-epsg-3857}',\n                bbox\n            );\n\n\n        \/*\n         * ArcGIS image overlay\n         *\/\n\n        if (\n            map.getLayer(\n                'vumatel-coverage-image'\n            )\n        ) {\n\n            map.removeLayer(\n                'vumatel-coverage-image'\n            );\n\n        }\n\n\n        if (\n            map.getSource(\n                'vumatel-coverage-image'\n            )\n        ) {\n\n            map.removeSource(\n                'vumatel-coverage-image'\n            );\n\n        }\n\n\n        map.addSource(\n            'vumatel-coverage-image',\n            {\n                type:\n                    'image',\n\n                url:\n                    imageUrl,\n\n                coordinates:\n                    [\n                        [west, north],\n                        [east, north],\n                        [east, south],\n                        [west, south]\n                    ]\n            }\n        );\n\n\n        map.addLayer(\n            {\n                id:\n                    'vumatel-coverage-image',\n\n                type:\n                    'raster',\n\n                source:\n                    'vumatel-coverage-image',\n\n                paint:\n                    {\n                        'raster-opacity':\n                            0.60\n                    }\n            }\n        );\n\n\n        console.log(\n            'Vumatel coverage image:',\n            imageUrl\n        );\n\n    }\n\n})()\n\n\ndocument.addEventListener('DOMContentLoaded', function () {\n\n    const button = document.getElementById('afronet-check');\n\n    if (!button) {\n        console.log('AfriNet check button not found.');\n        return;\n    }\n\n    button.addEventListener('click', function (e) {\n\n        e.preventDefault();\n\n        button.disabled = true;\n        button.innerText = 'Checking...';\n\n        const formData = new FormData();\n\n        formData.append('action', 'drakensberg_test_afrinet');\n\n        \/*\n         * Get the coordinates from the selected address.\n         * These IDs should be used by the Mapbox code.\n         *\/\n        const latitude =\n            document.getElementById('latitude')?.value || '';\n\n        const longitude =\n            document.getElementById('longitude')?.value || '';\n\n        formData.append('latitude', latitude);\n        formData.append('longitude', longitude);\n\n        fetch('\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            body: formData\n        })\n\n        .then(response => response.json())\n\n        .then(data => {\n\n            console.log('AFRINET RESPONSE:', data);\n\n            button.disabled = false;\n            button.innerText = 'Check Fibre Availability';\n\n            if (data.success) {\n\n                alert(\n                    'Fibre check completed.\\n\\n' +\n                    JSON.stringify(data.data, null, 2)\n                );\n\n            } else {\n\n                alert(\n                    'Fibre check failed.\\n\\n' +\n                    'Stage: ' +\n                    (data.data?.stage || 'unknown') +\n                    '\\n\\n' +\n                    'Message: ' +\n                    (data.data?.message || 'Unknown error') +\n                    '\\n\\n' +\n                    'HTTP: ' +\n                    (data.data?.http_code || 'N\/A')\n                );\n            }\n\n        })\n\n        .catch(error => {\n\n            console.error('FETCH ERROR:', error);\n\n            button.disabled = false;\n            button.innerText = 'Check Fibre Availability';\n\n            alert(\n                'JavaScript connection error:\\n\\n' +\n                error.message\n            );\n        });\n\n    });\n\n});\n\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Check Fibre Availability Check Fibre Availability<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_eb_attr":"","site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-436","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/drakensbergtech.solutions\/index.php?rest_route=\/wp\/v2\/pages\/436","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/drakensbergtech.solutions\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/drakensbergtech.solutions\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/drakensbergtech.solutions\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/drakensbergtech.solutions\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=436"}],"version-history":[{"count":73,"href":"https:\/\/drakensbergtech.solutions\/index.php?rest_route=\/wp\/v2\/pages\/436\/revisions"}],"predecessor-version":[{"id":522,"href":"https:\/\/drakensbergtech.solutions\/index.php?rest_route=\/wp\/v2\/pages\/436\/revisions\/522"}],"wp:attachment":[{"href":"https:\/\/drakensbergtech.solutions\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=436"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}