diff --git a/e2e/steps/pro-project.ts b/e2e/steps/pro-project.ts
index 05c95895f..438caebef 100644
--- a/e2e/steps/pro-project.ts
+++ b/e2e/steps/pro-project.ts
@@ -14,12 +14,15 @@ export async function enterCreditCard(page: Page) {
state: 'visible'
});
await page.getByPlaceholder('cardholder').fill('Test User');
- const stripe = page.frameLocator('[title="Secure payment input frame"]');
+ const stripe = page.locator('[title="Secure payment input frame"]').nth(0).contentFrame();
await stripe.locator('id=Field-numberInput').fill('4242424242424242');
await stripe.locator('id=Field-expiryInput').fill('1250');
await stripe.locator('id=Field-cvcInput').fill('123');
await stripe.locator('id=Field-countryInput').selectOption('DE');
await dialog.getByRole('button', { name: 'Add', exact: true }).click();
+ await page.locator('id=state-picker').click(); // open dropdown
+ await page.getByRole('option', { name: 'Alabama' }).click();
+ await dialog.getByRole('button', { name: 'Add', exact: true }).click();
await dialog.waitFor({
state: 'hidden'
});
diff --git a/package.json b/package.json
index f41ea9556..77499856c 100644
--- a/package.json
+++ b/package.json
@@ -22,11 +22,11 @@
},
"dependencies": {
"@ai-sdk/svelte": "^1.1.24",
- "@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2289",
+ "@appwrite.io/console": "^1.10.0",
"@appwrite.io/pink-icons": "0.25.0",
- "@appwrite.io/pink-icons-svelte": "^2.0.0-RC.1",
+ "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@e6b154b",
"@appwrite.io/pink-legacy": "^1.0.3",
- "@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@95bdb79",
+ "@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@e6b154b",
"@popperjs/core": "^2.11.8",
"@sentry/sveltekit": "^8.38.0",
"@stripe/stripe-js": "^3.5.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3c18de482..7aa3f74a5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -12,20 +12,20 @@ importers:
specifier: ^1.1.24
version: 1.1.24(svelte@5.25.3)(zod@3.24.3)
'@appwrite.io/console':
- specifier: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2289
- version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2289
+ specifier: ^1.10.0
+ version: 1.10.0
'@appwrite.io/pink-icons':
specifier: 0.25.0
version: 0.25.0
'@appwrite.io/pink-icons-svelte':
- specifier: ^2.0.0-RC.1
- version: https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-icons-svelte@12707b9(svelte@5.25.3)
+ specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@e6b154b
+ version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@e6b154b(svelte@5.25.3)
'@appwrite.io/pink-legacy':
specifier: ^1.0.3
version: 1.0.3
'@appwrite.io/pink-svelte':
- specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@95bdb79
- version: https://pkg.vc/-/@appwrite/%40appwrite.io%2Fpink-svelte@95bdb79(svelte@5.25.3)
+ specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@e6b154b
+ version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@e6b154b(svelte@5.25.3)
'@popperjs/core':
specifier: ^2.11.8
version: 2.11.8
@@ -257,17 +257,16 @@ packages:
'@analytics/type-utils@0.6.2':
resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==}
- '@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2289':
- resolution: {tarball: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2289}
- version: 1.9.0
+ '@appwrite.io/console@1.10.0':
+ resolution: {integrity: sha512-7ErAZgS0djmB41ZFXPTlJH5kBNvJeKv2UHOEcI6uAOyXO4UoVWlhQk0D/3oktNylwOsr/K/98EWfsUDeYbq68w==}
'@appwrite.io/pink-icons-svelte@2.0.0-RC.1':
resolution: {integrity: sha512-iLFlV55hj8mGuAbmxJGenxN5RaZMmVT4GJb9dv/MP1xBAtYibFq7JvBcxm18qV2KU8c31Rntf+Ub4GL7HwqTYg==}
peerDependencies:
svelte: ^4.0.0
- '@appwrite.io/pink-icons-svelte@https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-icons-svelte@12707b9':
- resolution: {tarball: https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-icons-svelte@12707b9}
+ '@appwrite.io/pink-icons-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@e6b154b':
+ resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@e6b154b}
version: 2.0.0-RC.1
peerDependencies:
svelte: ^4.0.0
@@ -281,8 +280,8 @@ packages:
'@appwrite.io/pink-legacy@1.0.3':
resolution: {integrity: sha512-GGde5fmPhs+s6/3aFeMPc/kKADG/gTFkYQSy6oBN8pK0y0XNCLrZZgBv+EBbdhwdtqVEWXa0X85Mv9w7jcIlwQ==}
- '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/%40appwrite.io%2Fpink-svelte@95bdb79':
- resolution: {tarball: https://pkg.vc/-/@appwrite/%40appwrite.io%2Fpink-svelte@95bdb79}
+ '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@e6b154b':
+ resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@e6b154b}
version: 2.0.0-RC.2
peerDependencies:
svelte: ^4.0.0
@@ -3646,13 +3645,13 @@ snapshots:
'@analytics/type-utils@0.6.2': {}
- '@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2289': {}
+ '@appwrite.io/console@1.10.0': {}
'@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)':
dependencies:
svelte: 5.25.3
- '@appwrite.io/pink-icons-svelte@https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-icons-svelte@12707b9(svelte@5.25.3)':
+ '@appwrite.io/pink-icons-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@e6b154b(svelte@5.25.3)':
dependencies:
svelte: 5.25.3
@@ -3665,7 +3664,7 @@ snapshots:
'@appwrite.io/pink-icons': 1.0.0
the-new-css-reset: 1.11.3
- '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/%40appwrite.io%2Fpink-svelte@95bdb79(svelte@5.25.3)':
+ '@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@e6b154b(svelte@5.25.3)':
dependencies:
'@appwrite.io/pink-icons-svelte': 2.0.0-RC.1(svelte@5.25.3)
'@floating-ui/dom': 1.6.13
diff --git a/src/app.html b/src/app.html
index 18a92b1fa..7ca4eefe8 100644
--- a/src/app.html
+++ b/src/app.html
@@ -5,9 +5,9 @@
-
-
-
+
+
+
%sveltekit.head%
@@ -40,13 +40,13 @@
(null);
onMount(() => {
- projects = page.data.projects?.projects || [];
+ projects = page.data.allProjects?.projects || [];
});
let projectsToArchive = $derived(
diff --git a/src/lib/components/billing/paymentBoxes.svelte b/src/lib/components/billing/paymentBoxes.svelte
index be241fdf7..27719cba5 100644
--- a/src/lib/components/billing/paymentBoxes.svelte
+++ b/src/lib/components/billing/paymentBoxes.svelte
@@ -5,6 +5,8 @@
import { initializeStripe, unmountPaymentElement } from '$lib/stores/stripe';
import { Badge, Card, Layout } from '@appwrite.io/pink-svelte';
import type { PaymentMethodData } from '$lib/sdk/billing';
+ import type { PaymentMethod } from '@stripe/stripe-js';
+ import StatePicker from './statePicker.svelte';
export let methods: PaymentMethodData[];
export let group: string;
@@ -14,6 +16,9 @@
export let disabledCondition: string = null;
export let setAsDefault = false;
export let showSetAsDefault = false;
+ export let showState = false;
+ export let paymentMethod: PaymentMethod | null = null;
+ export let state: string = '';
let element: HTMLDivElement;
let loader: HTMLDivElement;
@@ -79,25 +84,29 @@
{/each}
{#if group === '$new'}
-
+ {#if showState}
+
+ {:else}
+
-
-
- {#if showSetAsDefault}
-
+ {#if showSetAsDefault}
+
+ {/if}
{/if}
{/if}
diff --git a/src/lib/components/billing/paymentModal.svelte b/src/lib/components/billing/paymentModal.svelte
index c79602517..72accfd10 100644
--- a/src/lib/components/billing/paymentModal.svelte
+++ b/src/lib/components/billing/paymentModal.svelte
@@ -2,12 +2,14 @@
import { FakeModal } from '$lib/components';
import { InputText, Button } from '$lib/elements/forms';
import { createEventDispatcher, onMount } from 'svelte';
- import { initializeStripe, submitStripeCard } from '$lib/stores/stripe';
+ import { initializeStripe, setPaymentMethod, submitStripeCard } from '$lib/stores/stripe';
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { addNotification } from '$lib/stores/notifications';
import { page } from '$app/state';
import { Spinner } from '@appwrite.io/pink-svelte';
+ import type { PaymentMethod } from '@stripe/stripe-js';
+ import StatePicker from './statePicker.svelte';
export let show = false;
@@ -16,10 +18,36 @@
let name: string;
let error: string;
let modal: FakeModal;
+ let showState: boolean = false;
+ let state: string = '';
+ let paymentMethod: PaymentMethod | null = null;
async function handleSubmit() {
try {
+ if (showState && !state) {
+ throw Error('Please select a state');
+ }
+
+ if (showState) {
+ const card = await setPaymentMethod(paymentMethod.id, name, state);
+ modal.closeModal();
+ await invalidate(Dependencies.PAYMENT_METHODS);
+ dispatch('submit', card);
+ addNotification({
+ type: 'success',
+ message: 'A new payment method has been added to your account'
+ });
+ return;
+ }
+
const card = await submitStripeCard(name, page?.params?.organization ?? null);
+ if (card && Object.hasOwn(card, 'id')) {
+ if ((card as PaymentMethod).card.country === 'US') {
+ paymentMethod = card as PaymentMethod;
+ showState = true;
+ return;
+ }
+ }
modal.closeModal();
await invalidate(Dependencies.PAYMENT_METHODS);
dispatch('submit', card);
@@ -73,28 +101,30 @@
bind:error
onSubmit={handleSubmit}>
-
-
-
- {#if isLoading}
-
-
+ {#if showState}
+
+ {:else}
+
+
+ {#if isLoading}
+
+
+
+ {/if}
+
+
- {/if}
-
-
-
-
+ {/if}
(show = false)}>Cancel
diff --git a/src/lib/components/billing/state.ts b/src/lib/components/billing/state.ts
new file mode 100644
index 000000000..d3f08a113
--- /dev/null
+++ b/src/lib/components/billing/state.ts
@@ -0,0 +1,238 @@
+export const states: Array<{ name: string; abbreviation: string }> = [
+ {
+ name: 'Alabama',
+ abbreviation: 'AL'
+ },
+ {
+ name: 'Alaska',
+ abbreviation: 'AK'
+ },
+ {
+ name: 'American Samoa',
+ abbreviation: 'AS'
+ },
+ {
+ name: 'Arizona',
+ abbreviation: 'AZ'
+ },
+ {
+ name: 'Arkansas',
+ abbreviation: 'AR'
+ },
+ {
+ name: 'California',
+ abbreviation: 'CA'
+ },
+ {
+ name: 'Colorado',
+ abbreviation: 'CO'
+ },
+ {
+ name: 'Connecticut',
+ abbreviation: 'CT'
+ },
+ {
+ name: 'Delaware',
+ abbreviation: 'DE'
+ },
+ {
+ name: 'District Of Columbia',
+ abbreviation: 'DC'
+ },
+ {
+ name: 'Federated States Of Micronesia',
+ abbreviation: 'FM'
+ },
+ {
+ name: 'Florida',
+ abbreviation: 'FL'
+ },
+ {
+ name: 'Georgia',
+ abbreviation: 'GA'
+ },
+ {
+ name: 'Guam',
+ abbreviation: 'GU'
+ },
+ {
+ name: 'Hawaii',
+ abbreviation: 'HI'
+ },
+ {
+ name: 'Idaho',
+ abbreviation: 'ID'
+ },
+ {
+ name: 'Illinois',
+ abbreviation: 'IL'
+ },
+ {
+ name: 'Indiana',
+ abbreviation: 'IN'
+ },
+ {
+ name: 'Iowa',
+ abbreviation: 'IA'
+ },
+ {
+ name: 'Kansas',
+ abbreviation: 'KS'
+ },
+ {
+ name: 'Kentucky',
+ abbreviation: 'KY'
+ },
+ {
+ name: 'Louisiana',
+ abbreviation: 'LA'
+ },
+ {
+ name: 'Maine',
+ abbreviation: 'ME'
+ },
+ {
+ name: 'Marshall Islands',
+ abbreviation: 'MH'
+ },
+ {
+ name: 'Maryland',
+ abbreviation: 'MD'
+ },
+ {
+ name: 'Massachusetts',
+ abbreviation: 'MA'
+ },
+ {
+ name: 'Michigan',
+ abbreviation: 'MI'
+ },
+ {
+ name: 'Minnesota',
+ abbreviation: 'MN'
+ },
+ {
+ name: 'Mississippi',
+ abbreviation: 'MS'
+ },
+ {
+ name: 'Missouri',
+ abbreviation: 'MO'
+ },
+ {
+ name: 'Montana',
+ abbreviation: 'MT'
+ },
+ {
+ name: 'Nebraska',
+ abbreviation: 'NE'
+ },
+ {
+ name: 'Nevada',
+ abbreviation: 'NV'
+ },
+ {
+ name: 'New Hampshire',
+ abbreviation: 'NH'
+ },
+ {
+ name: 'New Jersey',
+ abbreviation: 'NJ'
+ },
+ {
+ name: 'New Mexico',
+ abbreviation: 'NM'
+ },
+ {
+ name: 'New York',
+ abbreviation: 'NY'
+ },
+ {
+ name: 'North Carolina',
+ abbreviation: 'NC'
+ },
+ {
+ name: 'North Dakota',
+ abbreviation: 'ND'
+ },
+ {
+ name: 'Northern Mariana Islands',
+ abbreviation: 'MP'
+ },
+ {
+ name: 'Ohio',
+ abbreviation: 'OH'
+ },
+ {
+ name: 'Oklahoma',
+ abbreviation: 'OK'
+ },
+ {
+ name: 'Oregon',
+ abbreviation: 'OR'
+ },
+ {
+ name: 'Palau',
+ abbreviation: 'PW'
+ },
+ {
+ name: 'Pennsylvania',
+ abbreviation: 'PA'
+ },
+ {
+ name: 'Puerto Rico',
+ abbreviation: 'PR'
+ },
+ {
+ name: 'Rhode Island',
+ abbreviation: 'RI'
+ },
+ {
+ name: 'South Carolina',
+ abbreviation: 'SC'
+ },
+ {
+ name: 'South Dakota',
+ abbreviation: 'SD'
+ },
+ {
+ name: 'Tennessee',
+ abbreviation: 'TN'
+ },
+ {
+ name: 'Texas',
+ abbreviation: 'TX'
+ },
+ {
+ name: 'Utah',
+ abbreviation: 'UT'
+ },
+ {
+ name: 'Vermont',
+ abbreviation: 'VT'
+ },
+ {
+ name: 'Virgin Islands',
+ abbreviation: 'VI'
+ },
+ {
+ name: 'Virginia',
+ abbreviation: 'VA'
+ },
+ {
+ name: 'Washington',
+ abbreviation: 'WA'
+ },
+ {
+ name: 'West Virginia',
+ abbreviation: 'WV'
+ },
+ {
+ name: 'Wisconsin',
+ abbreviation: 'WI'
+ },
+ {
+ name: 'Wyoming',
+ abbreviation: 'WY'
+ }
+];
diff --git a/src/lib/components/billing/statePicker.svelte b/src/lib/components/billing/statePicker.svelte
new file mode 100644
index 000000000..839b31dd9
--- /dev/null
+++ b/src/lib/components/billing/statePicker.svelte
@@ -0,0 +1,44 @@
+
+
+
+ {#if card}
+
+
+
+ ending in {card.card?.last4}
+
+
+ {card.card.country}
+ {card.billing_details.address.postal_code}
+
+
+ {/if}
+
+
+
+ To complete the billing information, select your state so we can apply the correct taxes
+ and meet U.S. legal requirements.
+
+
+
+ ({
+ label: state.name,
+ value: state.abbreviation,
+ id: state.abbreviation.toLowerCase()
+ }))} />
+
diff --git a/src/lib/components/code.svelte b/src/lib/components/code.svelte
index f08dee3da..9e4e11636 100644
--- a/src/lib/components/code.svelte
+++ b/src/lib/components/code.svelte
@@ -8,7 +8,8 @@
-
-
+
{#if progressCard}
{projectOption.name}
{/each}
-
-
+ {#if project}
+
+ {/if}
{:else if $isSmallViewport}