feat: project level

This commit is contained in:
loks0n
2025-01-09 17:19:14 +00:00
parent 90036b32ab
commit 760122d4e4
5 changed files with 279 additions and 4 deletions
+191
View File
@@ -0,0 +1,191 @@
const dialingCodes = {
'213': 'Algeria',
'376': 'Andorra',
'244': 'Angola',
'54': 'Argentina',
'374': 'Armenia',
'297': 'Aruba',
'61': 'Australia',
'43': 'Austria',
'994': 'Azerbaijan',
'973': 'Bahrain',
'880': 'Bangladesh',
'375': 'Belarus',
'32': 'Belgium',
'501': 'Belize',
'229': 'Benin',
'975': 'Bhutan',
'591': 'Bolivia',
'387': 'Bosnia and Herzegovina',
'267': 'Botswana',
'55': 'Brazil',
'673': 'Brunei',
'359': 'Bulgaria',
'226': 'Burkina Faso',
'257': 'Burundi',
'855': 'Cambodia',
'237': 'Cameroon',
'1': 'North America',
'238': 'Cape Verde Islands',
'56': 'Chile',
'86': 'China',
'57': 'Colombia',
'269': 'Comoros and Mayotte',
'242': 'Congo',
'682': 'Cook Islands',
'506': 'Costa Rica',
'385': 'Croatia',
'53': 'Cuba',
'357': 'Cyprus',
'420': 'Czech Republic',
'45': 'Denmark',
'253': 'Djibouti',
'593': 'Ecuador',
'20': 'Egypt',
'503': 'El Salvador',
'240': 'Equatorial Guinea',
'291': 'Eritrea',
'372': 'Estonia',
'251': 'Ethiopia',
'500': 'Falkland Islands',
'298': 'Faroe Islands',
'679': 'Fiji',
'358': 'Finland',
'33': 'France',
'594': 'French Guiana',
'689': 'French Polynesia',
'241': 'Gabon',
'220': 'Gambia',
'995': 'Georgia',
'49': 'Germany',
'233': 'Ghana',
'350': 'Gibraltar',
'30': 'Greece',
'299': 'Greenland',
'590': 'Guadeloupe',
'1671': 'Guam',
'502': 'Guatemala',
'224': 'Guinea',
'245': 'Guinea-Bissau',
'592': 'Guyana',
'509': 'Haiti',
'504': 'Honduras',
'852': 'Hong Kong',
'36': 'Hungary',
'354': 'Iceland',
'91': 'India',
'62': 'Indonesia',
'98': 'Iran',
'964': 'Iraq',
'353': 'Ireland',
'972': 'Israel',
'39': 'Italy',
'81': 'Japan',
'962': 'Jordan',
'254': 'Kenya',
'686': 'Kiribati',
'850': 'North Korea',
'82': 'South Korea',
'965': 'Kuwait',
'996': 'Kyrgyzstan',
'856': 'Laos',
'371': 'Latvia',
'961': 'Lebanon',
'266': 'Lesotho',
'231': 'Liberia',
'218': 'Libya',
'423': 'Liechtenstein',
'370': 'Lithuania',
'352': 'Luxembourg',
'853': 'Macao',
'389': 'Macedonia',
'261': 'Madagascar',
'265': 'Malawi',
'60': 'Malaysia',
'960': 'Maldives',
'223': 'Mali',
'356': 'Malta',
'692': 'Marshall Islands',
'596': 'Martinique',
'222': 'Mauritania',
'52': 'Mexico',
'691': 'Micronesia',
'373': 'Moldova',
'377': 'Monaco',
'976': 'Mongolia',
'212': 'Morocco',
'258': 'Mozambique',
'95': 'Myanmar',
'264': 'Namibia',
'674': 'Nauru',
'977': 'Nepal',
'31': 'Netherlands',
'687': 'New Caledonia',
'64': 'New Zealand',
'505': 'Nicaragua',
'227': 'Niger',
'234': 'Nigeria',
'683': 'Niue',
'672': 'Norfolk Islands',
'1670': 'Northern Mariana Islands',
'47': 'Norway',
'968': 'Oman',
'680': 'Palau',
'507': 'Panama',
'675': 'Papua New Guinea',
'595': 'Paraguay',
'51': 'Peru',
'63': 'Philippines',
'48': 'Poland',
'351': 'Portugal',
'974': 'Qatar',
'262': 'Reunion',
'40': 'Romania',
'7': 'Russia, Kazakhstan, Uzbekistan, Turkmenistan, and Tajikistan',
'250': 'Rwanda',
'378': 'San Marino',
'239': 'Sao Tome and Principe',
'966': 'Saudi Arabia',
'221': 'Senegal',
'381': 'Serbia',
'248': 'Seychelles',
'232': 'Sierra Leone',
'65': 'Singapore',
'421': 'Slovak Republic',
'386': 'Slovenia',
'677': 'Solomon Islands',
'252': 'Somalia',
'27': 'South Africa',
'34': 'Spain',
'94': 'Sri Lanka',
'290': 'St. Helena',
'249': 'Sudan',
'597': 'Suriname',
'268': 'Swaziland',
'46': 'Sweden',
'41': 'Switzerland',
'963': 'Syria',
'886': 'Taiwan',
'66': 'Thailand',
'228': 'Togo',
'676': 'Tonga',
'216': 'Tunisia',
'90': 'Turkey',
'688': 'Tuvalu',
'256': 'Uganda',
'380': 'Ukraine',
'971': 'United Arab Emirates',
'44': 'United Kingdom',
'598': 'Uruguay',
'678': 'Vanuatu',
'58': 'Venezuela',
'84': 'Vietnam',
'967': 'Yemen',
'260': 'Zambia',
'255': 'Zanzibar',
'263': 'Zimbabwe'
};
export function getCountryName(diallingCode: string): string {
return dialingCodes[diallingCode] ?? 'Unknown';
}
+15
View File
@@ -299,4 +299,19 @@ export type UsageProject = {
* Aggregated statistics of total number of buckets.
*/
bucketsTotal: number;
/**
* Aggregated statistics of total number of SMS sent.
*/
authPhoneTotal: number;
/**
* Aggregated statistics of estimated SMS cost.
*/
authPhoneEstimate: number;
/**
* Aggregated statistics of total number SMS by country
*/
authPhoneCountriesBreakdown: Models.MetricBreakdown[];
};
@@ -19,7 +19,7 @@
import { trackEvent } from '$lib/actions/analytics';
import TotalMembers from './totalMembers.svelte';
import { tooltip } from '$lib/actions/tooltip';
import { formatCurrency } from '$lib/helpers/numbers';
import { formatCurrency, formatNumberWithCommas } from '$lib/helpers/numbers';
export let data;
@@ -393,7 +393,7 @@
<div class="u-flex u-main-space-between">
<p>
<span class="heading-level-4"
>{formatNum(data.organizationUsage.authPhoneTotal)}</span>
>{formatNumberWithCommas(data.organizationUsage.authPhoneTotal)}</span>
<span class="body-text-1 u-bold">SMS OTPs</span>
</p>
<p class="u-flex u-gap-8 u-cross-center">
@@ -10,7 +10,7 @@
TableRowLink,
TableScroll
} from '$lib/elements/table';
import { abbreviateNumber, formatCurrency } from '$lib/helpers/numbers';
import { abbreviateNumber, formatCurrency, formatNumberWithCommas } from '$lib/helpers/numbers';
import { humanFileSize } from '$lib/helpers/sizeConvertion';
import type { OrganizationUsage } from '$lib/sdk/billing';
import { base } from '$app/paths';
@@ -59,7 +59,7 @@
function format(value: number): string {
switch (metric) {
case 'authPhoneTotal':
return value.toString();
return formatNumberWithCommas(value);
case 'executions':
case 'users':
return abbreviateNumber(value);
@@ -2,6 +2,7 @@
import { Container } from '$lib/layout';
import { CardGrid, Heading, Card, ProgressBarBig } from '$lib/components';
import {
TableRow,
TableBody,
TableCell,
TableCellHead,
@@ -18,6 +19,10 @@
import { total } from '$lib/layout/usage.svelte';
import { BillingPlan } from '$lib/constants.js';
import { base } from '$app/paths';
import { formatCurrency, formatNumberWithCommas } from '$lib/helpers/numbers';
import Collapsible from '$lib/components/collapsible.svelte';
import CollapsibleItem from '$lib/components/collapsibleItem.svelte';
import { getCountryName } from '$lib/helpers/diallingCodes.js';
export let data;
@@ -380,6 +385,70 @@
{/if}
</svelte:fragment>
</CardGrid>
<CardGrid>
<Heading tag="h6" size="7">SMS OTP</Heading>
<p class="text">
Calculated for all SMS OTP sent across your project. Resets at the start of each billing
cycle.
</p>
<svelte:fragment slot="aside">
{#if data.usage.authPhoneTotal}
<div class="u-flex u-main-space-between">
<p>
<span class="heading-level-4"
>{formatNumberWithCommas(data.usage.authPhoneTotal)}</span>
<span class="body-text-1 u-bold">SMS OTPs</span>
</p>
<p class="u-flex u-gap-8 u-cross-center">
<span class="u-color-text-offline">Estimated cost</span>
<span class="body-text-2">
{formatCurrency(data.usage.authPhoneEstimate)}
</span>
</p>
</div>
{#if data.usage.authPhoneCountryBreakdown.length > 0}
<Collapsible>
<CollapsibleItem>
<svelte:fragment slot="title">Region breakdown</svelte:fragment>
<Table noMargin noStyles style="table-layout: auto">
<TableHeader>
<TableCellHead>Region</TableCellHead>
<TableCellHead>Amount</TableCellHead>
<TableCellHead>Estimated cost</TableCellHead>
</TableHeader>
<TableBody>
{#each data.usage.authPhoneCountryBreakdown as phone}
<TableRow>
<TableCell title="Region">
{getCountryName(phone.name)}
</TableCell>
<TableCell title="Usage">
{formatNumberWithCommas(phone.value)}
</TableCell>
<TableCell title="Estimated cost">
{formatCurrency(phone.estimate)}
</TableCell>
</TableRow>
{/each}
</TableBody>
</Table>
</CollapsibleItem>
</Collapsible>
{/if}
{:else}
<Card isDashed>
<div class="u-flex u-cross-center u-flex-vertical u-main-center u-flex">
<span
class="icon-chart-square-bar text-large"
aria-hidden="true"
style="font-size: 32px;" />
<p class="u-bold">No data to show</p>
</div>
</Card>
{/if}
</svelte:fragment>
</CardGrid>
<p class="text u-text-color-gray u-margin-block-start-16">
Metrics are estimates updated every 24 hours and may not accurately reflect your invoice.
</p>