Spaces:
Running
Running
File size: 4,235 Bytes
627798d 1828161 627798d 1828161 03369df 1828161 627798d 1828161 a4c6b8b 1828161 17c8ce5 1828161 627798d 03369df 627798d 03f4c35 627798d 7f41bd4 627798d 03369df 627798d 03369df 627798d 03369df 627798d 1828161 627798d | 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 | <script lang="ts">
import * as Dialog from '$lib/components/ui/dialog/index.js';
import * as Select from '$lib/components/ui/select/index.js';
import { authState } from '$lib/state/auth.svelte';
import { Save } from '@lucide/svelte';
import Button from '../ui/button/button.svelte';
import Spinner from '../loading/Spinner.svelte';
let { open = $bindable(false) }: { open: boolean } = $props();
const planColors = {
team: 'bg-purple-500/10 text-purple-600',
enterprise: 'bg-green-500/10 text-green-600'
};
let billingOption = $derived(authState.user?.billingOption || 'personal');
let selectedOrg = $derived(authState.user?.orgs?.find((org) => org.name === billingOption));
let loading = $state.raw<boolean>(false);
async function saveSettings() {
if (loading) return;
loading = true;
await new Promise((resolve) => setTimeout(resolve, 600));
loading = false;
if (billingOption === 'personal') {
localStorage.removeItem('hf-playground-billing-option');
} else {
localStorage.setItem('hf-playground-billing-option', selectedOrg?.name ?? '');
}
authState.user!.billingOption = billingOption;
open = false;
}
function resetSettings() {
billingOption = authState.user?.billingOption || 'personal';
}
</script>
<Dialog.Root
bind:open
onOpenChange={(value) => {
if (!value) {
resetSettings();
}
}}
>
<Dialog.Content class="max-w-sm! p-0!">
<Dialog.Header class="mb-0 rounded-none border-b p-5">
<Dialog.Title>Billing Settings</Dialog.Title>
<Dialog.Description>Manage your billing information.</Dialog.Description>
</Dialog.Header>
<Dialog.Description class="mt-0 px-5 pb-5">
<div>
<p class="mb-1.5 font-medium text-primary">
Billing option <span class="font-normal text-muted-foreground"
>(personal or organization)</span
>
</p>
<Select.Root type="single" bind:value={billingOption}>
<Select.Trigger
class="flex w-full items-center justify-start gap-2 py-5!"
disabled={loading}
>
{#if billingOption === 'personal'}
<img
src={authState.user?.avatarUrl}
alt={authState.user?.name}
class="size-5 rounded"
/>
{authState.user?.name}
<span class="text-xs text-muted-foreground">(Personal Account)</span>
{:else}
<img
src={selectedOrg?.avatarUrl}
alt={selectedOrg?.fullname || selectedOrg?.name}
class="size-5 rounded"
/>
{selectedOrg?.fullname || selectedOrg?.name}
{#if selectedOrg?.plan}
<span
class="rounded px-1 py-0.5 text-[10px] font-semibold {planColors[
selectedOrg?.plan as keyof typeof planColors
]} uppercase"
>
{selectedOrg?.plan}
</span>
{/if}
{/if}
</Select.Trigger>
<Select.Content class="space-y-3!">
<Select.Item value="personal" class="p-2.5!">
<div class="flex items-center gap-2">
<img
src={authState.user?.avatarUrl}
alt={authState.user?.name}
class="size-5 rounded"
/>
{authState.user?.name}
<span class="text-xs text-muted-foreground">(Personal Account)</span>
</div>
</Select.Item>
{#each authState.user?.orgs as org}
<Select.Item value={org.name} class="p-2.5!">
<div class="flex items-center gap-2 text-sm">
<img src={org.avatarUrl} alt={org.fullname || org.name} class="size-5 rounded" />
{org.fullname || org.name}
{#if org.plan}
<span
class="rounded px-1 py-0.5 text-[10px] font-semibold {planColors[
org.plan as keyof typeof planColors
]} uppercase"
>
{org.plan}
</span>
{/if}
</div>
</Select.Item>
{/each}
</Select.Content>
</Select.Root>
</div>
<div class="mt-5 flex items-center justify-end gap-3">
<Button variant="outline" onclick={resetSettings}>Reset</Button>
<Button class="flex-1" onclick={saveSettings}>
{#if loading}
<Spinner className="text-lg" />
Saving...
{:else}
<Save />
Save settings
{/if}
</Button>
</div>
</Dialog.Description>
</Dialog.Content>
</Dialog.Root>
|