Published
Edited
May 10, 2021
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
campaigns = fetch(campaignsURL)
.then((response) => response.json())
.then((data) => data.campaigns)
Insert cell
Insert cell
selectedCampaign = campaigns.filter(c => c.code === selectedCampaignCode)[0]
Insert cell
Insert cell
promocodes = selectedCampaign.promocodes
Insert cell
Insert cell
promcodeProductsURL = `${baseURL}/marketing/products/promos/${promocodes.join(
','
)}?sellable_online=true`
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
promocodeProducts = fetch(promcodeProductsURL).then(response => response.json())
Insert cell
Insert cell
Insert cell
getSummarizedProduct = ({productCode, productName, productRate, subcategory}) => {
const provider = subcategory.replace('Uncapped', '').replace('Capped', '').trim()
return {productCode, productName, productRate, provider}
}
Insert cell
getProductsFromPromo = (pc) => {
const promoCode = pc.promoCode
return pc.products.reduce((prods, p) => [...prods, getSummarizedProduct(p)], [])
}
Insert cell
summarizedProducts = promocodeProducts.reduce((prods, pc) => [...prods, ...getProductsFromPromo(pc)], [])
Insert cell
providers = [...new Set(summarizedProducts.map(p => p.provider))]
Insert cell
Insert cell
selectedProducts = {
// filter products by infrastructure provider
const selectedProviderSet = new Set(selectedProviders)
let selectedProducts = summarizedProducts.filter(p => selectedProviderSet.has(p.provider))
// filter products by price range
selectedProducts = selectedProducts.filter(filterByPriceRanges)
// sort by price from lowest to highest
selectedProducts = selectedProducts.sort((pa, pb) => pa.productRate - pb.productRate)
return selectedProducts
}
Insert cell
selectedPriceRanges = priceRanges.filter(range => selectedPriceRangeLabels.includes(range.label))
Insert cell
filterByPriceRanges = (product) => {
// If no price range has been selected then include all products
if (selectedPriceRanges.length === 0) {
return true
}
for (const range of selectedPriceRanges) {
const price = product.productRate
if (price >= range.min && price <= range.max) {
return true
}
}
return false
}
Insert cell
Insert cell
html`
<div ${{ style: { display: "grid" } }}>
${providerInfo.map(p => html.fragment`<img src="${p.url}" alt="${p.name}">`)}
</div>
`
Insert cell
Insert cell
providerInfo = [
{
code: 'centurycity',
name: 'Century City Connect',
url: `${logoBaseURL}/provider-century.png`
},
{
code: 'evotel',
name: 'Evotel',
url: `${logoBaseURL}/provider-evotel.png`
},
{
code: 'octotel',
name: 'Octotel',
url: `${logoBaseURL}/provider-octotel.png`
},
{
code: 'vumatel',
name: 'Vumatel',
url: `${logoBaseURL}/provider-vuma.png`
},
{
code: 'openserve',
name: 'Openserve',
url: `${logoBaseURL}/provider-openserve.png`
},
{
code: 'frogfoot',
name: 'Frogfoot',
url: `${logoBaseURL}/provider-frogfoot.png`
},
{
code: 'mfn',
name: 'MFN',
url: `${logoBaseURL}/provider-metrofibre.png`
},
{
code: 'vodacom',
name: 'Vodacom',
url: `${logoBaseURL}/provider-vodacom.png`
},
{
code: 'linkafrica',
name: 'Link Africa',
url: `${logoBaseURL}/provider-linkafrica.png`
},
{
code: 'linklayer',
name: 'Link Layer',
url: `${logoBaseURL}/provider-link-layer.png`
},
{
code: 'lightstruck',
name: 'Lightstruck',
url: `${logoBaseURL}/provider-lightstruck.png`
},
{
code: 'mitchells',
name: 'Mitchells Fibre',
url: `${logoBaseURL}/provider-mitchells.png`
},
{
code: 'vumareach',
name: 'Vuma Reach',
url: `${logoBaseURL}/provider-vuma.png`
}
]
Insert cell
Insert cell
baseURL = "https://apigw.mweb.co.za/prod/baas/proxy"
Insert cell
priceRanges = [{min: 0, max: 699, label: 'R0 - R699'}, {min: 700, max: 999, label: 'R700 - R999'}, {min: 1000, max: 9999, label: 'R1000+'}]
Insert cell
import {html, svg} from "@observablehq/htl"

Insert cell
import {radio, checkbox} from "@jashkenas/inputs"

Insert cell
import { emoji } from '@asg017/emojis'
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more