diff --git a/components/src/api/.openapi-generator/FILES b/components/src/api/.openapi-generator/FILES index 4331c1fb..7675b91d 100644 --- a/components/src/api/.openapi-generator/FILES +++ b/components/src/api/.openapi-generator/FILES @@ -35,6 +35,8 @@ models/FlagResponseData.ts models/GetSetupIntentResponse.ts models/HydrateComponentResponse.ts models/InvoiceResponseData.ts +models/ListInvoicesParams.ts +models/ListInvoicesResponse.ts models/PaymentMethodResponseData.ts models/PlanDetailResponseData.ts models/PlanEntitlementResponseData.ts @@ -52,5 +54,7 @@ models/RuleDetailResponseData.ts models/RuleResponseData.ts models/SetupIntentResponseData.ts models/StripeEmbedInfo.ts +models/UpdatePaymentMethodRequestBody.ts +models/UpdatePaymentMethodResponse.ts models/index.ts runtime.ts diff --git a/components/src/api/apis/CheckoutApi.ts b/components/src/api/apis/CheckoutApi.ts index 9b469d8b..cf049705 100644 --- a/components/src/api/apis/CheckoutApi.ts +++ b/components/src/api/apis/CheckoutApi.ts @@ -19,7 +19,10 @@ import type { CheckoutResponse, GetSetupIntentResponse, HydrateComponentResponse, + ListInvoicesResponse, PreviewCheckoutResponse, + UpdatePaymentMethodRequestBody, + UpdatePaymentMethodResponse, } from "../models/index"; import { ApiErrorFromJSON, @@ -32,8 +35,14 @@ import { GetSetupIntentResponseToJSON, HydrateComponentResponseFromJSON, HydrateComponentResponseToJSON, + ListInvoicesResponseFromJSON, + ListInvoicesResponseToJSON, PreviewCheckoutResponseFromJSON, PreviewCheckoutResponseToJSON, + UpdatePaymentMethodRequestBodyFromJSON, + UpdatePaymentMethodRequestBodyToJSON, + UpdatePaymentMethodResponseFromJSON, + UpdatePaymentMethodResponseToJSON, } from "../models/index"; export interface CheckoutRequest { @@ -48,10 +57,19 @@ export interface HydrateComponentRequest { componentId: string; } +export interface ListInvoicesRequest { + limit?: number; + offset?: number; +} + export interface PreviewCheckoutRequest { changeSubscriptionRequestBody: ChangeSubscriptionRequestBody; } +export interface UpdatePaymentMethodRequest { + updatePaymentMethodRequestBody: UpdatePaymentMethodRequestBody; +} + /** * */ @@ -223,6 +241,60 @@ export class CheckoutApi extends runtime.BaseAPI { return await response.value(); } + /** + * List invoices + */ + async listInvoicesRaw( + requestParameters: ListInvoicesRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + const queryParameters: any = {}; + + if (requestParameters["limit"] != null) { + queryParameters["limit"] = requestParameters["limit"]; + } + + if (requestParameters["offset"] != null) { + queryParameters["offset"] = requestParameters["offset"]; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-Schematic-Api-Key"] = await this.configuration.apiKey( + "X-Schematic-Api-Key", + ); // ApiKeyAuth authentication + } + + const response = await this.request( + { + path: `/components/invoices`, + method: "GET", + headers: headerParameters, + query: queryParameters, + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + ListInvoicesResponseFromJSON(jsonValue), + ); + } + + /** + * List invoices + */ + async listInvoices( + requestParameters: ListInvoicesRequest = {}, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.listInvoicesRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } + /** * Preview checkout */ @@ -280,4 +352,62 @@ export class CheckoutApi extends runtime.BaseAPI { ); return await response.value(); } + + /** + * Update payment method + */ + async updatePaymentMethodRaw( + requestParameters: UpdatePaymentMethodRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise> { + if (requestParameters["updatePaymentMethodRequestBody"] == null) { + throw new runtime.RequiredError( + "updatePaymentMethodRequestBody", + 'Required parameter "updatePaymentMethodRequestBody" was null or undefined when calling updatePaymentMethod().', + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters["Content-Type"] = "application/json"; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["X-Schematic-Api-Key"] = await this.configuration.apiKey( + "X-Schematic-Api-Key", + ); // ApiKeyAuth authentication + } + + const response = await this.request( + { + path: `/checkout/paymentmethod/update`, + method: "POST", + headers: headerParameters, + query: queryParameters, + body: UpdatePaymentMethodRequestBodyToJSON( + requestParameters["updatePaymentMethodRequestBody"], + ), + }, + initOverrides, + ); + + return new runtime.JSONApiResponse(response, (jsonValue) => + UpdatePaymentMethodResponseFromJSON(jsonValue), + ); + } + + /** + * Update payment method + */ + async updatePaymentMethod( + requestParameters: UpdatePaymentMethodRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction, + ): Promise { + const response = await this.updatePaymentMethodRaw( + requestParameters, + initOverrides, + ); + return await response.value(); + } } diff --git a/components/src/api/models/ListInvoicesParams.ts b/components/src/api/models/ListInvoicesParams.ts new file mode 100644 index 00000000..466bb2a2 --- /dev/null +++ b/components/src/api/models/ListInvoicesParams.ts @@ -0,0 +1,72 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schematic API + * Schematic API + * + * The version of the OpenAPI document: 0.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * Input parameters + * @export + * @interface ListInvoicesParams + */ +export interface ListInvoicesParams { + /** + * Page limit (default 100) + * @type {number} + * @memberof ListInvoicesParams + */ + limit?: number; + /** + * Page offset (default 0) + * @type {number} + * @memberof ListInvoicesParams + */ + offset?: number; +} + +/** + * Check if a given object implements the ListInvoicesParams interface. + */ +export function instanceOfListInvoicesParams( + value: object, +): value is ListInvoicesParams { + return true; +} + +export function ListInvoicesParamsFromJSON(json: any): ListInvoicesParams { + return ListInvoicesParamsFromJSONTyped(json, false); +} + +export function ListInvoicesParamsFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): ListInvoicesParams { + if (json == null) { + return json; + } + return { + limit: json["limit"] == null ? undefined : json["limit"], + offset: json["offset"] == null ? undefined : json["offset"], + }; +} + +export function ListInvoicesParamsToJSON( + value?: ListInvoicesParams | null, +): any { + if (value == null) { + return value; + } + return { + limit: value["limit"], + offset: value["offset"], + }; +} diff --git a/components/src/api/models/ListInvoicesResponse.ts b/components/src/api/models/ListInvoicesResponse.ts new file mode 100644 index 00000000..edccbd65 --- /dev/null +++ b/components/src/api/models/ListInvoicesResponse.ts @@ -0,0 +1,87 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schematic API + * Schematic API + * + * The version of the OpenAPI document: 0.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +import type { ListInvoicesParams } from "./ListInvoicesParams"; +import { + ListInvoicesParamsFromJSON, + ListInvoicesParamsFromJSONTyped, + ListInvoicesParamsToJSON, +} from "./ListInvoicesParams"; +import type { InvoiceResponseData } from "./InvoiceResponseData"; +import { + InvoiceResponseDataFromJSON, + InvoiceResponseDataFromJSONTyped, + InvoiceResponseDataToJSON, +} from "./InvoiceResponseData"; + +/** + * + * @export + * @interface ListInvoicesResponse + */ +export interface ListInvoicesResponse { + /** + * The returned resources + * @type {Array} + * @memberof ListInvoicesResponse + */ + data: Array; + /** + * + * @type {ListInvoicesParams} + * @memberof ListInvoicesResponse + */ + params: ListInvoicesParams; +} + +/** + * Check if a given object implements the ListInvoicesResponse interface. + */ +export function instanceOfListInvoicesResponse( + value: object, +): value is ListInvoicesResponse { + if (!("data" in value) || value["data"] === undefined) return false; + if (!("params" in value) || value["params"] === undefined) return false; + return true; +} + +export function ListInvoicesResponseFromJSON(json: any): ListInvoicesResponse { + return ListInvoicesResponseFromJSONTyped(json, false); +} + +export function ListInvoicesResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): ListInvoicesResponse { + if (json == null) { + return json; + } + return { + data: (json["data"] as Array).map(InvoiceResponseDataFromJSON), + params: ListInvoicesParamsFromJSON(json["params"]), + }; +} + +export function ListInvoicesResponseToJSON( + value?: ListInvoicesResponse | null, +): any { + if (value == null) { + return value; + } + return { + data: (value["data"] as Array).map(InvoiceResponseDataToJSON), + params: ListInvoicesParamsToJSON(value["params"]), + }; +} diff --git a/components/src/api/models/PaymentMethodResponseData.ts b/components/src/api/models/PaymentMethodResponseData.ts index b274fef4..a1c285aa 100644 --- a/components/src/api/models/PaymentMethodResponseData.ts +++ b/components/src/api/models/PaymentMethodResponseData.ts @@ -14,7 +14,7 @@ import { mapValues } from "../runtime"; /** - * + * The created resource * @export * @interface PaymentMethodResponseData */ diff --git a/components/src/api/models/PlanDetailResponseData.ts b/components/src/api/models/PlanDetailResponseData.ts index 067bfbaa..47c93102 100644 --- a/components/src/api/models/PlanDetailResponseData.ts +++ b/components/src/api/models/PlanDetailResponseData.ts @@ -86,6 +86,12 @@ export interface PlanDetailResponseData { * @memberof PlanDetailResponseData */ id: string; + /** + * + * @type {boolean} + * @memberof PlanDetailResponseData + */ + isDefault: boolean; /** * * @type {BillingPriceResponseData} @@ -132,6 +138,7 @@ export function instanceOfPlanDetailResponseData( if (!("features" in value) || value["features"] === undefined) return false; if (!("icon" in value) || value["icon"] === undefined) return false; if (!("id" in value) || value["id"] === undefined) return false; + if (!("isDefault" in value) || value["isDefault"] === undefined) return false; if (!("name" in value) || value["name"] === undefined) return false; if (!("planType" in value) || value["planType"] === undefined) return false; if (!("updatedAt" in value) || value["updatedAt"] === undefined) return false; @@ -166,6 +173,7 @@ export function PlanDetailResponseDataFromJSONTyped( ), icon: json["icon"], id: json["id"], + isDefault: json["is_default"], monthlyPrice: json["monthly_price"] == null ? undefined @@ -199,6 +207,7 @@ export function PlanDetailResponseDataToJSON( ), icon: value["icon"], id: value["id"], + is_default: value["isDefault"], monthly_price: BillingPriceResponseDataToJSON(value["monthlyPrice"]), name: value["name"], plan_type: value["planType"], diff --git a/components/src/api/models/UpdatePaymentMethodRequestBody.ts b/components/src/api/models/UpdatePaymentMethodRequestBody.ts new file mode 100644 index 00000000..c9879ec6 --- /dev/null +++ b/components/src/api/models/UpdatePaymentMethodRequestBody.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schematic API + * Schematic API + * + * The version of the OpenAPI document: 0.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +/** + * + * @export + * @interface UpdatePaymentMethodRequestBody + */ +export interface UpdatePaymentMethodRequestBody { + /** + * + * @type {string} + * @memberof UpdatePaymentMethodRequestBody + */ + paymentMethodId: string; +} + +/** + * Check if a given object implements the UpdatePaymentMethodRequestBody interface. + */ +export function instanceOfUpdatePaymentMethodRequestBody( + value: object, +): value is UpdatePaymentMethodRequestBody { + if (!("paymentMethodId" in value) || value["paymentMethodId"] === undefined) + return false; + return true; +} + +export function UpdatePaymentMethodRequestBodyFromJSON( + json: any, +): UpdatePaymentMethodRequestBody { + return UpdatePaymentMethodRequestBodyFromJSONTyped(json, false); +} + +export function UpdatePaymentMethodRequestBodyFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): UpdatePaymentMethodRequestBody { + if (json == null) { + return json; + } + return { + paymentMethodId: json["payment_method_id"], + }; +} + +export function UpdatePaymentMethodRequestBodyToJSON( + value?: UpdatePaymentMethodRequestBody | null, +): any { + if (value == null) { + return value; + } + return { + payment_method_id: value["paymentMethodId"], + }; +} diff --git a/components/src/api/models/UpdatePaymentMethodResponse.ts b/components/src/api/models/UpdatePaymentMethodResponse.ts new file mode 100644 index 00000000..67e199b8 --- /dev/null +++ b/components/src/api/models/UpdatePaymentMethodResponse.ts @@ -0,0 +1,83 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Schematic API + * Schematic API + * + * The version of the OpenAPI document: 0.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from "../runtime"; +import type { PaymentMethodResponseData } from "./PaymentMethodResponseData"; +import { + PaymentMethodResponseDataFromJSON, + PaymentMethodResponseDataFromJSONTyped, + PaymentMethodResponseDataToJSON, +} from "./PaymentMethodResponseData"; + +/** + * + * @export + * @interface UpdatePaymentMethodResponse + */ +export interface UpdatePaymentMethodResponse { + /** + * + * @type {PaymentMethodResponseData} + * @memberof UpdatePaymentMethodResponse + */ + data: PaymentMethodResponseData; + /** + * Input parameters + * @type {object} + * @memberof UpdatePaymentMethodResponse + */ + params: object; +} + +/** + * Check if a given object implements the UpdatePaymentMethodResponse interface. + */ +export function instanceOfUpdatePaymentMethodResponse( + value: object, +): value is UpdatePaymentMethodResponse { + if (!("data" in value) || value["data"] === undefined) return false; + if (!("params" in value) || value["params"] === undefined) return false; + return true; +} + +export function UpdatePaymentMethodResponseFromJSON( + json: any, +): UpdatePaymentMethodResponse { + return UpdatePaymentMethodResponseFromJSONTyped(json, false); +} + +export function UpdatePaymentMethodResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean, +): UpdatePaymentMethodResponse { + if (json == null) { + return json; + } + return { + data: PaymentMethodResponseDataFromJSON(json["data"]), + params: json["params"], + }; +} + +export function UpdatePaymentMethodResponseToJSON( + value?: UpdatePaymentMethodResponse | null, +): any { + if (value == null) { + return value; + } + return { + data: PaymentMethodResponseDataToJSON(value["data"]), + params: value["params"], + }; +} diff --git a/components/src/api/models/index.ts b/components/src/api/models/index.ts index 03954526..34ff8658 100644 --- a/components/src/api/models/index.ts +++ b/components/src/api/models/index.ts @@ -33,6 +33,8 @@ export * from "./FlagResponseData"; export * from "./GetSetupIntentResponse"; export * from "./HydrateComponentResponse"; export * from "./InvoiceResponseData"; +export * from "./ListInvoicesParams"; +export * from "./ListInvoicesResponse"; export * from "./PaymentMethodResponseData"; export * from "./PlanDetailResponseData"; export * from "./PlanEntitlementResponseData"; @@ -50,3 +52,5 @@ export * from "./RuleDetailResponseData"; export * from "./RuleResponseData"; export * from "./SetupIntentResponseData"; export * from "./StripeEmbedInfo"; +export * from "./UpdatePaymentMethodRequestBody"; +export * from "./UpdatePaymentMethodResponse"; diff --git a/components/src/components/elements/invoices/Invoices.tsx b/components/src/components/elements/invoices/Invoices.tsx index 097a4d09..830f8ea5 100644 --- a/components/src/components/elements/invoices/Invoices.tsx +++ b/components/src/components/elements/invoices/Invoices.tsx @@ -1,8 +1,10 @@ -import { forwardRef, useMemo } from "react"; +import { forwardRef, useEffect, useState } from "react"; import { useTheme } from "styled-components"; +import { type ListInvoicesResponse } from "../../../api"; import { type FontStyle } from "../../../context"; +import { useEmbed } from "../../../hooks"; import type { RecursivePartial, ElementProps } from "../../../types"; -import { toPrettyDate } from "../../../utils"; +import { formatCurrency, toPrettyDate } from "../../../utils"; import { Icon, Flex, Text } from "../../ui"; interface DesignProps { @@ -53,35 +55,34 @@ function resolveDesignProps(props: RecursivePartial): DesignProps { }; } -export type InvoicesProps = DesignProps; +function formatInvoices(invoices?: ListInvoicesResponse["data"]) { + return (invoices || []).map(({ amountDue, dueDate }) => ({ + ...(dueDate && { date: toPrettyDate(dueDate) }), + amount: formatCurrency(amountDue), + })); +} + +export type InvoicesProps = DesignProps & { + data?: ListInvoicesResponse["data"]; +}; export const Invoices = forwardRef< HTMLDivElement | null, - ElementProps & - RecursivePartial & - React.HTMLAttributes + ElementProps & InvoicesProps & React.HTMLAttributes >(({ className, ...rest }, ref) => { const props = resolveDesignProps(rest); const theme = useTheme(); - const { invoices } = useMemo(() => { - /** - * @TODO: resolve from data - */ - return { - invoices: [ - { - date: toPrettyDate(new Date("2024-05-12")), - amount: 200, - }, - { - date: toPrettyDate(new Date("2024-04-12")), - amount: 200, - }, - ], - }; - }, []); + const { api } = useEmbed(); + + const [invoices, setInvoices] = useState(() => formatInvoices(rest.data)); + + useEffect(() => { + api?.listInvoices().then(({ data }) => { + setInvoices(formatInvoices(data)); + }); + }, [api]); return (
@@ -117,7 +118,7 @@ export const Invoices = forwardRef< } $color={theme.typography[props.date.fontStyle].color} > - {toPrettyDate(date)} + {date} )} @@ -132,7 +133,7 @@ export const Invoices = forwardRef< } $color={theme.typography[props.amount.fontStyle].color} > - ${amount} + {amount} )}