-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathTablePricing.astro
More file actions
244 lines (210 loc) · 6.93 KB
/
TablePricing.astro
File metadata and controls
244 lines (210 loc) · 6.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
---
// @ts-nocheck
const {
coin='dolar',
lang='pt-br',
metric,
metric_slug,
product_slug,
billing
} = Astro.props;
///////////////
// I18N DATA //
///////////////
const i18n = {
"pt-br": {
'USA': 'Estados Unidos',
'Canada': 'Canadá',
'Europe': 'Europa',
'Brazil': 'Brasil',
'Latam': 'Latam',
'Other_Regions': 'Todas Outras Regiões',
'First 10 TB / month': 'Primeiros 10 TB / mês',
'First 50 TB / month': 'Primeiros 50 TB / mês',
'Next 20 TB / month': 'Próximos 20 TB / mês',
'Next 40 TB / month': 'Próximos 40 TB / mês',
'Next 100 TB / month': 'Próximos 100 TB / mês',
'Next 350 TB / month': 'Próximos 350 TB / mês',
'Next 500 TB / month': 'Próximos 500 TB / mês',
'Next 4 PB / month': 'Próximos 4 PB / mês',
'Next 4 PB / month': 'Próximos 4 PB / mês',
'Over 5 PB / month': 'Acima de 5 PB / mês',
'Over 50 TB / month': 'Acima de 50 TB por mês',
'First 50 TB per month': 'Primeiros 50 TB por mês',
'Next 450 TB per month': 'Próximos 450 TB por mês',
'Next 450 TB / month': 'Próximos 450 TB por mês',
'Over 500 TB per month': 'Acima de 500 TB por mês',
'Over 500 TB / month': 'Acima de 500 TB por mês',
'First 10 million images processed/month': 'Primeiros 10 milhões de imagens processadas / mês',
'Next 40 million images processed/month': 'Próximos 40 milhões de imagens processadas / mês',
'Next 100 million images processed/month': 'Próximos 100 milhões de imagens processadas / mês',
'Next 350 million images processed/month': 'Próximos 350 milhões de imagens processadas / mês',
'Next 500 million images processed/month': 'Próximos 500 milhões de imagens processadas / mês',
'Next 4,000 million images processed/month': 'Próximos 4.000 milhões de imagens processadas / mês',
'Over 5,000 million images processed/month': 'Acima de 5.000 milhões de imagens processadas / mês',
'First 1 billion requests /month': 'Primeiro 1 bilhão de requisições / mês',
'First 1 billion requests/month': 'Primeiro 1 bilhão de requisições / mês',
'First 1 billion requests / month': 'Primeiro 1 bilhão de requisições / mês',
'Next 4 billion requests /month': 'Próximos 4 bilhões de requisições / mês',
'Next 4 billion requests/month': 'Próximos 4 bilhões de requisições / mês',
'Next 4 billion requests / month': 'Próximos 4 bilhões de requisições / mês',
'Next 15 billion requests/month': 'Próximos 15 bilhões de requisições/mês',
'Next 15 billion requests / month': 'Próximos 15 bilhões de requisições / mês',
'Over 20 billion requests/month': 'Acima de 20 bilhões de requisições/mês',
'Over 20 billion requests / month': 'Acima de 20 bilhões de requisições / mês',
'Over 20 billion requests /month': 'Acima de 20 bilhões de requisições / mês',
'First 25 hosted zones': 'Primeiras 25 zonas hospedadas',
'26 through 10,000 hosted zones': 'De 26 até 10.000 zonas hospedadas',
'Over 10,000 hosted zones': 'Acima de 10.000 zonas hospedadas',
'First 1 billion queries / month': 'Primeiros 1 bilhão de consultas / mês',
'Over 1 billion queries / month': 'Acima de 1 bilhão de consultas / mês',
'Compute Time': 'Tempo de Computação',
'HTTP/HTTPS Requests, all methods': 'Requisições HTTP/HTTPS, todos os métodos',
'Invocations': 'Invocações',
'Operations': 'Operações',
'Rate': 'Taxa',
'Single Tier': 'Tier unico'
}
};
///////////////
// FUNCTIONS //
///////////////
async function fetchPricingData() {
// product_slug come from Astro.props
const url = `https://www.azion.com/api/pricing/get/product_slug/${product_slug}`;
try {
const response = await fetch(url);
// If the API fails or returns a non-2xx status, avoid trying to parse JSON
if (!response.ok) {
console.error(`[TablePricing] Failed to fetch pricing data`, {
url,
status: response.status,
statusText: response.statusText
});
return [];
}
const contentType = response.headers.get('content-type') || '';
// The pricing API should always return JSON; if it doesn't, bail out gracefully
if (!contentType.includes('application/json')) {
console.error(`[TablePricing] Unexpected content-type when fetching pricing data`, {
url,
contentType
});
return [];
}
return await response.json();
} catch (error) {
// Handle network / runtime errors so the docs build doesn't break
console.error(`[TablePricing] Error fetching pricing data`, {
url,
error
});
return [];
}
}
function isReal() {
// coin come from Astro.props
return coin === 'real';
}
function normalizeRegionName(region) {
const mappings = {
'United States': 'USA',
'All Other Regions': 'Other_Regions'
};
return mappings[region] || region.replace(' ', '_');
};
function transformData(data) {
const tiers = {};
const filteredData = data.filter(item => item.metric_slug === metric_slug);
filteredData.forEach((item, index) => {
const tiersCountry = {
'USA': '',
'Canada': '',
'Europe': '',
'Brazil': '',
'Latam': '',
'Other_Regions': ''
};
const tier = lang === 'pt-br' ? i18n[lang][item.tier_name] : item.tier_name;
const region = normalizeRegionName(item.region);
let price = '';
if (item.brazilian_real_formatted || item.american_dollar_formatted) {
price = isReal() ? item.brazilian_real_formatted : item.american_dollar_formatted;
} else {
price = isReal() ? item.brazilian_real : item.american_dollar
}
if(lang === 'pt-br') {
price = price.replace('.', ',');
}
price = `${price} ${(isReal() ? 'R$' : 'USD')}`;
if (!tiers[tier]) {
tiers[tier] = tiersCountry;
}
// this validation is to when is the same tier but
// should be repeated with another price
// without this validation the last tier will replace the already setted
const indexTier = `#${index} ${tier}`;
if(tiers[tier][region]) {
tiers[indexTier] = tiersCountry;
tiers[indexTier][region] = price;
} else {
tiers[tier][region] = price;
}
});
return tiers;
}
///////////
// EXEC //
/////////
const pricingData = await fetchPricingData();
const transformedData = transformData(pricingData);
---
<style lang="scss">
.content-pricing-table {
table {
thead, tbody {
tr {
th, td {
white-space: nowrap;
min-width: 110px;
padding-left: 1rem;
padding-right: 1rem;
&:first-child {
padding-left: 0;
padding-right: 0;
min-width: 200px
}
}
}
}
}
}
</style>
<div class="content-pricing-table w-full flex-nowrap overflow-x-scroll">
<table>
<thead>
<tr>
<th>{metric}</th>
{billing.map((item) => <th>{item}</th>)}
</tr>
</thead>
<tbody>
{
Object.entries(transformedData).map(([tierName, prices]) => (
<tr>
<td class="whitespace-normal">
{
tierName.replace(/^#[^\s]+\s/, '')
}
</td>
{
Object.entries(prices).map((price) => {
return (price[1] ? <td>{price[1]}</td> : null)
})
}
</tr>
))
}
</tbody>
</table>
</div>